I am enumerating through the children of a given window with the help of EnumChildWindow. I want to store the received window handles (via EnumChildProc) in a collection. Is it guaranteed that the received handles are unique? According to the MSDN article it sounds like they are unique during the enumeration but I am not sure if I understand it correctly ;)
Yes, they're unique during the enumeration. You get a shapshot.
Related
I am developing an app like Narrator (a program that reads text from some windows). The platform is Windows.
I use Microsoft Active Accessibility to implement this function. I had a window that displayed some messages. Narrator could read them out as "IEMsgView ...(the messages contained)" I soon got the IAccessible interface of this Accessible Object "IEMsgView". And I confirmed that there is only one such object by comparing its name and location.
// Let IAccessible *pList represent the one I got.
By calling pList->get_accChildCount() I acknowledged that it had several childs. Yet pList->get_accChild() returns S_FALSE when I passed it a valid child ID, which meant that its childs were elements and pList itself contained information about them, according to MSDN.
However, after called every method of pList that could give me something I still couldn't have the messages the window displayed. But Narrator did read them out! So there must be some way to obtain it.
Could someone please tell me how can I obtain these messages? Do I need IAccessible or something else?
I've done some research (with single input device altrough) in this field and discovered that in most situations messages are sent by pair, first WM_INPUT and then WM_KEYDOWN. So it's merely possible to link them together for filtering, i.e. WM_INPUT flags that it's corresponding WM_KEYDOWN shoudn't be sent to reciever (in my case first i discard all WM_KEYDOWN and then decide whenever i need to send them back to their recipients). I just assume that all next WM_KEYDOWN are belong to last WM_INPUT.
My question exactly: can i seriously rely on that principle? Won't those messages mix up if i use multiple input devices?
There are some serious questions about its reliability already:
1. How do i distinguish repeating input from multiple devices (answer is obvious - i can't).
2. Would WM_INPUT-WM_KEYDOWN pairs mix up in case of input from multiple devices? i.e. form an cortege like WM_INPUT, WM_INPUT, WM_KEYDOWN, WM_KEYDOWN?
Also maybe it is possible to just discard all WM_KEYDOWN and generate all keyboard events by myself? Altrough it would be technically quite difficult, because there may be multiple WM_KEYDOWNs from one WM_INPUT (key repeatence work that way, multiple WM_KEYDOWN, one WM_KEYUP).
Just in case, here's what i need to achieve:
I need to filter all messages by time between them. All user input gets filtered by time interval between keypresses. If two messages were sent with interval <50ms i discard first message and second awaits while its TTL exceeds and if so, it sent to its recipient.
Difficulty is that there can be multiple input devices and those timings will mess up with each other.
I understand your issue having multiple devices and things getting messed up.
Every device has there Product and Vendor Id which is not same, so what I suggest is to is to differentiate them on the basis of their Product and Vendor Id.
I have been working on a HID device recently so this might help you too.
I figured out that keyboard hook (WH_KEYBOARD) actually occurs before WM_KEYDOWN message, can't check if simultanious input from several devices will mess up order of WM_INPUTS and KeyboardHook events (like sequence of events: Dev0_WM_INPUT Dev1_WM_INPUT Dev0_KBDHook Dev1_KBDHook - altrough that sequence of event will be handle, what i fear is if Dev1_KBDhook will appear before Dev0_KBDhook or worse).
With WM_KEYDOWN such mess was possible, still don't know if it will be same with keyboad hook.
Anyway it is possible solution. On WM_INPUT i create Message itself and partly fill, on next KeyboardHookEvent i just fill remaining part.
Generally WM_INPUTs and KeyboardHook events occur by pairs, but as i mentioned before, i don't exactly know if it can mess up, but if even so, if it will maintain order of KeyboardHookEvents and WM_INPUTS (like Dev0_INPUT, Dev1_INPUT and then Dev0_KBDEvent, Dev1_KBDEvent) it will give no trouble to parse those sequences. For example one stack:
WM_INPUT pushes new message struct, KBDEvent pops and fill remaining parts.
Not generally good solution, but i guess it is good enough to use if no other exists, solves the problem, atleas partially.
If i'll manage to test its behavious upon simultanious input from multiple devices, i will post info here. Altrough i really doubt there will be any mess that can't handled. Unless windows chooses time to send corresponding keyboard event by random...
Forgot to mention, yes it's partially possible to discard all input and generate manually. I just PostMessage manually forged message (i get lparam from KeyboardHookEvent). But it will give some problems. Like hotkeys won't work and also anything that uses GetAsyncKeyState. In my case it is acceptable altrough.
Simply put, if I were to call some API returning a handle, such as GetActiveWindow(), which would give me a handle of type HWND, what do I get back? Is it a unique address in the process' VAS, or a unique index into some OS structure? Or something else?
An opaque integer identifier that has no meaning or use outside the API calls it's designed to work with - IOW, there's no way of knowing most of the time, and most of the time you shouldn't care. :-)
Yes to all of the above. In other words, it varies (widely) by handle type. Some are addresses (often hashed), others are indexes into particular tables, etc.
A very simple question, if i create a HANDLE in app1.exe and it gets value 0x01 is that value globally unique ?
Or is it possible that when some other process creates a HANDLE that also has value 0x01.
If they are not unique what other construct can i use to get a unique id compatible with handles (such that it will be impossible or highly unlikely that a HANDLE with that id is created anywhere else).
The important thing to understand is that handles are not objects. Handles are pointers (or indexes) to per-process object table. To answer your question, HANDLES are not globally unique, but they are scoped to only make sense inside a particular process.
For any kernel object to be able to be accessible from other process, you have to DuplicateHandle.
Another way to share objects across processes is to call CreateProcess with bInheritHandles set to true.
They are not unique. HANDLE values are local to the current process. Same value may be invalid handle or refer to a different object in another process. An exception to this rule are handles inherited from parent process.
The only way to have unique id without a centralized registry is to use GUID. But they are not compatible with HANDLE, they are 128-bit while handles are 32 or 64-bit.
Use DuplicateHandle to pass handles between processes.
There's a registry key where I can check (& set) the currently set GDI object quota for processes. However, if a user changes that registry key, the value remains the old value until a reboot occurs. In my program, I need to know if there's a way to determine, programatically, how many more GDI objects I can create. Is there an API for getting GDI information for the current process? What about at the system level?
Always hard to prove the definite absence of an API, but this one is a 95% no-go. Lots of system settings are configured through the registry without an API to tweak it afterward.
Raymond Chen's typical response to questions like these is "if you want to know then you are doing something wrong". It applies here, the default quota of 10,000 handles is enormous.
If you want to find the current quota that matters to you, create GDI objects until that fails. Record that number. Then, destroy all of them.
If you feel like doing this on a regular basis to get an accurate number, you can do so. It's probably going to be fairly expensive though.
Since Hans mentioned Raymond already, we should play his "Imagine if this were true" game. If this API - GetGDIObjectLimit or whatever - existed, what would it return? If the object count limit is 10000, then you expect it to return that right? So what happens when the system is low on memory? The API tells you a value which has no actual meaning. If you're getting close to 10000 GDI objects, you are doing something wrong and you should concentrate on fixing that.