Edit: Thanks to guys below I learned that windows doesn't have this last activity info. So I'll make this question more precise. I have a list of HWNDs and I want the one that was more recently active. I read of GetLastActivePopup but it seems to not give me the right one, it seems to always give me the same hwnd i pass to it. Is this because popup is different from hwnd?
Old question was this:
I have a list of HWNDs.
I actually used EnumWindowsProc, EnumWindows, and EnumChildWindows to get a list of all windows. I grouped them by PID. (I got PID with GetWindowThreadProcessId). I would like to sort the windows in each each group by last focus time. How can I get the info of when the window was last focused?
In X11 (Unix/Linux) we have this property called _NET_WM_USER_TIME on windows. Is there something similar like this on Windows HWNDs?
Thanks
Related
I'm trying to automate a many clicking process, just to narrow it to the user input.
I encountered problems in controlClicking interface elements, which seems not to be standard Windows GUI elements.
When pointing them with WinSpy they don't appear as separate buttons, but I can point the whole child Window which is drawn in the main program window.
As on pic1, I pointed the whole window and I can find each tab/button by it's text inside and on pic2 I can inspect the ClassNN of that element and it's ID.
As far as clicking other buttons in the main menu bar of the program works, a simple:
ControlClick, ClaTab_01000000H26, WindowName
doesn't work. I think during the day, and many possibilities I tried, I could ControlClick the above button by pointing it with its ID, but that ID changes every instance. I could confirm that tomorrow if it works by ID.
Of course I tried SetControlDelay -1 and ,NN option. But don't take that for granted, I can try any of your suggestions tomorrow.
Both tabs marked with purple color, are to find in the Windows->SiblingWindows tab. I really don't want using x,yCoords (that actually work), but I need the script to be as reliable as possible.
So my questions are:
Am I missing something or you have any suggestions how to click that elements?
Is it correct, that no matter how deep the child windows get (one has buttons to open another on top of it), all the time the WinName stays the same pointing to the main program ***.exe?
Could you provide an example from the web or yours, to find an element's ID by providing the text attached to the button (pic1-red line and also pic2 in "text")?
I also cannot maximize the child window. Double clicking it works, but I can't find the appropriate ClassNN of the window to call.
Could you provide an example, how to use the Messages tab? I assume, if I find the button as on the pictures, I could send a message with controlClick and see if there's a reaction?
1.Ugh. I found the solution, which is awesome, but a little frustrating that with a bit of luck I tried another aproach that's not that logical for a newbie like me:
instead:
ControlClick, ClaTab_01000000H6, ahk_class ClaWin01000000H_2,,,, NA
it's just
ControlFocus, ClaTab_01000000H6, ahk_class ClaWin01000000H_2,,,, NA
2._Yep. One child window creates another and another and another, but winTitle stays the same. In my case:
ahk_class ClaWin01000000H_2
3._Code below returns the handle/ID of the element you specify. Change ClaTab and ClaWin to your chouice.
ControlGet, OutputVar, hwnd,, ClaTab_01000000H1, ahk_class ClaWin01000000H_2
MsgBox, %OutputVar%`
Probably to be continued.
I highly recomend to both use
WinSpy https://www.autohotkey.com/boards/viewtopic.php?t=28220
SimpleSpy https://www.the-automator.com/downloads/simple-spy/
First one has lots of useful information and the window tab provides information of hidden buttons/windows. Second one in a more clear way indicates the parent window and its class.
I have a windows application which has several sub-forms. i have to navigate through 5 or 6 forms to reach the form i need. this is time consuming since i have to open it several times through the day and i do it daily.
my need: i dont have the source project for this application, i got it as an executable program, but i need to create some application that does these steps for me automatically. In other words i need to find a way to automatically click the buttons that navigate through the forms and opens the form i need from step one.
is there any way i can do this ?
There is indeed, though generic solutions already exist to perform just this kind of function to arbitrary programs.
You can use Spy++ or a resource-editor, like ResHack or ResEdit to look at the program and get the control ids of the navigation buttons.
Once done, you can get a handle to the program itself and then send messages to it's WindowProcedure that would be generated if the user clicked the controls with a mouse,
Another alternative, is to get the position of the running target application, after you've got it's HWND, by using the GetWindowRect function. You could then use this position along with vert/horiz distances to generate mouse events.
The two have more-or-less the same result, though some applications won't work with approach #1.
In one instance, you need to use Spy++ to get the control IDs.
In the other instance, you need to use an image editor to get the pixel offsets of the controls.
In both instances, you'll need to use FindWindow, along with the window's title-text in order to get a HWND handle.
You could use a combination of the two - asking the program itself with GetDlgItem for the handle of the controls you need to click. You could then query the control for its position, before using mouse_event to position the mouse above it and again to click it.
Quite a few ways to skin this cat, actually.
Pre-existing solutions like AutoIt are said to be very easy to use and will be much easier than coding a new program for each target.
I'm using the following piece of code to get all windows:
CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
This gives me an array of dictionaries as found here: Front most window using CGWindowListCopyWindowInfo
Then I check their bounds to see if the mouse is in it, and the first I find is is the one my mouse is over.
Then I would like to be able to move it. I know how to use AXUIElementSetAttributeValue to move a window, though then I need a AXUIElementRef, which I can't figure out how to get out of the dictionary.
How can I solve this?
There is no way to go from a window number to an AXUIElementRef.
The closest you can get is to find the owner of the window, then ask it through Accessibility for its windows and look for one with the same titleābut an app may have more than one window with the same title, so you need to figure out what you'll do in that case.
The only ways to move another application's windows are by AppleScript or by Accessibility. Using Accessibility is much more reliable than AppleScript (many, if not most, apps have incomplete and/or flaky scripting support). You can get the process ID and window title from the same window dictionary that gives the window number, but that's as specific as you can get. With AppleScript, you could only use the window's index within its application's window list, and hope that the list hasn't changed order in the split-second between you computing the index and trying to use it.
I am writing an app with raw windows API (opensource Win32++) where I have a ListView.
The problem I have now is that whenever an item in the ListView is clicked, the system/app will generate a warning tone/sound "ding". Furthermore, I noticed I cannot get the LVN_ITEMACTIVATE through item-dbl-click or item-keypress-enter, which would normally work if this problem had not occur.
Would anyone have any idea how this might be happening?
I believe there is nothing wrong with Win32++, it just could be one of the things I do is causing this. But my program has become quite big to dissect plus I have no idea where to start looking.
Thanks.
PS: I had my computer muted for the longest time, hence, I don't know when this started eventhough I had the listview since a long time ago. T_T
Start looking with a tool that can show you the Windows messages that the control generates and receives. Like Microsoft's Spy++. Compare it with a working list view to have an idea what might be amiss. Also check the parent window. I haven't otherwise heard of listviews that dingaling, the LVN_ACTIVATEITEM should fire the first WM_LBUTTONDOWN, no double-click necessary.
Basically, I'm looking for a IsWindowMoving(HWND) Win32 API call. I need to know if the user is currently moving a window.
The window doesn't belong to me, so listening for WM_SYSCOMMAND / SC_MOVE or WM_MOVING isn't possible (I don't want to subclass or hook due to 32/64 interop).
You can do this with GetGUIThreadInfo - no hooking needed. Use GetWindowThreadProcessId to get the TID for your hwnd then check the GUITHREADINFO.flags and GUITHREADINFO.hwndMoveSize to see if your window is in a move / size loop.
If the window doesn't belong to you and you're not going to snoop messages, the best you can I think is get hold of a handle to that window. That limits you to whatever informational function calls exist which work on a handle. I know of no such call which can inform the user that the window is being moved.
You may be out of luck.
If you don't want to hook, subclass, or anything else like that, I think polling might be the easiest way left. Using GetWindowRect you can track the previous and current position and size of a window. Doing a delta will let you detect if the user is moving (or even resizing) the window. Since you are dealing with UI, there is no need to poll too quickly (even 2-5 times a second should be plenty).