windows API : Pass mouse click through windows - c++

I'm working on an on-screen Annotation flutter desktop app where I want to let the mouse click pass through to the window beneath my window. Now Basically I know that there is a win32api window that hosting the flutter content.
Also, I was able to find a way by using SetWindowLong and applying GWL_EXSTYLE to my window.
int extendedStyleSettings = GetWindowLong(window,GWL_EXSTYLE);
SetWindowLong(window,GWL_EXSTYLE, extendedStyleSettings | WS_EX_LAYERED | WS_EX_TRANSPARENT);
SetLayeredWindowAttributes(window, 0, 255, LWA_ALPHA);
The problem with this solution is I don't know how to restore mouse event on windows or keep it active on my window because I can't do anything I can't click on the border, caption bar, system menu, or minimize/maximize/close buttons.
It just completely disables my window

Related

WS_EX_LAYERED window appearing invisible over RDP

I have developed a screen capture application for Windows using pure Win32 - no MFC or ATL.
To do this, I am using two top-level layered windows - one (entirely transparent) to capture mouse events like dragging, and another (semi-transparent) to act as a highlight rectangle. When a user is selecting the area of their screen to grab, I used SetWindowPos() to change the size and position of the semi-transparent highlight window.
This works fine on a physical device, but I have discovered that on a virtual machine (Windows 7) over RDP, my semi-transparent window doesn't show at all. I can still capture the screen, but not provide visual feedback to the user mid-capture.
I have tried altering my RDP settings to use 32bpp, but that doesn't help.
I am using:
COLORRED highlightColor = RGB(0, 0, 255);
SetLayeredWindowAttributes(hWnd, highlightColor, 255*0.6, LWA_ALPHA);
in the WM_CREATE event for my highlight window.
Does anybody know how to display a semi-transparent layered window over RDP on a VM?

partially click through on layered windows win32

In using layered windows in win32 or atl/wtl c++ if I set the main window's alpha to 0 and paint on the child, fake window so that it is viewable and click the window, the entire window is a click through.
I want to be able to make only regions of the window click through, not the entire window, let's say if I want to paint a rounded corner window, I make the bottom/main window to be click through but I don't want the upper "fake" window to be click through, i want to be able to click on it. How do I do that?
Where I am so far:
In the OnInitDialog function of the main window :
::SetWindowLong( m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
BYTE bTran = 0;
::SetLayeredWindowAttributes( m_hWnd, 0, bTran, LWA_ALPHA);
and when I create the fake window:
m_hFakeWnd = ::CreateWindowEx( WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE | WS_EX_LEFT
, m_strWndClassName
, NULL
, WS_VISIBLE | WS_OVERLAPPED
, rc.left
, rc.top
, rc.Width()
, rc.Height()
, GetSafeHwnd()
, NULL
, ::GetModuleHandle(NULL)
, NULL
);
IF, I set eliminate the WS_EX_TRANSPARENT flag the fake window is click-able while the main is click through, but! it doesn't respond to anything! click/drag. none.
It sounds like you are covering another window solely for the purpose of intercepting clicks?
Anyway, you need to handle window's WM_NCHITTEST message in order to be able to let system know that particular position is transparent, in which case you return HTTRANSPARENT:
In a window currently covered by another window in the same thread (the message will be sent to underlying windows in the same thread until one of them returns a code that is not HTTRANSPARENT).
Use alpha 1 instead of 0 in the regions you want to accept clicks. The window will still be completely invisible but the areas of alpha 1 will register clicks and mouse movements as normal.
Note that to get per-pixel alpha you'll need to use UpdateLayeredWindow rather than SetLayeredWindowAttributes.
Make two windows, one with click-through properties and another with normal ones.

Fullscreen mode for ActiveX control

I tried to implement a switch-to-fullscreen mode for an ActiveX control. This currently works by removing and hiding the parent window and changing my control's placement and position.
However, I have a problem with switching between applications while the control is in fullscreen mode. If I switch to another application and then click on my window area (not in the taskbar), it seems to not be activated. You can see in the taskbar, that another application still has the highlight and on the main screen, my window is partly hidden behind the taskbar unless it has the focus.
I process the WM_LBUTTONDOWN window message to detect if my window is clicked. And I already tried to call the following WINAPI functions:
::ShowWindow(m_hWnd, SW_RESTORE);
::SwitchToThisWindow(m_hWnd, FALSE);
::SetForegroundWindow(m_hWnd);
::SetActiveWindow(m_hWnd);
::SetFocus(m_hWnd);
::BringWindowToTop(m_hWnd);
::SetWindowPos(m_hWnd, HWND_TOP, m_monitorInfo.rcMonitor.left, m_monitorInfo.rcMonitor.top, m_monitorInfo.rcMonitor.right, m_monitorInfo.rcMonitor.bottom, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); // SWP_NOACTIVATE, SWP_NOOWNERZORDER
I also tried to use ::SetWindowLongW(m_hWnd, GWL_STYLE, WS_VISIBLE); which surprisingly gave my window the focus back. But it then suddenly disappeared when trying to switch back from fullscreen mode again.
I have no idea why there are so many different functions that for me seem all to do roughly the same. But it doesn't matter as none of them worked anyway.
What is the/one correct way to behave my control correctly?
Windows might be getting a bit confused because you're filling the screen with a child window, but you want it to behave like a top-level (overlapped) window. The host application is probably not getting activated because you've hidden its window.
You might do better to create a new top-level full-screen window for full-screen mode. If this is owned by the top-level window that (ultimately) hosts your control then your new window will always be above it, so you don't need to hide the existing window. Activation should just work. In short, you want your window to behave like a pop-up modal dialog.
Adobe's flash player seems to do something similar. Full-screen playback is in a window of class ShockwaveFlashFullScreen.

windows beneath not being painted when using a layered window

I will try to explain my problem the best i can,
I'm creating a layered window in c++ (using windowsXP), all works fine until i drag my created window near the windows start button, and then when i press the star button of windows taskbar and close it again all the windows beneath of my layered window aren't being painted (only in the area of the start window that pops over my window).
My create window is like this:
CWnd::CreateEx( WS_EX_TOOLWINDOW |
WS_EX_LAYERED,
AfxRegisterWndClass(0),
lpstr_name, WS_POPUP, 0,0,0,0,
pc_parent->GetSafeHwnd(), 0);
...
When i create the window with this styles the problem ocurrs, but if i create with the extended style WS_EX_TRANSPARENT and all the others the problem does not occur any more. And if instead of a WS_POPUP window is a WS_CHILD or WS_OVERLAPPED then this also doesn't occur...
Can anyone please explain why when i create a WS_POPUP window with the WS_EX_LAYERED style all the beneath windows aren't updated, and if i add the style WS_EX_TRANSPARENT this works fine.
Note: why i do not use the WS_EX_TRANSPARENT style if it works right? if i use it then my window can not be dragged and i need it to do it :)
Updated:
alt text http://img17.imageshack.us/img17/586/clipboard01il.jpg
The image above is to describe better what is happening:
The first part of the image you can see my leyered window and beneath is the vs, in the second img i press the start button and then in the last image i already drag my layered window to the right and you can see that the vs window does not updates the affected area.
Note that this situation until now only occurs with the start window?! with other windows it does not happen!?...
Thanks
only in the area of the start window that pops over my window
That's expected. Only that clipping rectangle is obscured by the start menu so only that region will be repainted. What behavior are you expecting? If there are windows covered by more upper level windows, then they won't be repainted either -- why repaint something just to paint over it?
All underneath windows need to get repainted though if you use transparent because GDI can't calculate the final color of the pixel without knowing the area below the window's color.

How do you have a window that has no icon in the tasktray?

I found the windows style WS_EX_TOOLWINDOW but this changes the title bar. Is there a way to not have the tasktray icon but keep the normal window titlebar?
You usually do want to do this if you have added an alternate means to restore the window - for example placing an icon in the notification tray.
The usual way of ensuring the taskbar does not display your window is to create it with a hidden parent window. Whenever a window has a parent, the parent window is used to create the button - hidden windows are not shown on the taskbar.
Also, WS_EX_APPWINDOW should be removed as that performs the opposite hint to the shell and forces the window onto the taskbar even if it would otherwise not have been shown.