0

I am writing a simple program, that prints some text on the screen, overlaying the other windows.

#include "stdafx.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
HWND hwnd = GetDesktopWindow();
HDC hdc;

    RECT rect;
//LPRECT rect = new RECT;
wchar_t text[] = L"test";

GetClientRect(hwnd, &rect);

do{
    hdc = GetWindowDC(hwnd);
    SetBkMode(hdc, TRANSPARENT);
    SetTextColor(hdc, RGB(100, 100, 100));
    DrawText(hdc, text, -1, &rect, DT_NOCLIP);
    ReleaseDC(hwnd, hdc);
    Sleep(15);
} while (1);
return 0;
}

The problem is that I would like the background of the printed text to be transparent, but SetBkMode does not seem to work (it actually makes no difference if I set it to OPAQUE or TRANSPARENT) so I get a solid background. Any ideas? What am I missing?

edit: Changed LPRECT to RECT, as suggested.

edit: using transparent window:

creating window:

CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED,                  // extended style
    (LPCWSTR)WINDOW_CLASS_NAME,     // class
    L"test", // title
     NULL,
    0, 0,     // initial x,y
    400, 300,  // initial width, height
    NULL,     // handle to parent 
    NULL,     // handle to menu
    hinstance,// instance of this application
    NULL)

globals:

wchar_t tst_Str[] = L"TEST";

WM_PAINT:

    PAINTSTRUCT ps;
    HDC hdc;         
    RECT rc;

    hdc = BeginPaint(hwnd, &ps);

    GetClientRect(hwnd, &rc);
    SetTextColor(hdc, RGB(255, 0, 0));
    DrawText(hdc, tst_Str, -1, &rc,NULL);

    EndPaint(hwnd, &ps);
    return 0;
Werner Henze
  • 16,404
  • 12
  • 44
  • 69
acoundexist
  • 1
  • 1
  • 2
  • Just so you don't keep having pointless memory leaks, `RECT rec; GetClientRect(hwnd, &rect);` – chris Jun 22 '14 at 02:59
  • 5
    Create your own window and draw into that. Don't draw into a window that is not yours. As you have seen, the results are unreliable if you do that. – Raymond Chen Jun 22 '14 at 03:02
  • Thanks for the suggestions. The whole point of that program is to overlay text on other windows. Creating a new window beats the purpose of writing that program on the first place. Isn't there a reliable way of doing this? – acoundexist Jun 22 '14 at 03:21
  • 5
    The window you create can be transparent. See [Layered Windows](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632599(v=vs.85).aspx#layered) for more information. – Jonathan Potter Jun 22 '14 at 03:36
  • The way I am doing this, allows me to draw over the fullscreen windows etc. Using a transparent window won't allow me to do that. So.. Is my only option to use something like this: [link](http://stackoverflow.com/questions/925981/overlaying-on-a-3d-fullscreen-application)? – acoundexist Jun 22 '14 at 09:45
  • Why wouldn't it? You create a transparent window that overlays the window you want to draw on, and then you draw to it. – Jonathan Potter Jun 22 '14 at 10:12

2 Answers2

0

Windows are responsible for painting themselves. The system is not designed to allow external parties to draw on other windows in the manner you are attempting. You will have to recalibrate your expectations.

If you wish to draw something you should create a window and draw on it. You are at liberty to make the window a transparent layered window and position your drawing so that it appears on top of another window. And you also gain the benefit that you don't need to run a busy loop. You can paint in the standard way, in response to WM_PAINT messages.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks for the reply, but I was not able to create a transparent window and draw on it. I already tried to CreateWindowEx with WS_EX_LAYERED, but I wasn't able to draw anything on the screen. Could you guide me to the right way of doing this? Also, will I be able to use that technique to draw over a fullscreen window? – acoundexist Jun 23 '14 at 01:11
  • When did you draw? In response to WM_PAINT? – David Heffernan Jun 23 '14 at 06:01
0

To make a layered window appear on the desktop, you have to call SetLayeredWindowAttributes function, for example

   SetLayeredWindowAttributes(hWnd,
           RGB(255, 255, 255),         // The transparent color
           128,                        // Opacity of the window
           LWA_ALPHA | LWA_COLORKEY);  // Enable both features

This example will make portions of the window with white color completely transparent. Parameter bAlpha specifies the opacity of the window (the pixels not affected with crKey).

Here's a screen shot of such window with Test text floating over browser window with this question:

Semi-transparent text “Test” floating over the desktop

If you create your window without border, using these window styles: WS_POPUP | WS_SYSMENU, then it will look like on the screen shot. I included WS_SYSMENU to have the standard window menu in the taskbar. To force the taskbar to display a button for popup window, include WS_EX_APPWINDOW extended style.

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68