Making a toggle gadget.

BlitzPlus Forums/BlitzPlus Programming/Making a toggle gadget.

Shagwana(Posted 2003) [#1]
Right, I want to change an existing blitz built gadget to a toggle type. But now im unsure of what to do inorder to overcome some short commings in my code;

The User32.decls file in userlib folder...
.lib "user32.dll"
SendMessage%(hWnd%,Msg%,wParam%,lParam%):"SendMessageA"


Blitz code...
;Event flags
Const EVENT_KEYDOWN      = $101  ; Key pressed 
Const EVENT_KEYUP        = $102  ; Key released 
Const EVENT_KEYCHAR      = $103  ; Key generated ASCII character 
Const EVENT_MOUSE_DOWN   = $201  ; Mouse button pressed 
Const EVENT_MOUSE_UP     = $202  ; Mouse button released 
Const EVENT_MOUSE_MOVE   = $203  ; Mouse moved 
Const EVENT_MOUSE_ENTER  = $205  ; Mouse enters canvas area
Const EVENT_MOUSE_EXIT   = $206  ; Mouse leaves canvas area
Const EVENT_GADGET       = $401  ; Gadget clicked 
Const EVENT_MOVE         = $801  ; Window moved 
Const EVENT_SIZE         = $802  ; Window resized 
Const EVENT_CLOSE        = $803  ; Window closed 
Const EVENT_MENU         = $1001 ; Menu item selected 
Const EVENT_APP_PAUSED   = $2001 ; The app has been suspended (loss windows focus) 
Const EVENT_APP_STARTED  = $2002 ; The app has been resumed (regained windows focus) 
Const EVENT_TIMERTICK    = $4001 ; A blitz timer has ticked

Const QUERYID_WIN32_HWND   = 1   ; Win32 HWND

;Win32
Const BM_SETSTATE= 243   ;Set a buttons state (up / down)

;Example code...
pWin=CreateWindow("Toggle gadget",100,100,400,300,0,%1011)


pGadget1=CreateButton("Layer1",10,14,100,24,pWin,0)
pGadget2=CreateButton("Layer2",10,54,100,24,pWin,0)
pGadget3=CreateButton("Layer2",10,88,100,24,pWin,0)


pHwnd1=QueryObject(pGadget1,QUERYID_WIN32_HWND)     ;Gets a windows handle
pHwnd2=QueryObject(pGadget2,QUERYID_WIN32_HWND)
pHwnd3=QueryObject(pGadget3,QUERYID_WIN32_HWND)

bDone=False
Repeat

  Ev=WaitEvent()
  Es=EventSource()


  Select Es
    Case pGadget1
    SetStatusText(pWin,"Gadget1 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd1))
    SendMessage(pHwnd1,BM_SETSTATE,1,0)
    SendMessage(pHwnd2,BM_SETSTATE,0,0)
    SendMessage(pHwnd3,BM_SETSTATE,0,0)


    Case pGadget2
    SetStatusText(pWin,"Gadget2 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd2))
    SendMessage(pHwnd1,BM_SETSTATE,0,0)
    SendMessage(pHwnd2,BM_SETSTATE,1,0)
    SendMessage(pHwnd3,BM_SETSTATE,0,0)


    Case pGadget3
    SetStatusText(pWin,"Gadget3 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd3))
    SendMessage(pHwnd1,BM_SETSTATE,0,0)
    SendMessage(pHwnd2,BM_SETSTATE,0,0)
    SendMessage(pHwnd3,BM_SETSTATE,1,0)

    Case pWin
    ;Window based events
    Select Ev
      Case EVENT_CLOSE  
      bDone=True

      End Select

    End Select

  Until KeyDown(1) Or bDone=True

  End


So far, this sort of works as expected. Now I need to figure out how to deal with 2 problems ...

#1) After pushing one of these gadgets down, tapping tab with pop the gadget back up

#2) Clicking a gadget thats already down, then while holding the mouse, drag the mouse away and release will pop the gadget back up :(


I guess what I need to do is write some sort of .dll to hook into the gadget to deal with these events when they happen. As I dont really know a whole lot about windows hooks, anyone got some pointers on how to implement it?. I plan on using purebasic to code any such .dll thats gona be needed.

Or anyone got a better method to pull off what i want to do (not using a canvas if possible).


Pepsi(Posted 2003) [#2]
I gave it a honost go but couldn't quite get it. This code below doesn't want to push down the button on a toggle of a new button unless your moving the mouse at the same time. I thought I might as well post it in case if it might give you any other ideas. I used toggle variables to help in toggling of the buttons. If you keep the mouse moving as you toggle the buttons, it looks smooth. Try it and see.

Sorry couldnt help any furthor. :/


;Event flags
Const EVENT_KEYDOWN      = $101  ; Key pressed 
Const EVENT_KEYUP        = $102  ; Key released 
Const EVENT_KEYCHAR      = $103  ; Key generated ASCII character 
Const EVENT_MOUSE_DOWN   = $201  ; Mouse button pressed 
Const EVENT_MOUSE_UP     = $202  ; Mouse button released 
Const EVENT_MOUSE_MOVE   = $203  ; Mouse moved 
Const EVENT_MOUSE_ENTER  = $205  ; Mouse enters canvas area
Const EVENT_MOUSE_EXIT   = $206  ; Mouse leaves canvas area
Const EVENT_GADGET       = $401  ; Gadget clicked 
Const EVENT_MOVE         = $801  ; Window moved 
Const EVENT_SIZE         = $802  ; Window resized 
Const EVENT_CLOSE        = $803  ; Window closed 
Const EVENT_MENU         = $1001 ; Menu item selected 
Const EVENT_APP_PAUSED   = $2001 ; The app has been suspended (loss windows focus) 
Const EVENT_APP_STARTED  = $2002 ; The app has been resumed (regained windows focus) 
Const EVENT_TIMERTICK    = $4001 ; A blitz timer has ticked

Const QUERYID_WIN32_HWND   = 1   ; Win32 HWND

;Win32

Const BM_SETSTATE= 243   ;Set a buttons state (up / down)

;Example code...
pWin=CreateWindow("Toggle gadget",100,100,400,300,0,%1011)

pGadget1=CreateButton("Layer1",10,14,100,24,pWin,0)
pGadget2=CreateButton("Layer2",10,54,100,24,pWin,0)
pGadget3=CreateButton("Layer2",10,88,100,24,pWin,0)
pgtoggle1=0
pgtoggle2=0
pgtoggle3=0

pHwnd1=QueryObject(pGadget1,QUERYID_WIN32_HWND)     ;Gets a windows handle
pHwnd2=QueryObject(pGadget2,QUERYID_WIN32_HWND)
pHwnd3=QueryObject(pGadget3,QUERYID_WIN32_HWND)

bDone=False
Repeat
	Ev=WaitEvent()
	Es=EventData()
	Es=EventSource()

	Select Es
	Case pGadget1
		SetStatusText(pWin,"Gadget1 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd1))
		pgtoggle1=1-pgtoggle1
		If pgtoggle1=1
			SendMessage(pHwnd1,BM_SETSTATE,1,0)
			pgtoggle2=0
			pgtoggle3=0
		Else
			SendMessage(pHwnd1,BM_SETSTATE,0,0)
		EndIf
		SendMessage(pHwnd2,BM_SETSTATE,0,0)
		SendMessage(pHwnd3,BM_SETSTATE,0,0)

	Case pGadget2
		SetStatusText(pWin,"Gadget2 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd2))
		pgtoggle2=1-pgtoggle2
		SendMessage(pHwnd1,BM_SETSTATE,0,0)
		If pgtoggle2=1
			SendMessage(pHwnd2,BM_SETSTATE,1,0)
			pgtoggle1=0
			pgtoggle3=0
		Else
			SendMessage(pHwnd2,BM_SETSTATE,0,0)
		EndIf
		SendMessage(pHwnd3,BM_SETSTATE,0,0)

	Case pGadget3
		SetStatusText(pWin,"Gadget3 - $"+Hex$(Ev)+" "+ButtonState(pGadget1)+" $"+Hex(pHwnd3))
		pgtoggle3=1-pgtoggle3
		SendMessage(pHwnd1,BM_SETSTATE,0,0)
		SendMessage(pHwnd2,BM_SETSTATE,0,0)
		If pgtoggle3=1
			SendMessage(pHwnd3,BM_SETSTATE,1,0)
			pgtoggle1=0
			pgtoggle2=0
		Else
			SendMessage(pHwnd3,BM_SETSTATE,0,0)
		EndIf
	Case pWin
	End Select

	;Window based events
	Select Ev
	Case EVENT_CLOSE  
		bDone=True
	End Select	
	
Until KeyDown(1) Or bDone=True

End





Shagwana(Posted 2003) [#3]
Thanks for your effort there pepsi.

I managed to get a form of grouped toggle gadget working (very handy for what I want to do) ...

This bit goes in the user32.decls file;
SetFocus%(hWnd):"SetFocus"
GetWindowLong%(hWnd%,nIndex%):"GetWindowLongA"
SetWindowLong%(hWnd%,nIndex%,iValue%):"SetWindowLongA"


Now the code;

;Event flags
Const EVENT_KEYDOWN      = $101  ; Key pressed 
Const EVENT_KEYUP        = $102  ; Key released 
Const EVENT_KEYCHAR      = $103  ; Key generated ASCII character 
Const EVENT_MOUSE_DOWN   = $201  ; Mouse button pressed 
Const EVENT_MOUSE_UP     = $202  ; Mouse button released 
Const EVENT_MOUSE_MOVE   = $203  ; Mouse moved 
Const EVENT_MOUSE_ENTER  = $205  ; Mouse enters canvas area
Const EVENT_MOUSE_EXIT   = $206  ; Mouse leaves canvas area
Const EVENT_GADGET       = $401  ; Gadget clicked 
Const EVENT_MOVE         = $801  ; Window moved 
Const EVENT_SIZE         = $802  ; Window resized 
Const EVENT_CLOSE        = $803  ; Window closed 
Const EVENT_MENU         = $1001 ; Menu item selected 
Const EVENT_APP_PAUSED   = $2001 ; The app has been suspended (loss windows focus) 
Const EVENT_APP_STARTED  = $2002 ; The app has been resumed (regained windows focus) 
Const EVENT_TIMERTICK    = $4001 ; A blitz timer has ticked


;Query ID 
Const QUERYID_WIN32_HWND   = 1   ; Win32 HWND        
       

;Win32
Const BM_SETSTATE= 243   ;Set a buttons state (up / down)


Const WS_OVERLAPPED       = $00000000
Const WS_POPUP            = $80000000
Const WS_CHILD            = $40000000
Const WS_MINIMIZE         = $20000000
Const WS_VISIBLE          = $10000000
Const WS_DISABLED         = $08000000
Const WS_CLIPSIBLINGS     = $04000000
Const WS_CLIPCHILDREN     = $02000000
Const WS_MAXIMIZE         = $01000000
Const WS_CAPTION          = $00C00000
Const WS_BORDER           = $00800000
Const WS_DLGFRAME         = $00400000
Const WS_VSCROLL          = $00200000
Const WS_HSCROLL          = $00100000
Const WS_SYSMENU          = $00080000
Const WS_THICKFRAME       = $00040000
Const WS_GROUP            = $00020000
Const WS_TABSTOP          = $00010000
Const WS_MINIMIZEBOX      = $00020000
Const WS_MAXIMIZEBOX      = $00010000
Const WS_TILED            = $00000000
Const WS_ICONIC           = $20000000
Const WS_SIZEBOX          = $00040000
Const WS_POPUPWINDOW      = $80880000
Const WS_OVERLAPPEDWINDOW = $00CF0000
Const WS_TILEDWINDOW      = $00CF0000
Const WS_CHILDWINDOW      = $40000000


Const GWL_WNDPROC         = (-4)
Const GWL_HINSTANCE       = (-6)
Const GWL_HWNDPARENT      = (-8)
Const GWL_STYLE           = (-16)
Const GWL_EXSTYLE         = (-20)
Const GWL_USERDATA        = (-21)
Const GWL_ID              = (-12)


;__ main program __



pWin=CreateWindow("Toggle gadget",100,100,400,300,0,%1011)


pGadget1=CreateButton("Layer1",10,14,100,24,pWin,0)
pGadget2=CreateButton("Layer2",10,54,100,24,pWin,0)



pHwnd1=QueryObject(pGadget1,QUERYID_WIN32_HWND)     ;Gets a windows handle
pHwnd2=QueryObject(pGadget2,QUERYID_WIN32_HWND)



bDone=False
Repeat

  Ev=WaitEvent()
  Es=EventSource()



  Select Es
    Case pGadget1

;gadget 1 is down!

    n=GetWindowLong(pHwnd1,GWL_STYLE)
    SetWindowLong(pHwnd1,GWL_STYLE,n Or WS_DISABLED)

    n=GetWindowLong(pHwnd2,GWL_STYLE)
    SetWindowLong(pHwnd2,GWL_STYLE,n And ~WS_DISABLED)

    SetFocus(pHwnd2)

    SendMessage(pHwnd1,BM_SETSTATE,1,0)
    SendMessage(pHwnd2,BM_SETSTATE,0,0)



    Case pGadget2

;gadget 2 is down!

    n=GetWindowLong(pHwnd1,GWL_STYLE)
    SetWindowLong(pHwnd1,GWL_STYLE,n And ~WS_DISABLED)

    n=GetWindowLong(pHwnd2,GWL_STYLE)
    SetWindowLong(pHwnd2,GWL_STYLE,n Or WS_DISABLED)

    SetFocus(pHwnd1)

    SendMessage(pHwnd1,BM_SETSTATE,0,0)
    SendMessage(pHwnd2,BM_SETSTATE,1,0)


    Case pWin
    ;Window based events
    Select Ev
      Case EVENT_CLOSE  
      bDone=True

      End Select


    End Select

  Until KeyDown(1) Or bDone=True

End


Now to get a single toggle gadget working somehow!