I try to grab specific windows on Windows 10. I read some articles from MSDN to get familiar with APIs. My goal is to grab some certain windows, even if there are some windows on top of them (equivalent to OS X CGWindowList API). So if there are 2 windows: A and B, and windows B partially overlaps window A, I would like to be able to capture window A content, without capturing window B that partially covers window it.
According to this link, there are 5 different ways to capture the screen, if I understood them correct, most of them can capture only some regions on the screen, i.e. they don't distinguish between windows. The only API which allows to grab specific windows is "old standby, GDI".
I tried to acquire windows' device contexts using GetWindowDC() function, create a compatible bitmap and then use bit block transfer (BitBlt()). However, it seems that it does not always work as expected.
I've noticed several problems on Windows 10 (did not test on other operating systems):
Window's title bar usually is not captured. I tried to open Notepad and capture the window, but it was not fully captured, part of the scroll bar was not captured as well as a title bar. I tried to capture child windows of Notepad, but it did not work as expected, moreover some child windows are seem to have coordinates which seem to be wrong (the msctls_statusbar32msctls_statusbar32 child window of Notepad had the width which was 3 times bigger than the actual width of the window).
Some apps are not captured at all. For instance applications like "Photos", "Calc", "Settings" are not captured with that approach, when I try to capture them I get a black bitmap. There should be an API which allows capturing such windows, for instance TeamViewer is able to capture those Windows. It seems that all such windows are rendered by ApplicationFrameHost.exe process.
Does anyone know how to solve those issues?
Related
I created a little Vision2 window with an animation in it.
In my Windows 7 environment, I want this animation to be always visible on top all other windows on my desktop. I'm able to periodically call raise to bring the Vision2-window in front - but I lose focus of my selected window doing that.
To boil it down:
Q1: Is it even possible to keep a window "always on top" all other windows with Vision2 ?
Q2: Is it possible to do it with Eiffel WEL (and Windows 7) ?
Talking about Windows in general, it is not possible to guarantee that a window will be on top of all other windows, because if you have 2 windows that have this property, one of them will be on top of the other. As you will see in the post below, you have 2 categories of windows and z-order:
http://blogs.msdn.com/b/oldnewthing/archive/2005/11/21/495246.aspx
Assuming you are ok with something on top of all your windows, in WEL, you can use the Win32 API to achieve that by using WEL_WINDOW.set_z_order ({WEL_HWND_CONSTANTS}.hwnd_topmost).
In Vision, you can also do that by using EV_POPUP_WINDOW and calling `disconnect_from_window_manager' on it.
On either Win32 or wxWidgets, is there an easy way to get a screen capture of an application which has several windows open - e.g. floating toolbars and similar - without getting their desktop, etc, as well?
The easiest would be capturing entire desktop, then enumerating windows and their positions so that you create a region/mask which leaves the windows of the process/application in question. Then applying the mask onto captured image would get you the requested snapshot.
I'm wondering if there's a way to reliably retrieve all open VALID windows in all spaces?
The problem I'm encountering now is that on programs like Microsoft Word for Mac there are lots of child windows, resulting in my list being muddied by blank windows with no title, or windows that just don't lead anywhere. For example, for Word I'm getting these 3 windows when I only have 1 document open:
Document 1
Microsoft Word
Desktop
All are from Microsoft Word, and same goes for Excel and Powerpoint, the problem seems to be pretty exclusive to the Microsoft Office suite. Any ideas on how to deal with windows that don't actually have anything?
You can try to correlate with Accessibility (you don't mention how you're getting the window list right now), or just use some heuristics (ignore windows with no title, no workspace number, look at the window tag bits, etc.). Pull up the window list in Quartz Debug, browse around and you'll see some differences. If the window is visible, you can also hold down Control-Option with Quartz Debug in the background to get a pop up HUD with some more detailed information about the window underneath the cursor.
If you're really desperate you could grab the window contents and see if they're all transparent or white.
I am trying to write a program that gets the windows that are displayed on the screen. Something like screen.getActiveWindow().size would be cool, but it only addresses the active window.
I am looking for the sizes of all windows on the screen, as well as event information when they are resized, cover each other up.
Am I just daydreaming or is there a way to get this information on windows?
You need to use EnumWindow Function go get the hwnd of each window then user EnumChildWindow to get the child windows and finally get windowinfo the clr doesn't have all of the necessary function to do low level window manipulation unless its been added in 4.0 and I haven't noticed.
I have a hidden process that waits for non-standard hardware button messages and runs an application (with CreateProcess). No problem with the user disturbing, it's an action that the user approved himself. Everything is fine when it's usual layout with taskbar shown and multiply captioned and non captioned- windows. But the situation is different in XP and 7, when the current application is full-screen. Full-screen application in this case is window without borders having exactly the same dimension as the screen. Windows hides taskbar for such application even if it's always on.
In Xp, it's ok, the taskbar is being shown in this case and appication (for example calculator) also, the full-screen app is still visible in areas other than the launched app's and taskbar'. But in Windows 7 nothing visual happens, the full-screen app is still on and if I switch to taskbar, the executed application is there. I tried to solve it with SetForegroundWindow, BringWindowToTop, even AllowSetForegroundWindow(GetCurrentProcessId()) call for a window handle found with CreateProcess-WaitForIntputIdle-EnumThreadWindows, no change. So did something change since XP related to full-screen windows that officially documented?
Thanks,
Max
I would imagine that, if you have your own hardware device, that there is some API for generating "real" user input. Clearly the legacy keyboard and mouse, and now USB HID drivers (many of which are usermode I think?) have access to an API to do so.
Synergy+ for example can generate fake keyboard and mouse events on connected PCs, and the consequence of the faked input is windows switching activation normally.
So, my initial idea is for your usermode "Device" application to synthesize actual keyboard messages - SendInput seems a likely candidate for "the API that can "fake" real user input events.
Then, use an API like RegisterHotKey in your "UI" app to respond to the hotkey combination your device app generates.
Now, (assuming that SendInput IS generating user input events at the correct level), you should (from within the WM_HOTKEY handler in your UI app) have permission (because everything was "user initiated") to change the foreground window (to yourself).
Vista introduced the desktop composition feature. In short, all windows are drawing to a memory bitmaps and the Desktop Window Manager is then composing these bitmaps and drawing on a full-screen Direct3D surface. Full-screen windows do not participate in the desktop composition and get to draw directly on the screen (mostly because the majority of full-screen apps are games that need real-time screen updates).
In particular, this means that when a full screen app is up and running, it is covering the DWM composed image and the user needs to switch to a DWM-managed window for the DWM to start drawing on top of the full-screen app.
I don't have a good solution for your problem, unfortunately. One way to solve it would be to add the WS_CAPTION style to your app and then handle WM_NCPAINT/WM_NCCALCSIZE/WM_NCHITTEST yourself. This would allow you to lie to the DWM that you are a regular windowed application, but change visually your NC area to look like you have no title. However, this does require certain amount of additional code and might be a bit more effort you want to invest.
Another way you can try to solve your problem is to explicitly minimize your full-screen application window when launching the new process. However, you will then have to solve the problem of when to maximize it back again.
Btw, you might find the comments on this post from Raymond Chen interesting.
Windows supports multiple desktops and my guess would be that the full screen up is using a different desktop than the default one (where your application will be shown). A desktop object in Windows is "a logical display surface and contains user interface objects such as windows, menus, and hooks". For example, screen savers normally are started on a separate desktop.
You can find out which desktop an application is running on using Process Explorer:
Set Process Explorer to replace Task Manager and to run always on top.
When your full screen up is shown, launch Process Explorer by pressing Ctrl + Shift + Esc
Within Process Explorer, select the full screen process and press Ctrl + H to display the handles of this process
See the value of the Desktop item in the list. Usually this would be set to Default
If you know what desktop this app is running on you can start your process on the same desktop by first calling OpenDesktop to get a handle to this desktop and then pass it into the STARTUPINFO of your CreateProcess call.