Middle mouse close TAB

Just starting out? Need help? Post your questions and find answers here.
A.I
User
User
Posts: 16
Joined: Wed Jul 27, 2005 2:09 pm
Location: Finland

Middle mouse close TAB

Post by A.I »

Tried to search for this, but couldn't find the answer.

You Opera and Firefox users must be familiar with the feature that allows you to close a panel tab via mouse middle click. Now i'd like to implement this feature to one of my programs, but I don't know how to retrieve to "point of hit" relative to gadget itself. Also I need to know what's the width of panels so I can calculate which tab it hit.

I'm currently able to detect if the panel gadget was clicked:

Code: Select all

GetCursorPos_(mouse.POINT)

Case #WM_MBUTTONDOWN
If WindowFromPoint_(mouse\x,mouse\y) = GadgetID(#GADGET_PANEL)
;something here
EndIf
I guess this goes beautifully with the help of win API...
Specialized in "AI Programming Games".
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

Post by dagcrack »

Code: Select all

w=640 : h=480
OpenWindow(1,0,0,w,h,13107201,"");
CreateGadgetList(WindowID(1));
PanelGadget(1,0,0,w,h)

For m=1 To 15;
AddGadgetItem(1,m,Str(Random(1000)))
Next


Repeat
  wwe = WaitWindowEvent()
  gid = EventGadgetID()
  
  If gid = 1
      If wwe = #WM_MBUTTONDOWN
        pos =  GetGadgetState(1)
        RemoveGadgetItem(1,pos)
        SetGadgetState(1,pos-1)
      EndIf
  EndIf

Until wwe = #PB_Event_CloseWindow
End
Thats just to show you a possible way.

That code will let you erase the selected tab if the middle mouse button is pressed. But it wont erase the one where the mouse is over at.

If you cant get the logical way to know at which tab you're over, then you might only have one method left: calculate everything by "hand" (as you suggested).

I would like to mimic firefox's behavior, but I have no time at the moment, hope that helps as a pointer and as testing platform. But yep, using the Windows API you'll get to it.
! Black holes are where God divided by zero !
My little blog!
(Not for the faint hearted!)
A.I
User
User
Posts: 16
Joined: Wed Jul 27, 2005 2:09 pm
Location: Finland

Post by A.I »

Thanks for your example, but it really didn't bring anything new to my attempts.

EDIT:

Seems that EventlParam() returns different kind of values on every click. It also seems related to cursor position. May be that's a lead.

Debug Str(EventlParam())
Specialized in "AI Programming Games".
A.I
User
User
Posts: 16
Joined: Wed Jul 27, 2005 2:09 pm
Location: Finland

Post by A.I »

OK, I can now retrieve the X-coordinate of the click:

Code: Select all

Structure HDHITTESTINFO 
   pt.POINT 
   flags.l 
   iItem.l 
EndStructure 

TestHit.HDHITTESTINFO
GetCursorPos_(Hit\pt)
ScreenToClient_(GadgetID(#GADGET_PANEL), Hit\pt)
Debug Hit\pt\x
Now I need to know what's the size of panel items in order to calculate which tab the cursor is over.
Specialized in "AI Programming Games".
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

May need a little fine tuning but try this...

Code: Select all

tchti.TC_HITTESTINFO

;-->  TC_HITTESTINFO\flags
;-->
;-->  Variable that receives the results of a hit test.
;-->  the tab control sets this member To one of the following values: 
;-->
;-->  #TCHT_NOWHERE = 1
;-->    the position is not over a tab.
;-->  #TCHT_ONITEM = #TCHT_ONITEMICON | #TCHT_ONITEMLABEL
;-->    the position is over a tab but not over its icon Or its text.
;-->    For owner-drawn tab controls, this value is specified If the
;-->    position is anywhere over a tab.
;-->  #TCHT_ONITEMICON = 2
;-->    the position is over a tab's icon.
;-->  #TCHT_ONITEMLABEL = 4
;-->    the position is over a tab's text. 
;--> 
;-->  #TCHT_ONITEM is a bitwise-Or operation on TCHT_ONITEMICON And TCHT_ONITEMLABEL

#WINDOW_MAIN = 0
#GADGET_PANEL = 0
If OpenWindow(#WINDOW_MAIN, 0, 0, 600, 400, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Panel Tab Test") And CreateGadgetList(WindowID(#WINDOW_MAIN))
  PanelGadget(#GADGET_PANEL, 0, 0, 600, 400) 
  For i = 0 To 10 
    AddGadgetItem(#GADGET_PANEL, i, "Tab " + Str(i)) 
  Next 
  ActivateGadget(#GADGET_PANEL)
  SetGadgetState(#GADGET_PANEL, 5)
  Repeat 
    event = WaitWindowEvent() 
    If event = #WM_MBUTTONDOWN 
      GetCursorPos_(mouse.POINT)
      If WindowFromPoint_(mouse\x,mouse\y) = GadgetID(#GADGET_PANEL)
        ;--> Fill in our TC_HITTESTINFO pt values
        tchti\pt\x = WindowMouseX()
        tchti\pt\y = WindowMouseY()
        ;--> Send #TCM_HITTEST to PanelGadget
        ;--> tabNum = Tab index or -1 if no tab was clicked
        tabNum = SendMessage_(GadgetID(#GADGET_PANEL), #TCM_HITTEST, 0, @tchti)
        If tchti\flags > #TCHT_NOWHERE And tabNum > -1
          RemoveGadgetItem(#GADGET_PANEL, tabNum) 
          SetGadgetState(#GADGET_PANEL, tabNum)
        EndIf
      EndIf
    EndIf 
  Until event = #PB_Event_CloseWindow 
EndIf
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
A.I
User
User
Posts: 16
Joined: Wed Jul 27, 2005 2:09 pm
Location: Finland

Post by A.I »

Wow, this seems to work exactly as I want :D
It works even if there's more tabs than fit to window and they're scrolled.

Many thanks.

Cheers.
Specialized in "AI Programming Games".
Post Reply