How to Ownerdraw a Button

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

One of the arguments to CreateWindowEx_() requires an 'instance handle' of the module which is to be associated with the window. GetModule_() will furnish an instance handle of any module linked into the current process; dll's etc. GetModule_(0) essentially returns an instance handle of the 'main' module which can thus be used in CreateWindowEx_().

I guess if 0 is used within the CreateWindowEx_() function, then this has the same effect as using GetModule_(0). You're probably best off using GetModule_() though.
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 »

HANDLE :twisted:

ps - nice post count...
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Bloody hell, I hadn't looked at it for a while. Last time I remember looking it was about 1100 or so!

Mind you, most of my posts are full of horse manure and used baby wipes 'cause I don't know what I'm talking about when I'm sober, let alone half baked!

I'm going to hunt out my very first post...
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 »

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 »

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 »

Wed Oct 29, 2003 5:01 pm
Wed Oct 29, 2003 3:47 pm

U're right te search is lying :roll:
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 »

So updated the Code, Enabled Disableing and Made the code easyer to read.
And I have 2 new problems now ;)
First how can I recognize a Mouseover event? I guess It has something to do with #BCN_HOTITEMCHANGE but It's not declared.
Second. #WS_TABSTOP isn't working, does someone know why? I guess I need #BS_NOTIFY as a Window Parameter but it isn't declared.

Code: Select all

EnableExplicit

Global DisableButton

Structure IntParts
    Part1.w
    Part2.w
EndStructure

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 DrawButton(hwnd,hdc,*Coor.RECT,State)
  Protected Dim Vert.TRIVERTEX(1)       ;Allocate an array with 2 Element. One is the top the other one the bottom color
  Protected TCol.l
  Protected Rect.GRADIENT_RECT
  Protected x.l
  Protected y.l
  Protected w.l
  Protected h.l  
  Protected SysCol.l
  Protected Text.s{255} ;Allocating the Text for getting the Text
  Protected Pen
  Protected OldPen
  
  With *Coor 
    x.l=\Left
    y.l=\top
    w.l=\right-\left
    h.l=\bottom-\top
  EndWith
  
  If  State & #ODS_SELECTED     ;{ Button down (selected)   
     With Vert(0)    ;Set the Colors
        \x=1
        \y=1                            
        \Blue=$FF00              
    EndWith
  
    With Vert(1)
        \x=w-1
        \y=h-1            
        \Red=$9700
        \Green=$BF00
        \Blue=$F000
    EndWith
        
    TCol=$DDDDDD
    ;}
  ElseIf State & #ODS_HOTLIGHT ;{ Mouseover
     With Vert(0)    ;Set the Colors
      \x=w-1
      \y=h-1                  
      \Blue=$FF00  
    EndWith
  
    With Vert(1)
      \x=1
      \y=1
      \Red=$9700
      \Green=$BF00
      \Blue=$F000      
    EndWith    
    
    TCol=$DDDDDD
  ;}
  ElseIf State & #ODS_FOCUS ;{ Focus
     With Vert(0)    ;Set the Colors
      \x=w-1
      \y=h-1                  
      \Blue=$FF00  
    EndWith
  
    With Vert(1)
      \x=1
      \y=1
      \Red=$9700
      \Green=$BF00
      \Blue=$F000      
    EndWith    
    
    TCol=$DDDDDD
    

  ;}
  ElseIf State & #ODS_DISABLED  ;{ Disabled
     With Vert(1)   
        \x=1
        \y=1                            
        \Red=$FF00     
        \Green=$FF00   
        \Blue=$FF00   
    EndWith
  
    With Vert(0)    ;Set the Colors
        \x=1
        \y=1                             
        \Red=$EE00
        \Green=$E400
        \Blue=$E900
    EndWith
        
    TCol=$CCCCCC 
  ;}
  Else                               ;{ Normal
    With Vert(0)   
        \x=1
        \y=1                             
        \Red=$EE00
        \Green=$E400
        \Blue=$E900
    EndWith
  
    With Vert(1)
        \x=w-1
        \y=h-1            
        \Red=$C700
        \Green=$B900
        \Blue=$C200
    EndWith
   
    TCol=$222222
    ;}
  EndIf

      ;Set the Elements of te Array wich are used (here 0 and 1)
  With Rect  
    \UpperLeft  = 0
    \LowerRight = 1 
  EndWith
  
  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,TCol)     ;Set a Text Color
  SendMessage_(hwnd,#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.
  
  If State & #ODS_FOCUS
    Pen=CreatePen_(#PS_DOT,1,0) 
    oldpen=GetCurrentObject_(hdc,#OBJ_PEN) 
    SelectObject_(hdc,Pen)
      ;Rectangle_(hdc,2,2,w-3,h-3)
      MoveToEx_(hdc,2,2,0)
      LineTo_(hdc,w-3,2)
      LineTo_(hdc,w-3,h-3)
      LineTo_(hdc,2,h-3)
      LineTo_(hdc,2,2)
    SelectObject_(hdc,oldpen)
    DeleteObject_(Pen)  
  EndIf
EndProcedure

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Protected Result
  Protected *Item.DRAWITEMSTRUCT
  Protected *Parts.IntParts

  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=lParam       ;Set the Pointer To the Structure
      With *Item
        DrawButton(\hwndItem,\hdc,\rcItem,\itemState)
      EndWith
      Result=1 

    Case #WM_COMMAND      
      *Parts=@wParam
      Select *Parts\Part2
        Case #BN_CLICKED
          Debug "Click"
          If IsWindowEnabled_(DisableButton)
            EnableWindow_(DisableButton,0)
          Else
            EnableWindow_(DisableButton,1)
          EndIf  
        
        Case #BN_SETFOCUS
          Debug "Focus"  
          
      EndSelect
      
      ProcedureReturn 0
      
    Default 
      Result  = DefWindowProc_(Window, Message, wParam, lParam) 
      
  EndSelect 

    
  ProcedureReturn Result 
EndProcedure 

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

Define WindowClass.s
Define wc.WNDCLASSEX 
Define hWndMain
Define msg.MSG
Define Init.INITCOMMONCONTROLSEX


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

WindowClass.s  = "My Window"    ;register a Window 
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
CreateWindowEx_(0, "Button", "Button 1", #WS_CHILD | #WS_VISIBLE|#WS_TABSTOP|#BS_OWNERDRAW  , 10, 10, 60,60, hWndMain, 1337,0, 0) ;Create the Button 1
DisableButton=CreateWindowEx_(0, "Button", "Button 2", #WS_CHILD|#WS_TABSTOP| #WS_VISIBLE|#BS_OWNERDRAW  , 100, 100, 200,30, hWndMain, 1338,0, 0) ;Create the Button 2
CreateWindowEx_(0, "Button", "Button 3", #WS_CHILD | #WS_VISIBLE|#WS_TABSTOP|#BS_OWNERDRAW  , 300, 300, 100,100, hWndMain, 1339,0, 0) ;Create the Button 3

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

While GetMessage_(msg, #Null, 0, 0 ) ;Windowevent()
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend
Apart from that Mrs Lincoln, how was the show?
ABBKlaus
Addict
Addict
Posts: 1143
Joined: Sat Apr 10, 2004 1:20 pm
Location: Germany

Post by ABBKlaus »

Konne wrote:#WS_TABSTOP isn't working, does someone know why? I guess I need #BS_NOTIFY as a Window Parameter but it isn't declared.
It´s the missing IsDialogMessage http://msdn.microsoft.com/en-us/library ... S.85).aspx

Code: Select all

#BCN_FIRST=-1250
#NM_CUSTOMTEXT=#NM_FIRST-24
#NM_FONTCHANGED=#NM_FIRST-23
#NM_GETCUSTOMSPLITRECT=#BCN_FIRST + 3
#NM_TVSTATEIMAGECHANGING=#NM_FIRST - 24
#BCN_HOTITEMCHANGE=#BCN_FIRST+1

#HICF_OTHER          =$00000000
#HICF_MOUSE          =$00000001
#HICF_ARROWKEYS      =$00000002
#HICF_ACCELERATOR    =$00000004
#HICF_DUPACCEL       =$00000008
#HICF_ENTERING       =$00000010
#HICF_LEAVING        =$00000020
#HICF_RESELECT       =$00000040
#HICF_LMOUSE         =$00000080
#HICF_TOGGLEDROPDOWN =$00000100

Structure NMCBHOTITEM
  hdr.NMHDR
  dwFlags.l
EndStructure

Procedure wndproc(hwnd,msg,wparam,lparam) 
  Protected Result
  
  Select msg
    Case #WM_NOTIFY ; http://msdn.microsoft.com/en-us/library/bb775583(VS.85).aspx
      ;Debug "#WM_NOTIFY"
      *lpnmhdr.NMHDR=lParam
      ;Debug "hwndFrom="+Str(*lpnmhdr\hwndFrom)
      ;Debug "idFrom="+Str(*lpnmhdr\idFrom)
      ;Debug "code="+Str(*lpnmhdr\code)
      Select *lpnmhdr\code
        Case #TTN_FIRST
          Debug "#TTN_FIRST"
        Case #TTN_GETDISPINFO
          Debug "#TTN_GETDISPINFO"
        Case #TTN_LAST
          Debug "#TTN_LAST"
        Case #TTN_POP
          Debug "#TTN_POP"
        Case #TTN_SHOW
          Debug "#TTN_SHOW"
        Case #NM_CHAR ; http://msdn.microsoft.com/en-us/library/bb775497(VS.85).aspx
          Debug "#NM_CHAR"
        Case #NM_CUSTOMDRAW
          Debug "#NM_CUSTOMDRAW"
        Case #NM_CUSTOMTEXT
          Debug "#NM_CUSTOMTEXT"
        Case #NM_FONTCHANGED
          Debug "#NM_FONTCHANGED"
        Case #NM_GETCUSTOMSPLITRECT
          Debug "#NM_GETCUSTOMSPLITRECT"
        Case #NM_HOVER
          Debug "#NM_HOVER"
        Case #NM_KEYDOWN
          Debug "#NM_KEYDOWN"
        Case #NM_KILLFOCUS
          Debug "#NM_KILLFOCUS"
        Case #NM_LDOWN
          Debug "#NM_LDOWN"
        Case #NM_NCHITTEST
          Debug "#NM_NCHITTEST"
        Case #NM_OUTOFMEMORY
          Debug "#NM_OUTOFMEMORY"
        Case #NM_RDOWN
          Debug "#NM_RDOWN"
        Case #NM_RELEASEDCAPTURE
          Debug "#NM_RELEASEDCAPTURE"
        Case #NM_RETURN
          Debug "#NM_RETURN"
        Case #NM_SETCURSOR
          Debug "#NM_SETCURSOR"
        Case #NM_SETFOCUS
          Debug "#NM_SETFOCUS"
        Case #NM_THEMECHANGED
          Debug "#NM_THEMECHANGED"
        Case #NM_TOOLTIPSCREATED
          Debug "#NM_TOOLTIPSCREATED"
        Case #NM_TVSTATEIMAGECHANGING
          Debug "#NM_TVSTATEIMAGECHANGING"
        Case #BCN_HOTITEMCHANGE ; http://msdn.microsoft.com/en-us/library/bb775959(VS.85).aspx
          Debug "#BCN_HOTITEMCHANGE"
          *nmcbhotiem.NMCBHOTITEM=lParam
          If *nmcbhotiem\dwFlags & #HICF_ENTERING
            Debug "#HICF_ENTERING"
          EndIf
          If *nmcbhotiem\dwFlags & #HICF_LEAVING
            Debug "#HICF_LEAVING"
          EndIf
        Default
          Debug "Unknown message "+Str(*lpnmhdr\code)
      EndSelect
      Debug "----------------------------------------------"
    Case #WM_CLOSE
      DestroyWindow_(hwnd) 
      Result=0
    Case #WM_DESTROY
      PostQuitMessage_(0) 
      Result=0
    Default
      Result=DefWindowProc_(hwnd,msg,wparam,lparam)
  EndSelect
  
  ProcedureReturn Result
EndProcedure 

Procedure Main()
  Protected wnd.wndclass 
  Protected Init.INITCOMMONCONTROLSEX
  Protected hInstance.l = GetModuleHandle_(0)
  
  Init\dwSize = SizeOf(INITCOMMONCONTROLSEX) 
  Init\dwICC  = #ICC_STANDARD_CLASSES|#ICC_WIN95_CLASSES
  CoInitialize_(0)
  InitCommonControlsEx_(Init) 
  
  wnd\style         = #CS_HREDRAW | #CS_VREDRAW 
  wnd\lpfnWndProc   = @wndproc() 
  wnd\hInstance     = GetModuleHandle_(0) 
  wnd\hcursor       = LoadCursor_(0,#IDC_ARROW) 
  wnd\hbrBackground = GetSysColorBrush_(#COLOR_WINDOW)
  wnd\lpszClassName = @"mywindow"
  
  RegisterClass_(wnd)
  
  ;http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx
  hwnd = CreateWindowEx_(0,"mywindow","Title",#WS_VISIBLE|#WS_BORDER|#WS_SYSMENU,000,000,500,500,   0,  0,hInstance,0)
  btn1 = CreateWindowEx_(0,"Button","Button 1",#WS_CHILD|#WS_TABSTOP|#WS_VISIBLE,010,010,060,060,hwnd,100,hInstance,0)
  btn2 = CreateWindowEx_(0,"Button","Button 2",#WS_CHILD|#WS_TABSTOP|#WS_VISIBLE,100,100,200,030,hwnd,101,hInstance,0)
  btn3 = CreateWindowEx_(0,"Button","Button 3",#WS_CHILD|#WS_TABSTOP|#WS_VISIBLE,300,300,100,100,hwnd,102,hInstance,0)
  SendMessage_(btn1,#WM_SETFONT,GetGadgetFont(#PB_Default),1)
  SendMessage_(btn2,#WM_SETFONT,GetGadgetFont(#PB_Default),1)
  SendMessage_(btn3,#WM_SETFONT,GetGadgetFont(#PB_Default),1)
  
  ShowWindow_(hwnd,#SW_SHOW)
  SetFocus_(btn1)
  While GetMessage_(msg.msg,0,0,0)
    If IsDialogMessage_(hwnd,msg) ; http://msdn.microsoft.com/en-us/library/ms645498(VS.85).aspx
    Else
      TranslateMessage_(msg)
      DispatchMessage_(msg)
    EndIf
  Wend
EndProcedure

Main()
Post Reply