Transparent transparent window, no drag and drop [C ++]
There are several ways to do this using .NET (like this ), but I haven't been able to reproduce the same thing using only C ++ win32.
My approach was to use WS_EX_LAYERED
, then SetLayeredWindowAttributes
, to have some control over the opacity, but I read more and I found out that it is WS_EX_TRANSPARENT
"better" - it allows for click-through.
However, using
hWnd = CreateWindowEx(WS_EX_TRANSPARENT, fooName, fooName, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPSIBLINGS, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
doesn't seem to do the trick. There is one more thing, once I get the click-through window, can I use
PostMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(GET_X_LPARAM(lParam) ,GET_Y_LPARAM(lParam)));
to block the drag state while passing through?
Note: The drag state is created using the touchpad device.
source to share
Scrolling:
Indeed, WS_EX_TRANSPARENT
in itself is a big lie; so i used WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST
.
I have control over the opacity using SetLayeredWindowAttributes(hWnd, 0, (255 * opacity) / 100, LWA_ALPHA);
(rather unorthodox, but it works) and I also use
SetCapture(hWnd);
ShowCursor(false);
to grab the mouse focus as the top-level window doesn't release and hides the cursor.
I also tried to focus on the window by adding WM_NCACTIVATE
and WM_ACTIVEAPP
:
case WM_MOUSEMOVE:
fprintf(stdout, "Mouse move [%d][%d]\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
SetForegroundWindow(hWnd);
break;
case WM_LBUTTONDOWN:
printf("Mouse click\n");
SetForegroundWindow(hWnd);
break;
case WM_NCACTIVATE:
return false;
case WM_ACTIVATEAPP:
wActive = (bool)wParam;
if(wActive == false)
return 0;
else
return DefWindowProc(hWnd, message, wParam, lParam);
The drag part :
In my particular case, I wanted to "pop" the window under the (child window) without losing focus; unfortunately, any mouse click event will change focus to this child window - the solution would be as follows:
- set a timer (
SetTimer
,WM_TIMER
) and check if your application has lost focus or not. - set a binding to your window and reply to the message with a
WM_KILLFOCUS
messageWM_SETFOCUS
source to share
Lately I've been working on creating windows with opacity and click-through properties and I just tried this:
HWND hWnd = CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT, cName, wTitle, NULL, 0, 0, 640, 480, NULL, 0, GetModuleHandle(NULL), 0);
You cannot close it, collapse it, drag it, etc. - every click you make goes straight ahead as if it didn't. Then just change the opacity using:
SetLayeredWindowAttributes(hWnd, 0, 100, LWA_ALPHA);
It achieves everything in your question, if I understood it correctly.
Maybe your approach didn't work because it WS_EX_LAYERED
must be defined if you are using WS_EX_TRANSPARENT
.
source to share