Sign in to follow this  
Followers 0
zfisherdrums

Using WM_GETCONTROLNAME [SOLVED]

2 posts in this topic

#1 ·  Posted (edited)

I came across an MSDN article describing how to use WM_GETCONTROLNAME to retrieve the names of .NET controls as defined at compile time. If this example can be ported over to AutoIt, it may prove helpful in .NET control discovery. However, I'm encountering an issue while I'm attempting to port it over. I'm unsure of how to implement "reinterpret_cast" in AutoIt. I'm in hopes someone with more intimate knowledge of C++ can point out my horrible mistake(s). Below is the original example from MSDN:

/*
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
Steps:
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,
&NumRead);

//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);

Here is my attempt:

Const $SMTO_NORMAL          = 0x0000
Const $SMTO_BLOCK           = 0x0001
Const $SMTO_ABORTIFHUNG     = 0x0002

Const $PROCESS_VM_OPERATION = 0x8
Const $PROCESS_VM_READ      = 0x10
Const $PROCESS_VM_WRITE     = 0x20
Const $PROCESS_ALL_ACCESS   = 0xFFFF

Dim $bufSize = 1024  ; <--- Conflicting examples: Some example set the buffer size to 65536 ( ? )
Dim $ctrlName[$bufSize];
Dim $processID = WinGetProcess( "Form1" );
Dim $hWnd = 0x001D080C; <--- obtained HWND via AutoIt Info
Dim $numRead = ""

Dim $getName = _WinAPI_RegisterWindowMessage( "WM_GETCONTROLNAME" )
Dim $dwResult = _WinAPI_GetWindowThreadProcessId( $hWnd, $processID )
Dim $hProcess = _WinAPI_OpenProcess( $PROCESS_ALL_ACCESS, False, $processID, True )
Dim $otherMem = _MemVirtualAllocEx( $hProcess, 0, $bufSize, $MEM_COMMIT, $PAGE_READWRITE )
Dim $SendFlags = BitOR( $SMTO_ABORTIFHUNG, $SMTO_BLOCK )

$result = DllCall( "User32", "lresult", "SendMessageTimeout", _
    "hwnd", $hWnd, _
    "uint", $getName, _
    "wparam", $bufSize, _
    "lparam", $otherMem, _
    "uint", $SendFlags, _
    "uint", 1000, _
    "dword*", $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
;~  
$bResult = _WinAPI_ReadProcessMemory($hProcess, $otherMem, $ctrlName, $bufSize, $numRead)
                                                
;~; CtlName now contains the instance name of the control, or is empty if there is no name
ConsoleWrite( $ctrlName & @CRLF)

; clean up 
Func OnAutoItExit()
    ConsoleWrite( "Secrest out." & @CRLF)
    $bResult = _WinAPI_CloseHandle( $hProcess )
    $bResult = _MemVirtualFreeEx( $hProcess, $otherMem, 1024, $MEM_RELEASE )
EndFunc
Edited by zfisherdrums

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0