Hello guys :)
how to capture a WM_MOUSEMOVE but for a static control?
I try so (WNDPROC):
.elseif eax==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr namet,WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov handlestatic,eax
.elseif eax==WM_MOUSEMOVE
mov edx,hWnd
.if edx==hanldestatic ; handle to static control
....
.endif
mov eax,NULL
ret
but, it cannot work :| why guys ?
addr myclass
i hope that points to a string that looks like this :P
myclass db 'Static',0
the SS_NOTIFY flag probably isn't going to help
it only affects certain messages, and WM_MOUSEMOVE isn't one of them
WM_MOUSEMOVE is sent to the window that contains the cursor, unless the mouse is captured
so - the WndProc for the static control receives that message
other than that - we need to see more code
it is easier if you post an example program with the problem code in it
Per the Microsoft documentation:
Quote
The WM_MOUSEMOVE message is posted to a window when the cursor moves. If the mouse is not captured, the message is posted to the window that contains the cursor. Otherwise, the message is posted to the window that has captured the mouse.
So to receive WM_MOUSEMOVE for the static control you can subclass the static control and handle WM_MOUSEMOVE in the subclass procedure.
i think he already has it subclassed - so that's the way to go
otherwise, he could capture the mouse - i never liked doing that - it seems messy :P
oh yeah im sorry , my code ( modified template ):
I want hide the static control when it is in control area
.386
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
WinMain proto :DWORD,:DWORD
.data
ClassName db "mypaint",0
AppName db "paint program",0
myclass db "Static",0
sname db "statictohide",0
hstatic dd 0
.data?
hInstance HINSTANCE ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr sname, WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax ; save hanlde static control
;.ELSEIF uMsg==WM_MESSAGE? ;when the cursor is moved in static control area
; i want hide the static control
;invoke ShowWindow,hstatic,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
MichaelW, you mean something like this: ( but I cannot assembler,I do not know bcz... lol )
.386
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
myWNDPROC proto :HWND,:UINT,:WPARAM,:LPARAM
WinMain proto :DWORD,:DWORD
.data
ClassName db "mypaint",0
AppName db "paint program",0
myclass db "Static",0
sname db "statictohide",0
hstatic dd 0
mysubclass dd 0
.data?
hInstance HINSTANCE ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
invoke SetWindowLong,mysubclass,GWL_WNDPROC,myWNDPROC
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr sname,SS_BITMAP or WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax ; save hanlde static control
invoke SetWindowLong,hstatic,GWL_WNDPROC,myWNDPROC
mov mysubclass,eax
;.ELSEIF uMsg==WM_MESSAGE? ;when the cursor is moved in static control area
; i want hide the static control
;invoke ShowWindow,hstatic,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
.endif
ret
myWNDPROC endp
hey guys, I could :bg
.386
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
myWNDPROC proto :HWND,:UINT,:WPARAM,:LPARAM
WinMain proto :DWORD,:DWORD
.data
ClassName db "mypaint",0
AppName db "paint program",0
myclass db "Static",0
sname db "statictohide",0
hstatic dd 0
mysubclass dd 0
.data?
hInstance HINSTANCE ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
xor eax,eax
ret
.else
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
.endif
myWNDPROC endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
invoke SetWindowLong,mysubclass,GWL_WNDPROC,myWNDPROC
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr sname,WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax ; save hanlde static control
invoke SetWindowLong,hstatic,GWL_WNDPROC,myWNDPROC
mov mysubclass,eax
;.ELSEIF uMsg==WM_MESSAGE? ;when the cursor is moved in static control area
; i want hide the static control
;invoke ShowWindow,hstatic,NULL
xor eax,eax
ret
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
.endif
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
myWNDPROC endp
in this case, it probably won't make much difference if the static control sees the WM_MOUSEMOVE message or not
but - the other messages that you do not handle need to go to the original WndProc for the static
now - you have to figure out how to unhide it :P
you may want to use TrackMouseEvent
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646265%28v=vs.85%29.aspx
yeah! lol, i thinking do it with handle of main windows, capturing the WM_MOUSEMOVE but, now that u say.. :D
i try :/
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
mov edx,hWnd
mov LEAVEAREA.cbSize,sizeof TRACKMOUSEEVENT
mov LEAVEAREA.dwFlags,TME_NONCLIENT
mov LEAVEAREA.hwndTrack,edx
mov LEAVEAREA.dwHoverTime,HOVER_DEFAULT
invoke TrackMouseEvent,addr LEAVEAREA
xor eax,eax
ret
.elseif uMsg==WM_MOUSELEAVE
invoke ShowWindow,hWnd,SW_SHOW
xor eax,eax
ret
.else
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
.endif
myWNDPROC endp
also, this, i would have do it ( subclassed the constrols ) with all controls?...
make a proc per each control? :S :P
code looks pretty good :U
you may be able to use the same WndProc for all of them
if all you want to do is show and hide them
to do the subclassing - make a loop :P
Quote from: dedndave on April 17, 2012, 03:44:39 AM
code looks pretty good :U
you may be able to use the same WndProc for all of them
if all you want to do is show and hide them
to do the subclassing - make a loop :P
perfect then...
thanks u dave, MichaelW :bg
fixed:
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
mov edx,hWnd
mov LEAVEAREA.cbSize,sizeof(TRACKMOUSEEVENT)
mov LEAVEAREA.dwFlags,TME_HOVER or TME_LEAVE
mov LEAVEAREA.dwHoverTime,1000
mov LEAVEAREA.hwndTrack,edx
invoke TrackMouseEvent,addr LEAVEAREA
xor eax,eax
ret
.elseif uMsg==WM_MOUSELEAVE
invoke ShowWindow,hWnd,SW_SHOW
xor eax,eax
ret
.else
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
.endif
myWNDPROC endp
verifing each second :bg
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
mov eax,uMsg
.if eax==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
.elseif eax==WM_MOUSELEAVE
invoke ShowWindow,hWnd,SW_SHOW
.elseif eax==WM_CREATE
mov edx,hWnd
mov LEAVEAREA.cbSize,sizeof(TRACKMOUSEEVENT)
mov LEAVEAREA.dwFlags,TME_HOVER or TME_LEAVE
mov LEAVEAREA.dwHoverTime,1000
mov LEAVEAREA.hwndTrack,edx
invoke TrackMouseEvent,addr LEAVEAREA
.endif
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
myWNDPROC endp
right!!! the code is executed each time in WM_MOUSEMOVE message! :S
dave, but your code not work me, is not redisplay me the static control :P
EDIT: aparently, the WM_CREATE message, never is executed :P
ok
you are not getting WM_CREATE messages, then
that's because the window isn't subclassed yet when that message is sent :P
maybe put it in the parent window WndProc WM_CREATE
be sure to use hStatic instead of hWnd
invoke CreateWindowEx,NULL,addr myclass,addr sname,
WS_VISIBLE or WS_CHILD,0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax ; save handle static control
mov LEAVEAREA.cbSize,sizeof(TRACKMOUSEEVENT)
mov LEAVEAREA.dwFlags,TME_HOVER or TME_LEAVE
mov LEAVEAREA.dwHoverTime,1000
mov LEAVEAREA.hwndTrack,eax
invoke TrackMouseEvent,addr LEAVEAREA
continues without re-showing the static control :|
also, if created, the static control without SS_NOTIFY, do not even control hides
my code:
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;LOCAL LEAVEAREA:TRACKMOUSEEVENT
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
.elseif uMsg==WM_MOUSELEAVE
invoke ShowWindow,hWnd,SW_SHOW
.endif
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
myWNDPROC endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
invoke SetWindowLong,mysubclass,GWL_WNDPROC,myWNDPROC
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr sname,WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax
mov LEAVEAREA.cbSize,sizeof(TRACKMOUSEEVENT)
mov LEAVEAREA.dwFlags,TME_HOVER or TME_LEAVE
mov LEAVEAREA.dwHoverTime,1000
mov LEAVEAREA.hwndTrack,eax
invoke TrackMouseEvent,addr LEAVEAREA
invoke SetWindowLong,hstatic,GWL_WNDPROC,myWNDPROC
mov mysubclass,eax
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
QuoteWM_MOUSELEAVE
The mouse left the client area of the window specified in a prior call to TrackMouseEvent.
All tracking requested by TrackMouseEvent is canceled when this message is generated.
The application must call TrackMouseEvent when the mouse reenters its window if it requires
further tracking of mouse hover behavior.
:P
Quote from: dedndave on April 17, 2012, 06:24:41 AM
QuoteWM_MOUSELEAVE
The mouse left the client area of the window specified in a prior call to TrackMouseEvent.
All tracking requested by TrackMouseEvent is canceled when this message is generated.
The application must call TrackMouseEvent when the mouse reenters its window if it requires
further tracking of mouse hover behavior.
:P
oh yeah!, then is required call the function in WM_MOUSEMOVE :P thanks dave, now, I will do it with controls multiples and i will post
Hello :P
I try do it with multiple controls but I couldn't do it... well - yes, I do it,but incorrectly, apparently...
bcz the cpu is rise 50%-60% when I move the cursor in the control area... :|
I think bcz sometime a return wrong in EAX : P
Dave, ur code also do the cpu rise to 50-60% : P
I read the comments in your code, apparently there is a error in EAX, right?
.386
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
myWNDPROC proto :HWND,:UINT,:WPARAM,:LPARAM
WndProc proto :HWND,:UINT,:WPARAM,:LPARAM
WinMain proto :DWORD,:DWORD
.data
ClassName db "mypaint",0
AppName db "paint program",0
myclass db "Static",0
sname db "statictohide",0
sname2 db "statictohide2",0
hstatic dd 0
hstatic2 dd 0
mysubclass dd 0
returnclass dd 0
.data?
hInstance HINSTANCE ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
myWNDPROC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
.if uMsg==WM_MOUSEMOVE
invoke ShowWindow,hWnd,SW_HIDE
mov edx,hWnd
mov LEAVEAREA.cbSize,sizeof(TRACKMOUSEEVENT)
mov LEAVEAREA.dwFlags,TME_HOVER or TME_LEAVE
mov LEAVEAREA.dwHoverTime,1000
mov LEAVEAREA.hwndTrack,edx
invoke TrackMouseEvent,addr LEAVEAREA
.elseif uMsg==WM_MOUSELEAVE
invoke ShowWindow,hWnd,SW_SHOW
.else
invoke CallWindowProc,mysubclass,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
myWNDPROC endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL LEAVEAREA:TRACKMOUSEEVENT
.IF uMsg==WM_DESTROY
invoke SetWindowLong,mysubclass,GWL_WNDPROC,myWNDPROC
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr myclass,addr sname,WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
0h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic,eax ; save hanlde static control
invoke CreateWindowEx,NULL,addr myclass,addr sname2,WS_VISIBLE or WS_CHILD or SS_NOTIFY, \
60h,0h,50h,50h,hWnd,NULL,hInstance,NULL
mov hstatic2,eax
invoke SetWindowLong,hstatic,GWL_WNDPROC,myWNDPROC
invoke SetWindowLong,hstatic2,GWL_WNDPROC,myWNDPROC
mov mysubclass,eax
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
all is ok - but the CPU increases to 50% ( only when move the cursor in the static control area )
-
-
-
I tried do it to several ways, but none worked it
for example, return eax = 1, eax = 0
return with callwindowProc....
and, sometimes the program would crashed...
Now that I have had time to test it, my "subclass" solution did not work as expected, but it did provide some useful information. For a static control the WM_MOUSEMOVE message is sent to the parent window only, and the cursor coordinates are relative to the client area of the parent window, even when the cursor is over the control. If I change the static control to a button, for example, then the subclass procedure receives WM_MOUSEMOVE messages and the cursor coordinates are relative to the client area of the button. So it looks like the problem here is specific to static controls.
In the WM_MOUSEMOVE handler for the parent you can determine if the cursor is in the static control by comparing the cursor coordinates to the control coordinates. This test app includes the subclass code, now commented out. Build as a console app:
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
IDC_STC equ 1001
;==============================================================================
.data
hInstance HANDLE 0
hwndStatic HWND 0
wpOrigStaticProc WNDPROC 0
pt POINT <>
rc RECT <>
.code
;==============================================================================
SubclassProc proc hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_MOUSEMOVE
printf("S\t%d\t%d\n",wParam,lParam)
ENDSW
invoke CallWindowProc, wpOrigStaticProc, hwnd, uMsg, wParam, lParam
ret
SubclassProc endp
;==============================================================================
DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_INITDIALOG
invoke GetDlgItem, hwndDlg, IDC_STC
mov hwndStatic, eax
;invoke SetWindowLong, hwndStatic, GWL_WNDPROC, SubclassProc
;mov wpOrigStaticProc, eax
CASE WM_MOUSEMOVE
;-------------------------------------------------------
; Load the cursor coordinates into the POINT structure.
;-------------------------------------------------------
mov eax, lParam
movzx ecx, ax
shr eax, 16
movzx edx, ax
mov pt.x, ecx
mov pt.y, edx
;----------------------------------------------------------
; Convert the client coordinates in the POINT structure to
; screen coordinates.
;-----------------------------------------------------------
invoke ClientToScreen, hwndDlg, ADDR pt
;--------------------------------------------------------------
; Get the screen coordinates for the static control rectangle.
;--------------------------------------------------------------
invoke GetWindowRect, hwndStatic, ADDR rc
;------------------------------------------------------------
; Determine if the cursor is within the bounds of the static
; control.
;
; Because the MASM32 PtInRect proto specifies three DWORD
; args instead of one DWORD and one POINT arg, the POINT
; arg must be split into its DWORD components.
;------------------------------------------------------------
invoke PtInRect, ADDR rc, pt.x, pt.y
.IF eax
printf("X")
.ELSE
printf("0")
.ENDIF
CASE WM_COMMAND
SWITCH wParam
CASE IDCANCEL
invoke EndDialog, hwndDlg, NULL
ENDSW
CASE WM_CLOSE
invoke EndDialog, hwndDlg, NULL
ENDSW
return 0
DlgProc endp
;==============================================================================
start:
;==============================================================================
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"MS Sans Serif",10, \
WS_VISIBLE or WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
1,0,0,100,100,1024
DlgStatic 0,WS_BORDER or SS_BITMAP,10,10,78,70,IDC_STC
;DlgButton "X",0,10,10,78,70,IDC_STC
CallModalDialog hInstance,0,DlgProc,NULL
exit
;==============================================================================
end start
you may get hundreds of WM_MOUSEMOVE messages
what we need is a flag that we can test to see if the code has been executed
there are a few things we can do to speed things up
1) put the TRACKMOUSEEVENT in the initialized .DATA section
initialize everything except the hwndTrack member
2) when you execute the WM_MOUSEMOVE code, test the hwndTrack member to see if it matches the current hWnd
if it does, you have already hidden the window and set up tracking, so exit
if it does not, hide the window and set up tracking
3) when you receive the WM_MOUSELEAVE message, set the hwndTrack member to 0 (or some non-hWnd value)
very strange
i continually get WM_MOUSELEAVE messages while hovering over the static control
i guess i'll have to add code that tests the cursor position inside the bounds of the static rectangle ::)
EDIT: that won't help, as the tracking event is supposedly canceled each time the message is sent :(
i must be doing something wrong
ok - once again, we have to force windows to behave the way it should - lol
observe processor usage while hovering over the static controls....
i should probably add a test to see if the parent is the top window
it keeps working when the static control is partially obscured by another window - lol
ok - now it only works if the dialog is the foreground window :P
back to the other project...
All that looks like an overkill to me... why not simple use a region matching the control??
QuoteCASE WM_MOUSEMOVE
if 0 ; in WM_SIZE:
invoke DeleteObject, hRgn
lea eax, [esi+ButtonWidth]
mov hRgn, rv(CreateRectRgn, esi, 11+ButtonHeight*(1+UseButton2), eax, 11+ButtonHeight*(2+UseButton2))
endif
movsx eax, word ptr lParam
movsx edx, word ptr lParam+2
invoke PtInRegion, hRgn, eax, edx
.if eax
.if !rgnHit
SetWin$ hStatic="Get outta here"
or rgnHit, -1
.endif
.if wParam == MK_SHIFT
SetWin$ hStatic="SHIFT outta here"
.endif
.elseif rgnHit
and rgnHit, 0
SetWin$ hStatic="Bye"
.endif
dave, amazing! :| but i have a question!
HOW YOU DO IT?
how to you know where is error? ( actually is not error, is a bad program structured )
how to you know what to functions ?
tell me!, I want learn lol :red
I will convert it to WNDPROC procedure program : P
@JJ
where i can download the Masmbasic.inc , gives me errors : P
Quote from: RHL on April 17, 2012, 09:26:50 PM
@JJ
where i can download the Masmbasic.inc , gives me errors : P
http://www.masm32.com/board/index.php?topic=12460
Jochen's method might be a good one :P
the way i fgured out when messages were being sent...
i use lines like this to tell me - sometimes it tells you more than olly
invoke Beep,300,40
i also have this other program i wrote to tell me what messages are sent...
http://www.masm32.com/board/index.php?topic=17163.0
for a different program, i am using SetCapture and ReleaseCapture
i also handle WM_CAPTURECHANGED messages
and - i am using Keith's suggestion for PtInRect :U
it seems to be working quite well :bg