What exactly is a top-level window in win32 programming? - windows

I don't quite understand what the difference between a window that I create via CreateWindowEx and a "top-level" window.
What is a top level window in win32 programming?

The MSDN entry About Windows offers the following definition:
A window that has no parent, or whose parent is the desktop window, is called a top-level window.
A more practical explanation is given in the blog post A window can have a parent or an owner but not both:
A window can be created as a child window (WS_CHILD set) or a top-level window (WS_CHILD not set).

A top-level window is a window that is not a child window, or has no parent window (which is the same as having the "desktop window" as a parent).

Related

how to create window child window outside primary window

I've learned how to create a child window within the parent window, but I want to create a window outside the program's primary window. If I'm not mistaken, a window outside the primary one is still a child window, right? Does it have its own class that needs to be registered? I tried just making another window, but changing the arguments. I got some interesting results, but not a separate window.

How to keep child window always on top of its parent on mac os

As the title says, I found difference between windows and mac os.On windows, the child window is always on top of its parent like this QWidget *child = new QWidget(parent);. But the difference on mac os, when I clicked the parent window, it raise to the top, and it cover the child window.
So, I want to keep the child window always on top of the parent window, and the effect like windows.
I have tried to set the child windowflag to "Qt::tool","Qt::WindowStaysOnTopHint",but it's not I wanted. It prevents me from clicking other windows or dialogs.
Forgive my poor English.Thanks.

Stop being topmost window

My window should be on top of a specific "target" window that I don't have control over.
When the target window is activated, I call SetWindowPos with HWND_TOPMOST to place my window on top of it while the target can still be the active window.
When the target window is no longer the foreground window, I want my window to still be on top of the target window, but no longer topmost, so other windows are not covered by it.
Two ideas I had:
Call SetWindowPos with hWndInsertAfter to be the just activated window. This fails when the just activated window is topmost, because my window then does not lose the topmost status. Another issue with this: If the just activated window is the desktop, then my window is placed below the target window.
Call SetWindowPos with HWND_NOTOPMOST to lose the topmost status. However, this brings my window to the top of all non-topmost windows, so it covers the just activated window. To fix this I have to bring the just activated window on top again with another SetWindowPos with HWND_TOP. This feels like the wrong way to do it and may cause flicker.
Is it possible to have a window just stop being topmost and placing it below the current foreground window?
The only automatic method to make a window permanently on top of another one whether the target window is top-most or not is an owner/owned relationship. You could try using SetParent to create this relationship but note that Raymond Chen does say it's not recommended.
Assuming you're tracking window activations somehow, I think your SetWindowPos idea (the first one) is the way to do it, with the following modification:
When the target window is active, set your window to HWND_TOPMOST
When the target loses activation, insert your window after the target window's immediate predecessor in the z-order (i.e. effectively still on top of the target window, but not top-most)
Something like this psuedo-code:
if (foregroundwindow == targetwindow)
SetWindowPos(my_window, HWND_TOPMOST, ...);
else
{
HWND hwndPred = GetWindow(targetwindow, GW_HWNDPREV);
if (!hwndPred)
{
// no predecessor so my_window will still be on top, just not top-most any more
if (GetWindowLong(targetwindow, GWL_EXSTYLE) & WS_EX_TOPMOST)
hwndPred = HWND_NOTOPMOST;
}
SetWindowPos(my_window, hwndPred, ...);
}

XLIB Decoration questions

I'm writing a small window manager, that add a basic decoration around a window, but actually i have several question about adding/remove decoration of a window.
First Question
Actually the decoration is added during MapNotify event, but it seems to be not a good idea, because it add decoration also to a menu opened by an application everytime the mapnotify is fired with a new window, but i want only to add decoration to main window. Maybe i have to check if the current window is a child of another window ? Actually my code just create the decoration window with a specific name, so at every MapNotify request i give the decoration window a dummy name (Parent) to distinguish it from all other windows in that way if the MapNotify event is launched on a decoration window, at least it doesn't add another decoration.
But i don't understand if MapNotify is launched not only for parent window but also for childrend probably the risk is that i add more than one decoration window.
The actual code is the following:
void map_notify_handler(XEvent local_event, Display* display, ScreenInfos infos){
printf("Map Notify\n");
XWindowAttributes win_attr;
char *child_name;
XGetWindowAttributes(display, local_event.xmap.window, &win_attr);
XFetchName(display, local_event.xmap.window, &child_name);
printf("Attributes: W: %d - H: %d - Name: %s\n", win_attr.width, win_attr.height, child_name);
if(child_name!=NULL){
if(strcmp(child_name, "Parent")){
Window new_win = draw_window_with_name(display, RootWindow(display, infos.screen_num), "Parent", infos.screen_num,
win_attr.x, win_attr.y, win_attr.width, win_attr.height+DECORATION_HEIGHT, 0,
BlackPixel(display, infos.screen_num));
XMapWindow(display, new_win);
XReparentWindow(display,local_event.xmap.window, new_win,0, DECORATION_HEIGHT);
XSelectInput(display, local_event.xmap.window, SubstructureNotifyMask);
put_text(display, new_win, child_name, "9x15", 10, 10, BlackPixel(display,infos.screen_num), WhitePixel(display, infos.screen_num));
}
}
XFree(child_name);
}
So how to avoid adding of decoration on every window except the main application window (or the popup windows, there is a way to distinguish the type of window? How can i figure it out?)
Second Question
WHen i exit a program the window that is destroyed is just the application window not the parent decoration, how to destroy the current window and also the decoration?
I tried with the following:
void destroy_notify_handler(XEvent local_event, Display *display){
Window window = local_event.xdestroywindow.event;
XDestroyWindow(display, window);
}
But i receive the following error:
Error occurred: BadWindow (invalid Window parameter)
I use event instead of window because it seems that it contains the parent window (i read it from there: http://tronche.com/gui/x/xlib/events/window-state-change/destroy.html)
But even if i use window i have the same problem.
Or maybe i have to destroy the parent window earlier? Maybe during UnMapNotify? But how to understand if the event is launched just because the window is going to be closed or for some other reasons?
Thanks for the help :)
Read EWMH spec and you'll find answers to all questions.
Check "override redirect" window flag
You are trying
to destroy window which is already destroyed. Instead of using
event.xdestroywindow.event window id just delete your decoration
window.
Don't forget to add client window to save set if you are
writing reparenting WM. That way if you kill wm application windows
are not destroyed but reparented back to root window

What are the Win32APIs corresponding to the "Parent" and "Owner" Window values displayed by MS Spy++?

I'd like to obtain the same values via code. However I'd like to obtain the top-most or root windows in the hierarchy
I seem to have got the Root Parent with
HWND rootWinHandle = GetAncestor(activatedWinHandle, GA_PARENT);
However I can't get the owner window correctly. Tried
HWND rootOwnerWinHandle = GetAncestor(activatedWinHandle, GA_ROOTOWNER);
For a particular modeless dialog, Spy++ returns the Main Exe window whereas the above line returns the input i.e. activatedWinHandle. Am I looking at the wrong api ?
I'd like to obtain this without MFC if possible... coz nothing else in my project requires it.
See the GW_OWNER flag for GetWindow.
The GetParent documentation states:
If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window.
Try GetParent(). I believe this will return the owner window of a window without the WS_CHILD style, and the parent window of a window with WS_CHILD.
Only bit of insight i can add it from Raymond Chen:
Remember that owner and parent are two
different things.
Modal dialogs disable their OWNERs.
All top-level windows have the desktop
as their PARENT.
From: What's so special about the desktop window?
Special demo (+src):
http://files.rsdn.ru/42164/parentowner.zip
screenshot: http://files.rsdn.ru/42164/parentowner.png
kero

Resources