Changing opacity of child window without using WS_EX_LAYERED - c++

I have a window and then I create a child window using the following code:
HWND childHwnd = CreateWindowExA(WS_EX_LAYERED, "Test", "Test", WS_CHILD, 0, 0, 500, 500, mainHwnd, NULL, instance, NULL);
After it has been created I can control the opacity using:
static COLORREF color = RGB(255, 0, 0);
SetLayeredWindowAttributes(childHwnd, color, 127, LWA_ALPHA);
It works fine but I also have to support Windows 7 and MSDN says the following:
Windows 8: The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.
I have installed Windows 7 in a VM and sadly it doesn't works. What could be the workaround to achieve the same opacity control over a child window in Windows 7?
I also tried to make it a standalone window and just follow the position of the parent window but the user experience is not that good when the window gets moved fast.

According to the documentation:
Using Layered Windows
In order to use layered child windows, the application has to declare itself Windows 8-aware in the manifest.
I suggest you refer to this answer:
https://stackoverflow.com/a/42570249/11872808
In Windows 7, you could try to use the SetWindowRgn() function.
I suggest you refer to this question:
Creating a Transparent Child window on top of non-transparent Parent Window (win32)

Related

create QWidget width HWND parent

OS Windows. Qt 5.5.1
I made library (dll) with GUI on Qt.
I connected it to new project. I have parent's hwnd. How to set parent for library-window (Qwidget)?
If use winapi SetParent(), then child window does not leave bounds the parent window.
I tried QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow), but it is not working, because according to documentation the parameter window is ignored in Qt 5.
I found a way that works, but there are unknown messages on the screen
windowsProc: No Qt Window found for event 0x24 (WM_GETMINMAXINFO), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x83 (WM_NCCALCSIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x5 (WM_SIZE), hwnd=0x0x110956.
windowsProc: No Qt Window found for event 0x3 (WM_MOVE), hwnd=0x0x110956.
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry: 640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
setGeometryDp: Unable to set geometry 640x480+0+0 on QWindow/''. Resulting geometry: 640x480+-760+-370 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 0x0, maximum size: 16777215x16777215).
listLabels.size() 4
Let a parent window be an ownerWin, and a child one QWidget-window named childWin;
If to use SetWindowLongPtr, the desirable result is achieved (the child window overlaps the parent one), but the child window still is in the memory when the parent window closes.
To fix a problem I create one more child window (middleWin with a parent ownerWin.) using WinApi. After wrapping this window with QWidget using createWindowContainer() it stops working normally. Then using standard Qt methods we can link our QWidget window. So we have three windows: parent, intermediate and mine. Then I close middleWin using close().All that manipulations needs to insure that when ownerWin closes, also childWin closes as well. If SetWindowLongPtr is used, then childWin will always be above the parent window, but it works only if called after function show() in child window.
Below are the functions I use. First call setWinParent(), then showWindow().
In setWinParent() lines 1 through 5 is "black box" for me. I don't know why window is created that way.
void setWinParent(HWND ownerWin)
{
HWND hwnd = (HWND)this->winId();
DWORD exStyle = GetWindowLong(hwnd, GWL_EXSTYLE) ;//1
DWORD style = GetWindowLong(hwnd, GWL_STYLE);//2
WCHAR className[256];//3
GetClassName(hwnd, className,256);//4
HWND newHwnd = CreateWindowEx(exStyle, className, NULL, style,//5
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
ownerWin, NULL, qWinAppInst(), NULL);
QWindow *qw=QWindow::fromWinId((WId)newHwnd);
QWidget* qWidget = createWindowContainer(qw);
qWidget->show();
this->setParent(qWidget);
this->setWindowFlags(Qt::Window);
qWidget->close();
}
void showWindow(HWND ownerHwnd)
{
show();
SetWindowLongPtr((HWND)this->winId(), GWLP_HWNDPARENT, (LONG)ownerHwnd);
}
Unfortunately, this is a long-running issue with Qt on Windows (and other platforms). You'll have to find a way to hook into the parent window to catch mouse and keyboard events, etc. to propagate to your Qt child window. The internal Qt code for this is perpetually a work in progress.
There's a good page about these issues and the subject in general here. Here's the bug report discussing the issue, as well.
Note: QAxWidget isn't exactly helpful, either. It looks promising, but suffers the same issues with event propagation.
The parameter window is ignored in Qt 5. Please use
QWindow::fromWinId() to create a QWindow wrapping a foreign window and
pass it to QWidget::createWindowContainer() instead.
What's unclear about the Qt documentation?
QWindow *wndParent = QWindow::fromWinId(hwnd); // hwnd - your WId
if(wndParent)
{
QWidget *parent = QWidget::createWindowContainer(wndParent);
if(parent)
// ...
}
else
{
// unsupported window...
}

Constraining draggable child windows within parent window?

Please take a look at this screenshot:
As you can see, the "Executable modules" and "Threads" child windows are free to roam about in the sandbox-like "Themida" parent window, and if they get dragged past the edge the overflow simply gets hidden. How can I create this effect?
That is a Multiple Document Interface (MDI) application. The containing window, with the dark grey background is the MDI client window, and the windows inside are the MDI child windows.
The use of MDI has been discouraged by Microsoft for many years so you may wish to think twice about using it in a new application.
Simply set the window style to WS_CHILD, and the window will be confined in the parent client rectangle.
You can do this during window creation, or after using SetWindowLongPtr() and GetWindowLongPtr():
SetWindowLongPtr(hwnd, GWL_STYLE, WS_CHILD | GetWindowLongPtr(hwnd, GWL_STYLE));
P.S. You don't need to create an MDI application to have this behavior.

Transparent hwnd window

Is it possible to create a "transparent" hwnd window ? What I mean by that is that there is no background or borders of that window but that only text is visible...like if I have a main window background and I have something written on the background ( or if I just want to add text on some area via window ) and I want to make it a clickable option, to create that kind of window that will be invisible but still clickable.
On Windows 2000 and later, you can create a top-level window with the WS_EX_LAYERED style (on Windows 8 and later, child windows can now use the WS_EX_LAYERED style as well), and then use SetLayeredWindowAttributes() or UpdateLayeredWindow() to make the window transparent.
Create a solid background color, and then set that color as the window's transparent color. Anything on the window that is not using that color will not be transparent. The OS will handle the rest for you.
Refer to MSDN for more details:
Layered Windows
Using Layered Windows
SetLayeredWindowAttributes()
UpdateLayeredWindow()
From your tag of hwnd, I'm assuming that you are working with C++ or at least have access to the Win32 API, there are plenty of resources to help you get started. The concept is called Window Compositing.
Transparent win32 window and text
Quick and Dirty Window Transparency
If you use WPF instead of C++, here's a link:
Transparent Windows in WPF
First set the styles to enable the layers:
SetWindowLong(itsec->first, GWL_EXSTYLE, GetWindowLong(itsec->first, GWL_EXSTYLE) & WS_EX_LAYERED);
Then indicate if you want the transparency to be alpha or not:
SetLayeredWindowAttributes(itsec->first, RGB(154,255,214), 200, LWA_ALPHA);

Child window created by CreateEx() overlapped by sibling windows

I tried to create a child window using:
CreateWindowEx( NULL, NULL, "MyChild", WS_CHILD | WS_VISIBLE | WS_BORDER, 300, 300, 400, 200, hParentWnd, NULL, NULL );
where the parent HWND hParentWnd has many other child windows already. However, this created a child window hiding behind all the siblings. Windows Spy++ shows that it is on top (first) of the z-order among the child windows of hParentWnd. I have tried all different win32 commands including SetWindowPos(), BringWindowToTop(), SetForegroundWindow(), SetFocus(), SetActiveWindow(), SendMessage(WM_ACTIVATE, 0, 0), etc., but none brings it from behind the siblings. When I replaced WS_CHILD by WS_OVERLAPPEDWINDOW in the CreateWindowEx() command, the created non-child window has no problem showing as the topmost foreground active window. So what must I do to get the child window to the top from behind the siblings?
Thanks a million.
z/0
It is quite explicit in the MSDN article for CreateWindowEx():
If the created window is a child window, its default position is at the bottom of the Z-order. If the created window is a top-level window, its default position is at the top of the Z-order.
You'll need to move it to the top of the Z-order with SetWindowPos().

Float GLUT window on top without titlebar on OSX

I'm creating a simple commandline applicatiation that starts a GLUT window.
I need that GLUT window to be always on top and remove the titlebar.
Basically GLUT does not provide anything for this so i'm looking into other options. On Windows i would do something like:
glutCreateWindow( "dpd" ); //create window with glut
HWND hwnd = FindWindow( "GLUT", "dpd" );
SetWindowPos( hwnd, HWND_TOPMOST, NULL, NULL, NULL, NULL, SWP_NOREPOSITION | SWP_NOSIZE ); //set the window always-on-top
But how can i do such a thing on OSX? (C++)
I already use some Carbon code to remove the menubar, but the titlebar is still visible:
SetSystemUIMode(kUIModeAllHidden,KWindowNoTitleBarAttribute);
i'm new to OSX development and out of ideas..
thanks
Ok, i found out that there is now way to make changes / ajustments to a glut window. So i finaly created a workaround: i start glut on one thread, on an other thread i created a fullscreen window with a transparent background and created a dynamic backgroundimage (png) with a viewport with just the size of the GLUT window without the titlebar. Sound kind a ugly but hey, it works, the client does get the result they want within budget :)
If you think there is a better solution for this without creating a manual openGL implementation please let me know!