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.
Related
I get list of windows with Win32.EnumWindows and then filter them to keep the ones I want. I want to keep the normal, visible Skype window and skip the hidden Microsoft Edge window. (I use Chrome, and no accessible instances of Edge are visible in my Alt-TAB output or on my screen.)
I already filter out a few Edge windows that are of class Windows.UI.Core.CoreWindow but there is one Edge window still in the list. Maybe it is a main or parent window or something? Maybe the Task Manager window or the Settings windows that I have open are Edge underneath the hood?
I dumped the properties of both Skype and Edge windows, and they are the same for the items that I looked at. (I recognize that having WS_VISIBLE set does not mean that I get to see the window.) Here are the items that are identical for both windows.
Skype window: (Identical to the output for the Edge window that I can't see.)
Is visible.
Has no owner.
Has no parent.
Is not APPWIN.
Is not a toolwindow.
Is not a cloaked store window.
Class is ApplicationFrameWindow
Could anyone give me an answer on how to identify the Edge window (other than by using its name as a special case in the code) as distinct from the Skype window? Or maybe point me to a web article that I haven't seen yet? (I have looked at a dozen or so, without success.) Thank you.
Thank you everyone for your help. I ended up using the window titles because I found that there were several windows on my list that did not show up in the normal Alt-TAB display. Special cases were always required (on the net examples) to remove them from the list to help match the normal Alt-TAB display. Once I accepted the need for special cases, then using the title was the easiest way for these two windows.
I also learned that Microsoft Edge (and probably other apps too) start-up some background processes and windows even if you are not using them. Someone on the net said that you could disable these background processes in Settings, so I did that to get rid of some unwanted windows on my Alt-TAB (or nearly Alt-TAB) list.
I am currently researching how to spot windows (like Edge and Settings) that have IS_VISIBLE windows (that you can't see, but that have all the attributes mentioned earlier in the original question) attached to background processes that don't show up in the Apps list in the Task Manager.
Very strange. The OS obviously knows how to spot those windows and keep them out of the Task Manager Apps list and the Alt-TAB display. I wish I knew how to do it. Maybe the answer lies with processes, as Rita said earlier (but I didn't see any example of that method in my net research). Even Raymond Chen's famous method of walking ancestors does not produce the right answer that matches the Alt-TAB display.
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?
I have a Windows shell extension that uses IShellIconOverlayIdentifier interface to display overlay icons on files and folders. My extension is a little like TortoiseCVS or TortoiseSVN.
Sometimes I need to make Windows Explorer redraw all it's icons. To do this, I call SHChangeNotify like this:
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL)
This refreshes the desktop and right hand pane of any open explorer windows. It doesn't refresh the folder tree on the left hand side of any Explorer windows.
So I tried sending WM_SETTINGCHANGE like this:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)
on Vista this refreshes the folder tree, but not the right hand pane.
The combination of SHChangeNotify() followed by WM_SETTINGCHANGE seems to work quite well on Vista. But I still can't refresh the folder tree on XP if it is displayed.
Does anyone have any ideas how to do this better?
Is there a better solution for XP?
Sending SHCNE_ASSOCCHANGED is a bit like clubbing Explorer over the head. It causes the whole desktop to refresh quite violently and casues any open Explorer windows to loose there scroll position. Is there anything that's a bit less violent?
Does anyone have any ideas how to do
this better?
Personally I don't know. You mention the Tortoise programs which do a similar thing, so an excellent starting point would be to have a look at what they do in their source :)
These look to be the relevant source files that handle this problem:
TortoiseCVS - ShellUtils.cpp
TortoiseSVN - ShellUpdater.cpp (username: "guest", password: "")
I note in the RebuildIcons method in each of those will:
set the shell icon size or colour depth to a temporary value
updates all the windows by broadcasting the setting change
resets the shell icon size or colour depth to the original value
updates all the windows a second time with a broadcast of the setting change
Perhaps this is part of the trick to get things working in XP.
Use spy++ to see what WM_COMMMAND message gets sent when you press F5 in windows explorer or find what menu message is used for view/refresh
Then use FindWindow to get the explorer window you want and send the WM_COMMAND recorded earlier etc message to it.
This is a fun way to control all sorts of Windows programs.
You can also send a WM_KEYDOWN message with the F5 keycode to all open explorer windows. This is a bit of a hack though.
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 a Mac user and a Windows user (and once upon a time I used to be an Amiga user). I much prefer the menu-bar-at-the-top-of-the-screen approach that Mac (and Amiga) take (/took), and I'd like to write something for Windows that can provide this functionality (and work with existing applications).
I know this is a little ambitious, especially as it's just an itch-to-scratch type of a project and, thanks to a growing family, I have virtually zero free time. I looked in to this a few years a go and concluded that it was very difficult, but that was before StackOverflow ;)
I presume that I would need to do something like this to achieve the desired outcome:
Create application that will be the custom menu bar that sits on top of all other windows. The custom menus would have to provide all functionality to replace the standard Win32 in-window menus. That's OK, it's just an application that behaves like a menu bar.
It would continuously enumerate windows to find windows that are being created/destroyed. It would enumerate the child windows collection to find the menu bar.
It would build a menu that represents the menu options in the window.
It would hide the menu bar in the window and move all direct child windows up by a corresponding pixel amount. It would shorten the window height too.
It would capture all messages that an application sends to its menu, to adjust the custom menu accordingly.
It would constantly poll for the currently active window, so it can switch menus when necessary.
When a menu hit occurs, it would post a message to the window using the hwnd of the real menu child control.
That's it! Easy, eh? No, probably not.
I would really appreciate any advice from Win32 gurus about where to start, ideas, pitfalls, thoughts on if it's even possible. I'm not a Win32 C++ programmer by day, but I've done a bit in my time and I don't mind digging my way through the MSDN platform SDK docs...
(I also have another idea, to create a taskbar for each screen in a multi-monitor setup and show the active windows for the desktop -- but I think I can do that in managed code and save myself a lot of work).
The real difference between the Mac menu accross the top, and the Windows approach, is not just in the menu :- Its how the menu is used to crack open MDI apps.
In windows, MDI applications - like dev studio and office - have all their document windows hosted inside an application frame window. On the Mac, there are no per-application frame windows, all document windows share the desktop with all other document windows from other applications.
Lacking the ability to do a deep rework of traditional MDI apps to get their document windows out and onto the desktop, an attempt, however noble, to get a desktop menu, seems doomed to be a novelty with no real use or utility.
I am, all things considered, rather depressed by the current state of window managers on both Mac and Windows (and Linux): Things like tabbed paged in browsers are really acts of desperation by application developers who have not been given such things as part of the standard window manager - which is where I believe tabs really belong. Why should notepad++ have a set of tabs, and chrome, and firefox, and internet explorer (yes, I have been known to run all 4), along with dev studios docking view, various paint programs.
Its just a mess of different interpretations of what a modern multi document interface should look like.
The menu bar on a typical window is part of the non-client area of the window. It's drawn when the WndProc gets a WM_NCPAINT message and passes it on to DefWindowProc, which is part of User32.dll - the core window manager code.
Other things that are drawn in the same message? The caption, the window borders, the min/max/close boxes. These are all drawn while processing a single message. So in order to hide the menu for an application, you will have to take over handling of this message, which means changing the behavior of user32.dll. Hiding the menu is going to mean that you become responsible for drawing all of the non-client area.
And the appearance of all of these elements - The caption, the borders, etc. changes with every major version of Windows. So you have to chase that as well.
That's just one of about a dozen insurmountable problems with this idea. Even Microsoft probably couldn't pull this off and they have access to the source code of user32.dll!
It would be a far less difficult job to echo the menu for each application at the top of the screen, and even that is a nearly impossible job. When the menu pops there is lots of interaction with the application during which the menu can be (and often is) changed. It is very common for applications to change the state of menu items just before they are drawn. So you will have to replicate not only the appearance of the menus, but their entire message flow interaction with the application.
What you are trying to do is about a dozen impossible jobs all at once, If you try it, you will probably learn a lot, but you will never get it to work.