// Name: KOL Addon - Visual XP Styles // Rev.: 1.99 + KOL 3.00.A // Date: 02 oct 2010 // Author: MTsv DN // Thanks: mdw, Vladimir Kladov {$IFDEF _FPC} const clGrey = TColor($808080); clLtGrey = TColor($C0C0C0); clDkGrey = TColor($808080); {$ENDIF} procedure ConvertBitmap2Grayscale(var Bmp: PBitmap); type TRGBArray = array[0..32767] of TRGBTriple; PRGBArray = ^TRGBArray; var x, y, Gray: Integer; Row: PRGBArray; R, G, B : Byte; TrColor : Integer; begin Bmp.PixelFormat := pf24bit; TrColor := Bmp.Pixels[Bmp.Width - 1, 0]; for y := 0 to Bmp.Height - 1 do begin Row := Bmp.ScanLine[y]; for x := 0 to Bmp.Width - 1 do begin R := LoByte(LoWord(TrColor)); G := HiByte(LoWord(TrColor)); B := LoByte(HiWord(TrColor)); if (Row[x].rgbtRed = R) and (Row[x].rgbtGreen = G) and (Row[x].rgbtBlue = B) then continue; Gray := (Row[x].rgbtRed + Row[x].rgbtGreen + Row[x].rgbtBlue) div 3; Row[x].rgbtRed := Gray; Row[x].rgbtGreen := Gray; Row[x].rgbtBlue := Gray; end; end; end; //********************* Creating font on Sender font base ********************// function CreateNewFont(Sender : PControl): HFont; const CLEARTYPE_QUALITY = 5; var fnWeight : Integer; fnItalic, fnUnderline, fnStrikeOut, fnQuality, fnPitch : DWORD; begin // Font style if Sender.Font.FontStyle = [fsBold] then fnWeight := 700 else fnWeight := 0; if Sender.Font.FontStyle = [fsItalic] then fnItalic := DWORD(TRUE) else fnItalic := DWORD(FALSE); if Sender.Font.FontStyle = [fsUnderline] then fnUnderline := DWORD(TRUE) else fnUnderline := DWORD(FALSE); if Sender.Font.FontStyle = [fsStrikeOut] then fnStrikeOut := DWORD(TRUE) else fnStrikeOut := DWORD(FALSE); // Font quality case Sender.Font.FontQuality of fqAntialiased: fnQuality := DWORD(ANTIALIASED_QUALITY); {$IFDEF AUTO_REPLACE_CLEARTYPE} fqClearType: fnQuality := DWORD(CLEARTYPE_QUALITY); {$ELSE} fqClearType: fnQuality := DWORD(ANTIALIASED_QUALITY); {$ENDIF} fqDraft: fnQuality := DWORD(DRAFT_QUALITY); fqNonAntialiased: fnQuality := DWORD(NONANTIALIASED_QUALITY); fqProof: fnQuality := DWORD(PROOF_QUALITY); {fqDefault:} else fnQuality := DWORD(DEFAULT_QUALITY); end; // Font pitch case Sender.Font.FontPitch of fpFixed: fnPitch := DWORD(FIXED_PITCH); fpVariable: fnPitch := DWORD(VARIABLE_PITCH); {fpDefault:} else fnPitch := DWORD(DEFAULT_PITCH); end; Result := CreateFont(Sender.Font.FontHeight, Sender.Font.FontWidth, 0, Sender.Font.FontOrientation, fnWeight, fnItalic, fnUnderline, fnStrikeOut, Sender.Font.FontCharset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, fnQuality, fnPitch, PKOLChar(Sender.Font.FontName)); end; //***************************** Initializing themes **************************// function InitThemes : boolean; begin Result := false; ThemeLibrary := LoadLibrary(themelib); if ThemeLibrary > 0 then begin OpenThemeData := GetProcAddress(ThemeLibrary, 'OpenThemeData'); DrawThemeBackground := GetProcAddress(ThemeLibrary, 'DrawThemeBackground'); IsThemeBackgroundPartiallyTransparent := GetProcAddress(ThemeLibrary, 'IsThemeBackgroundPartiallyTransparent'); DrawThemeParentBackground := GetProcAddress(ThemeLibrary, 'DrawThemeParentBackground'); DrawThemeText := GetProcAddress(ThemeLibrary, 'DrawThemeText'); CloseThemeData := GetProcAddress(ThemeLibrary, 'CloseThemeData'); IsThemeActive := GetProcAddress(ThemeLibrary, 'IsThemeActive'); IsAppThemed := GetProcAddress(ThemeLibrary, 'IsAppThemed'); GetThemeColor := GetProcAddress(ThemeLibrary, 'GetThemeColor'); Result := true; end; end; //***************************** Deinitializing themes ************************// procedure DeinitThemes; begin if ThemeLibrary > 0 then begin FreeLibrary(ThemeLibrary); ThemeLibrary := 0; OpenThemeData := nil; DrawThemeBackground := nil; IsThemeBackgroundPartiallyTransparent := nil; DrawThemeParentBackground := nil; CloseThemeData := nil; IsAppThemed := nil; IsThemeActive := nil; GetThemeColor := nil; end; end; //****************************** Checking themes *****************************// procedure CheckThemes; // Check Manifest file or resource function IsManifestFilePresent : boolean; begin Result := false; if FileExists(ParamStr(0) + '.manifest') then //dufa. в случае с DLL ExePath вернет путь до нее, а не до EXE begin Result := true; exit; end; if FindResource(hInstance, MAKEINTRESOURCE(1), MakeIntResource(24)) <> 0 then Result := true; end; // Check activity themes function UseThemes: Boolean; begin if (ThemeLibrary > 0) then Result := IsThemeActive else Result := False; end; begin AppTheming := false; if IsManifestFilePresent then if InitThemes then begin if UseThemes then AppTheming := true; DeinitThemes; end; end; //****************************** Drawing Splitter ****************************// procedure WndSplitterXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); const Bit : Word = $FF; var B, Brush : HBRUSH; fDC : HDC; Bmp : HBITMAP; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndSplitterXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; // Draw back layer Brush := CreateSolidBrush(Color2RGB(Sender.fParent.Color)); fDC := SelectObject(DC, Brush); FillRect(DC, Sender.ClientRect, Brush); SelectObject(DC, fDC); DeleteObject(Brush); // Creating brush and pen if {$IFDEF USE_FLAGS} G4_Pressed in Sender.fFlagsG4 {$ELSE} Sender.fPressed {$ENDIF} then begin Bmp := CreateBitmap(2, 2, 1, 1, @Bit); B := CreatePatternBrush(Bmp); fDC := SelectObject(DC, B); // Drawing splitter PatBlt (DC, 0, 0, Sender.Width, Sender.Height, PATINVERT); // Destroying brush and pen SelectObject(DC, fDC); DeleteObject(B); DeleteObject(Bmp); end; end; //*************************** Drawing TabControl Page ************************// procedure WndTabXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var hThemes : THandle; Color : COLORREF; Brush : HBRUSH; fDC : HDC; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndTabXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; hThemes := OpenThemeData(Sender.fHandle, 'TAB'); if hThemes <> 0 then begin GetThemeColor(hThemes, 10, 0, 3805, Color); Sender.Color := Color2RGB(Color); Brush := CreateSolidBrush(Color2RGB(Color)); fDC := SelectObject(DC, Brush); FillRect(DC, Sender.ClientRect, Brush); SelectObject(DC, fDC); DeleteObject(Brush); CloseThemeData(hThemes); end; end; //*************************** Drawing Panel control **************************// procedure WndPanelXPResize( Dummy : Pointer; Sender: PObj ); var R : TRect; begin R := PControl(Sender).ClientRect; InvalidateRect(PControl(Sender).fHandle, @R, False); end; procedure WndPanelXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var RClient, RText : TRect; LPos : DWORD; S : KOLString; F : HFONT; fDC1, fDC2 : HDC; hThemes : THandle; TxtColor, Color : COLORREF; Brush : HBRUSH; Pen : HPEN; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndPanelXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; // Getting rects RClient := Sender.ClientRect; // Getting text and text flags S := Sender.fCaption; LPos := 0; if S <> '' then begin case Sender.fVerticalAlign of vaTop: LPos := DT_TOP; vaCenter: LPos := DT_VCENTER; vaBottom: LPos := DT_BOTTOM; end; case Sender.fTextAlign of taLeft: LPos := LPos or DT_LEFT; taCenter: LPos := LPos or DT_CENTER; taRight: LPos := LPos or DT_RIGHT; end; end; // Draw back layer if (Sender.EdgeStyle = esTransparent) or ({$IFDEF USE_FLAGS} (G2_Transparent in Sender.fFlagsG2) {$ELSE} Sender.fTransparent {$ENDIF}) then else begin Brush := CreateSolidBrush(Color2RGB(Sender.fParent.Color)); fDC1 := SelectObject(DC, Brush); FillRect(DC, RClient, Brush); case Sender.EdgeStyle of esRaised, esLowered: begin Sender.fStyle.Value := Sender.fStyle.Value and (not SS_SUNKEN) and (not WS_DLGFRAME); Sender.fExStyle := Sender.fExStyle and (not WS_EX_STATICEDGE) or WS_EX_WINDOWEDGE; Pen := CreatePen(PS_SOLID, 1, Color2RGB(clLtGrey)); fDC2 := SelectObject(DC, Pen); RoundRect(DC, RClient.Left, RClient.Top, RClient.Right, RClient.Bottom, 5, 5); SelectObject(DC, fDC2); DeleteObject(Pen); end; end; SelectObject(DC, fDC1); DeleteObject(Brush); end; if S <> '' then begin hThemes := OpenThemeData(Sender.fHandle, 'button'); Color := Sender.Font.Color; if hThemes <> 0 then begin {$IFDEF USE_FLAGS} if (F3_Disabled in Sender.fStyle.f3_Style) then {$ELSE} if not Sender.fEnabled then {$ENDIF} GetThemeColor(hThemes, 1, 4, 3803, Color); CloseThemeData(hThemes); end; RText := MakeRect(2, 2, Sender.Width-2, Sender.Height-2); // Create font F := CreateNewFont(Sender); fDC1 := SelectObject(DC, F); // Draw text SetBkMode(DC, TRANSPARENT); TxtColor := SetTextColor(DC, Color2RGB(Color)); DrawText(DC, PKOLChar(S), Length(S), RText, LPos or DT_SINGLELINE); // Backup color SetTextColor(DC, Color2RGB(TxtColor)); SetBkMode(DC, OPAQUE); // Destroying font SelectObject(DC, fDC1); DeleteObject(F); end; end; //************************** Drawing GroupBox control ************************// procedure WndGroupBoxXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var hThemes : THandle; RClient, RText, RClipMain, RClipLeft, RClipRight : TRect; LPos, fState : DWORD; S : KOLWideString; F : HFONT; fDC : HDC; TxtColor, Color : COLORREF; TextWidth, TextHeight : Integer; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndGroupBoxXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; // Getting text and text flags LPos := 0; case Sender.fVerticalAlign of vaTop: LPos := DT_TOP; vaCenter: LPos := DT_VCENTER; vaBottom: LPos := DT_BOTTOM; end; case Sender.fTextAlign of taLeft: LPos := LPos or DT_LEFT; taCenter: LPos := LPos or DT_CENTER; taRight: LPos := LPos or DT_RIGHT; end; S := KOLWideString( Sender.fCaption ); // Getting rects TextWidth := Sender.Canvas.WTextWidth(S); TextHeight := Sender.Canvas.WTextHeight(S); RClient := Sender.ClientRect; RClient.Left := RClient.Left - Sender.MarginLeft; RClient.Top := RClient.Top - Sender.MarginTop + (TextHeight div 2); RClient.Right := RClient.Right + Sender.MarginRight; RClient.Bottom := RClient.Bottom + Sender.MarginBottom; case Sender.fTextAlign of taCenter: begin RText := MakeRect(((RClient.Right div 2) - (TextWidth div 2)) - 2, RClient.Top-6, ((RClient.Right div 2) + (TextWidth div 2)) + 2, TextHeight + (RClient.Top-6)); RClipLeft := MakeRect(RClient.Left, RClient.Top, ((RClient.Right div 2) - (TextWidth div 2)) - 2, TextHeight + (RClient.Top-6)); RClipRight := MakeRect(((RClient.Right div 2) + (TextWidth div 2)) + 2, RClient.Top-6, RClient.Right, TextHeight + (RClient.Top-6)); end; taRight: begin RText := MakeRect((RClient.Right-4) - TextWidth, RClient.Top-6, RClient.Right-4, TextHeight + (RClient.Top-6)); RClipLeft := MakeRect(RClient.Left, RClient.Top, (RClient.Right-4) - TextWidth, TextHeight + (RClient.Top-6)); RClipRight := MakeRect(RClient.Right-4, RClient.Top-6, RClient.Right, TextHeight + (RClient.Top-6)); end; else RText := MakeRect(RClient.Left+4, RClient.Top-6, TextWidth + RClient.Left+4, TextHeight + RClient.Top-6); RClipLeft := MakeRect(RClient.Left, RClient.Top, RClient.Left+4, TextHeight + RClient.Top-6); RClipRight := MakeRect(TextWidth + RClient.Left+4, RClient.Top-6, RClient.Right, TextHeight + RClient.Top-6); end; RClipMain := MakeRect(RClient.Left, TextHeight + RClient.Top-6, RClient.Right, RClient.Bottom); // Open themes hThemes := OpenThemeData(Sender.fHandle, 'button'); if hThemes <> 0 then begin Sender.Color := Sender.fParent.fColor; {$IFDEF USE_FLAGS} if not (F3_Disabled in Sender.fStyle.f3_Style) then {$ELSE} if Sender.fEnabled then {$ENDIF} fState := 1 else fState := 2; // Drawing GroupBox rect "step by step" DrawThemeBackground(hThemes, DC, 4{BP_GROUPBOX}, fState{GBS_XXXXXX}, RClient, @RClipMain); DrawThemeBackground(hThemes, DC, 4{BP_GROUPBOX}, fState{GBS_XXXXXX}, RClient, @RClipLeft); DrawThemeBackground(hThemes, DC, 4{BP_GROUPBOX}, fState{GBS_XXXXXX}, RClient, @RClipRight); // Drawing GroupBox text {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} GetThemeColor(hThemes, {WP_CAPTION} 1, {CS_DISABLED} 3, 3803, Color) else GetThemeColor(hThemes, {WP_CAPTION} 1, {CS_ACTIVE} 1, 3803, Color); // Close themes CloseThemeData(hThemes); // Create font F := CreateNewFont(Sender); fDC := SelectObject(DC, F); // Draw text SetBkMode(DC, TRANSPARENT); TxtColor := SetTextColor(DC, Color2RGB(Color)); DrawTextW(DC, PWideChar(S), Length(S), RText, LPos or DT_SINGLELINE); // Backup color SetTextColor(DC, Color2RGB(TxtColor)); SetBkMode(DC, OPAQUE); // Destroying font SelectObject(DC, fDC); DeleteObject(F); end; end; //************************* Drawing CheckBox control *************************// procedure WndCheckBoxXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var hThemes : THandle; RClient, RCheck, RText : TRect; fState : DWORD; W, H : Integer; S : KOLString; F : HFONT; fDC : HDC; Color : COLORREF; TxtColor : COLORREF; Brush : HBRUSH; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndCheckBoxXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; // Getting metrics W := GetSystemMetrics( SM_CXMENUCHECK ); H := GetSystemMetrics( SM_CYMENUCHECK ); // Getting caption S := Sender.fCaption; // Getting rects RClient := Sender.ClientRect; RCheck := RClient; RCheck.Right := RCheck.Left + W; if {$IFDEF USE_FLAGS} G1_WordWrap in Sender.fFlagsG1 {$ELSE} Sender.fWordWrap {$ENDIF} then RCheck.Top := RCheck.Top + Sender.Border else RCheck.Top := RCheck.Top + (RCheck.Bottom - RCheck.Top - H) div 2; RCheck.Bottom := RCheck.Top + H; RText := MakeRect(RCheck.Right + Sender.fMargin, RCheck.Top, RClient.Right, RCheck.Bottom); // Getting state fState := 1; {CBS_UNCHECKEDNORMAL} {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} fState := 4 {CBS_UNCHECKEDDISABLED} else if {$IFDEF USE_FLAGS} G4_Hot in Sender.fFlagsG4 {$ELSE} Sender.fHot {$ENDIF} then fState := 2; {CBS_UNCHECKEDHOT} if {$IFDEF USE_FLAGS} G4_Pressed in Sender.fFlagsG4 {$ELSE} Sender.fPressed {$ENDIF} then fState := 3{CBS_UNCHECKEDPRESSED}; case Sender.Check3 of tsChecked : Inc( fState, 4 ); tsIndeterminate : Inc( fState, 8 ); end; // Draw back layer if {$IFDEF USE_FLAGS} not( G2_Transparent in Sender.fFlagsG2 ) {$ELSE} not Sender.fTransparent {$ENDIF} then begin Brush := CreateSolidBrush(Color2RGB(Sender.fParent.Color)); fDC := SelectObject(DC, Brush); FillRect(DC, RClient, Brush); SelectObject(DC, fDC); DeleteObject(Brush); end; // Draw theme Color := Sender.Font.Color; hThemes := OpenThemeData(Sender.fHandle, 'button'); if hThemes <> 0 then begin {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} GetThemeColor(hThemes, 1, 4, 3803, Color); DrawThemeBackground(hThemes, DC, 3 {BP_CHECKBOX}, fState, RCheck, @RCheck); CloseThemeData(hThemes); end; // Create font F := CreateNewFont(Sender); fDC := SelectObject(DC, F); // Draw text SetBkMode(DC, TRANSPARENT); TxtColor := SetTextColor(DC, Color2RGB(Color)); DrawText(DC, PKOLChar(S), Length(S), RText, DT_LEFT or DT_VCENTER or DT_SINGLELINE); // Destroying font SetTextColor(DC, Color2RGB(TxtColor)); SetBkMode(DC, OPAQUE); // Destroying object SelectObject(DC, fDC); DeleteObject(F); // Draw focusrect if GetFocus = Sender.fHandle then begin dec( RText.Left ); DrawFocusRect(DC, RText); end; end; //************************* Drawing RadioBox control *************************// procedure WndRadioBoxXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var hThemes : THandle; RClient, RDot, RText : TRect; fState : DWORD; W, H : Integer; S : KOLString; F : HFONT; fDC : HDC; Color, TxtColor : COLORREF; Brush : HBRUSH; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (@Sender.EV.fOnPaint <> @WndRadioBoxXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; // Getting metrics W := GetSystemMetrics( SM_CXMENUCHECK ); H := GetSystemMetrics( SM_CYMENUCHECK ); // Getting caption S := Sender.fCaption; // Getting rects RClient := Sender.ClientRect; RDot := RClient; RDot.Right := RDot.Left + W; if {$IFDEF USE_FLAGS} G1_WordWrap in Sender.fFlagsG1 {$ELSE} Sender.fWordWrap {$ENDIF} then RDot.Top := RDot.Top + Sender.Border else RDot.Top := RDot.Top + (RDot.Bottom - RDot.Top - H) div 2; RDot.Bottom := RDot.Top + H; RText := MakeRect(RDot.Right + Sender.Border, RDot.Top, RClient.Right, RDot.Bottom); // Getting state fState := 1; {CBS_UNCHECKEDNORMAL} {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} fState := 4 {CBS_UNCHECKEDDISABLED} else if {$IFDEF USE_FLAGS} G4_Hot in Sender.fFlagsG4 {$ELSE} Sender.fHot {$ENDIF} then fState := 2; {CBS_UNCHECKEDHOT} if {$IFDEF USE_FLAGS} G4_Pressed in Sender.fFlagsG4 {$ELSE} Sender.fPressed {$ENDIF} then fState := 3{CBS_UNCHECKEDPRESSED}; if Sender.Checked then Inc( fState, 4 ); // Draw back layer if {$IFDEF USE_FLAGS} not( G2_Transparent in Sender.fFlagsG2 ) {$ELSE} not Sender.fTransparent {$ENDIF} then begin Brush := CreateSolidBrush(Color2RGB(Sender.fParent.Color)); fDC := SelectObject(DC, Brush); FillRect(DC, RClient, Brush); SelectObject(DC, fDC); DeleteObject(Brush); end; // Draw theme Color := Sender.Font.Color; hThemes := OpenThemeData(Sender.fHandle, 'button'); if hThemes <> 0 then begin {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} GetThemeColor(hThemes, 1, 4, 3803, Color); DrawThemeBackground(hThemes, DC, 2 {BP_RADIOBOX}, fState, RDot, @RDot); CloseThemeData(hThemes); end; // Create font F := CreateNewFont(Sender); fDC := SelectObject(DC, F); // Draw text SetBkMode(DC, TRANSPARENT); TxtColor := SetTextColor(DC, Color2RGB(Color)); DrawText(DC, PKOLChar(S), Length(S), RText, DT_LEFT or DT_VCENTER or DT_SINGLELINE); // Destroying font SetTextColor(DC, Color2RGB(TxtColor)); SetBkMode(DC, OPAQUE); // Destroying object SelectObject(DC, fDC); DeleteObject(F); // Draw focusrect if GetFocus = Sender.fHandle then begin dec( RText.Left ); DrawFocusRect(DC, RText); end; end; //******************** Drawing Button and BitButton control ******************// procedure WndButtonXPDraw( Dummy : Pointer; Sender: PControl; DC: HDC ); var hThemes : THandle; F : HFONT; fDC1, fDC2 : HDC; RClient : TRect; RText, R1 : TRect; RIcon : TRect; S : WideString; fState, bStyle : DWORD; Bmp : HBITMAP; W, H : Integer; HPos, VPos : DWORD; Brush : HBRUSH; Pen : HPEN; SenderWidth, SenderHeight : integer; Flags: DWORD; _DC : HDC; OldBmp: HBitmap; ic : PIcon; b : PBitmap; i : integer; il : PImageList; begin // Checking user owner-draw if Assigned(Sender.EV.fOnPaint) and (TMethod(Sender.EV.fOnPaint).Code <> @WndButtonXPDraw) then begin Sender.EV.fOnPaint(Sender, DC); exit; end; if Assigned(Sender.EV.fOnBitBtnDraw) and (TMethod(Sender.EV.fOnBitBtnDraw).Code <> @DummyProc123_0) then begin fState := 0{PBS_NORMAL}; {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} fState := 2{PBS_DISABLED} else if GetFocus = Sender.fHandle then fState := 3{PBS_PRESSED} else if {$IFDEF USE_FLAGS} G4_Hot in Sender.fFlagsG4 {$ELSE} Sender.fHot {$ENDIF} then fState := 4{PBS_HOT}; if {$IFDEF USE_FLAGS} G4_Pressed in Sender.fFlagsG4 {$ELSE} Sender.fPressed {$ENDIF} then fState := 1{PBS_PRESSED}; Sender.EV.fOnBitBtnDraw(Sender, fState); exit; end; // Getting rects RClient := Sender.ClientRect; RText := RClient; // Calc bitmap rect Bmp := Sender.DF.fGlyphBitmap; HPos := 0; VPos := 0; if Bmp <> 0 then begin SenderWidth := Sender.Width; SenderHeight := Sender.Height; W := Sender.DF.fGlyphWidth; H := Sender.DF.fGlyphHeight; if Sender.DF.fGlyphLayout in [ glyphLeft ] then begin RIcon := MakeRect((SenderWidth div 2) - (W + (W div 4)), (SenderHeight div 2) - (H div 2), W, SenderHeight); RText.Left := (SenderWidth div 2) + (W div 4); HPos := DT_LEFT; VPos := DT_VCENTER; end; if Sender.DF.fGlyphLayout in [ glyphRight ] then begin RIcon := MakeRect((SenderWidth div 2) + (W div 4), (SenderHeight div 2) - (H div 2), W, SenderHeight); RText.Right := (SenderWidth div 2) - (W div 4); HPos := DT_RIGHT; VPos := DT_VCENTER; end; if Sender.DF.fGlyphLayout in [ glyphOver ] then begin RIcon := MakeRect((SenderWidth div 2) - (W div 2), (SenderHeight div 2) - (H div 2), W, SenderHeight); HPos := DT_CENTER; VPos := DT_VCENTER; end; if Sender.DF.fGlyphLayout in [ glyphTop ] then begin RIcon := MakeRect((SenderWidth div 2) - (W div 2), (SenderHeight div 2) - (H + (H div 4)), W, SenderHeight); RText.Top := (SenderHeight div 2) + (H div 4); HPos := DT_CENTER; VPos := DT_TOP; end; if Sender.DF.fGlyphLayout in [ glyphBottom ] then begin RIcon := MakeRect((SenderWidth div 2) - (W div 2), (SenderHeight div 2) + (H div 4), W, SenderHeight); RText.Bottom := (SenderHeight div 2) - (H div 4); HPos := DT_CENTER; VPos := DT_BOTTOM; end; end else begin HPos := DT_CENTER; VPos := DT_VCENTER; RIcon := MakeRect(0, 0, 0, 0); end; // Getting caption S := KOLWideString( Sender.fCaption ); // Getting state fState := 1{PBS_NORMAL}; {$IFDEF USE_FLAGS} if F3_Disabled in Sender.fStyle.f3_Style then {$ELSE} if not Sender.fEnabled then {$ENDIF} fState := 4{PBS_DISABLED} else if {$IFDEF USE_FLAGS} G4_Hot in Sender.fFlagsG4 {$ELSE} Sender.fHot {$ENDIF} then fState := 2{PBS_HOT}; if {$IFDEF USE_FLAGS} G4_Pressed in Sender.fFlagsG4 {$ELSE} Sender.fPressed {$ENDIF} then fState := 3{PBS_PRESSED}; // Opening themes hThemes := OpenThemeData(Sender.fHandle, 'button'); if hThemes <> 0 then begin Brush := CreateSolidBrush(Color2RGB(Sender.fParent.Color)); fDC1 := SelectObject(DC, Brush); FillRect(DC, RClient, Brush); if (Sender.Flat) and (fState = 1{PBS_NORMAL}) then begin Pen := CreatePen(PS_SOLID, 1, clLtGrey); fDC2 := SelectObject(DC, Pen); RoundRect(DC, RClient.Left+2, RClient.Top+2, RClient.Right-2, RClient.Bottom-2, 3, 3); SelectObject(DC, fDC2); DeleteObject(Pen); end else DrawThemeBackground(hThemes, DC, 1{BP_PUSHBUTTON}, fState, RClient, @RClient); SelectObject(DC, fDC1); DeleteObject(Brush); if Bmp <> 0 then begin if bboImageList in Sender.DF.fBitBtnOptions then begin bStyle := ILD_TRANSPARENT; {$IFDEF USE_FLAGS} if not (F3_Disabled in Sender.fStyle.f3_Style) then {$ELSE} if Sender.fEnabled then {$ENDIF} i := Sender.BitBtnImgIdx else begin ic := NewIcon; ic.fSize := Sender.DF.fGlyphWidth; ic.fHandle := ImageList_GetIcon(Bmp, Sender.BitBtnImgIdx, bStyle); b := NewBitmap(ic.fSize, ic.fSize); b.fHandle := ic.Convert2Bitmap(clBtnFace); ConvertBitmap2Grayscale(b); i := ImageList_Add(Bmp, b.fHandle, 0); Free_And_Nil(b); Free_And_Nil(ic); end; ImageList_Draw(Bmp, i, DC, RIcon.Left, RIcon.Top, bStyle); end else begin _DC := CreateCompatibleDC( 0 ); {$IFDEF USE_FLAGS} if not (F3_Disabled in Sender.fStyle.f3_Style) then {$ELSE} if Sender.fEnabled then {$ENDIF} OldBmp := SelectObject( _DC, Bmp) else begin bStyle := ILD_TRANSPARENT; il := NewImageList(Sender.fParent); il.HandleNeeded; i := ImageList_Add(il.fHandle, Bmp, 0); ic := NewIcon; ic.fSize := Sender.DF.fGlyphWidth; ic.fHandle := ImageList_GetIcon(il.fHandle, i, bStyle); b := NewBitmap(ic.fSize, ic.fSize); b.fHandle := ic.Convert2Bitmap(clBtnFace); ConvertBitmap2Grayscale(b); OldBmp := SelectObject( _DC, b.fHandle); Free_And_Nil(b); Free_And_Nil(ic); Free_And_Nil(il); end; StretchBlt( DC, RIcon.Left, RIcon.Top, Sender.DF.fGlyphWidth, Sender.DF.fGlyphHeight, _DC, 0, 0, Sender.DF.fGlyphWidth, Sender.DF.fGlyphHeight, SRCCOPY); SelectObject( _DC, OldBmp ); DeleteDC( _DC ); end; end; // Create font F := CreateNewFont(Sender); fDC1 := SelectObject(DC, F); // Draw text Flags := HPos or VPos; R1 := RText; if Sender.Style and BS_MULTILINE = 0 then Flags := Flags or DT_SINGLELINE else begin Flags := Flags and not DT_VCENTER or DT_WORDBREAK; if VPos and DT_VCENTER <> 0 then begin DrawTextW(DC, PWideChar( S ), Length(S), R1, Flags or DT_CALCRECT); OffsetRect( R1, 0, ( (RText.Bottom - RText.Top) - (R1.Bottom - R1.Top) ) div 2 ); if HPos and DT_CENTER <> 0 then OffsetRect( R1, ( (RText.Right - RText.Left) - (R1.Right - R1.Left) ) div 2, 0 ); end; end; DrawThemeText(hThemes, DC, 1{BP_PUSHBUTTON}, fState, PWideChar(S), Length(S), Flags, 0, R1); // Destroying font SelectObject(DC, fDC1); DeleteObject(F); CloseThemeData(hThemes); end; if (GetFocus = Sender.fHandle) and (bboFocusRect in Sender.DF.fBitBtnOptions) then DrawFocusRect(DC, MakeRect(RClient.Left+4, RClient.Top+4, RClient.Right-4, RClient.Bottom-4)); end; //************************* Control MouseEnter event *************************// {$IFDEF ASM_VERSION} procedure WndXPMouseEnter( Dummy : Pointer; Sender: PObj ); asm {$IFDEF USE_FLAGS} OR [EDX].TControl.fFlagsG4, 1 shl G4_Hot {$ELSE} MOV [EDX].TControl.fHot, 1 {$ENDIF} {$IFDEF EVENTS_DYNAMIC} MOV EAX, [EDX].TControl.EV MOV ECX, [EAX].TEvents.fOnMouseEnter.TMethod.Code {$ELSE} MOV ECX, [EDX].TControl.EV.fOnMouseEnter.TMethod.Code {$ENDIF} JECXZ @@fin CMP ECX, offset[WndXPMouseEnter] JZ @@fin {$IFDEF EVENTS_DYNAMIC} MOV EAX, [EAX].TEvents.fOnMouseEnter.TMethod.Data {$ELSE} MOV EAX, [EDX].TControl.EV.fOnMouseEnter.TMethod.Data {$ENDIF} CALL ECX @@fin: end; {$ELSE} procedure WndXPMouseEnter( Dummy : Pointer; Sender: PObj ); begin with PControl(Sender)^ do begin {$IFDEF USE_FLAGS} fFlagsG4 := fFlagsG4 + [G4_Hot]; {$ELSE} fHot := true; {$ENDIF} if Assigned(EV.fOnMouseEnter) and (@EV.fOnMouseEnter <> @WndXPMouseEnter) then EV.fOnMouseEnter(Sender); end; end; {$ENDIF} //************************* Control MouseLeave event *************************// {$IFDEF ASM_VERSION} procedure WndXPMouseLeave( Dummy : Pointer; Sender: PObj ); asm {$IFDEF USE_FLAGS} AND [EDX].TControl.fFlagsG4, not(1 shl G4_Hot) {$ELSE} MOV [EDX].TControl.fHot, 0 {$ENDIF} {$IFDEF EVENTS_DYNAMIC} MOV EAX, [EDX].TControl.EV MOV ECX, [EAX].TEvents.fOnMouseLeave.TMethod.Code {$ELSE} MOV ECX, [EDX].TControl.EV.fOnMouseLeave.TMethod.Code {$ENDIF} JECXZ @@fin CMP ECX, offset[WndXPMouseLeave] JZ @@fin {$IFDEF EVENTS_DYNAMIC} MOV EAX, [EAX].TEvents.fOnMouseLeave.TMethod.Data {$ELSE} MOV EAX, [EDX].TControl.EV.fOnMouseLeave.TMethod.Data {$ENDIF} CALL ECX @@fin: end; {$ELSE} procedure WndXPMouseLeave( Dummy : Pointer; Sender: PObj ); begin {$IFDEF USE_FLAGS} PControl(Sender).fFlagsG4 := PControl(Sender).fFlagsG4 - [G4_Hot]; {$ELSE} PControl(Sender).fHot := false; {$ENDIF} if Assigned(PControl(Sender).EV.fOnMouseLeave) and (@PControl(Sender).EV.fOnMouseLeave <> @WndXPMouseLeave) then PControl(Sender).EV.fOnMouseLeave(Sender); end; {$ENDIF} //*************************** Control Message event **************************// function WndXPMessage( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; var pt : TPoint; Mouse: TMouseEventData; dDC : HDC; begin Result := false; case Msg.message of WM_LBUTTONDBLCLK: begin if Assigned(Sender.EV.fOnMouseDblClk) then begin Mouse.Button := mbLeft; Mouse.StopHandling := false; Mouse.R1 := 0; Mouse.R2 := 0; Mouse.Shift := 120; Mouse.X := 0; Mouse.Y := 0; GetCursorPos(pt); if ScreenToClient(Sender.fHandle, pt) then begin Mouse.X := pt.X; Mouse.Y := pt.Y; end; Sender.EV.fOnMouseDblClk(Sender, Mouse); end; if {$IFDEF USE_FLAGS} not(G5_IsSplitter in Sender.fFlagsG5) {$ELSE} not Sender.fIsSplitter {$ENDIF} then Sender.Perform( WM_LBUTTONDOWN, Msg.wParam, Msg.lParam ); end; WM_LBUTTONDOWN: begin if Assigned(Sender.EV.fOnMouseDown) then begin Mouse.Button := mbLeft; Mouse.StopHandling := false; Mouse.R1 := 0; Mouse.R2 := 0; Mouse.Shift := 120; Mouse.X := 0; Mouse.Y := 0; GetCursorPos(pt); if ScreenToClient(Sender.fHandle, pt) then begin Mouse.X := pt.X; Mouse.Y := pt.Y; end; Sender.EV.fOnMouseDown(Sender, Mouse); end; {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 + [G4_Pressed]; {$ELSE} Sender.fPressed := true; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); // vampir_infernal 15.10.2008 end; WM_LBUTTONUP: begin if Assigned(Sender.EV.fOnMouseUp) then begin Mouse.Button := mbLeft; Mouse.StopHandling := false; Mouse.R1 := 0; Mouse.R2 := 0; Mouse.Shift := 120; Mouse.X := 0; Mouse.Y := 0; GetCursorPos(pt); if ScreenToClient(Sender.fHandle, pt) then begin Mouse.X := pt.X; Mouse.Y := pt.Y; end; Sender.EV.fOnMouseUp(Sender, Mouse); end; {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 - [G4_Pressed]; {$ELSE} Sender.fPressed := false; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); end; WM_KEYDOWN: begin if Msg.wParam = VK_SPACE then begin if Assigned(Sender.EV.fOnKeyDown) then Sender.EV.fOnKeyDown(Sender, Msg.wParam, GetShiftState); {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 + [G4_Pressed]; {$ELSE} Sender.fPressed := true; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); end; end; WM_KEYUP: begin if Msg.wParam = VK_SPACE then begin if Assigned(Sender.EV.fOnKeyUp) then Sender.EV.fOnKeyUp(Sender, Msg.wParam, GetShiftState); {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 - [G4_Pressed]; {$ELSE} Sender.fPressed := false; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); end; end; WM_KILLFOCUS: begin {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 - [G4_Hot]; {$ELSE} Sender.fHot := false; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); end; WM_SETFOCUS: begin {$IFDEF USE_FLAGS} Sender.fFlagsG4 := Sender.fFlagsG4 + [G4_Hot]; {$ELSE} Sender.fHot := TRUE; {$ENDIF} dDC := GetWindowDC(Msg.hWnd); Sender.EV.fOnPaint(Sender, dDC); ReleaseDC( Msg.hWnd, dDC ); Result := true; end; end; end; //*************************** Events for CheckBox ****************************// procedure XP_Themes_For_CheckBox(Sender : PControl); begin if AppTheming then Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndCheckBoxXPDraw ) ); end; //*************************** Events for RadioBox ****************************// procedure XP_Themes_For_RadioBox(Sender : PControl); begin if AppTheming then Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndRadioBoxXPDraw ) ); end; //**************************** Events for Panel ******************************// procedure XP_Themes_For_Panel(Sender : PControl); begin if AppTheming then begin if Sender.EdgeStyle = esTransparent then Sender.SetTransparent(True) else begin Sender.OnResize := TOnEvent( MakeMethod( nil, @WndPanelXPResize ) ); Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndPanelXPDraw ) ); end; end; end; //*************************** Events for Splitter ****************************// procedure XP_Themes_For_Splitter(Sender : PControl); begin if AppTheming then begin Sender.AttachProc(WndXPMessage); Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndSplitterXPDraw ) ); end; end; //**************************** Events for Label ******************************// procedure XP_Themes_For_Label(Sender : PControl); begin if AppTheming then Sender.SetTransparent(True); end; //************************** Events for GroupBox *****************************// procedure XP_Themes_For_GroupBox(Sender : PControl); begin if AppTheming then Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndGroupBoxXPDraw ) ); end; //************************** Events for TabPanel *****************************// procedure XP_Themes_For_TabPanel(Sender : PControl); begin if AppTheming then Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndTabXPDraw ) ); end; //********************* Events for Button and BitButton **********************// procedure XP_Themes_For_BitBtn(Sender : PControl); begin if AppTheming then begin Sender.AttachProc(WndXPMessage); Sender.OnMouseEnter := TOnEvent( MakeMethod( nil, @WndXPMouseEnter ) ); Sender.OnMouseLeave := TOnEvent( MakeMethod( nil, @WndXPMouseLeave ) ); Sender.OnPaint := TOnPaint( MakeMethod( nil, @WndButtonXPDraw ) ); end; end; //*********************** Deattach ownerdraw function ************************// procedure Deattach(Sender : PControl; PaintProc : Pointer); begin if Sender.IsProcAttached(WndXPMessage) then Sender.DetachProc(WndXPMessage); if {$IFDEF NIL_EVENTS} Assigned(Sender.EV.fOnMouseEnter) and {$ENDIF} (@Sender.EV.fOnMouseEnter = @WndXPMouseEnter) and ({$IFDEF USE_FLAGS} not(G3_Flat in Sender.fFlagsG3) {$ELSE} not Sender.fFlat {$ENDIF}) then {$IFDEF NIL_EVENTS} Sender.EV.fOnMouseEnter := nil; {$ELSE} TMethod( Sender.EV.fOnMouseEnter ).Code := @DummyObjProc; {$ENDIF} if {$IFDEF NIL_EVENTS} Assigned(Sender.EV.fOnMouseLeave) and {$ENDIF} (@Sender.EV.fOnMouseLeave = @WndXPMouseLeave) and ({$IFDEF USE_FLAGS} not(G3_Flat in Sender.fFlagsG3) {$ELSE} not Sender.fFlat {$ENDIF}) then {$IFDEF NIL_EVENTS} Sender.EV.fOnMouseLeave := nil; {$ELSE} TMethod( Sender.EV.fOnMouseLeave ).Code := @DummyObjProc; {$ENDIF} if {$IFDEF NIL_EVENTS} Assigned(Sender.EV.fOnPaint) and {$ENDIF} (@Sender.EV.fOnPaint = PaintProc) then {$IFDEF NIL_EVENTS} Sender.EV.fOnPaint := nil; {$ELSE} TMethod( Sender.EV.fOnPaint ).Code := @DummyObjProc; {$ENDIF} end; //********************* Handling of message WM_THEMECHANGED ******************// function WndXP_WM_THEMECHANGED( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; begin Result := false; if Msg.message = $31A {WM_THEMECHANGED} then begin if AppTheming then DeinitThemes; CheckThemes; if AppTheming then begin InitThemes; if ((Sender.fStyle.Value and BS_AUTOCHECKBOX) = BS_AUTOCHECKBOX) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin XP_Themes_For_CheckBox(Sender); exit; end; if ((Sender.fStyle.Value and BS_AUTO3STATE) = BS_AUTO3STATE) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin XP_Themes_For_CheckBox(Sender); exit; end; if ((Sender.fStyle.Value and BS_RADIOBUTTON) = BS_RADIOBUTTON) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin XP_Themes_For_RadioBox(Sender); exit; end; if ((Sender.fStyle.Value and BS_GROUPBOX) = BS_GROUPBOX) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = [G5_IsGroupbox]) {$ELSE} (Sender.fIsGroupBox = true) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin XP_Themes_For_GroupBox(Sender); exit; end; if (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) {$ENDIF} then begin XP_Themes_For_BitBtn(Sender); exit; end; if (Sender.SubClassName = 'obj_STATIC') then begin if {$IFDEF USE_FLAGS} G1_IsStaticControl in Sender.fFlagsG1 {$ELSE} Sender.fIsStaticControl > 0 {$ENDIF} then XP_Themes_For_Label(Sender) else begin if {$IFDEF USE_FLAGS} G5_IsSplitter in Sender.fFlagsG5 {$ELSE} Sender.fIsSplitter {$ENDIF} then XP_Themes_For_Splitter(Sender) else begin if Sender.fParent.SubClassName = 'obj_SysTabControl32' then XP_Themes_For_TabPanel(Sender) else XP_Themes_For_Panel(Sender); end; end; exit; end; end else begin if ((Sender.fStyle.Value and BS_AUTOCHECKBOX) = BS_AUTOCHECKBOX) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin Deattach(Sender, @WndCheckBoxXPDraw); exit; end; if ((Sender.fStyle.Value and BS_AUTO3STATE) = BS_AUTO3STATE) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin Deattach(Sender, @WndCheckBoxXPDraw); exit; end; if ((Sender.fStyle.Value and BS_RADIOBUTTON) = BS_RADIOBUTTON) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin Deattach(Sender, @WndRadioBoxXPDraw); exit; end; if ((Sender.fStyle.Value and BS_GROUPBOX) = BS_GROUPBOX) and (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter, G5_IsBitBtn] * Sender.fFlagsG5 = [G5_IsGroupbox]) {$ELSE} (Sender.fIsGroupBox = true) and (Sender.fIsSplitter = false) and (Sender.fIsBitBtn = false) {$ENDIF} then begin Deattach(Sender, @WndGroupBoxXPDraw); exit; end; if (Sender.SubClassName = 'obj_BUTTON') and {$IFDEF USE_FLAGS} ([G5_IsGroupbox, G5_IsSplitter] * Sender.fFlagsG5 = []) {$ELSE} (Sender.fIsGroupBox = false) and (Sender.fIsSplitter = false) {$ENDIF} then begin Deattach(Sender, @WndButtonXPDraw); exit; end; if (Sender.SubClassName = 'obj_STATIC') then begin if {$IFDEF USE_FLAGS} G1_IsStaticControl in Sender.fFlagsG1 {$ELSE} Sender.fIsStaticControl > 0 {$ENDIF} then else begin if {$IFDEF USE_FLAGS} G5_IsSplitter in Sender.fFlagsG5 {$ELSE} Sender.fIsSplitter {$ENDIF} then Deattach(Sender, @WndSplitterXPDraw) else if Sender.fParent.SubClassName = 'obj_SysTabControl32' then Deattach(Sender, @WndTabXPDraw) else begin Deattach(Sender, @WndPanelXPDraw); case Sender.EdgeStyle of esRaised: begin Sender.fStyle.Value := Sender.fStyle.Value and (not SS_SUNKEN); Sender.fExStyle := Sender.fExStyle and (not WS_EX_STATICEDGE); Sender.fExStyle := Sender.fExStyle or WS_EX_WINDOWEDGE; Sender.fStyle.Value := Sender.fStyle.Value or WS_DLGFRAME; end; esLowered: begin Sender.fStyle.Value := Sender.fStyle.Value and (not WS_DLGFRAME); Sender.fExStyle := Sender.fExStyle or WS_EX_WINDOWEDGE; Sender.fExStyle := Sender.fExStyle or WS_EX_STATICEDGE; Sender.fStyle.Value := Sender.fStyle.Value or SS_SUNKEN; end; else Sender.fStyle.Value := Sender.fStyle.Value and (not SS_SUNKEN) and (not WS_DLGFRAME); Sender.fExStyle := Sender.fExStyle and (not WS_EX_STATICEDGE) or WS_EX_WINDOWEDGE; end; end; end; Sender.SetTransparent( {$IFDEF USE_FLAGS} G2_ClassicTransparent in Sender.fFlagsG2 {$ELSE} Sender.fClassicTransparent {$ENDIF} ); exit; end; end; end; end; //********************* Attaching to message WM_THEMECHANGED *****************// type TSenderProc = procedure(Sender: PControl); {$IFDEF ASM_VERSION} procedure Attach_WM_THEMECHANGED(Sender : PControl; const XP_Themes_for: TSenderProc); asm {$IFDEF USE_FLAGS} MOV CX, word ptr [EAX].TControl.fFlagsG2 AND CX, not(1 shl G3_ClassicTransparent)shl 8 or (1 shl G2_Transparent) OR CL, CH MOV [EAX].TControl.fFlagsG3, CL {$ELSE} MOV CL, [EAX].TControl.fTransparent MOV [EAX].TControl.fClassicTransparent, CL {$ENDIF} PUSH EDX PUSH EAX MOV EDX, offset[WndXP_WM_THEMECHANGED] CALL TControl.AttachProc POP EAX POP EDX CALL EDX end; {$ELSE PASCAL} procedure Attach_WM_THEMECHANGED(Sender : PControl; const XP_Themes_for: TSenderProc); begin {$IFDEF USE_FLAGS} if G2_Transparent in Sender.fFlagsG2 then Sender.fFlagsG3 := Sender.fFlagsG3 + [G3_ClassicTransparent] else Sender.fFlagsG3 := Sender.fFlagsG3 - [G3_ClassicTransparent]; {$ELSE} Sender.fClassicTransparent := Sender.fTransparent; {$ENDIF} Sender.AttachProc(WndXP_WM_THEMECHANGED); XP_Themes_for(Sender); end; {$ENDIF ASM_VERSION} //********************************* End File *********************************//