Why is a window not coming to top, inspite using setwindowpos? - c++

m_pMainWnd->SetForegroundWindow();
m_pMainWnd->SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
i used the above lines to bring one of my windows to top. But to my disappointment, nothing is happening.
Although using <&CWnd::wndTopMost> is bringong the window to topmost, but no focus on it.
VS15, mfc

I'm sorry, but what you are asking is not (trivially) possible. The reason your window does not come on top is because your application is not the foreground application (i.e. - the application responsible for the foreground window).
From the manual page:
To use SetWindowPos to bring a window to the top, the process that
owns the window must have SetForegroundWindow permission.
Of course, you did that. You did not, however, check its return code. Here is what that man page has to say:
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The process is being debugged.
The foreground process is not a Modern Application or the Start Screen.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
The sum of these restrictions is that, in all probability, you cannot turn your window into a foreground window, and you cannot bring it to front.
There are ways around that. You can make sure the foreground process calls SetForegroundWindow. Unfortunately, that is not running your code.
The one time I had to do that, I used hooks in order to inject my code into the foreground window's process. This is not a beginner's trick. If you are not up to doing that, then there is no way to do what you are trying to do.
Edited to add: There is a reason Windows tries to stop you from doing what you are trying to do. Stealing the focus from another application creates very poor UI experience for the user. Please reconsider whether you want to do what you are trying to do.

You should use CWnd::wndTopMost instead of CWnd::wndTop.
CWnd::wndTopMost will cause the window to remain topmost even when deactivated.
See documentation:
https://msdn.microsoft.com/en-us/library/a1yzfz6d.aspx
An old new thing article on the difference between the two:
https://blogs.msdn.microsoft.com/oldnewthing/20051121-10/?p=33263

Related

GLFW Window poll events lag

I have a problem handling GLFW poll events. As far as I know, all user input events are handled via callbacks or via constantly checking keyboard / mouse states. The latter is not so efficient an can even result in missing some input (e. g. when button pressed and then released between checking state). What is more, some events like window resizing cannot be handled without callbacks.
So, the problem is that whenever user starts resizing window (presses mouse button but doesn't move mouse), the app seems to freeze. This is, assuming resize callback is enabled and defined validly (even when copied right from GLFW API). And the problem is not that window doesn't redraw. Redraw on callback can be done with creating and calling own render() function in callback function.
The actual problem is that even when I handle resize event properly and redraw on callback, there is still some lag. This lag is after mouse press on decorated window border and when mouse is not moving. Here's a demonstration (button click is highlighted green):
Sorry for messed up GIF. All callbacks listed in GLFW API are enabled and handled (window-, input-, joystick- and monitor-callbacks) and redraw is called in each one. It seems that I'm missing some of the callbacks or GLFW just works like that.
According to this answer, this can't be done without threading:
That only works when the user moves the mouse while holding - just holding left-click on the resize window part still stalls. To fix that, you need to render in a separate thread in addition to this. (No, you can't do that without threading. Sorry, this is how GLFW works, no one except them can change it.)
So, the questions are:
How can I fix this issue without threading? If I can't, I guess I can emulate resizing with different cursors shapes and resizing zones or smth like that...
If this is still impossible to solve in GLFW, do other GLFW alternatives have this issue?
Are there any problems with GLFW similar to this one?
GLFW is not at fault here. It's how the operating system handles certain user input events like mouse down on the decorator resize handles of a window or moving the whole window.
See this answer for a more elaborate detail: Win32: My Application freezes while the user resizes the window
GLFW uses the standard Windows PeekMessage -> TranslateMessage/DispatchMessage loop which you will find in any GUI Windows application. This will get invoked when you call glfwPollEvents() and it processes all Window event messages that the OS has accumulated so far for all windows in this process. After all messages so far have been processed, the call to glfwPollEvents() will return and will allow your own window/game loop to continue.
What happens is that once the user clicks down the window decoration's resize handles, effectively the call to glfwPollEvents() will block within the OS itself in order for the OS / window-manager to intercept the mouse and keyboard messages to do its window resizing/reshaping thing.
I'm afraid that even though Windows will inform the process about the start of a window resize or move action (after which the OS will have control of the window message processing) and GLFW already handling these events internally, right now GLFW will not notify the client application about this. It would be possible though for GLFW to provide an appropriate event callback to the application, so that the application can start a timer or thread only for as long as the window resize/move action happens (as is also mentioned in the linked other Stackoverflow answer).
So, the only thing that you can do in order to keep rendering while the user holds onto the resize handles or while the user moves the window around, is to render in a separate thread.

Old xlib programs hang the Linux GUI on window resize. Why?

I have noticed, that with the older X programs, when the user start to resize window by dragging its edges, the whole GUI of the OS freezes.
I am testing with glxgears - the gears stop rotating. The same happens with the content update of all other programs - such as the task manager, terminal windows and so on.
After stopping moving the mouse, all activity starts again.
Resizing newer program windows (I mean using GTK or Qt) does not freeze anything.
In the same time, the GUI of the older programs is much more responsive than the new. Only the dragging resize is the problem.
The older programs all use the standard documented way of handling the message queue. Something like the following (more complex, of course):
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg));
}
}
I have tried to eliminate the whole message processing by setting XSetWindowAttributes.event_mask = 0 on main window creation. The events stop flowing at all, but on resizing the empty window, all GUI still freezes.
So, the problem is not (only) on the client side. Although, it can be in the way the client and the server interact. For example it can be because the client does not do something.
So, what the newer toolkits do differently? What to change in the older programs in order to avoid such freezes.
Well, after some research I have found the answer.
The problem is that the old programs does not use the _NEW_WM_SYNC_REQUEST protocol in order to synchronize their ability to redraw the window content with the rate of the resize events from the window manager.
Because of this the window manager resizes the window in too high rate and the application can't draw so fast. This way, the window manager effectively loads the X server and provides DoS hanging to the other running applications.
Of course in this case, the rate of the resize events depends on the window manager, but most of them simply resize the window on every mouse move.
The _NET_WM_SYNC_REQUEST protocol is aimed to provide information to the window manager when the application finished drawing its window and to stop it from resizing the window before previous resize is processed.
The implementation is pretty simple.
At first, the application must include the _NET_WM_SYNC_REQUEST in the WM_PROTOCOLS property of the window.
Also, the application should provide one (possibly two) synchronization counters (see SYNC X extension or xcb-sync library or the libX variant)
Then the protocol looks the following way:
Before to resize the window, WM sends to the application ClientMessage with data[0] set to the Atom of _NEW_WM_SYNC_REQUEST string. In the data[2] and data[3] of this event there is an 64 bit number. The application must store this number somewhere.
After processing the following ConfigureNotify and Expose events and having the window surface fully redrawn, it must set the synchronization counter to this 64 bit value.
The window manager checks the value of the counter and after see there its number, knows that it is safe to resize the window again.
Of course, there are some timeout mechanisms and if the program responds too slow or does not responds at all, the window manager switches to fall-back mode and starts to resize the windows the old way.
There is another variant of this protocol with two synchronization counters, but IMHO, it aims to solve another programs. With the window resizing, the first version of the protocol works great.

Detect when window gets overlapped by another window from the same or different process

Background
We are running our application in XenDesktop mode and our window shows some real time information. But if some other application is also launched in that XenDekstop and that application is overlapping our window then we want to stop rendering. And once its moved out of our window then we want to start rendering again. Unfortunately, right now these kind of notifications are not supported by Citrix.
Question
How can we detect when a part or the whole of the application window has been overlapped by other windows, and also detect when that's no longer the case?
I found the WindowFromPoint family of functions when Googling, however, that is not practical for my purpose because I'd need to keep polling all co-ordinates that my window covers.
Bonus points: For a start, it's enough if I can just detect when such overlapping occurs. However, if I can detect exactly which area(s) of my window is/are covered that would be great.
There is no such API function. And usually the it isn't needed. WM_PAINT cares for itself.
If you get a WM_PAINT message you receive a region and a update rectangle of the area that needs a repaint. But it is a rectangle only, no complex region. Also there is a clipping region too.
But it should be possible to calculate the region by yourself. If we are talking about a top level window.
Create a rectangular region that is consists of your window rect
Walk all top level windows from back to front
Ignore all windows until you find your top level window
For each visible top level window create a rectangular region and XOR it with your current one.
Should be easy with GetWindow GW_HWNDNEXT
The resulting region is what you are searching for.
Again: There is no such function or message that determine, that is fired or can be executed to find such overlapping. There is no need for such an information. The system cares for itself with the appropriate WM_PAINT message. If an area is covered. There is no need for an action. If an area is uncovered WM_PAINT gets fired.
I think you should be able to get this kind of information when processing the WM_PAINT message, since normally the clipping region would be set accordingly. Calls to the RectVisible() function should tell you, for any part of your window, whether it "should be painted" (and so, whether it was just uncovered).
Despite this is not a solution to the OP's problem, I want to remark that once an overlapping window reveals part of your window (and also if you drag more area of your window back to screen), you will get a WM_ERASEBKGND message before the WM_PAINT.

Fullscreen mode on monitor A in dual-monitor setup breaks when moving windows from monitor B onto it

I am building a Win7/8/10 x64 Direct3D11 desktop application that allows the user to switch between windowed and fullscreen mode (proper dedicated fullscreen mode, not just a maximized window*). On a dual-monitor setup I am encountering some issues.
The switch itself is performed manually using IDXGISwapChain::SetFullscreenState and works as intended: The monitor that houses the lion's share of the window area (let's call it monitor A) goes into dedicated fullscreen mode while leaving the other (monitor B) as it was, allowing the user to interact normally with windows on B as well as the fullscreen application on A.
However, if a window on B is dragged or resized so that it crosses over to A, the application's fullscreen state gets disturbed: Sometimes it just reverts back to windowed mode (leaving the application's internal tracking variable out of sync), sometimes it stays in a quasi fullscreen mode where it seemingly refuses further mode switches, and so on. The same thing happens if a window that overlapped both A and B before the application went into fullscreen mode gets focus.
Is there any way to prevent this?
I wish the OS would honor my application's dedicated fullscreen mode and keep it in a robust state even if other windows are dragged onto that monitor. I'd want the behavior to be similar to having an "always-on-top, maximized borderless window" in its stead, i.e. have other windows just "disappear behind it" and not affect the state of my fullscreen window at all.
I have tried some workarounds, like responding to WM_KILLFOCUS and temporarily switching my application into a "maximixed borderless window" until it receives WM_SETFOCUS again, but the WM_KILLFOCUS message has a lag during which there is time for a user to drag another window into the area that is then still in fullscreen mode, thereby setting me back to square one.
*The reason I want this feature rather than simply using a maximized borderless window (which is also a supported mode, btw) has to do with it allowing for much lower mouse-movement-to-rendering latency, vsync control (ON/OFF) etc.. all of which are - in short - important to the nature of this application (which is not a game).
Although not ideal (ideal would be that there was a way to have the OS itself handle this properly), I have found a reasonable workaround that I suppose I can live with for now. It is a variation of the concept mentioned in the question ("..like responding to WM_KILLFOCUS and temporarily switching my application into a maximixed borderless window.."), but without the crippling delay problem:
Whenever the application enters dedicated fullscreen mode, it also captures the mouse with a call to SetCapture. This will not affect the user's ability to interact with other windows on monitor B, but it will ensure that any such de/activating interaction - like a mouse click in another application - will send a WM_LBUTTONDOWN to my application before it loses focus. Importantly, this happens immediately, unlike the WM_KILLFOCUS message that has significant latency.
When such a WM_LBUTTONDOWN message is received (while in fullscreen), the application checks whether the click happened outside its screen area. If so, it means it is about to lose focus and thus expose itself to all the complications brought up in the original question. So it temporarily exits dedicated fullscreen mode and "replaces" it with a (visually identical) borderless maximized window. When the application regains focus, it goes back into dedicated fullscreen.
This works OK, since you don't really care about the application's responsiveness when you're not interacting with it anyway. The biggest inconvenience here is the mode switch flickering that occurs on these focus transfers, but given the alternatives, I find it an acceptable price to pay for what I want to accomplish (but by all means - I'd be very interested in a better solution).
Edit 1: It is worth noting that since there are other ways for an application to lose focus than through mouse clicks, WM_KILLFOCUS is also handled.
Edit 2: I recently realized that handling the WM_BUTTONDOWN message is redundant. SetCapture alone will ensure that the WM_KILLFOCUS message is received quickly enough.

How do I place my app window in a certain position in the desktop window hierarchy on Windows using win32 api?

I want my application window to be in a certain spot in the window hierarchy. That is, say I have 3 windows on my desktop. At the very bottom I have Word, the window on top of word is explorer, and the active foreground window is itunes. I want to place my application window on top of word but beneath explorer. How can I achieve this with win32?
You might be able to use SetWindowPos - look at the hWndInsertAfter parameter. I'm not sure if this will work across process boundaries, but it's worth a shot. Perform this after your window is created but before you make it visible.
This is most likely not possible, because you will get caught by the code that tries to prevent focus stealing - it might work if your app initially has focus and you try to give it away (i.e. you are on top, then you try to hide behind the Explorer window)
If you want to maintain this arrangement, the simplest way is to create your window specifying Words window as your parent
Otherwise SetwindowPos is the all purpose worker for controlling a windows position, visibility and depth. But any z-ordering performed here will obviously be lost as soon as the user actually starts switching tasks.
One thing to watch out for: windows always raises the active window to the top of the z-order, and likewise, activates any window that is moved to the top of the z-order. There are restrictions however :- to prevent all manner of irritating behaviour Windows prevents applications from stealing activation without a user interaction - which means that, if word is currently the active window, SetWindowPos to place yourself above Word will only succeed if your app is allowed to take activation at that time.