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.
Related
I am writing a flight simulator application. For that my Qt Application window should stay on top of the flight simulator application window.
The flight simulators (P3D, FSX, XPlane) offer 2 different window modes, i.e. "windowed" and "full screen". The windowed modes are no problem, I can just set Qt::WindowStaysOnTopHint for my window and it works. However, it does not work for the XPlane fullscreen mode (but does for P3D/FSX).
I have no idea what XPlane fullscreen mode really does, only that it uses OpenGL. Obviously my window looses focus when I click into the XPlane Window. On Windows I can get it back on top with ALT+TAB
I have tried (triggered by timer) widget->activateWindow(); with no result. Are there any more "tricks" I could try.
In general, an application can't force itself to the front. It can request being brought to the front, but whether that request is granted is up to the window manager.
Applications (on some platforms) can tell the window manager that they will allow certain other applications to be brought to the front instead of themselves (which allows those applications to forcefully bring themselves to the front over the granting applications, but not over other uncooperative applications). Generally this is all a cooperative thing and no one application can force its will on all the others (which IMHO is a good thing).
I am trying to draw on top of another process while it is in immersive full-screen mode.
I know this is possible using GDI and I have 2 questions:
Is it possible using a top-level transparent window ? (on top of the immersive process)
Is there a higher level API witch I can use instead of GDI?
Thank you :)
In Windows, you have two possibilities for creating a fullscreen window:
A full-screen application with exclusive drawing rights to the display.
A borderless window that extends to the full desktop resolution.
The first option allows you to change display properties like resolution, bit depth and refresh rate, while the second option is bound to use the same options here as a normal (windowed) desktop application.
Overlaying a fullscreen window with a top-level window is only possible if the fullscreen application is implemented with option 2. In that case however, any code that is able to create a transparent top-level window will do (be it pure WinAPI/GDI, or something more sophisticated, like Qt).
With option 1, as the description suggests, the fullscreen application has exclusive drawing rights to the display. Attempting to bring another window in front of it will either minimize the fullscreen application or force it into windowed mode.
There are some hacks how you can still get an overlay in this case, but they are rather invasive. For example, with a fullscreen application based on D3D, you can hook into D3D's Present routine and have D3D draw your overlay before displaying the back buffer. The important point here is that the code for drawing the overlay is executed from within the process of the fullscreen application, as that is the only process that is allowed draw to the screen at that point.
Note that some applications (in particular video games protected by anti-cheat software) do not like it very much if you inject code into the process this way.
Note that the Win API also provides an interface for so called hardware overlays, which allow drawing on top of exclusive fullscreen applications. Unfortunately, this mechanism is not widely supported on consumer hardware and might not work depending on which graphics card you are trying to run it on.
Situation: I have a software that performs screen sharing over the Internet, where one user acts as a presenter, and other users act as viewers/attendees.
Besides the presentation windows, the presenter also has a set of NON-SHARING-WINDOWS that appear on the screen (a button bar for start sharing/stop sharing/etc., a Skype window etc.).
The presenter can configure from the setup of the screen sharing software to make these NON-SHARING-WINDOWS invisible (i.e. they will not appear in the screen sharing that is being sent to the attendees, but the window content behind them will appear in the screenshot).
The screenshots are sent at approximately 10 frames-per-second, or faster.
Question: how can I programmatically capture the screen, except for these NON-SHARING-WINDOWS windows?
Notes:
Because of the higher frames-per-second value, I cannot minimize/maximize/set alpha for these windows, because then the windows will flicker. The application is written in Win32 C++.
I would use layered windows, but because of the Windows 7 Desktop Composition feature, this is not usable out-of-the-box (and in Windows 8, you cannot use DwmEnableComposition anymore to temporarily and programmatically disable composition)
I could use the layered window approach for Windows XP/2000/7 etc., and a different approach for Windows 8 (if there is one), though I would prefer a single process that works on all systems
I could also try to "compose" the screenshots by capturing individual images (of the desktop, the windows that need to be captured) and using their z-index to create the final image, but because of the required frames-per-second value, this process would be too slow.
In windows even the desktop is considered a window and has its own HWND.
It seems however, not easily possible to only copy the "wallpaper" on its own.
So i basically see two ways to do that.
1. Copy the entire desktop e.g. BitBlt(GetWindowDC(GetDesktopWindow()),...)
OR
Use GetWindow and traverse the window list in backward direction starting from the Desktop-Window whose HWND you just can determine with GetDesktopWindow(), Like this:
// paint on a black DC
hwnd=GetDesktopWindow()
while (hwnd = GetWindow(hwnd, GW_HWNDPREV))
{
// is this window not shared? continue
// else bitblt it into our dc
}
Hope i gave some inspiration :-)
If someone knows a way how to copy ONLY the desktop without its child windows please let me know.
You can use Magnifier API.
There is a function in magnifier API that allows you to exclude specific windows from your target window (your window with 1x magnification where magnifier renders).
You can set this window to full screen and make it transparent and then use PrintWindow function.
The function: https://learn.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowfilterlist
Sample projects:
https://www.codeproject.com/Articles/607288/Screenshot-using-the-Magnification-library
https://code.msdn.microsoft.com/windowsdesktop/Magnification-API-Sample-14269fd2
I'm aware this question is pretty old, but I ran into the same problem and it was very, very hard to find any information at all regarding this.
Since Windows 10 version 2004 (build 10.0.19041), the SetWindowDisplayAffinity API has been expanded to include a flag called WDA_EXCLUDEFROMCAPTURE (0x00000011). This will remove the window from images captured with BitBlt
The window is displayed only on a monitor. Everywhere else, the window does not appear at all.
One use for this affinity is for windows that show video recording controls, so that the controls are not included in the capture.
Introduced in Windows 10 Version 2004. See remarks about compatibility regarding previous versions of Windows.
For versions before 2004, it will use the existing WDA_MONITOR flag.
I have tested this with a screen capture of the desktop and I am unsure what would happen if you were to use a window DC.
So I guess a possible solution would be:
// get window handle
hWnd = (...)
BOOL result = SetWindowDisplayAffinity(m_hWnd, WDA_EXCLUDEFROMCAPTURE);
// do bitblt stuff
mabye you can use Magnification API, even Microsoft said The MagImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality., but it still work on Windows 10;
Here is the overview of this API : https://learn.microsoft.com/en-us/previous-versions/windows/desktop/magapi/magapi-intro
The sample code of Microsoft is here : https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Magnification
If you want to get the screenshot rgb data, you can use this api MagSetImageScalingCallback to set callback of Magnifier window, every time you use MagSetWindowSource or InvalidRect of magnifer window, this callback function MagImageScalingCallback will be called, so you can get screenshot rgb data here.
I think that to limit the capture content within a big window will be more simple. otherwise you will need to cut some windows from the screen capture.
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.
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.