Opened 16 years ago

Closed 15 years ago

#529 closed Feature Request (Completed)

Identifying .NET controls using WM_GETCONTROLNAME

Reported by: zfisherdrums Owned by: Jon
Milestone: Component: AutoIt
Version: Severity: None
Keywords: NET controls Cc:


Having read previous request and response for DataGrid on ticket #23, I do not wish to beleaguer the point. Nor is it my place to specifiy what is/is not trivial to accommodate into AutoIT. However, with all the requests for persistent .NET control identification, I wonder what is the possibility of utilizing the "WM_GETCONTROLNAME" message either natively or in a standard UDF.

I enclose the following MSDN code only to provide some fruits of my "research" on this, and my failed attempt to port it into a UDF:

given an hWnd, this code attempts to send a message to the window to get the
instance name of the control bound to the window
1. Get the Value of the WM_GETCONTROLNAME message (RegisterWindowMessage)
2. Get the Process Info for this window (GetWindowThreadProcessId)
3. Open the process and get a process handle (OpenProcess)
4. Allocate memory within the target process (VirtualAllocEx)
5. Send the target window a WM_GETCONTROLNAME message and a pointer to the
memory (SendMessageTimeout)
6. Read the response from the allocated memory (ReadProcessMemory)
7. Close process handle, release memory
//we enter this code with hwnd set to a specific window handle
//error checking omitted for brevity

const int bufsize = 1024;
wchar_t CtlName[bufsize];
DWORD ProcessId;
SIZE_T NumRead;

unsigned int GetName = RegisterWindowMessage(L"WM_GETCONTROLNAME");
DWORD dwResult = GetWindowThreadProcessId(hwnd, &ProcessId);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,ProcessId);
LPVOID OtherMem = VirtualAllocEx(hProcess, 0, bufsize, MEM_COMMIT,PAGE_READWRITE);
LPARAM lpOtherMem = reinterpret_cast<LPARAM>(OtherMem);
unsigned int SendFlags = SMTO_ABORTIFHUNG|SMTO_BLOCK;
LRESULT lResult = SendMessageTimeout(hwnd, GetName, bufsize, lpOtherMem, SendFlags, 5000, &NumRead);

//if lResult == 0 then failure or timeout, if GetLastError reports 0, then it is a timeout
//if successful NumRead contains the number of characters, if NumRead == 0 then the name is empty

BOOL bResult = ReadProcessMemory(hProcess, OtherMem, CtlName, bufsize,

//CtlName now contains the instance name of the control, or is empty if there is no name

//clean up
bResult = CloseHandle(hProcess);
bResult = VirtualFreeEx(hProcess,OtherMem,1024,MEM_RELEASE);

Attachments (0)

Change History (4)

comment:1 Changed 16 years ago by TicketCleanup

  • Milestone Future Release deleted
  • Version Other deleted

Automatic ticket cleanup.

comment:2 Changed 16 years ago by Valik

  • Resolution set to Rejected
  • Status changed from new to closed

Since you did figure out how to do it via I'm closing this as rejected.

comment:3 Changed 15 years ago by Jon

  • Resolution Rejected deleted
  • Status changed from closed to reopened


comment:4 Changed 15 years ago by Jon

  • Milestone set to
  • Owner set to Jon
  • Resolution set to Completed
  • Status changed from reopened to closed

Added in version:

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

as closed The owner will remain Jon.

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.