PDA

View Full Version : mouse over



Michael Clease
14-11-2007, 01:59
I will keep it simple.

I have a dialog window with a button and I want to know when the mouse pointer is on top of the button.

Do I %WM_Command to find the button control
or
%WM_MOUSEMOVE and then find the button control.

I know XP has NMBCHOTITEM http://msdn2.microsoft.com/en-us/library/bb775959.aspx but I am not sure how to implement that.

Anyone care to point me in the right direction.

sandyrepope
17-11-2007, 03:33
Abraxas, I've been waiting for someone to give an answer because I don't understand just what you are trying to do. I am dying of curiosity.... What exactly are you trying to do?

Thanks
Sandy

Michael Clease
17-11-2007, 10:31
Sandy you will have to wait and see. ;D

I am getting there but its not quite working.

ErosOlmi
17-11-2007, 13:11
Abraxas,

sorry for the delay I take to reply on this.
I looked at NMBCHOTITEM (that I didn't know) and it is valid only from Win2K up. So not sure if it is a valid road.

I have this idea. Use %WM_MOUSEMOVE (http://msdn2.microsoft.com/en-us/library/ms645616.aspx) return message. It returns in LParam the x/y coordinates of the mouse relative to the client area of the window. That use ChildWindowFromPoint (http://msdn2.microsoft.com/en-us/library/ms632676.aspx) function (see declaration below) to get the handle of the child window (any control is in reality a window) where the mouse is located. If it correspond to the button you need than bingo.

Of course you need to know the windows handle of your button and this can be achieve using CONTROL HANDLE (http://www.thinbasic.com/public/products/thinBasic/help/html/control_handle.htm) statement passing the window handle and the control ID. Also consider that all CONTROL ADD ... functions from thinBasic stable version 1.5.0.0 automatically return the window handle of the control just added.




DECLARE FUNCTION ChildWindowFromPoint LIB "USER32.DLL" _
ALIAS "ChildWindowFromPoint" _
(BYVAL hwndParent AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG) AS DWORD





I didn't test my idea so far, so, please, let me know if it works or not.
Ciao
Eros

ErosOlmi
17-11-2007, 18:48
Forget my previous idea, I was not able to make it working.
Anyhow, here a 99% of the times working example. There are some cases that will not work, for example when you window is not the current one but below some other. In this case some side effects can take place.



uses "UI"

TYPE RECT
nLeft AS LONG
nTop AS LONG
nRight AS LONG
nBottom AS LONG
END TYPE

TYPE POINTAPI
x AS LONG
y AS LONG
END TYPE

DECLARE FUNCTION PtInRect LIB "USER32.DLL" ALIAS "PtInRect" (lpRect AS RECT, BYVAL ptx AS LONG, BYVAL pty AS LONG) AS LONG
DECLARE FUNCTION SetCapture LIB "USER32.DLL" ALIAS "SetCapture" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION ReleaseCapture LIB "USER32.DLL" ALIAS "ReleaseCapture" () AS LONG
DECLARE FUNCTION GetCursorPos LIB "USER32.DLL" ALIAS "GetCursorPos" (lpPoint AS POINTAPI) AS LONG
DECLARE FUNCTION GetWindowRect LIB "USER32.DLL" ALIAS "GetWindowRect" (BYVAL hWnd AS DWORD, lpRect AS RECT) AS LONG

%btn_OK = 101
%txt_Result = 102

MAIN

FUNCTION MAIN() as long
DIM Msg AS LONG
DIM wParam AS LONG
DIM lParam AS LONG
DIM hDlg AS DWORD

dim hBtn_OK as dword
dim pt as POINTAPI
dim rc as RECT

DIALOG NEW 0, "MouseOver test", -1, -1, _
100, 100, %WS_SYSMENU or %ds_center OR %WS_CAPTION TO hDlg

CONTROL ADD textbox , hDlg, %txt_Result , "" , 10, 10, 80, 14, %WS_TABSTOP
CONTROL ADD BUTTON , hDlg, %btn_OK , "OK" , 25, 80, 50, 14, %WS_TABSTOP

control handle hDlg, %btn_OK to hBtn_OK


DIALOG SHOW MODELESS hDlg

'---Start the main message loop
WHILE IsWindow(hDlg)

'---Get the message and fill wParam and lParam
Msg = GetMessage(hDlg, wParam, lParam)

SELECT CASE Msg

case %WM_MOUSEMOVE

SetCapture hDlg

GetCursorPos pt
GetWindowRect hBtn_OK, rc

IF ptInRect(rc,pt.x,pt.y) THEN
control set text hDlg, %txt_Result, "Bingo"
ELSE
control set text hDlg, %txt_Result, ""
END IF

ReleaseCapture

CASE %WM_COMMAND

'---Test which control has been clicked
SELECT CASE wParam

CASE %btn_OK
exit while

END SELECT

CASE %WM_SYSCOMMAND

SELECT CASE wParam

CASE %SC_CLOSE
EXIT WHILE


END SELECT

CASE ELSE

END SELECT

WEND

DIALOG END hDlg


END FUNCTION

Petr Schreiber
17-11-2007, 19:08
Hi Eros,

here it works even if window is partially covered.
Really nice sample, thanks !


Petr