0

I have a layered window, having the size of the screen but being almost completely transparent. (apart from a little cross drawn where the user clicks)

wc.style        = 0;
wc.lpfnWndProc  = (WNDPROC) wnd_top_rect_proc;
wc.cbClsExtra   = 0;
wc.cbWndExtra   = 0;
wc.hInstance    = hInst;
wc.hIcon        = NULL;
wc.hCursor      = LoadCursor(hInst, IDC_CROSS);
wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName= L"POGO_WND_TOP";
RegisterClass(&wc);

hWnd = CreateWindowEx(
WS_EX_TOPMOST | WS_EX_LAYERED,
L"POGO_WND_TOP",        //class name
NULL,                   //wnd name
WS_POPUP,               //style
0, 0,                   //x, y
screen.right-screen.left,//w
screen.bottom-screen.top,//h
g_hWnd,                 //parent
NULL,                   //menu
hInst,                  //instance
NULL);                  //lparam
SetLayeredWindowAttributes(hWnd, WND_TOP_BG, 0, LWA_COLORKEY);
ShowWindow(hWnd, SW_SHOW);

How can I set a custom cursor for this window, or for the whole desktop? I have specified a class cursor in the window class but it does not display it (I expect this to be because of the transparency)
Also, I'd like to know how is actually transparency manged in windows: why can't I get WM_LBUTTON messages if the mouse is in the transparent area of the window? Isn't there any way to get transparent areas of the window working just like colored area?

1 Answers1

0

To set the cursor, you use the surprisingly obviously named function SetCursor.

Pretty much SetCursor(wc.hCursor) should do that.

It is a shared resource, so you really shouldn't change the cursor for a region outside of your own window. Or, as it's put in the link:

The cursor is a shared resource. A window should set the cursor shape only when the cursor is in its client area or when the window is capturing mouse input. In systems without a mouse, the window should restore the previous cursor before the cursor leaves the client area or before it relinquishes control to another window.

Also:

If your application must set the cursor while it is in a window, make sure the class cursor for the specified window's class is set to NULL. If the class cursor is not NULL, the system restores the class cursor each time the mouse is moved.

I haven't looked too deeply into it, I expect that a fully transparent region of a window doesn't actually capture mouse-clicks, since there is nothing visible from that window [of course, you could in theory click invisible things, but one of the points of transparency is to create windows that are odd shapes, and if you had to let the application handle the detection of "is it in my window or the guy underneath me", you can see how that would get mismanaged - so if the window is not contributing to the actual "displayed stuff", mouse clicks should be passed to the layer underneath which provides a contribution (in other words is not 100% transparent)]. So, as per the comment, try setting the transparency value to "just a notch away from 100% transparent".

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • SetCursor doesn't work as other windows will set it again to another cursor. About window transparency, we could just put some boolean that would let us enable/disable the self control of the window shape but I guess that's not how windows work.. – Jean Gabin Sep 29 '13 at 14:40
  • So, when your window comes into focus, you will need to call `SetCursor` again. I'm pretty sure there is support for that in the framework. – Mats Petersson Sep 29 '13 at 14:44
  • Well I actually finally just made a classic window instead of a layered one, with a NULL_BRUSH as a background, and destroy/recreating it (anyway I had to). But I'd still be pleased to find a way to control a transparent window like a regular one, it's odd that I can't find anything about it.. – Jean Gabin Sep 29 '13 at 14:52
  • Like I said above, if the window is completely transparent everywhere, it will not appear to be a "window" at all (at least that's my understanding). – Mats Petersson Sep 29 '13 at 14:54