October 31, 2025, 05:21:34 AM

News:

IWBasic runs in Windows 11!


ToolBar HitTest

Started by LarryMc, January 05, 2010, 07:56:01 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

When you begin a drag operation on a button in a toolbar, the toolbar sends a message (TBN_BEGINDRAG) to the parent window.

When this message is recieved MS says you can send a message (TB_HITTEST) to the toolbar to determine which button is being dragged.
MS says:
QuoteReturns an integer value. If the return value is zero or a positive value, it is the zero-based index of the nonseparator item in which the point lies.
This is the salient code fragment:LOADTOOLBAR(source,hBitmap,IDTOOLBAR,tbArray,10,@TBTOP|@TBFROMHANDLE|@TBTRANSPARENT|@TBTOOLTIPS|@TBNORESIZE|@TBNOALIGN|CCS_NODIVIDER)
SELECT @CONTROLID
CASE IDTOOLBAR:'toolbar
IF @NOTIFYCODE = TBN_BEGINDRAG
print sendmessage( source,TB_HITTEST,0,&pt,IDTOOLBAR)
print "a", pt.x,pt.y
endif
endselect

Regardless of which button I try to drag the sendmessage always returns the same, very large number and the pt.x/y always return the size of the toolbar itself.

Anyone know what I'm missing?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ficko

Hi Larry!

Maybe that's a stupid answer - I didn't actually try it out - :-[

but how I am reading MS

Quote
Determines where a point lies in a toolbar control.

You have to supply the coordinates of a point.

Quote
....returns the same, very large number ...

MS says:
Quote
If the return value is negative, the point does not lie within a button...

Can that be a unsigned negative value?

LarryMc

I put the mouse location in the pt and now it returns 10 regardless of the button I drag.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

fasecero

Hi Larry.

Perhaps you can try an alternative way:

* TBN_BEGINDRAG send in lParam a structure NMTOOLBAR

* take the member iItem of NMTOOLBAR

* Use the message TB_COMMANDTOINDEX with iItem to get the index of the button.

sapero

Quote from: msdnThe coordinates are relative to the toolbar's client area.
The @MOUSE* coordinates are relative to dropsource-window client area, use
pt.x = @mousex : pt.y = @mousey
MapWindowPoints(win.hwnd, toolbar.hwnd, &pt, 1)
TB_HITTEST

Or just call GetCursorPos and map the result to toolbar relative position:
case @IDDRAGOVER
POINT pt
pointer pwin = @HITWINDOW : settype pwin,window
GetCursorPos(&pt) : ScreenToClient(GetControlHandle(*pwin, IDTOOLBAR), &pt)
pt.x = sendmessage(*pwin, TB_HITTEST, 0, &pt, IDTOOLBAR)
if (pt.x >= 0)
setcaption(*pwin, using("button index: #", pt.x))
else
setcaption(*pwin, using("nearest button index: #", -pt.x))
endif

LarryMc

Thanks guys.
I had just figured out that this works:
SELECT @CONTROLID
CASE IDTOOLBAR:'toolbar
IF @NOTIFYCODE = TBN_BEGINDRAG
GetCursorPos(pt)
ScreenToClient(GETCONTROLHANDLE(source, IDTOOLBAR), pt)
print sendmessage( source,TB_HITTEST,0,pt,IDTOOLBAR)
endif
endselect

As Sapero said, my problem was with the pt.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

Larry,
While processing TBN_BEGINDRAG, source button ID is available in *<NMTOOLBAR>@LPARAM.iItem, so you don't need hit-testing. Include commctrl.inc.

LarryMc

Thanks Sapero!

That works a lot simpler!

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library