Keep one window always on top of another programatically - c++

I have a (non-commercial) program which creates two windows, one displaying scrolling text, which you type into in order to issue commands. The other displays assorted complex graphics in response to those commands. The graphics information is so detailed an complex that it needs to take up the entirety of a large monitor. I usually position the text window on a second monitor so there is never any thought given to which window is "on top".
I now wish to enable a (non-technical) friend to use my program and he wants it to work on a single monitor. What I'd like to do is position the (small) text window on top of the graphics window in one corner, but somehow arrange that the text window remains on top of the graphics window, even when the graphics window is selected. Can this be done, and if so how?

Make the window you wish to be on top be owned by the other window. An owned window is always above its owner. The documentation says:
Owned Windows
An overlapped or pop-up window can be owned by another overlapped or
pop-up window. Being owned places several constraints on a window.
An owned window is always above its owner in the z-order.
The system automatically destroys an owned window when its owner is destroyed.
An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child
window cannot be an owner window. An application creates an owned
window by specifying the owner's window handle as the hwndParent
parameter of CreateWindowEx when it creates a window with the
WS_OVERLAPPED or WS_POPUP style. The hwndParent parameter must
identify an overlapped or pop-up window. If hwndParent identifies a
child window, the system assigns ownership to the top-level parent
window of the child window. After creating an owned window, an
application cannot transfer ownership of the window to another window.
Dialog boxes and message boxes are owned windows by default. An
application specifies the owner window when calling a function that
creates a dialog box or message box.
An application can use the GetWindow function with the GW_OWNER flag
to retrieve a handle to a window's owner.
So, specify the owner of a window with the hWndParent arguments of CreateWindowEx. The documentation is a bit hard to follow. It says:
hWndParent [in, optional]
A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
What this is getting at is that the parameter is overloaded. For pop-up windows, this parameter specifies the owner. And when you wish to create an unowned window pass NULL. That's what it means by the parameter being optional for pop-up windows. For child windows, you pass the parent of the window in this parameter.
Now, in your case, you want to create an owned pop-up window, and so pass the owner in this parameter.

You can just set the graphics window as owner. This is the same CreateWindow argument as parent for a child window. May I suggest that you also provide some means of making the text window more or less transparent.

Related

Creating a POPUP style window

I have an answer regarding creation of the POPUP style window. The thing that do really bothers me is the hWndParent parameter. The docs says:
This parameter is optional for pop-up windows
My question is how does the POPUP window created with the hWndParent parameter set just to NULL behaves? Does it belong to the desktop itself? How is it z-ordered/displayed on the screen? Does it spwan above all other windows or just only over the desktop such that other windows covers it?
I suggest you could refer to the Doc: Window Features
A pop-up window is a special type of overlapped window used for dialog boxes, message boxes, and other temporary windows that appear outside an application's main window. Title bars are optional for pop-up windows; otherwise, pop-up windows are the same as overlapped windows of the WS_OVERLAPPED style.
An overlapped window is a top-level window (non-child window) that has a title bar, border, and client area; it is meant to serve as an application's main window.

Display child window on the screen where the parent window is located

C++
I have a modal child window that can be launched form a main window. The application runs on a Citrix server and when the user is on dual monitors, she can drag the child window to the secondary display and somehow Windows saves this position. When she moves to a workstation with a single display, she complains that the application is freezing when in reality the child window is off the screen and can be brought to the main display with some key combinations. Is there a way I can programmatically force the child window to always open on the screen where the parent window is located?
You can try calling CWnd::CenterWindow which will just position the window in the centre of the main monitor (usually above the parent window).
You should override PreCreateWindow and modify the the respective entries in the CREATESTRUCT to force the window into the visible area. Guidelines for positioning a window can be found at the MSDN ("Positioning Objects on Multiple Display Monitors").

Child window loses focus after MessageBox is displayed

So i have created a main window inside of which i have created a 2 child windows. They all have different WindowProcs. At the WM_CREATE message of the main window I am giving focus to one of the child windows with SetFocus(...). After I display a MessageBox from the child window proc the focus is set back to main window. How can I maintain focus on the child window?
When the message box window is destroyed, Windows makes another top-level window the active window. If that’s not what you want, it is up to you to respond to the WM_SETFOCUS message that your main (top-level) window will receive and use SetFocus() to direct the focus to the child.

Window message: Different between WM_CREATE and WM_NCCREATE?

I tried to create button (child window) inside WM_NCCREATE message, and its position seemed to be created respected to screen coordinates, rather than client coordinates. At first, I thought WM_CREATE and WM_NCCREATE provide us the same handle to window, but this seem to be untrue. Therefore, can anyone explain me the differences between WM_CREATE and WM_NCCREATE messages? Also what are the differences between handle to window in WM_CREATE and in WM_NCCREATE?
WM_NCCREATE is an example of an arms race in progress. It seems to have been introduced to serve a need where DefWindowProc (or the base window proc of a commonly subclassed window) needed to perform some initialization perhaps before WM_CREATE was processed (or to make up for the fact that many window implementations handle WM_CREATE directly and return TRUE rather than passing it on to DefWindowProc).
WM_NCCREATE therefore is the message you should respond to if you are implementing a default window procedure, that needs to perform initialization before the users window proc handles the WM_CREATE message. WM_NCCREATE also MUST be passed on to the appropriate DefWindowProc, probably before you do your own processing as some lower level aspects of the window are clearly in an uninitialized state before WM_NCCREATE is processed.
If trying to guarantee first-look processing is NOT your consideration, then WM_CREATE is the appropriate place to perform your window initialization: All other layers that might have jist-in-time setup via WM_NCCREATE have been done, and the window is in a stable state wrt things like its non client metrics, screen position etc.
Or: If you don't know why you should use WM_NCCREATE over WM_CREATE, then you should not be using WM_NCCREATE.
The WM_NC messages are for the non-client area, i.e. the window border and caption. For your needs you are not interested in these non-client messages.
Per MSDN:
WM_NCCREATE:
Sent prior to the WM_CREATE message
when a window is first created.
Return Value:
If an application processes this
message, it should return TRUE to
continue creation of the window. If
the application returns FALSE, the
CreateWindow or CreateWindowEx
function will return a NULL handle.
WM_CREATE:
Sent when an application requests that
a window be created by calling the
CreateWindowEx or CreateWindow
function. (The message is sent before
the function returns.) The window
procedure of the new window receives
this message after the window is
created, but before the window becomes
visible.
Return Value:
If an application processes this
message, it should return zero to
continue creation of the window. If
the application returns –1, the window
is destroyed and the CreateWindowEx or
CreateWindow function returns a NULL
handle.
This device context includes the window title bar, menu, scroll bars, and frame in addition to the client
area. Applications programs rarely use the GetWindowDC function. If you want to experiment with it,
you should also trap the WM_NCPAINT ("nonclient paint") message, which is the message Windows
uses to draw on the nonclient areas of the window.
from:《Programming Windows Fifth Edition》 -Charles Petzold
So I think it's believable, although MSDN didn't say it。
Not sure why you're creating a button in the WM_NCCREATE -- because the window onto which the button will appear doesn't exist yet, hence (I believe) the destop coords. WM_NCCREATE gets sent to you when the 'non-client' areas of the window are about to be created (non-client areas such as the window's border, title bar, etc.)
Are you needing to put a button on the non-client area? If the answer is no, then why not do the button create inside
WM_CREATE.
If you have to create the button for some reason inside WM_NCCREATE, then why not store the window handle returned by your Createwindow() call. Then, inside your WM_CREATE message handler, grab that button's window handle and do a 'MoveWindow(...)' on it using the app window which you should now have coordinates to when you're in the WM_CREATE message handler.
I believe one of the parameters you can pass to your CreateWindow(...) call to create the button allows you to specify an 'SW_...'
flag, such as 'SW_HIDE' if memory serves me correct. So create but don't show the button in WM_NCCREATE handling if you must, then when WM_CREATE comes quickly afterward, do a 'MoveWindow(....window coords,......SW_SHOW,......) etc.
to position and make visible the button.

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.