How to Ownerdraw a Button
Posted: Thu Aug 10, 2006 7:52 pm
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.
edit: Removing mistakes
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