Hallo,
zurzeit versuche ich, simple Skinning-Funktionalitäten in meine Anwendung zu implementieren. Dabei ist jetzt folgendes Problem aufgetaucht:
Erstelle ich OwnerDraw-Buttons (siehe #BS_OWNERDRAW) in Verbindung mit DrawIconEx, so werden diese eigentlich korrekt dargestellt.
Weise ich dem Fenster, auf dem der Button dargestellt werden soll, nun jedoch ein Hintergrundbild zu (siehe #GCL_HBRBACKGROUND), so wird der OwnerDraw-Button zwar immer noch dargestellt, jedoch nicht mehr transparent.
Wie wäre dieses Problem zu beheben?
Frage an die OwnerDraw-Experten
Re: Frage an die OwnerDraw-Experten
Hier mal ein Fake-Beispiel. Dabei wird der Hintergrund vom Parent-Fenster
genommen, funktioniert also nicht mit darunterliegenden Gadgets.
Den Window-Background kannst Du in Zeile 55 ersetzen:
CreateHatchBrush_(#HS_DIAGCROSS,RGB($80,$80,$80))
Vielleicht reicht das schon für Deine simple Skinning-Funktionalität.
genommen, funktioniert also nicht mit darunterliegenden Gadgets.
Den Window-Background kannst Du in Zeile 55 ersetzen:
CreateHatchBrush_(#HS_DIAGCROSS,RGB($80,$80,$80))
Code: Alles auswählen
Procedure WinCallback(hWnd, Msg, wParam, lParam)
If Msg = #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = lParam
If *dis
If *dis\CtlType = #ODT_BUTTON
hDC = *dis\hDC;GetDC_(*dis\hwndItem)
width = GadgetWidth(*dis\CtlID)
height = GadgetHeight(*dis\CtlID)
x = GadgetX(*dis\CtlID)
y = GadgetY(*dis\CtlID)
If GetGadgetData(*dis\CtlID) = 0
; no gadget data = transparent background
hDC2=CreateCompatibleDC_(hDC)
SelectObject_(hDC2,CreateCompatibleBitmap_(hDC,x+width,y+height))
SendMessage_(GetParent_(*dis\hwndItem),#WM_ERASEBKGND,hDC2,0)
;SendMessage_(GetParent_(*dis\hwndItem),#WM_PRINT,hDC2,#PRF_ERASEBKGND|#PRF_CLIENT) ; alternativ
BitBlt_(hDC,0,0,width,height,hDC2,x,y,#SRCCOPY)
DeleteDC_(hDC2)
Else
; gadget data = background color
backBrush = CreateSolidBrush_(GetGadgetData(*dis\CtlID))
SelectObject_(hDC,backBrush)
PatBlt_(hDC,0,0,width,height,#PATCOPY)
EndIf
; Draw Button
If *dis\itemState&#ODS_SELECTED
stateOffset = 1
EndIf
SetBkMode_(hDC,#TRANSPARENT)
SelectObject_(hDC,GetStockObject_(#HOLLOW_BRUSH))
SelectObject_(hDC,GetGadgetFont(*dis\CtlID))
Rectangle_(hDC,stateOffset,stateOffset,width-stateOffset*2,height-stateOffset*2)
GetClientRect_(*dis\hwndItem,@r.RECT)
DrawText_(hDC,GetGadgetText(*dis\CtlID),-1,@r,#DT_CENTER|#DT_VCENTER|#DT_SINGLELINE)
;ReleaseDC_(*dis\hwndItem,hDC)
ProcedureReturn #True
EndIf
EndIf
ElseIf Msg = #WM_ERASEBKGND
SelectObject_(wParam,GetClassLongPtr_(hWnd,#GCL_HBRBACKGROUND))
GetClientRect_(hWnd,@r.RECT)
PatBlt_(wParam,0,0,r\right,r\bottom,#PATCOPY)
ProcedureReturn #True
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
mainWin = OpenWindow(#PB_Any,0,0,1024,768,"Btn",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowCallback(@WinCallback())
SetClassLongPtr_(WindowID(mainWin),#GCL_HBRBACKGROUND,CreateHatchBrush_(#HS_DIAGCROSS,RGB($80,$80,$80)))
ButtonGadget(#PB_Any,10,10,100,25,"Button 0")
Btn1 = ButtonGadget(#PB_Any,10,40,100,25,"Button 1",#BS_OWNERDRAW)
;SetGadgetFont(Btn1,LoadFont(0,"Tahoma",12))
Btn2 = ButtonGadget(#PB_Any,10,70,100,25,"Button 2",#BS_OWNERDRAW)
SetGadgetData(Btn2,RGB($FF,$FF,$00))
Btn3 = ButtonGadget(#PB_Any,10,100,100,25,"Button 3",#BS_OWNERDRAW)
SetGadgetData(Btn3,RGB($80,$80,$FF))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Frage an die OwnerDraw-Experten
Vielen Dank,
aber hast du das ganze mal mit DrawIconEx für die OwnerDraw-Buttons ausprobiert?
aber hast du das ganze mal mit DrawIconEx für die OwnerDraw-Buttons ausprobiert?
Re: Frage an die OwnerDraw-Experten
Auf was willst Du denn hinaus?X0r hat geschrieben:Vielen Dank,
aber hast du das ganze mal mit DrawIconEx für die OwnerDraw-Buttons ausprobiert?
Verstehe noch nicht ganz wo Dein Problem liegt, aber ist ohne Beispiel
deinerseits auch nicht ganz leicht.

Aber von mir aus auch mit DrawIconEx:
Code: Alles auswählen
;
; by Danilo, 18. Juni 2011
;
Global hIcon
Procedure WinCallback(hWnd, Msg, wParam, lParam)
If Msg = #WM_DRAWITEM
*dis.DRAWITEMSTRUCT = lParam
If *dis
If *dis\CtlType = #ODT_BUTTON
hDC = *dis\hDC;GetDC_(*dis\hwndItem)
width = GadgetWidth(*dis\CtlID)
height = GadgetHeight(*dis\CtlID)
x = GadgetX(*dis\CtlID)
y = GadgetY(*dis\CtlID)
If GetGadgetData(*dis\CtlID) = 0
; no gadget data = transparent background
hDC2=CreateCompatibleDC_(hDC)
hBmp=CreateCompatibleBitmap_(hDC,x+width,y+height)
oldBmp=SelectObject_(hDC2,hBmp)
SendMessage_(GetParent_(*dis\hwndItem),#WM_ERASEBKGND,hDC2,0)
;SendMessage_(GetParent_(*dis\hwndItem),#WM_PRINT,hDC2,#PRF_ERASEBKGND|#PRF_CLIENT) ; alternativ
BitBlt_(hDC,0,0,width,height,hDC2,x,y,#SRCCOPY)
DeleteDC_(hDC2)
DeleteObject_(hBmp)
Else
; gadget data = background color
backBrush = CreateSolidBrush_(GetGadgetData(*dis\CtlID))
SelectObject_(hDC,backBrush)
PatBlt_(hDC,0,0,width,height,#PATCOPY)
EndIf
; Draw Button
If *dis\itemState&#ODS_SELECTED
stateOffset = 1
EndIf
SetBkMode_(hDC,#TRANSPARENT)
SelectObject_(hDC,GetStockObject_(#HOLLOW_BRUSH))
SelectObject_(hDC,GetGadgetFont(*dis\CtlID))
RoundRect_(hDC,stateOffset,stateOffset,width-stateOffset*2,height-stateOffset*2,6,6)
GetClientRect_(*dis\hwndItem,@r.RECT)
DrawText_(hDC,GetGadgetText(*dis\CtlID),-1,@r,#DT_CENTER|#DT_VCENTER|#DT_SINGLELINE)
DrawIconEx_(hDC,10,3,hIcon,0,0,0,0,#DI_DEFAULTSIZE|#DI_IMAGE|#DI_MASK)
;ReleaseDC_(*dis\hwndItem,hDC)
ProcedureReturn #True
EndIf
EndIf
ElseIf Msg = #WM_ERASEBKGND
SelectObject_(wParam,GetClassLongPtr_(hWnd,#GCL_HBRBACKGROUND))
GetClientRect_(hWnd,@r.RECT)
PatBlt_(wParam,0,0,r\right,r\bottom,#PATCOPY)
ProcedureReturn #True
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;hIcon = LoadImage_(0,#OIC_HAND,#IMAGE_ICON,16,16,#LR_SHARED)
hIcon = LoadCursor_(0,#IDC_ARROW)
mainWin = OpenWindow(#PB_Any,0,0,1024,768,"Btn",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowCallback(@WinCallback())
SetClassLongPtr_(WindowID(mainWin),#GCL_HBRBACKGROUND,CreateHatchBrush_(#HS_DIAGCROSS,RGB($80,$80,$80)))
ButtonGadget(#PB_Any,10,10,100,25,"Button 0")
Btn1 = ButtonGadget(#PB_Any,10,40,100,25,"Button 1",#BS_OWNERDRAW)
;SetGadgetFont(Btn1,LoadFont(0,"Tahoma",12))
Btn2 = ButtonGadget(#PB_Any,10,70,100,25,"Button 2",#BS_OWNERDRAW)
SetGadgetData(Btn2,RGB($FF,$FF,$00))
Btn3 = ButtonGadget(#PB_Any,10,100,100,25,"Button 3",#BS_OWNERDRAW)
SetGadgetData(Btn3,RGB($80,$80,$FF))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
ein minimales Beispiel mit Deinem Problem. Ich sehe bisher noch
kein Problem.

cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Frage an die OwnerDraw-Experten
Sorry für meine minimalistisch gehaltenen Beiträge. Ich hab es halt ohne diesen "Umweg" gemacht und mich gefragt, wieso die Win API da solche Probleme bereiten muss. 
