flat assembler
Message board for the users of flat assembler.
Index
> Windows > move two windows alongside each other |
Author |
|
DergMoney 26 May 2015, 17:10
OK, so I got the problem in the previous thread sorted so here's another.
I have added the ability to move my small black window (SBW) by pressing and holding the right mouse button whilst moving. Works fine. Another thing I want to have happen is that when the target window (windows calculator in this instance) is being moved, I want my SBW to move with it, so it remains in the same position relative to the target. When I move the target window, mine does not move until it receives some other event msg such as tabbing to give it focus or moving the mouse over it, then it jumps to the correct position. I've tried placing the code for this in different places in different procs. Where it is placed now, between the two ;************** is the only place it nearly does what I want. I can't think of any windows messages I can intercept to make this work. I've tried using SetWindowsHookEx with WH_CALLWNDPROCRET to capture the target's messages but my program crashes. Any way I can do this without hooking? Thanks for your time and sorry for the long read Code: format PE GUI 4.0 entry start include "%fasminc%\win32a.inc" section '.code' code readable executable start: invoke GetModuleHandle, 0 mov [wc.hInstance], eax mov [wcHUD.hInstance], eax invoke LoadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax mov [wcHUD.hIcon], eax invoke LoadCursor, 0, IDC_ARROW mov [wc.hCursor], eax mov [wcHUD.hCursor], eax invoke RegisterClass, wc invoke RegisterClass, wcHUD or eax,eax jz error invoke CreateWindowEx, NULL, ClassMain, AppName, WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 600, 200, NULL, NULL, [wc.hInstance], NULL test eax,eax jz error mov [hWndMain], eax invoke EnumWindows, EnumWindowsProc, 0 cmp [hWndPS], -1 je msgLoop invoke GetWindowRect, [hWndPS], psRectOld msgLoop: invoke GetMessage, msg, NULL, 0, 0 or eax, eax jz endLoop invoke TranslateMessage, msg invoke DispatchMessage, msg ; was target window found cmp [hWndPS], -1 ; if not, back to msgLoop je msgLoop ;****************** ; get position of target window invoke GetWindowRect, [hWndPS], psRectNew push edi esi mov ecx, 4 mov edi, psRectNew mov esi, psRectOld ; has it changed? rep cmpsd ; if not, back to msgLoop je msgLoop ; get new position of my window (since it may have been moved with right mouse button from psRectOld) invoke GetWindowRect, [hWndHUD], rect mov eax, [psRectNew.left] sub eax, [psRectOld.left] add [rect.left], eax mov eax, [psRectNew.top] sub eax, [psRectOld.top] add [rect.top], eax mov eax, [psRectNew.right] sub eax, [psRectOld.right] add eax, [rect.right] sub eax, [rect.left] mov [rect.right], eax mov eax, [psRectNew.bottom] sub eax, [psRectOld.bottom] add eax, [rect.bottom] sub eax, [rect.top] mov [rect.bottom], eax ; move my window invoke MoveWindow, [hWndHUD], [rect.left], [rect.top], [rect.right], [rect.bottom], TRUE ; save current position push [psRectNew.left] pop [psRectOld.left] push [psRectNew.top] pop [psRectOld.top] push [psRectNew.right] pop [psRectOld.right] push [psRectNew.bottom] pop [psRectOld.bottom] ;****************** jmp msgLoop error: invoke MessageBox, NULL, errorStr, NULL, MB_ICONERROR + MB_OK endLoop: invoke ExitProcess, [msg.wParam] proc WndProc hwnd, wmsg, wparam, lparam push ebx esi edi cmp [wmsg], WM_DESTROY je .wmDestroy .defWndProc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmDestroy: invoke DestroyWindow, [hWndHUD] invoke PostQuitMessage, 0 xor eax, eax .finish: pop edi esi ebx ret endp proc EnumWindowsProc hwnd, lparam push ebx esi edi invoke GetWindowText, [hwnd], strBuff, 1000 or eax, eax jz .retTrue invoke lstrlen, strBuff mov ecx, eax mov al, "C" mov edi, strBuff repne scasb jne .retTrue mov esi, searchStr + 1 invoke lstrlen, searchStr dec eax mov ecx, eax rep cmpsb jne .retTrue invoke GetClassName, [hwnd], strBuff, 1000 invoke lstrlen, psClass mov ecx, eax mov esi, psClass mov edi, strBuff rep cmpsb jne .retTrue ; have found the calculator window push [hwnd] pop [hWndPS] invoke CreateWindowEx, WS_EX_LAYERED, ClassHUD, NULL, WS_POPUP or WS_VISIBLE, 800, 100, 50, 25, [hWndPS], NULL, [wcHUD.hInstance], NULL test eax,eax jz error mov [hWndHUD], eax invoke SetLayeredWindowAttributes, [hWndHUD], 0, 255, LWA_ALPHA invoke SetFocus, [hWndPS] .retFalse: mov eax, FALSE jmp .finish .retTrue: mov eax, TRUE .finish: pop edi esi ebx ret endp proc WndProcHUD hwnd, wmsg, wparam, lparam push ebx esi edi cmp [rbd], TRUE jne @f cmp [wmsg], WM_MOUSEMOVE je .wmMouseMove @@: cmp [wmsg], WM_RBUTTONDOWN je .wmRButtonDown cmp [wmsg], WM_RBUTTONUP je .wmRButtonUp .defWndProc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmRButtonDown: mov [rbd], TRUE ; set flag to show right button is pressed mov eax, [lparam] and eax, 0x0000FFFF mov [mousePosOld.x], eax mov eax, [lparam] shr eax, 16 mov [mousePosOld.y], eax xor eax, eax jmp .finish .wmRButtonUp: mov [rbd], FALSE xor eax, eax jmp .finish .wmMouseMove: mov eax, [lparam] and eax, 0x0000FFFF mov [mousePos.x], eax mov eax, [lparam] shr eax, 16 mov [mousePos.y], eax invoke GetWindowRect, [hwnd], rect mov ebx, [mousePos.x] sub ebx, [mousePosOld.x] add ebx, [rect.left] ; ebx = new xPos of window mov esi, [mousePos.y] sub esi, [mousePosOld.y] add esi, [rect.top] ; esi = new yPos of window mov eax, [rect.left] sub [rect.right], eax ; rect.right = width of window mov eax, [rect.top] sub [rect.bottom], eax ; rect.bottom = height of window invoke MoveWindow, [hwnd], ebx, esi, [rect.right], [rect.bottom], TRUE xor eax, eax jmp .finish .finish: pop edi esi ebx ret endp showError: pushad invoke GetLastError invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, eax, LANG_NEUTRAL, errStrBuff, 0, NULL invoke MessageBox, HWND_DESKTOP, [errStrBuff], NULL, MB_ICONERROR or MB_OK popad ret section '.data' data readable writeable ClassMain db "WinClass", 00 ClassHUD db "hud", 00 hWndHUD dd ? AppName db "My App", 00 errorStr db "oops!", 00 hWndMain dd ? hWndPS dd -1 psWndProcHnd dd ? titlePS db 1002 dup ? strBuff db 1002 dup ? wordBuff db 40 dup ? space db " ", 00 errStrBuff dd ? wc WNDCLASS CS_HREDRAW or CS_VREDRAW, WndProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, ClassMain msg MSG searchStr db "Calculator", 00 rect RECT numStr db "%i", 00 psClass db "CalcFrame", 00 psRectOld RECT psRectNew RECT wcHUD WNDCLASS CS_HREDRAW or CS_VREDRAW, WndProcHUD, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 4, NULL, ClassHUD rbd dd FALSE mousePos POINT ; new position for mouse input mousePosOld POINT ; old position for mouse input section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32, 'USER32.DLL',\ gdi32, 'GDI32.DLL',\ comdlg32,'COMDLG32.DLL',\ advapi32,'ADVAPI32.DLL',\ comctl32,'COMCTL32.DLL',\ msvcrt, 'msvcrt.dll' include '%fasminc%\api\Kernel32.inc' include '%fasminc%\api\User32.inc' include '%fasminc%\api\Gdi32.inc' include '%fasminc%\api\Comdlg32.inc' include '%fasminc%\api\Advapi32.inc' include '%fasminc%\api\Comctl32.inc' import msvcrt,\ sprintf,'sprintf'
|
|||||||||||
26 May 2015, 17:10 |
|
DergMoney 26 May 2015, 23:24
Hi again El Tangas,
You are right in the first two things, yes my window does get those messages and it is due to a change in z-order. However, because it is only indicating this change in z-order, the x, y, width and height are NULL in the WINDOWPOS structure. It may be possible that my MoveWindow routine will work here, I'll give it a go tomorrow, 0:22am here. |
|||
26 May 2015, 23:24 |
|
El Tangas 27 May 2015, 13:25
Well, this doesn't seem to be easy. Maybe you have to set up a timer and regularly check if the target window has moved, say 10 times per second or so. Not elegant at all
Maybe your hook failed because of this: Quote: Because hooks run in the context of an application, they must match the "bitness" of the application. If a 32-bit application installs a global hook on 64-bit Windows, the 32-bit hook is injected into each 32-bit process (the usual security boundaries apply). In a 64-bit process, the threads are still marked as "hooked." However, because a 32-bit application must run the hook code, the system executes the hook in the hooking app's context; specifically, on the thread that called SetWindowsHookEx. This means that the hooking application must continue to pump messages or it might block the normal functioning of the 64-bit processes From what I gather, maybe calc.exe is 64 bit and needs a 64 bit hook code. Maybe the hook procedure should be assembled with use64. Sorry, never used hooks, actually. |
|||
27 May 2015, 13:25 |
|
DergMoney 27 May 2015, 15:09
Again, you are indeed right. In Win7 there are actually 2 calc.exe programs, one is in rootdrive:\Windows\System32 and the other is in rootdrive:\Windows\SysWOW64. These are different versions, one being 32-bit and the other 64-bit. I have tried it with both with no success.
This forum is very quiet nowadays so it is hard to get help. I see that Tomasz, the original developer of FASM hasn't even updated the copyright for the site since 2013. I was a member way back when but lost my login details and changed email address so had to rejoin when I came up against this problem. I have written a hook DLL for WH_CALLWNDPROC and WH_CALLWNDPROCRET and am fiddling with that at the minute. I'll let you know how it goes. |
|||
27 May 2015, 15:09 |
|
cod3b453 27 May 2015, 17:56
If you want the current size and position, GetWindowRect should be enough.
In addition to focus/zorder things from WM_WINDOWxxxx there are other potentially useful messages like WM_SIZE will tell you new size. |
|||
27 May 2015, 17:56 |
|
DergMoney 27 May 2015, 19:16
Hi cod3b453,
Thanks for the reply. I have used GetWindowRect but my window update until the other has stopped. I want mine to be dragged with one that is moving. |
|||
27 May 2015, 19:16 |
|
cod3b453 27 May 2015, 19:37
Forgot to finish my list with "and WM_MOVE will tell you the new position" in my previous; the combination of those two should allow to you handle moving and sizing.
|
|||
27 May 2015, 19:37 |
|
DergMoney 27 May 2015, 20:15
Thanks again, but as I say, I have no problem getting size and co-ordinates of the target window and using WM_MOVE etc for my window, but while the target has the focus mine will not update, i.e. move.
|
|||
27 May 2015, 20:15 |
|
El Tangas 27 May 2015, 20:33
Meanwhile, I was working on this problem using the timer method, since you are trying the hook method. I have a working prototype, check it out.
Made a few changes to your original code to simplify it. For example, I just search for the class name, since the window name changes with language, and removed your main window, there is only the HUD window (we can close it with ALT-F4). Used CreateTimerQueueTimer and DeleteTimerQueueTimer functions that were not even included in fasm's kernel32.inc, guess nobody here has used them before so I include source, binary and the updated kernel32.inc (Code may have some leftovers ) Code: format PE GUI 4.0 include 'win32ax.inc' struc LENSTRING [string] { common align 4 . db string .len = $ - . db 0 } .code start: invoke GetModuleHandle, 0 mov [wcHUD.hInstance], eax invoke LoadIcon, 0, IDI_APPLICATION mov [wcHUD.hIcon], eax invoke LoadCursor, 0, IDC_ARROW mov [wcHUD.hCursor], eax invoke RegisterClass, wcHUD or eax,eax jz error invoke EnumWindows, EnumWindowsProc, 0 msgLoop: invoke GetMessage, msg, NULL, 0, 0 or eax, eax jz endLoop invoke TranslateMessage, msg invoke DispatchMessage, msg jmp msgLoop error: invoke MessageBox, NULL, errorStr, NULL, MB_ICONERROR + MB_OK endLoop: invoke DeleteTimerQueueTimer, 0, [hTimer], 0 invoke ExitProcess, [msg.wParam] proc EnumWindowsProc hwnd, lparam push ebx esi edi ;invoke GetWindowText, [hwnd], strBuff, 1000 ;or eax, eax ;jz .retTrue ;mov ecx, eax ;mov eax, dword [searchStr] ;mov edi, strBuff ;shl ecx,2 ;repne scasd ;jne .retTrue ;mov esi, searchStr + 4 ;mov ecx, searchStr.len - 4 ;rep cmpsb ;jne .retTrue invoke GetClassName, [hwnd], strBuff, 1000 mov ecx, psClass.len mov esi, psClass mov edi, strBuff rep cmpsb jne .retTrue ; have found the calculator window ; int3 push [hwnd] pop [hWndPS] invoke CreateWindowEx, WS_EX_LAYERED, ClassHUD, NULL, WS_POPUP or WS_VISIBLE, 0, 0, 100, 100, [hWndPS], NULL, [wcHUD.hInstance], NULL test eax,eax jz error mov [hWndHUD], eax invoke SetLayeredWindowAttributes, [hWndHUD], 0, 255, LWA_ALPHA invoke SetFocus, [hWndPS] ;setup timer invoke CreateTimerQueueTimer, hTimer, 0, TimeUp, 0, 100, 100, 0 .retFalse: mov eax, FALSE jmp .finish .retTrue: mov eax, TRUE .finish: pop edi esi ebx ret endp proc TimeUp lpParameter, TimerOrWaitFired push ebx edi esi invoke GetWindowRect, [hWndPS], TgtPos invoke GetWindowRect, [hWndHUD], HUDPos mov eax,[TgtPos.left] cmp eax,[HUDPos.left] jne .repositionHUD mov eax,[TgtPos.top] cmp eax,[HUDPos.top] jne .repositionHUD .finish: pop esi edi ebx ret .repositionHUD: invoke SetWindowPos, [hWndHUD],0,[TgtPos.left],[TgtPos.top],0,0,SWP_SHOWWINDOW or SWP_NOSIZE or SWP_NOZORDER jmp .finish endp proc WndProcHUD hwnd, wmsg, wparam, lparam push ebx edi esi cmp [wmsg], WM_DESTROY je .wmDestroy .defWndProc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmDestroy: invoke PostQuitMessage, 0 xor eax, eax .finish: pop esi edi ebx ret endp showError: pushad invoke GetLastError invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, eax, LANG_NEUTRAL, errStrBuff, 0, NULL invoke MessageBox, HWND_DESKTOP, [errStrBuff], NULL, MB_ICONERROR or MB_OK popad ret .data ClassHUD LENSTRING "hud" errorStr LENSTRING "oops!" ;searchStr LENSTRING "Calculator" psClass LENSTRING "CalcFrame" align 4 hTimer dd ? hWndHUD dd ? hWndPS dd ? psWndProcHnd dd ? titlePS db 1004 dup ? strBuff db 1004 dup ? wordBuff db 40 dup ? errStrBuff dd ? msg MSG TgtPos RECT HUDPos RECT wcHUD WNDCLASS CS_HREDRAW or CS_VREDRAW, WndProcHUD, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 4, NULL, ClassHUD virtual at 0 windowpos WINDOWPOS end virtual .end start
|
|||||||||||
27 May 2015, 20:33 |
|
DergMoney 27 May 2015, 20:55
Great work El Tangas, you've got further than me As you say, there are things not included in the kernel, and also questions that have never been asked. i.e. WH_CALLWNDPROC and WH_CALLWNDPROCRET have no results in the forum. There is a FASM equivalent of Iczelion's hook tutorial for WH_MOUSE but not working very well. A google search shows that the 2 hooks I am looking at seem hard to implement.
Thanks for the time you put in, I only tried the *.exe, good stuff. I'll get a look at the code tomorrow If I manage to get the hook working I'll post it here in case it's of help to anyone else. |
|||
27 May 2015, 20:55 |
|
DergMoney 06 Jun 2015, 16:48
Finally got time to look at this again. I came across a function I didn't know existed, SetWinEventHook
https://msdn.microsoft.com/en-us/library/windows/desktop/dd373640%28v=vs.85%29.aspx I now have my black window doing all I required. It moves in tandem with the calculator window. It can be moved on its own with the righthand mouse button and will keep the same relative position to the calculator window when the calc window is moved again. If the calc window is minimized the black window is hidden and when the calc window is closed the black window is too. This doesn't destroy my main window, so if the calculator is re-opened my black window is created again Code: format PE GUI 4.0 entry start include "%fasminc%\win32a.inc" section '.code' code readable executable start: invoke GetModuleHandle, 0 mov [wc.hInstance], eax mov [wcHUD.hInstance], eax invoke LoadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax mov [wcHUD.hIcon], eax invoke LoadCursor, 0, IDC_ARROW mov [wc.hCursor], eax mov [wcHUD.hCursor], eax invoke RegisterClass, wc or eax,eax jz error invoke RegisterClass, wcHUD or eax,eax jz error invoke CreateWindowEx, NULL, ClassMain, AppName, WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 420, 170, NULL, NULL, [wc.hInstance], NULL test eax,eax jz error mov [hWndMain], eax mov [hWndPS], 00 ; check if the calculator is already opened invoke EnumWindows, EnumWindowsProc, 0 msgLoop: invoke GetMessage, msg, NULL, 0, 0 or eax, eax jz endLoop invoke TranslateMessage, msg invoke DispatchMessage, msg jmp msgLoop error: invoke MessageBox, NULL, errorStr, NULL, MB_ICONERROR + MB_OK endLoop: invoke ExitProcess, [msg.wParam] proc WndProc hwnd, wmsg, wparam, lparam push ebx edi esi cmp [wmsg], WM_CREATE je .wmCreate cmp [wmsg], WM_DESTROY je .wmDestroy .defWndProc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmCreate: ; create the 3 hooks for capturing calculator events invoke SetWinEventHook, EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY, NULL, winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT mov [hookDestroyHnd], eax invoke SetWinEventHook, EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, NULL, winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT mov [hookLocationHnd], eax invoke SetWinEventHook, EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT mov [hookCreateHnd], eax xor eax, eax jmp .finish .wmDestroy: ; kill the 3 hooks invoke UnhookWinEvent, [hookDestroyHnd] invoke UnhookWinEvent, [hookLocationHnd] invoke UnhookWinEvent, [hookCreateHnd] invoke PostQuitMessage, 0 xor eax, eax .finish: pop esi edi ebx ret endp proc WndProcHUD hwnd, wmsg, wparam, lparam push ebx esi edi mov eax, [hwnd] cmp eax, [hWndHUD] jne .defWndProc cmp [rbd], TRUE ; [rbd] is a flag to show if the right mouse button is down, if FALSE then don't process WM_MOUSEMOVE message jne @f cmp [wmsg], WM_MOUSEMOVE je .wmMouseMove @@: cmp [wmsg], WM_RBUTTONDOWN je .wmRButtonDown cmp [wmsg], WM_RBUTTONUP je .wmRButtonUp cmp [wmsg], WM_DESTROY je .wmDestroy .defWndProc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmRButtonDown: mov [rbd], TRUE ; set flag to show right button is pressed mov eax, [lparam] and eax, 0x0000FFFF mov [mousePosOld.x], eax ; save current mouse co-ordinates mov eax, [lparam] shr eax, 16 mov [mousePosOld.y], eax xor eax, eax jmp .finish .wmRButtonUp: mov [rbd], FALSE xor eax, eax jmp .finish .wmMouseMove: mov eax, [lparam] and eax, 0x0000FFFF mov [mousePos.x], eax mov eax, [lparam] shr eax, 16 mov [mousePos.y], eax invoke GetWindowRect, [hwnd], rectHUD mov eax, [rectHUD.left] ; get width and height sub [rectHUD.right], eax mov eax, [rectHUD.top] sub [rectHUD.bottom], eax mov eax, [mousePos.x] sub eax, [mousePosOld.x] add [rectHUD.left], eax mov eax, [mousePos.y] sub eax, [mousePosOld.y] add [rectHUD.top], eax invoke MoveWindow, [hwnd], [rectHUD.left], [rectHUD.top], [rectHUD.right], [rectHUD.bottom], TRUE xor eax, eax jmp .finish .wmDestroy: mov [hWndPS], 00 xor eax, eax jmp .finish .finish: pop esi edi ebx ret endp proc winEventProc hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime cmp [hWndPS], 00 jne @f ; calculator isn't running, check if this is a creation event, if it is then process it. cmp [event], EVENT_OBJECT_CREATE je .eventObjectCreate jmp .finish @@: mov eax, [hWndPS] cmp eax, [hwnd] ; if not the calculator don't do any further processing. jne .finish cmp [event], EVENT_OBJECT_DESTROY je .eventObjectDestroy cmp [event], EVENT_OBJECT_LOCATIONCHANGE je .eventObjectLocationChange jmp .finish .eventObjectCreate: ; see if the created object is the calculator, black window will be created before return if it is stdcall EnumWindowsProc, [hwnd], NULL jmp .finish .eventObjectLocationChange: ; calculator is being moved, update black window position invoke GetWindowRect, [hwnd], psRectNew mov eax, [psRectNew.left] cmp eax, [psRectOld.left] jne .moved mov eax, [psRectNew.top] cmp eax, [psRectOld.top] jne .moved mov eax, [psRectNew.right] cmp eax, [psRectOld.right] jne .moved mov eax, [psRectNew.bottom] cmp eax, [psRectOld.bottom] je .finish .moved: invoke GetWindowRect, [hWndHUD], rectHUD mov eax, [rectHUD.left] sub [rectHUD.right], eax ; width mov eax, [rectHUD.top] sub [rectHUD.bottom], eax ; height mov eax, [psRectNew.left] sub eax, [psRectOld.left] add [rectHUD.left], eax ; x pos mov eax, [psRectNew.top] sub eax, [psRectOld.top] add [rectHUD.top], eax ; y pos invoke MoveWindow, [hWndHUD], [rectHUD.left], [rectHUD.top], [rectHUD.right], [rectHUD.bottom], TRUE mov esi, psRectNew mov edi, psRectOld mov ecx, 4 rep movsd xor eax, eax jmp .finish .eventObjectDestroy: ; calculator is about to be closed, close black window invoke DestroyWindow, [hWndHUD] jmp .finish .finish: ret endp proc EnumWindowsProc hwnd, lparam ; checks [hwnd]'s class name to see if it's the calculator push ebx esi edi invoke GetClassName, [hwnd], strBuff, 1000 invoke lstrlen, psClass mov ecx, eax mov esi, psClass mov edi, strBuff rep cmpsb jne .retTrue ; have found the calculator window mov eax, [hwnd] call createHUD .retFalse: mov eax, FALSE jmp .finish .retTrue: mov eax, TRUE .finish: pop edi esi ebx ret endp showError: push ebx edi esi invoke GetLastError invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, eax, LANG_NEUTRAL, errStrBuff, 0, NULL invoke MessageBox, HWND_DESKTOP, [errStrBuff], NULL, MB_ICONERROR or MB_OK or MB_SETFOREGROUND pop esi edi ebx ret createHUD: ; gets position of calculator to position the black window mov [hWndPS], eax invoke GetWindowRect, [hWndPS], psRectOld invoke CreateWindowEx, WS_EX_LAYERED, ClassHUD, NULL, WS_POPUP or WS_VISIBLE, [psRectOld.left], [psRectOld.top], 100, 50, [hWndPS], NULL, [wcHUD.hInstance], NULL or eax, eax jnz @f call showError @@: mov [hWndHUD], eax invoke SetLayeredWindowAttributes, [hWndHUD], 0, 255, LWA_ALPHA invoke GetWindowRect, [hWndHUD], rectHUD mov [rectHUD.right], 100 mov [rectHUD.bottom], 50 ret section '.data' data readable writeable psRectOld RECT psRectNew RECT rectHUD RECT mousePosOld POINT mousePos POINT wc WNDCLASS CS_HREDRAW or CS_VREDRAW, WndProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, ClassMain wcHUD WNDCLASS CS_HREDRAW or CS_VREDRAW, WndProcHUD, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 4, NULL, ClassHUD msg MSG rbd dd FALSE ClassMain db "Main Class", 00 ClassHUD db "HUD Class", 00 AppName db "SetWinEventHook Test", 00 psClass db "CalcFrame", 00 errorStr db "oops!", 00 strBuff db 1000 dup ? hWndMain dd ? hWndPS dd ? hWndHUD dd ? hookLocationHnd dd ? hookDestroyHnd dd ? hookCreateHnd dd ? errStrBuff dd ? section '.idata' import data readable writeable library kernel32, 'KERNEL32.DLL',\ user32, 'USER32.DLL' include '%fasminc%\api\Kernel32.inc' include '%fasminc%\api\User32.inc' The equates for use with SetWinEventHook are not in the fasm user32.inc file so here they are... Code: ; Event codes for SetWinEventHook EVENT_MIN = 00000001h EVENT_SYSTEM_SOUND = 00000001h EVENT_SYSTEM_ALERT = 00000002h EVENT_SYSTEM_FOREGROUND = 00000003h EVENT_SYSTEM_MENUSTART = 00000004h EVENT_SYSTEM_MENUEND = 00000005h EVENT_SYSTEM_MENUPOPUPSTART = 00000006h EVENT_SYSTEM_MENUPOPUPEND = 00000007h EVENT_SYSTEM_CAPTURESTART = 00000008h EVENT_SYSTEM_CAPTUREEND = 00000009h EVENT_SYSTEM_MOVESIZESTART = 0000000ah EVENT_SYSTEM_MOVESIZEEND = 0000000bh EVENT_SYSTEM_CONTEXTHELPSTART = 0000000ch EVENT_SYSTEM_CONTEXTHELPEND = 0000000dh EVENT_SYSTEM_DRAGDROPSTART = 0000000eh EVENT_SYSTEM_DRAGDROPEND = 0000000fh EVENT_SYSTEM_DIALOGSTART = 00000010h EVENT_SYSTEM_DIALOGEND = 00000011h EVENT_SYSTEM_SCROLLINGSTART = 00000012h EVENT_SYSTEM_SCROLLINGEND = 00000013h EVENT_SYSTEM_SWITCHSTART = 00000014h EVENT_SYSTEM_SWITCHEND = 00000015h EVENT_SYSTEM_MINIMIZESTART = 00000016h EVENT_SYSTEM_MINIMIZEEND = 00000017h EVENT_OBJECT_CREATE = 00008000h EVENT_OBJECT_DESTROY = 00008001h EVENT_OBJECT_SHOW = 00008002h EVENT_OBJECT_HIDE = 00008003h EVENT_OBJECT_REORDER = 00008004h EVENT_OBJECT_FOCUS = 00008005h EVENT_OBJECT_SELECTION = 00008006h EVENT_OBJECT_SELECTIONADD = 00008007h EVENT_OBJECT_SELECTIONREMOVE = 00008008h EVENT_OBJECT_SELECTIONWITHIN = 00008009h EVENT_OBJECT_STATECHANGE = 0000800ah EVENT_OBJECT_LOCATIONCHANGE = 0000800bh EVENT_OBJECT_NAMECHANGE = 0000800ch EVENT_OBJECT_DESCRIPTIONCHANGE = 0000800dh EVENT_OBJECT_VALUECHANGE = 0000800eh EVENT_OBJECT_PARENTCHANGE = 0000800fh EVENT_OBJECT_HELPCHANGE = 00008010h EVENT_OBJECT_DEFACTIONCHANGE = 00008011h EVENT_OBJECT_ACCELERATORCHANGE = 00008012h EVENT_CONSOLE_CARET = 00004001h CONSOLE_CARET_SELECTION = 00000001h CONSOLE_CARET_VISIBLE = 00000002h EVENT_CONSOLE_UPDATE_REGION = 00004002h EVENT_CONSOLE_UPDATE_SIMPLE = 00004003h EVENT_CONSOLE_UPDATE_SCROLL = 00004004h EVENT_CONSOLE_LAYOUT = 00004005h EVENT_CONSOLE_START_APPLICATION = 00004006h CONSOLE_APPLICATION_16BIT = 00000001h EVENT_CONSOLE_END_APPLICATION = 00004007h EVENT_MAX = 7fffffffh WINEVENT_OUTOFCONTEXT = 0000 WINEVENT_SKIPOWNTHREAD = 0001 WINEVENT_SKIPOWNPROCESS = 0002 WINEVENT_INCONTEXT = 0004
|
|||||||||||
06 Jun 2015, 16:48 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.