636C65616E Posted January 20, 2021 Share Posted January 20, 2021 (edited) Heyo, I noticed something a bit weird. I was playing with Kernel32 and User32, after creating a window and loging the mesages received, I noticed that WinGetTitle (native AutoIt) was sending a (2 !!) WM_NULL msg instead of WM_GETTEXT. Quote $hwnd = 0x04680908 call: U32_SetWindowTextA($hwnd,"foo") [WndProc] hwnd:0x04680908 msg:0x000C call: WinGetTitle($hwnd) [WndProc] hwnd:0x04680908 msg:0x0000 [WndProc] hwnd:0x04680908 msg:0x0000 WinGetTitle > title = "" call: U32_GetWindowTextA($hwnd,$ptr,256) [WndProc] hwnd:0x04680908 msg:0x000D GetWindowTextA > title = "foo" I can provide the code ... Edited January 20, 2021 by 636C65616E Link to comment Share on other sites More sharing options...
Nine Posted January 20, 2021 Share Posted January 20, 2021 2 hours ago, 636C65616E said: I can provide the code ... Please do so... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
636C65616E Posted January 20, 2021 Author Share Posted January 20, 2021 expandcollapse popuplocal const $K32_HANDLE = DllOpen('kernel32.dll') local const $NT_HANDLE = DllOpen('ntdll.dll') local const $U32_HANDLE = DllOpen('user32.dll') func debug($msg) ConsoleWrite($msg & @CRLF) endfunc func WrapString($str, $wchar = FALSE) local $struct, $len = StringLen($str) if ($wchar) then $struct = DllStructCreate('WCHAR[' & ($len + 1) & ']') else $struct = DllStructCreate('CHAR[' & ($len + 1) & ']') endif DllStructSetData($struct, 1, $str) return $struct endfunc local const $STRUCTSTR_SYSTEM_INFO = '' & _ 'DWORD dwOemId;' & _ 'DWORD dwPageSize;' & _ 'PTR lpMinimumApplicationAddress;' & _ 'PTR lpMaximumApplicationAddress;' & _ 'DWORD dwActiveProcessorMask;' & _ 'DWORD dwNumberOfProcessors;' & _ 'DWORD dwProcessorType;' & _ 'DWORD dwAllocationGranularity;' & _ 'WORD wProcessorLevel;' & _ 'WORD wProcessorRevision;' local const $STRUCTSTR_MSG = '' & _ 'HWND hwnd;' & _ 'UINT message;' & _ 'WPARAM wParam;' & _ 'LPARAM lParam;' & _ 'DWORD time;' & _ 'LONG pt_x;' & _ ;'STRUCT;LONG x;LONG y;ENDSTRUCT pt;' & _ 'LONG pt_y;' & _ 'DWORD lPrivate;' local const $STRUCTSTR_WNDCLASSEXA = '' & _ 'UINT cbSize;' & _ 'UINT style;' & _ 'PTR lpfnWndProc;' & _ 'INT cbClsExtra;' & _ 'INT cbWndExtra;' & _ 'HANDLE hInstance;' & _ 'HANDLE hIcon;' & _ 'HANDLE hCursor;' & _ 'HANDLE hbrBackground;' & _ 'PTR lpszMenuName;' & _ 'PTR lpszClassName;' & _ 'HANDLE hIconSm;' func CheckError($name, $prefix = 'DLLCALL', $error = @ERROR) if ($error <> 0) then debug('[ERROR:' & $prefix & '] ' & $name & ': ' & $error) endif SetError($error) ; to maintain the error flag after this call endfunc func K32_SetLastError($error) DllCall($K32_HANDLE, 'NONE', 'SetLastError', 'DWORD', $error) CheckError('K32_SetLastError') endfunc func K32_GetLastError() local $ret = DllCall($K32_HANDLE, 'DWORD', 'GetLastError') CheckError('K32_GetLastError') return $ret[0] endfunc func K32_OpenProcess($dwDesiredAccess,$bInheritHandle,$dwProcessId) K32_SetLastError(0) local $ret = DllCall($K32_HANDLE, 'HANDLE', 'OpenProcess', _ 'DWORD', $dwDesiredAccess, _ 'BOOL' , $bInheritHandle, _ 'DWORD', $dwProcessId) CheckError('K32_OpenProcess') return $ret[0] endfunc func K32_CloseHandle($hObject) K32_SetLastError(0) local $ret = DllCall($K32_HANDLE, 'BOOL', 'CloseHandle', 'HANDLE', $hObject) CheckError('K32_CloseHandle') return $ret[0] endfunc ;HWND CreateWindowExA ; DWORD dwExStyle, ; LPCSTR lpClassName, ; LPCSTR lpWindowName, ; DWORD dwStyle, ; int X, ; int Y, ; int nWidth, ; int nHeight, ; HWND hWndParent, ; HMENU hMenu, ; HINSTANCE hInstance, ; LPVOID lpParam func U32_CreateWindowExA($dwExStyle,$lpClassName,$lpWindowName,$dwStyle,$X,$Y,$nWidth,$nHeight,$hWndParent,$hMenu,$hInstance,$lpParam) K32_SetLastError(0) local $ret = DllCall($U32_HANDLE, 'HWND', 'CreateWindowExA', _ 'DWORD', $dwExStyle, _ 'STR', $lpClassName, _ 'STR', $lpWindowName, _ 'DWORD', $dwStyle, _ 'INT', $X, _ 'INT', $Y, _ 'INT', $nWidth, _ 'INT', $nHeight, _ 'HWND', $hWndParent, _ 'HANDLE', $hMenu, _ 'HANDLE', $hInstance, _ 'PTR', $lpParam) CheckError('U32_CreateWindowExA') return $ret[0] endfunc func U32_DestroyWindow($hWnd) K32_SetLastError(0) local $ret = DllCall($U32_HANDLE, 'BOOL', 'DestroyWindow', 'HWND', $hWnd) CheckError('U32_DestroyWindow') return $ret[0] endfunc func U32_RegisterClassExA($arg) K32_SetLastError(0) local $ret = DllCall($U32_HANDLE, 'WORD', 'RegisterClassExA', 'PTR', $arg) CheckError('U32_RegisterClassExA') return $ret[0] endfunc ;LRESULT LRESULT DefWindowProcA ; HWND hWnd, ; UINT Msg, ; WPARAM wParam, ; LPARAM lParam func U32_DefWindowProcA($hWnd,$Msg,$wParam,$lParam) local $ret = DllCall($U32_HANDLE, 'LONG_PTR', 'DefWindowProcA', _ 'HWND', $hWnd, _ 'UINT', $Msg, _ 'WPARAM', $wParam, _ 'LPARAM', $lParam) CheckError('U32_DefWindowProcA') return $ret[0] endfunc ;int GetWindowTextA ; HWND hWnd, ; LPSTR lpString, ; int nMaxCount func U32_GetWindowTextA($hWnd,$lpString,$nMaxCount) K32_SetLastError(0) local $ret = DllCall($U32_HANDLE, 'INT', 'GetWindowTextA', _ 'HWND', $hWnd, _ 'PTR', $lpString, _ 'INT', $nMaxCount) CheckError('U32_GetWindowTextA') return $ret[0] endfunc ;BOOL SetWindowTextA ; HWND hWnd, ; LPCSTR lpString func U32_SetWindowTextA($hWnd,$lpString) K32_SetLastError(0) local $ret = DllCall($U32_HANDLE, 'BOOL', 'SetWindowTextA', _ 'HWND', $hWnd, _ 'STR', $lpString) CheckError('U32_SetWindowTextA') return $ret[0] endfunc global const $INVALID_HANDLE_VALUE = (-1) global const $NULLPTR = ptr(0) global const $PROCESS_ALL_ACCESS = 0x1FFFFF global const $CW_USEDEFAULT = 0x80000000 global const $HWND_MESSAGE = ptr(-3) ; --------------------------------------------------- ;LRESULT CALLBACK WindowProc( ; _In_ HWND hwnd, ; _In_ UINT uMsg, ; _In_ WPARAM wParam, ; _In_ LPARAM lParam func WndProcFunc($hwnd, $uMsg, $wParam, $lParam) debug('[WndProc] hwnd:' & ptr($hwnd) & ' msg:0x' & hex($uMsg,4)) return U32_DefWindowProcA($hWnd,$uMsg,$wParam,$lParam) endfunc local $WndProc = DllCallbackRegister(WndProcFunc, 'LONG_PTR', 'HWND;UINT;WPARAM;LPARAM;') local $className = 'MyWndMsg' local $wrappedClassName = WrapString($className) local $class_struct = DllStructCreate($STRUCTSTR_WNDCLASSEXA) $class_struct.cbSize = DllStructGetSize($class_struct) $class_struct.style = 0 $class_struct.lpfnWndProc = DllCallbackGetPtr($WndProc) $class_struct.cbClsExtra = 0 $class_struct.cbWndExtra = 0 $class_struct.hInstance = null ; $proc $class_struct.hIcon = null $class_struct.hCursor = null $class_struct.hbrBackground = null $class_struct.lpszMenuName = null $class_struct.lpszClassName = DllStructGetPtr($wrappedClassName) $class_struct.hIconSm = null local $res = U32_RegisterClassExA(DllStructGetPtr($class_struct)) if ($res = 0) then debug('U32_RegisterClassExA failed') local $err = K32_GetLastError() debug('LastError = ' & $err) endif debug('call: U32_CreateWindowExA(....)') local $hwnd = U32_CreateWindowExA(0x0, $className, null, 0x0, $CW_USEDEFAULT, $CW_USEDEFAULT, 0, 0, 0, null, null, null) if ($hwnd = $NULLPTR) then debug('U32_CreateWindowExA failed') local $err = K32_GetLastError() debug('LastError = ' & $err) endif debug('$hwnd = ' & $hwnd) debug('call: U32_SetWindowTextA($hwnd,"foo")') local $res = U32_SetWindowTextA($hwnd,'foo') if ($res = 0) then debug('U32_SetWindowTextA failed') local $err = K32_GetLastError() debug('LastError = ' & $err) endif debug('call: WinGetTitle($hwnd)') local $title = WinGetTitle($hwnd) debug('WinGetTitle > title = "' & $title & '"') local $title_struct = DllStructCreate('CHAR[256]') debug('call: U32_GetWindowTextA($hwnd,$ptr,256)') local $res = U32_GetWindowTextA($hwnd, DllStructGetPtr($title_struct), 256) if ($res = 0) then debug('U32_GetWindowTextA failed') local $err = K32_GetLastError() debug('LastError = ' & $err) endif local $title = DllStructGetData($title_struct, 1) debug('GetWindowTextA > title = "' & $title & '"') here it is Link to comment Share on other sites More sharing options...
argumentum Posted January 20, 2021 Share Posted January 20, 2021 (edited) hmmm, changing this local $className = 'AutoIt v3' ; 'MyWndMsg' make it work Edit: 'AutoIt v3 GUI' also works Edited January 20, 2021 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
636C65616E Posted January 20, 2021 Author Share Posted January 20, 2021 (edited) 13 minutes ago, argumentum said: hmmm, changing this local $className = 'AutoIt v3' ; 'MyWndMsg' make it work yep, it works ... tryed with random stuff with spaces and other combinations, and still doesn't work ... im not a Microsoft expert so guess I miss something haha edit: by changing the class name, you use the autoit class WndProc by overwriting the custom class (as this class already exists), but the DefWindowProc should handle the stuff (and it does for pure MS functions ...) Edited January 20, 2021 by 636C65616E Link to comment Share on other sites More sharing options...
argumentum Posted January 20, 2021 Share Posted January 20, 2021 could you try CreateWindowExW instead of CreateWindowExA ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
636C65616E Posted January 20, 2021 Author Share Posted January 20, 2021 yes, but the only difference is the support of WCHAR ... it should change nothing Link to comment Share on other sites More sharing options...
argumentum Posted January 20, 2021 Share Posted January 20, 2021 Just now, 636C65616E said: ... it should change nothing well, _WinAPI_CreateWindowEx() works, so, maybe ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
636C65616E Posted January 20, 2021 Author Share Posted January 20, 2021 (edited) just tested, and still not working ... but the real weirdy stuff is this 2 WM_NULL oO (the fact that it returns an empty string is only implied) Edited January 20, 2021 by 636C65616E Link to comment Share on other sites More sharing options...
Nine Posted January 20, 2021 Share Posted January 20, 2021 Works for me on Win7 (without changing any of your code) but fails on Win10. On Win7 there is that double WM_NULL also, but there is additional messages (WM_GETTEXTLENGTH + WM_GETTEXT). Whereas in Win10 there are no additional messages... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
argumentum Posted January 20, 2021 Share Posted January 20, 2021 (edited) ... tested _WinAPI_RegisterClassEx() and is basically what you'd like to do. Compare notes between the _WinAPI_RegisterClassEx() example and yours.( since I'm clueless of all this DLL calling, I may be missing the point. In that case ... let me know ) Yes, WinGetTitle() fails. debug( '! WinGetTitleByList > "' & WinGetTitleByList($hwnd) & '"') Func WinGetTitleByList($hwnd) Local $aWinList = WinList() For $n = 1 To UBound($aWinList) -1 If $hwnd = $aWinList[$n][1] Then Return SetError(0, UBound($aWinList) -1, $aWinList[$n][0]) ConsoleWrite($n & @TAB & $aWinList[$n][1] & @TAB & $aWinList[$n][0] & @CRLF) EndIf Next Return SetError(1, UBound($aWinList) -1, "") EndFunc this WinGetTitleByList() works, so, there should be a ticket opened. What say you @Nine Edited January 20, 2021 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Nine Posted January 20, 2021 Share Posted January 20, 2021 (edited) I believe there is bug with WinGetTitle under Win10 using parameter $hWnd. If you replace $hWnd with "foo", it works. If you use "[CLASS:MyWndMsg]", it works. If you do a WinList(), it will appear in the list. I don't see how it cannot be a bug... Edit : tested on beta still same bug. Edited January 20, 2021 by Nine argumentum 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
argumentum Posted January 20, 2021 Share Posted January 20, 2021 20 minutes ago, Nine said: tested on beta still same bug ...tested back to v3.3.6.1 with the same bug. So is not something newly introduced. I hope you open the ticket ( tho I saw jpm looking in this thread ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Nine Posted January 20, 2021 Share Posted January 20, 2021 1 minute ago, argumentum said: I hope you open the ticket ( tho I saw jpm looking in this thread ) I have asked the devs to look into it...before opening a ticket. argumentum 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
636C65616E Posted January 20, 2021 Author Share Posted January 20, 2021 7 minutes ago, Nine said: I have asked the devs to look into it...before opening a ticket. well, keep us posted argumentum 1 Link to comment Share on other sites More sharing options...
Nine Posted March 8, 2021 Share Posted March 8, 2021 Current Alpha version has resolved that issue argumentum and 636C65616E 2 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now