How to Ownerdraw a Button

Share your advanced PureBasic knowledge/code with the community.
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

How to Ownerdraw a Button

Post by Konne »

Hello,
Today I was reading a little bit MSDN and made some experiences with Ownerdraw. And because I'm a very nice person I post my result here ;)
Have a lot of fun with it.

If u do not understand something just ask.

Code: Select all

OpenLibrary(1,"Msimg32.dll")    ;load te Command GradientFill_() because it's missing in the PB predeclared Api Things
Prototype GradientFill_(hdc,*Vert,Int,*Rect,Int2,Flags)
Global GradientFill_.GradientFill_=GetFunction(1,"GradientFill")

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Select Message      ;selecting the Message of the callback
    Case #WM_CLOSE    ;If the [x] is pressed
      DestroyWindow_(Window) 
      
    Case #WM_DESTROY  ;If close Is made
      PostQuitMessage_(0) 
      Result  = 0 
    
    Case #WM_INITDIALOG   ;initializing of the Button
      Debug "Init"
      
    Case #WM_DRAWITEM     ;if the Gadget has to be redrawn      
      Debug "Draw" 
      
      *Item.DRAWITEMSTRUCT=lParam       ;Set the Pointer To the Structure
      
      With *Item
      Dim Vert.TRIVERTEX(1)       ;Allocate an array with 2 Element. One is the top the other one the bottom color
            
      *Coor.RECT=\rcItem      ;Set the Pointer to the Rect Structure and Caluculate x,y Width and Heigt
      x.l=*Coor\left
      y.l=*Coor\top
      w.l=*Coor\right-*Coor\left
      h.l=*Coor\bottom-*Coor\top      

      If \itemState & #ODS_SELECTED     ;if the Gadget is selected
        EndWith
      
        With Vert(1)    ;make the gradiant this way
          \x=1
          \y=1        
        EndWith 
        With Vert(0)
          \x=w-1
          \y=h-1        
        EndWith
      Else      ;otherwise te other way around
      
        With Vert(1)
          \x=w-1
          \y=h-1
        EndWith 
        With Vert(0)
          \x=1
          \y=1
        EndWith
      EndIf

      With Vert(0)    ;Set the Colors
        \Red=$9700
        \Green=$BF00
        \Blue=$F000
        \Alpha=0
      EndWith
      
      With Vert(1)
        \Red=0
        \Green=0
        \Blue=$FF00
        \Alpha=0       
      EndWith

      Rect.GRADIENT_RECT      ;Set the Elements of te Array wich are used (here 0 and 1)
      With Rect
      
      \UpperLeft  = 0
      \LowerRight = 1      
     
      EndWith
     
      With *Item
        Rectangle_(\hdc,0,0,w,h)        ;Draw a black rectangle on te hdc of the Gadget
        GradientFill_(\hdc,@Vert(),2,Rect,1,#GRADIENT_FILL_RECT_V)    ;Make the gradiant 2 and 1 stands for the Elements of the Array

        SysCol=$FFFFFF;GetSysColor_(COLOR_WINDOW+6)       ;Choose a color for te Edges of the Button
        SetPixelV_(\hdc,0,0,SysCol)         ;Draw the 4 Pixels at the Edges
        SetPixelV_(\hdc,w-1,0,SysCol)
        SetPixelV_(\hdc,0,h-1,SysCol)
        SetPixelV_(\hdc,w-1,h-1,SysCol)
                       
        SetBkMode_(\hdc,#TRANSPARENT)   ;Make the Background Transparent
        SetTextColor_(\hdc,$DDDDDD)     ;Set a Text Color
        Text.s{255} ;Allocating the Text for getting the Text
        SendMessage_( \hwndItem  ,#WM_GETTEXT,255,Text.s)                        ;Get the Text
        DrawText_(\hdc,Text.s,-1,*Coor,#DT_CENTER|#DT_VCENTER|#DT_SINGLELINE)         ;Draw the Text u want to draw, -1 sows that it's 0 terminated.
      EndWith

      ProcedureReturn 1  
      
    Case #WM_COMMAND

    Default 
      Result  = DefWindowProc_(Window, Message, wParam, lParam) 
      
  EndSelect 
    
  ProcedureReturn Result 
EndProcedure 

Init.INITCOMMONCONTROLSEX

With Init
  \dwSize=SizeOf(INITCOMMONCONTROLSEX)
  \dwICC=#ICC_STANDARD_CLASSES
EndWith
InitCommonControlsEx_(Init)

#Style  = #WS_VISIBLE | #WS_BORDER | #WS_SYSMENU 
#StyleEx  = #WS_EX_OVERLAPPEDWINDOW 

WindowClass.s  = "My Window"    ;register a Window 
wc.WNDCLASSEX 
wc\cbSize  = SizeOf(WNDCLASSEX) 
wc\lpfnWndProc  = @WindowCallback() 
wc\hCursor  = LoadCursor_(0, #IDC_ARROW); #IDC_ARROW   = Arrow 
wc\hbrBackground  = CreateSolidBrush_($FFFFFF) 
wc\lpszClassName  = @WindowClass 
RegisterClassEx_(@wc) 
;
hWndMain  = CreateWindowEx_(#StyleEx, WindowClass, "Test-Window", #Style, 10, 10, 500, 500, 0, 0, 0, 0) ;Crerate the MainWindow
hwndB=CreateWindowEx_(0, "Button", "Button 1", #WS_CHILD | #WS_VISIBLE|#BS_OWNERDRAW  , 10, 10, 60,60, hWndMain, 1337,GetModule_(0), 0) ;Create the Button 1
hwndB=CreateWindowEx_(0, "Button", "Button 2", #WS_CHILD | #WS_VISIBLE|#BS_OWNERDRAW  , 100, 100, 200,30, hWndMain, 1338,GetModule_(0), 0) ;Create the Button 2
hwndB=CreateWindowEx_(0, "Button", "Button 3", #WS_CHILD | #WS_VISIBLE|#BS_OWNERDRAW  , 300, 300, 100,100, hWndMain, 1339,GetModule_(0), 0) ;Create the Button 2

ShowWindow_(hWndMain,  #SW_SHOWDEFAULT) ;U Don't need it but it's saver
UpdateWindow_(hWndMain); 

While GetMessage_(msg.MSG, #Null, 0, 0 ) ;Windowevent()
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend

edit: Removing mistakes
Last edited by Konne on Fri Aug 11, 2006 12:15 am, edited 2 times in total.
Apart from that Mrs Lincoln, how was the show?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED.
Last edited by srod on Thu Aug 10, 2006 9:29 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Looks very good, Konne! Good work :wink:

@srod: Make sure the dll is loading?
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED.
Last edited by srod on Thu Aug 10, 2006 9:29 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED.
Last edited by srod on Thu Aug 10, 2006 9:30 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

You shouldn't need a CreateGadgetList. Could you try using GetModuleHandle_(0) as the second-last parameter for the buttons, see if that helps.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I do see a couple mistakes. The button handles all have the same variable and the hMenu's are not unique. They must each have a different identifier. The last 2 buttons both have 1338.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED.
Last edited by srod on Thu Aug 10, 2006 9:30 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Maybe throw a ShowWindow_ in for each of the buttons? (Give 'em unique vars first)
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED.
Last edited by srod on Thu Aug 10, 2006 9:31 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Got it. I had to place an InitCommonControls_() command in. Obviously on my system, using the API to create all windows leaves the common controls dll out of the link.

I'll remember this one! :)

Still, Konne, why are you using the api to create the windows and buttons etc? Why not use PB commands?
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I'm using XP pro here, you're using Home, srod, right? Could be a difference in the way things are being done between the two Windows versions.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Aye that must be it. I don't even have service pack 2 so that probably doesn't help!

Nice buttons by the way Konne. :)
I may look like a mule, but I'm not a complete ass.
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Post by Konne »

I didn't use PB commands because I'm trying to understand the API. Yes rigt with the ID and double stuff I was just copying and u know it was lake...
Yes I dind't use InitCommonControls that was very stupid. Te MSDN told me hundreds of times to do so but , I worked witout on my Computer.
Apart from that Mrs Lincoln, how was the show?
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Post by Konne »

Oh one last ting. GetModuleHandle_(0) what is that thing for. I see it all the time but it works without it too.
Apart from that Mrs Lincoln, how was the show?
Post Reply