Constraining draggable child windows within parent window? - c++

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.

Related

Win32 Child Window Style Not Matching Parent

I am creating a child window for a VST3 plugin and am finding that the style of the child is different to the parent - in fact windows seems to be picking up an older rounded style from somewhere when I am on windows 10 which has the modern square style.
I don't have control over the parent window style. In this scenario an audio workstation hands me a HWND that I use as the parent handle in
window->win32.handle = CreateWindowExW(exStyle,
_GLFW_WNDCLASSNAME,
wideTitle,
style,
xpos, ypos,
fullWidth, fullHeight,
parent_handle,
NULL,
GetModuleHandleW(NULL),
NULL);
I am using (a slightly modified - to accept a parent handle - and freshly compiled) version of GLFW to create the window.
Does anyone have an idea about where the style could be changing?
When I create the window as a parent window the correct style is applied. To create the child I am adding WS_CHILD to this. Digging out the exact style is hard because GLFW constructs it in a sequence of functions.
As a Late Edit. It seems similar to this problem reported with MDI windows
where MDI child window styles don't match the parent style from wayyy back in Win7 - but still is being mentioned.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/34b29567-28a1-4aeb-97d2-d1476ba856f5/mdi-child-window-appearance?forum=vcgeneral

Win32: Is it possible to show the window but to hide it from taskbar?

If I have an win32 application with several windows, is it possible to show a window but hide the window icon in the taskbar?
I have tried creating the window with WS_EX_TOOLWINDOW and WS_EX_APPWINDOW.
You have a few options:
Tool windows do not have taskbar buttons. Create a tool window by including the WS_EX_TOOLWINDOW extended window style.
Owned windows without the WS_EX_APPWINDOW extended style do not have taskbar buttons.
Hidden windows do not have taskbar buttons.
Option 1 is simple enough. If you don't want to use a tool window, use a combination of 2 and 3. Create a hidden unowned window that is the owner of your main window.

Wrong window painting behaviour in frameless Qt window (win32)

I have an QML application (also tested it with QWidgets, same problem) and to make it borderless (but still support the native WM features like aero snap, etc) I followed this by implementing an QAbstractNativeEventFilter and responding to the WM_NCCALSIZE signal with zero:
switch(msg->message) {
case WM_NCCALCSIZE:
*r = 0;
return 1;
...
}
I also set some window flags which are not in the Qt Namespace with
SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME);
This works fine until I move or resize the window which causes Qt to rerender and a unpainted area width the width of the title and the borders appears:
Before moving/resizing
After moving/resizing
I also found a workaround for this by adding the FramelessWindowHint flag in Qt:
window->setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Dialog);
But now this margins occurs again when the window state changes (maximizing, minimizing, ...). By blocking the WM_SIZE event for example when SIZE_MAXIMIZED is the parameter the margin doesn't appear but then I also am not able to maximize the window from Qt. This means it is a Qt side problem.
I also noticed by inspecting the window style with winspector, that after I have maximized it a new property atom appears:
Can you help me fixing this?
I think using SetWindowLong on your window handle and using the Qt Window Flags/Qt Widget Attributes is asking for trouble. You can go and look at the Qt source to see what happens when processing those window flags.
When I've created frameless windows, I've usually done it to prevent moving and resizing, because I am managing all that separately.
One problem that I had related to it, was when the On Screen Keyboard came up and docked, it would resize my windows. So besides calling resize() I had to also use setFixedSize to prevent my widget from getting manipulated when the operating system attempted to change the size of the window.
So in other words, I would add an application wide QShortcut, listening for the snapping keyboard shortcuts and resize your window the way you want it to when it happens, if you are managing a frameless window.
Hope that helps.
I wonder if this was a flaw of Qt message relay, coz I met with a similar problem which occurs on nested windows. If you press SIZE_MAXIMIZE or SIZE_MINIMIZE button of the parent window, the child window sometimes is not able to receive WM_SIZE message. I suppose there are roughly two solutions: 1. Fix Qt, 2. Work it around.
Here I have a OGL rendering child window, sometimes even the WM_SIZE message is not correctly passed. That is, if you resize parent window, you get part of the client area black.
I just use a simple workaround to fix this, which check the current size with the cached one, and make a sort of manually resize myself.

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.

How do I display a CFormView in a mainframe?

I created an SDI MFC app without the doc/view support. The MFC template gives me an app with a blank window (And a menu, etc)
I want to show my CFormView object on that main window. (Based on a dlg made in the gui editor)
How do I do that? CreateWindow and showwindow don't seem to be all that is needed. All the web pages I find seem to talk about MDI and other stuff that is not in my app.
This view is never going to change. It will have one list box control on it and that is all. How do I get a new form view to appear?
Additionally, how do I get a floating window with one control on it to appear as well? (DLG boxes and DoModal() will not work for me here.)
Give your CFormView the WS_CHILD style
Create it as a MODELESS dialog with the app window as the parent window
resize it to fit the parent's client area, or resize the parent to fit it.
The WS_CHILD style is not a default style for a dialog template, but you can add it.
this will cause the dialog to show up inside the client area of the main frame window you when create it.
You may also want to add a call to IsDialogMessage() to your message pump. This is needed get the TAB key to behave the way you expect it do in a dialog.
Edit ----
I'm not an MFC programmer, so I can only guess how you would go about this in MFC.
Presumably you still have dialog templates, so you would go into your .RC file
and remove the WS_POPUP and add the WS_CHILD style to your template declaration. like this:
IDD_WHATEVER DIALOG DISCARDABLE 0, 0, 275, 217
STYLE DS_MODALFRAME | DS_3DLOOK | WS_CHILD | WS_VISIBLE
CAPTION "General"
FONT 8, "MS Sans Serif"
BEGIN
// etc
END
Modeless dialogs are created in Win32 by using CreateDialog rather than DialogBox, in
MFC by using Create() rather than DoModal().