Page 1 of 2

Add Buttons to Windows Title Bar(Windows)

Posted: Tue Nov 09, 2010 8:22 pm
by RASHAD
You need 2 images
state1.bmp 24 x 24 pixel to represent the button in normal state
state2.bmp 24 x 24 pixel to represent the button in hover state

You can make it 3 state button
Tested with XP SP2 & Win 7 x64 PB x86 4.51

Code: Select all

Global x,y,buttonW,buttonH,borderW


Procedure WndProc(hwnd, uMsg, wParam, lParam)

      GetWindowRect_(WindowID(1),r.RECT)
      x = r\right - (buttonW*5) - borderW   ;5 = for Max & Restore & Min and 2 more buttons
      y = r\top
      If OSVersion() <= #PB_OS_Windows_XP
        y = y + 5
      Else
        x = x + 10
      EndIf
      result = #PB_ProcessPureBasicEvents 

 Select uMsg
   
        Case #WM_NOTIFY     
        
        Case #WM_GETMINMAXINFO     
            *pMinMax.MINMAXINFO = lParam
            *pMinMax\ptMinTrackSize\x=buttonW*5
        
      
        Case #WM_SIZE,#WM_MOVE,#WM_PAINT
           If GetWindowState(1) = #PB_Window_Maximize
              ResizeWindow(2,x,y+4,buttonW*2,buttonH)    
           Else
               ResizeWindow(2,x,y,buttonW*2,buttonH) 
           EndIf
             
   EndSelect
   
  ProcedureReturn result 
EndProcedure

LoadImage(0, "state1.bmp")              ;24 x 24 pixel    Button state 1
LoadImage(1, "state2.bmp")              ;24 x 24 pixel    Button state 2

buttonW = GetSystemMetrics_(#SM_CXSIZE)
buttonH = GetSystemMetrics_(#SM_CYSIZE)
borderW = GetSystemMetrics_(#SM_CXBORDER)

OpenWindow(1,0,0,600,400,"Add Button to Title Bar", #PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
OpenWindow(2,0,0,buttonW*2,buttonH,"",#WS_POPUP,WindowID(1))
SetWindowColor(2,#Red)
SetWindowLong_(WindowID(2),#GWL_EXSTYLE,GetWindowLong_(WindowID(2),#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(2),#Red,0,#LWA_COLORKEY)
ImageGadget(10,2,0,30,20,ImageID(0))
ImageGadget(11,28,0,30,20,ImageID(0))

SetWindowCallback(@WndProc())
SetActiveWindow(1)

Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
           Q = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
            Case 10
              Debug "Button 10 Pressed"

            Case 11
              Debug "Button 11 Pressed"

           EndSelect
           SetActiveWindow(1)
           
      Case #WM_MOUSEMOVE
         GetCursorPos_(@p.POINT)
         If p\x >= x+5 And p\x <= x+30 And p\y >= y+4 And p\y <=y+25
           SetGadgetState(10,ImageID(1))
         Else
           SetGadgetState(10,ImageID(0))
         EndIf
         If p\x >= x+35 And p\x <= x+55 And p\y >= y+4 And p\y <=y+25
           SetGadgetState(11,ImageID(1))
         Else
           SetGadgetState(11,ImageID(0))
         EndIf
           
  EndSelect 
Until Q =1
End


Re: Add Buttons to Windows Title Bar(Windows)

Posted: Wed Nov 10, 2010 1:30 am
by electrochrisso
Nice one RASHAD, I am now pretty well clued up on Title Bar Buttons. :D

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Wed Nov 10, 2010 10:08 pm
by Rook Zimbabwe
Excellent Rashad!!! You are rocking PB!!! :D

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Thu Nov 11, 2010 12:35 am
by blueznl
Cool!

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Thu Nov 11, 2010 12:38 am
by PB
Rashad's code has 3 problems though:

(1) It doesn't work if #PB_Window_Tool is used for the window,
because the images are too large. So, you'll need 2 additional
sized buttons for those. This is not a major problem.


(2) If the window gets maximized, the buttons are not aligned
correctly in the vertical position of the title bar:

Image


(3) It doesn't work with different color schemes. Check this:

Image


So, still some work to do to make it 100% bullet-proof on all PCs. ;)

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Thu Nov 11, 2010 2:35 am
by RASHAD
@electrochrisso
Thanks man "I am now pretty well clued up on Title Bar Buttons."
Yes you just summarized the whole idea, it is just an approach

@Rook thanks I definitely like you mate
You are rock

@blueznl
Thank you
You are always in the spot with your nice comments

@PB
Most of your comments is the coder responsibility
But I will see what I can do

Thank you guys

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Thu Nov 11, 2010 9:17 am
by RASHAD
New Update :
Now you can use any size for the images (Reasonable Size)
It will be resized to be fine with any TitleBar height

#1 :
Modified by MV
For solving a problem when the minimize animation is enabled in win 7

Code: Select all

Global x,y,w,buttonW,buttonH,borderW,r1.RECT,r2.RECT,ma


Procedure CreateButton(image,x,y,text.s="×",color=$c0c0c0)
   
    If CreateImage(image,x,y)
        StartDrawing(ImageOutput(image))
        Box(1,1,x-2,y-2,color)
        Plot(0,y-1,color)
        Plot(x-1,y-1,color)
        DrawingMode(#PB_2DDrawing_Transparent)
        x-TextWidth(text)
        y-TextHeight(text)
        DrawText(x>>1,y>>1,text)
        StopDrawing()
    EndIf
   
EndProcedure

Procedure WndProc(hwnd, uMsg, wParam, lParam)

      GetWindowRect_(WindowID(1),r.RECT)
      x = r\right - (buttonW*5) - borderW   ;5 = for Max & Restore & Min and 2 more buttons
      y = r\top
      If OSVersion() <= #PB_OS_Windows_XP
        y = y + 5
      Else
        x = x + 20
      EndIf
;       If w < 20
;         x = x = r\right - (buttonW*4) - borderW + 8
;       EndIf
      result = #PB_ProcessPureBasicEvents 

 Select uMsg
   
        Case #WM_NOTIFY     
        
        Case #WM_GETMINMAXINFO     
            *pMinMax.MINMAXINFO = lParam
            *pMinMax\ptMinTrackSize\x=buttonW*5
        
      
        Case #WM_SIZE,#WM_MOVE,#WM_PAINT
          GetWindowRect_(GadgetID(10),r1.RECT)
          GetWindowRect_(GadgetID(11),r2.RECT)
          r1\top = r1\top + 2
          r2\top = r2\top + 2
          If GetWindowState(1) = #PB_Window_Maximize
            If OSVersion() <= #PB_OS_Windows_XP
              ResizeWindow(2,x,y,(w+4)*2,buttonH)
            Else
              ResizeWindow(2,x-4,y+6,(w+4)*2,buttonH)
            EndIf
           Else
              ResizeWindow(2,x,y,(w+4)*2,buttonH) 
           EndIf
             
   EndSelect
   
  ProcedureReturn result 
EndProcedure

anm.ANIMATIONINFO\cbSize = SizeOf(ANIMATIONINFO)
SystemParametersInfo_($0048, SizeOf(ANIMATIONINFO), @anm, 0)
ma = anm.ANIMATIONINFO\iMinAnimate
If ma = 1
    anm.ANIMATIONINFO\iMinAnimate = 0
    SystemParametersInfo_($0049, SizeOf(ANIMATIONINFO), @anm, 0)
EndIf



;LoadImage(0, "state1.bmp")              ;24 x 24 pixel    Button state 1
;LoadImage(1, "state2.bmp")              ;24 x 24 pixel    Button state 2

OpenWindow(1,0,0,600,400,"Add Button to Title Bar",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget| #PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
  
w = GetSystemMetrics_(#SM_CYCAPTION) - 2  ;2 to 3
CreateButton(0,w,w)
CreateButton(1,w,w,"?",$f0c0c0)
  buttonW = GetSystemMetrics_(#SM_CXSIZE)
  buttonH = GetSystemMetrics_(#SM_CYSIZE)
  borderW = GetSystemMetrics_(#SM_CXBORDER)
OpenWindow(2,0,0,w*5,w,"",#WS_POPUP,WindowID(1))
SetWindowColor(2,#Red)
SetWindowLongPtr_(WindowID(2),#GWL_EXSTYLE,GetWindowLongPtr_(WindowID(2),#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(2),#Red,0,#LWA_COLORKEY)
;ResizeImage(0,w,w)
;ResizeImage(1,w,w)
;ImageGadget(10,0,0,0,0,ImageID(0))
;ImageGadget(11,0,0,0,0,ImageID(0))
ImageGadget(10,4,0,w,w,ImageID(0))
ImageGadget(11,4+w,0,w,w,ImageID(0))
SetWindowCallback(@WndProc())     
SetActiveWindow(1)

Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
          If ma = 1
              anm.ANIMATIONINFO\iMinAnimate = 1
              SystemParametersInfo_($0049, SizeOf(ANIMATIONINFO), @anm, 0)
          EndIf
           Q = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
            Case 10
              Debug "Button 10 Pressed"

            Case 11
              Debug "Button 11 Pressed"

           EndSelect
           SetActiveWindow(1)
           
           
      Case #WM_MOUSEMOVE,#WM_NCMOUSEMOVE
         GetCursorPos_(@p.POINT)
         If PtInRect_(@r1,PeekQ(@p))
           SetGadgetState(10,ImageID(1))
         Else
           SetGadgetState(10,ImageID(0))
         EndIf
         If PtInRect_(@r2,PeekQ(@p))
           SetGadgetState(11,ImageID(1))
         Else
           SetGadgetState(11,ImageID(0))
         EndIf
           
  EndSelect 
Until Q =1
End

#2 :
Keeping the min anim enabled
#2-1: Using Delay(350) to compensate the lag in timing
#2-2:Or using Windows Timer to do the job

Code: Select all

Global x,y,w,buttonW,buttonH,borderW,r1.RECT,r2.RECT,ma


Procedure WndProc(hwnd, uMsg, wParam, lParam)

      GetWindowRect_(WindowID(1),r.RECT)
      x = r\right - (buttonW*5) - borderW   ;5 = for Max & Restore & Min and 2 more buttons
      y = r\top
      If OSVersion() <= #PB_OS_Windows_XP
        y = y + 5
      Else
        x = x + 20
      EndIf
;       If w < 20
;         x = x = r\right - (buttonW*4) - borderW + 8
;       EndIf
      result = #PB_ProcessPureBasicEvents 

 Select uMsg
   
        Case #WM_NOTIFY     
        
        Case #WM_GETMINMAXINFO     
            *pMinMax.MINMAXINFO = lParam
            *pMinMax\ptMinTrackSize\x=buttonW*5
        
      
        Case #WM_SIZE,#WM_MOVE,#WM_PAINT
          GetWindowRect_(GadgetID(10),r1.RECT)
          GetWindowRect_(GadgetID(11),r2.RECT)
          r1\top = r1\top + 2
          r2\top = r2\top + 2
          If GetWindowState(1) = #PB_Window_Maximize
            If OSVersion() <= #PB_OS_Windows_XP
              ResizeWindow(2,x,y,(w+4)*2,buttonH)
            Else
              ResizeWindow(2,x-4,y+6,(w+4)*2,buttonH)
            EndIf
           Else
              ResizeWindow(2,x,y,(w+4)*2,buttonH) 
           EndIf
             
   EndSelect
   
  ProcedureReturn result 
EndProcedure

anm.ANIMATIONINFO\cbSize = SizeOf(ANIMATIONINFO)
SystemParametersInfo_($0048, SizeOf(ANIMATIONINFO), @anm, 0)
ma = anm.ANIMATIONINFO\iMinAnimate

LoadImage(0, "state1.bmp")              ;24 x 24 pixel    Button state 1
LoadImage(1, "state2.bmp")              ;24 x 24 pixel    Button state 2

OpenWindow(1,0,0,600,400,"Add Button to Title Bar",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget| #PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
;If GetWindowLongPtr_(WindowID(1),#GWL_EXSTYLE) <= 256
  w = GetSystemMetrics_(#SM_CYCAPTION) - 2
  buttonW = GetSystemMetrics_(#SM_CXSIZE)
  buttonH = GetSystemMetrics_(#SM_CYSIZE)
  borderW = GetSystemMetrics_(#SM_CXBORDER)
; Else
;   w = GetSystemMetrics_(#SM_CYSMCAPTION) - 2
;   buttonW = w
;   buttonH = w
; EndIf
OpenWindow(2,0,0,w*5,w,"",#WS_POPUP,WindowID(1))
SetWindowColor(2,#Red)
SetWindowLongPtr_(WindowID(2),#GWL_EXSTYLE,GetWindowLongPtr_(WindowID(2),#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(2),#Red,0,#LWA_COLORKEY)
ResizeImage(0,w,w)
ResizeImage(1,w,w)
ImageGadget(10,4,0,w,w,ImageID(0))
ImageGadget(11,4+w,0,w,w,ImageID(0))
SetWindowCallback(@WndProc())     
SetActiveWindow(1)

Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
           Q = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
            Case 10
              Debug "Button 10 Pressed"

            Case 11
              Debug "Button 11 Pressed"

           EndSelect
           SetActiveWindow(1)
           
      Case #PB_Event_MinimizeWindow
      If ma = 1 And OSVersion() > #PB_OS_Windows_XP
          HideWindow(2,1)
      EndIf
           
      Case #PB_Event_RestoreWindow
      If ma = 1 And OSVersion() > #PB_OS_Windows_XP
          Delay(350)
          ;AddWindowTimer(2, 10, 350)
          HideWindow(2,0)
          SetActiveWindow(1)
      EndIf          
          
      ;Case #PB_Event_Timer
          ;RemoveWindowTimer(2,10)
          ;HideWindow(2,0)
          ;SetActiveWindow(1)
           
      Case #WM_MOUSEMOVE,#WM_NCMOUSEMOVE
         GetCursorPos_(@p.POINT)
;          GetWindowRect_(GadgetID(10),r1.RECT)
;          GetWindowRect_(GadgetID(11),r2.RECT)
;          r1\top = r1\top + 2
;          r2\top = r2\top + 2
         If PtInRect_(@r1,PeekQ(@p))
           SetGadgetState(10,ImageID(1))
         Else
           SetGadgetState(10,ImageID(0))
         EndIf
         If PtInRect_(@r2,PeekQ(@p))
           SetGadgetState(11,ImageID(1))
         Else
           SetGadgetState(11,ImageID(0))
         EndIf
           
  EndSelect 
Until Q =1
End


To do:(If I have some free time)
Using Transparent Images to be compatible with different color schemes

Edit:
#1 Just updated taking into consideration yrriti & MV suggestions

Have fun

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 10:08 am
by Mistrel
If you packed some sample images into your code it would be a lot easier for people to quickly paste into their IDE and test it.

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 10:11 am
by PB
@Mistrel: That's exactly why my screenshots show 2 x black boxes. :)

I just replaced "LoadImage(0, "state1.bmp")" with "CreateImage(0,24,24)"
and "LoadImage(1, "state1.bmp")" with "CreateImage(1,24,24)". ;)

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 11:40 am
by kernadec
hi RASHAD
thanks for sharing
really well for the creation of toolbars included in the window

Good Bye

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 11:51 am
by RASHAD
Hi guys

Last Post updated
Any comments are welcomed

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 2:32 pm
by yrreti
Thanks a lot for this. It looks nice.
Just a little change I made that some might like, as I didn't want the buttons so close to
the min/max, and also to have a little spacing between the buttons. (using XP Pro)
I used PB's temp for the images.

Code: Select all

;LoadImage(0, "state1.bmp")              ;24 x 24 pixel    Button state 1
;LoadImage(1, "state2.bmp")              ;24 x 24 pixel    Button state 2
CreateImage(0,24,24)
CreateImage(1,24,24)
and changed the following lines:

Code: Select all

w = GetSystemMetrics_(#SM_CYCAPTION) - 3  ;2 to 3

;ImageGadget(10,4,0,w,w,ImageID(0))
ImageGadget(10,-2,0,w,w,ImageID(0))

;ImageGadget(11,4+w,0,w,w,ImageID(0))
ImageGadget(11,w,0,w,w,ImageID(0))
Thanks again

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 4:54 pm
by Michael Vogel
Some more changes to do some more checks without the need of bitmaps...

Code: Select all

Procedure CreateButton(image,x,y,text.s="×",color=$c0c0c0)
    
    If CreateImage(image,x,y)
        StartDrawing(ImageOutput(image))
        Box(1,1,x-2,y-2,color)
        Plot(0,y-1,color)
        Plot(x-1,y-1,color)
        DrawingMode(#PB_2DDrawing_Transparent)
        x-TextWidth(text)
        y-TextHeight(text)
        DrawText(x>>1,y>>1,text)
        StopDrawing()
    EndIf
    
EndProcedure

Code: Select all

w = GetSystemMetrics_(#SM_CYCAPTION) - 2  ;2 to 3
CreateButton(0,w,w)
CreateButton(1,w,w,"?",$f0c0c0)
ImageGadget(10,0,0,0,0,ImageID(0))
ImageGadget(11,0,0,0,0,ImageID(0))

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Fri Nov 12, 2010 5:03 pm
by RASHAD
Hey 'yrreti' 'MV' brought it back to
w = GetSystemMetrics_(#SM_CYCAPTION) - 2

Shoot him :mrgreen: :mrgreen:


Edit:
Thank you guys
Just beautiful MV we can use some symbols from webdings or wingdings

Edit:
#1 Just updated taking into consideration yrreti & MV suggestions

Re: Add Buttons to Windows Title Bar(Windows)

Posted: Sat Nov 13, 2010 12:53 pm
by Lewis
Hi folks!

This is an interesting thread! 8) However, it occurred to me that code to remove system icons in the titlebar would be of interest to many a programmer. For example, it's not unusual to see games with just the close icon visible/available.

Anyone care to propose a solution? ...

Cheers,
Lewis