Files
HeidiSQL/source/vcl-styles-utils/Vcl.Styles.OwnerDrawFix.pas

247 lines
8.8 KiB
ObjectPascal

//**************************************************************************************************
//
// Unit Vcl.Styles.OwnerDrawFix
// unit for the VCL Styles Utils
// https://github.com/RRUZ/vcl-styles-utils/
//
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either express or implied. See the License for the specific language governing rights
// and limitations under the License.
//
// The Original Code is Vcl.Styles.OwnerDrawFix.pas.
//
// The Initial Developer of the Original Code is Rodrigo Ruz V.
// Portions created by Rodrigo Ruz V. are Copyright (C) 2012-2015 Rodrigo Ruz V.
// All Rights Reserved.
//
//**************************************************************************************************
unit Vcl.Styles.OwnerDrawFix;
interface
uses
Winapi.Windows,
Winapi.CommCtrl,
Vcl.ComCtrls,
Vcl.Graphics,
Vcl.StdCtrls,
Vcl.Controls,
Vcl.Styles,
Vcl.Themes,
System.Classes;
type
TVclStylesOwnerDrawFix=class
public
procedure ComboBoxDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure ListBoxDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
procedure ListViewDrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);
procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
end deprecated 'Use the Vcl.Styles.Hooks unit Instead';
var
VclStylesOwnerDrawFix : TVclStylesOwnerDrawFix;
implementation
uses
System.SysUtils;
type
TCustomListViewClass=class(TCustomListView);
{ TVclStylesOwnerDrawFix }
procedure TVclStylesOwnerDrawFix.ComboBoxDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
const
ColorStates: array[Boolean] of TStyleColor = (scComboBoxDisabled, scComboBox);
FontColorStates: array[Boolean] of TStyleFont = (sfComboBoxItemDisabled, sfComboBoxItemNormal);
var
LStyles : TCustomStyleServices;
begin
LStyles :=StyleServices;
with Control as TComboBox do
begin
Canvas.Brush.Color := LStyles.GetStyleColor(ColorStates[Control.Enabled]);
Canvas.Font.Color := LStyles.GetStyleFontColor(FontColorStates[Control.Enabled]);
if odSelected in State then
begin
Canvas.Brush.Color := LStyles.GetSystemColor(clHighlight);
Canvas.Font.Color := LStyles.GetSystemColor(clHighlightText);
end;
Canvas.FillRect(Rect) ;
Canvas.TextOut(Rect.Left+2, Rect.Top, Items[Index]);
end;
end;
procedure TVclStylesOwnerDrawFix.ListBoxDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
Var
LListBox : TListBox;
LStyles : TCustomStyleServices;
LDetails : TThemedElementDetails;
begin
LListBox :=TListBox(Control);
LStyles :=StyleServices;
if odSelected in State then
LListBox.Brush.Color := LStyles.GetSystemColor(clHighlight);
LDetails := StyleServices.GetElementDetails(tlListItemNormal);
LListBox.Canvas.FillRect(Rect);
Rect.Left:=Rect.Left+2;
LStyles.DrawText(LListBox.Canvas.Handle, LDetails, LListBox.Items[Index], Rect, [tfLeft, tfSingleLine, tfVerticalCenter]);
if odFocused In State then
begin
LListBox.Canvas.Brush.Color := LStyles.GetSystemColor(clHighlight);
LListBox.Canvas.DrawFocusRect(Rect);
end;
end;
procedure TVclStylesOwnerDrawFix.ListViewDrawItem(Sender: TCustomListView;
Item: TListItem; Rect: TRect; State: TOwnerDrawState);
const
Spacing =4;
var
Dx : Integer;
r : TRect;
rc : TRect;
ColIdx : Integer;
s : string;
LDetails : TThemedElementDetails;
LStyles : TCustomStyleServices;
BoxSize : TSize;
LColor : TColor;
ImageSize : Integer;
begin
ImageSize:=0;
LStyles:=StyleServices;
if not LStyles.GetElementColor(LStyles.GetElementDetails(ttItemNormal), ecTextColor, LColor) or (LColor = clNone) then
LColor := LStyles.GetSystemColor(clWindowText);
Sender.Canvas.Brush.Color := LStyles.GetStyleColor(scListView);
Sender.Canvas.Font.Color := LColor;
Sender.Canvas.FillRect(Rect);
r := Rect;
inc(r.Left, Spacing);
for ColIdx := 0 to TListView(Sender).Columns.Count - 1 do
begin
Dx:=0;
r.Right := r.Left + Sender.Column[ColIdx].Width;
if (ColIdx > 0) and (Item.SubItems.Count>=ColIdx) then
s := Item.SubItems[ColIdx - 1]
else
begin
BoxSize.cx := GetSystemMetrics(SM_CXMENUCHECK);
BoxSize.cy := GetSystemMetrics(SM_CYMENUCHECK);
s := Item.Caption;
if TListView(Sender).Checkboxes then
begin
Inc(Dx,BoxSize.cx+3);
r.Left:=r.Left+BoxSize.cx+3;
end;
end;
if ColIdx = 0 then
begin
if not IsWindowVisible(ListView_GetEditControl(Sender.Handle)) and ([odSelected, odHotLight] * State <> []) then
begin
if ([odSelected, odHotLight] * State <> []) then
begin
rc:=Rect;
if TListView(Sender).Checkboxes then
rc.Left:=rc.Left+BoxSize.cx+Spacing;
if not TListView(Sender).RowSelect then
rc.Right:=Sender.Column[0].Width;
Sender.Canvas.Brush.Color := LStyles.GetSystemColor(clHighlight);
Sender.Canvas.FillRect(rc);
end;
end;
end;
if TListView(Sender).RowSelect then
Sender.Canvas.Brush.Color := LStyles.GetSystemColor(clHighlight);
if (ColIdx=0) and (TCustomListViewClass(Sender).SmallImages<>nil) and (TCustomListViewClass(Sender).SmallImages.Handle<>0) and (Item.ImageIndex>=0) then
begin
ImageList_Draw(TCustomListViewClass(Sender).SmallImages.Handle, Item.ImageIndex, Sender.Canvas.Handle, R.Left - 2, R.Top, ILD_NORMAL);
ImageSize:=TCustomListViewClass(Sender).SmallImages.Width;
Inc(Dx,ImageSize);
r.Left:=r.Left+ImageSize;
end;
if ([odSelected, odHotLight] * State <> []) then
LDetails := StyleServices.GetElementDetails(tlListItemSelected)
else
LDetails := StyleServices.GetElementDetails(tlListItemNormal);
Sender.Canvas.Brush.Style := bsClear;
LStyles.DrawText(Sender.Canvas.Handle, LDetails, s, r, [tfLeft, tfSingleLine, tfVerticalCenter, tfEndEllipsis]);
if (ColIdx=0) and TListView(Sender).Checkboxes then
begin
rc := Rect;
rc.Top := Rect.Top + (Rect.Bottom - Rect.Top - BoxSize.cy) div 2;
rc.Bottom := rc.Top + BoxSize.cy;
rc.Left := rc.Left + Spacing;
rc.Right := rc.Left + BoxSize.cx;
if Item.Checked then
LDetails := StyleServices.GetElementDetails(tbCheckBoxCheckedNormal)
else
LDetails := StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal);
LStyles.DrawElement(Sender.Canvas.Handle, LDetails, Rc);
end;
if ColIdx=0 then
r.Left:=r.Left - Dx;
{ else }
inc(r.Left, Sender.Column[ColIdx].Width);
end;
end;
procedure TVclStylesOwnerDrawFix.ListViewMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
const
Spacing =4;
var
LDetails : TThemedElementDetails;
Size : TSize;
begin
if TListView(Sender).OwnerDraw and (TListView(Sender).Checkboxes) then
begin
LDetails := StyleServices.GetElementDetails(tbCheckBoxCheckedNormal);
Size.cx:=0;
Size.cy:=0;
if StyleServices.GetElementSize(TListView(Sender).Canvas.Handle, LDetails, esMinimum, Size) and (X>Spacing) and (X<=Size.Width) then
TListView(Sender).Selected.Checked:=not TListView(Sender).Selected.Checked;
//OutputDebugString(PChar(Format('X %d Size.Width %d',[X, Size.Width])));
end;
end;
initialization
VclStylesOwnerDrawFix:=TVclStylesOwnerDrawFix.Create;
finalization
VclStylesOwnerDrawFix.Free;
end.