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

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.

Related

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

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

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.

Keeping a window always on top -- including menus (win32)

I would like to have a layered window that is always-on-top, which I can accomplish, but there are certain screen elements that still get drawn over it, such as menus (including the start menu).
Is there any way to make a window or child window of my application have a high enough top-ness property that it will draw over another application's menus? Or is there something built in to windows that ensures that menus in the currently active application are always drawn on top?
In fact, I don't really understand all that well how menus work. So it might not even make any sense for me to try to make my window "act like a menu" in hopes of making it cover more things.
There's only one level of TopMost, you'll compete with any other program that insists on being top-most. Try osk.exe for example. I'm guessing it uses a WH_SHELL hook to win.

Creating a new window that stays on top even when in full screen mode (Qt on Linux)

I'm using Qt 4.6.3, and ubuntu linux on an embedded target. I call
dlg->setWindowState(Qt::WindowFullScreen);
on my windows in my application (so I don't loose any real-estate on the touch screen to task bar and status panel on the top and bottom of the screen. This all works fine and as expected. The issue comes in when I want to popup the on screen keyboard to allow the user to input some data. I use
m_keyProc= new QProcess();
m_keyProc->start("onboard -s 640x120");
This pops up the keyboard but it is behind the full screen window. The onbaord keyboards preferences are set such that it is always on top, but that seems to actually mean "except for full screen windows". I guess that makes sense and probably meets most use cases, but I need it to be really on top.
Can I either A) Not be full screen mode (so the keyboard works) and programmatically hide the task bars? or B) Force the keyboard to be on top despite my full screen status?
Note: On windows we call
m_keyProc->start("C:\\Windows\\system32\\osk.exe");
and the osk keyboard is on top despite the full screen status. So, I'm guessing this is a difference in window mangers on the different operating systems. So do I need to set some flag on the window with the linux window manager?
Qt doesn't seem to have a way to bring other, non-Qt process in front. You may need to get the native, platform process ID from QProcess by calling QProcess::pid() and call the underlying OS API to do it.

Simulate fullscreen

I've seen an application that simulates a fullscreen application by removing the title bar and the window borders. I've done some research and found getWindowLongPtr() for that.
Now my question: How can I find and identify the application and get the appropriate window handle? How can I distinguish multiple instances of the application (running from different locations on disc)?
Just to make "simulate" more precise. If you make an application go fullscreen and you click on a different monitor, it minimizes itself. If the application runs in a window and you click on a different monitor, the window is not changed. If you remove the borders of the window and position it on the left or right monitor, you can still work with the other monitor without minimizing the application. Still it looks like the application running fullscreen on one of the monitors.
As an example: you can set Eve (www.eveonline.com) to fullscreen and windowed mode. In fullscreenmode you can not click on a second monitor without Eve minimizing itself. In window mode you can. There are tools like evemover that allow you to setup your window on one monitor, looking like fullscreen, but being in window mode. That's what I want to archieve. Evemover actually provides some of it's source code, that's why I know that removing the border and setting the position is done using the Win32-API with setWindowLongPtr and setWindowPos.
Many applications use divergent and confusing applications of the phrase "fullscreen".
A fullscreen application simply - occupies the full screen area.
DirectX applications can request a fullscreen exclusive mode. The advantage of this mode to DirectX applications is, with exclusive access to the (full) screen they are then allowed to change the resolution, bit depth etc, as well as gain access to vertical sync synchronized hardware buffering where the screen surface is 'flipped' between display intervals so that 'tearing' does not occur.
Anyway, the windows desktop understands 'fullscreen windows' - windows that occupy the full area of a monitor and have no non client elements. When windows like this are created, things like desktop gadgets and task bars automatically hide themselves. Modern games have come to call this mode 'fullscreen windowed'.
Back to your question: 'FindWindow' is the API used to discover other applications windows. Getting the path to the application that created the window is much harder. GetWindowThreadProcessId can get you the process id of the owning process. OpenProcess will get you a handle that you can pass to QueryFullProcessImageName (implemented on Vista and above) to get the full path to the process.
I think you are refering to applications like window aggregators, that 'plug in' to the system and act from outside the application.
Look at the code for the freeware app PuttyCM (for aggregating Putty (SSH) shell windows as tabs). IIRC, it ensures that the Window pointer passed to the application has the flags already set.
On applications running from different places, you will probably need some way of identifying it - registry entries / install log etc.