home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 October
/
Chip_2001-10_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d456
/
DCSLIB25.ZIP
/
DCChecklst.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-06-25
|
43KB
|
1,549 lines
{
BUSINESS CONSULTING
s a i n t - p e t e r s b u r g
Components Library for Borland Delphi 4.x, 5.x
Copyright (c) 1998-2000 Alex'EM
}
unit DCChecklst;
interface
{$I DCConst.inc}
uses
Windows, Messages, SysUtils, Classes, Controls, Forms, Graphics, StdCtrls,
Dialogs, CheckLst, DCEditButton, DCConst, DCChoice;
type
TSetTextEvent = procedure (Sender: TObject; Value: string) of object;
TDCPopupCheckListBox = class(TCheckListBox)
private
FButtons: TDCEditButtons;
FVisible: boolean;
FOwner: TControl;
FWindowRect: TRect;
FAlwaysVisible: boolean;
FPopupAlignment: TWindowAlignment;
FPopupBorderStyle: TPopupBorderStyle;
FBorderSize: integer;
FDropDownRows: integer;
FMargins: TRect;
FCursorMode: TCursorMode;
FShowHeader: boolean;
FOnButtonClick: TNotifyEvent;
procedure RedrawBorder;
procedure SetPopupAlignment(Value: TWindowAlignment);
procedure SetPopupBorderStyle(Value: TPopupBorderStyle);
procedure DrawHeader;
procedure DrawClientRect;
procedure DrawFooter;
procedure SetMargins;
procedure BeginMoving(XCursor, YCursor: integer);
procedure DoButtonClick(Sender: TObject);
procedure InvalidateButtons;
procedure SetShowHeader(const Value: boolean);
procedure DoDrawHint(Sender: TObject; Mode: Integer);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure WMMouseActivate(var Message: TWMActivate); message WM_MOUSEACTIVATE;
procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
procedure WMFontChange(var Message: TWMFontChange); message WM_FONTCHANGE;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
procedure CMSetAlignment(var Message: TMessage); message CM_SETALIGNMENT;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
public
procedure AdjustNewHeight;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure SetBoundsEx(ALeft, ATop, AWidth, AHeight: Integer);
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SetParent(AParent: TWinControl); override;
procedure Show;
procedure Hide;
property AlwaysVisible: boolean read FAlwaysVisible write FAlwaysVisible;
property PopupAlignment: TWindowAlignment read FPopupAlignment
write SetPopupAlignment;
property Owner: TControl read FOwner write FOwner;
property PopupBorderStyle: TPopupBorderStyle read FPopupBorderStyle write SetPopupBorderStyle;
property DropDownRows: integer read FDropDownRows write FDropDownRows;
property Columns;
property OnDblClick;
property BorderStyle;
property Buttons: TDCEditButtons read FButtons;
property ShowHeader: boolean read FShowHeader write SetShowHeader;
property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
end;
TDCCustomListComboBox = class(TDCCustomChoiceEdit)
private
FListBox: TDCPopupCheckListBox;
FListBoxVisible: boolean;
FStyle: TComboBoxStyle;
FOnDrawItem: TDrawItemEvent;
FOnDrawText: TDCDrawItemEvent;
FOnMeasureItem:TMeasureItemEvent;
FItemHeight: integer;
FLastText: string;
FDropDownWidth: integer;
FHintShow: boolean;
FInButtonArea: boolean;
FInCheckArea: boolean;
FUpdateCount: integer;
FOnSetText: TSetTextEvent;
FDropDownCount: integer;
procedure SetComboBoxStyle(Value: TComboBoxStyle);
procedure SetItems(Value: TStrings);
procedure PaintListItem(bFocused: boolean);
function NotEditControl: boolean;
function GetItems: TStrings;
procedure ListMeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
procedure ListDrawItem(Control: TWinControl; Index: Integer; Rect: TRect;
State: TOwnerDrawState);
function GetItemIndex: integer;
function GetChecked(Index: Integer): Boolean;
function GetItemEnabled(Index: Integer): Boolean;
function GetState(Index: Integer): TCheckBoxState;
procedure SetChecked(Index: Integer; const Value: Boolean);
procedure SetItemEnabled(Index: Integer; const Value: Boolean);
procedure SetState(Index: Integer; const Value: TCheckBoxState);
function GetAllowGrayed: Boolean;
procedure SetAllowGrayed(const Value: Boolean);
protected
procedure CloseUp(State: Byte; bPerform: boolean = False); override;
procedure Loaded; override;
procedure GetHintOnError; override;
function MinControlWidthBitmap: integer; override;
function GetDropDownVisible: boolean; override;
procedure EMGetSel(var Message: TMessage); message EM_GETSEL;
procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMLButtonDblClk(var Message: TWMLButtonDown); message WM_LBUTTONDBLCLK;
procedure EMSetReadOnly(var Message: TMessage); message EM_SETREADONLY;
procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
procedure CMPopupWindow(var Message: TMessage); message CM_POPUPWINDOW;
procedure CMPopupButtonClk(var Message: TMessage); message CM_POPUPBUTTONCLK;
function GetCanvas: TCanvas;
procedure CheckClick(Sender:TObject); override;
procedure WndProc(var Message: TMessage); override;
procedure DefineBtnChoiceStyle; override;
property Style: TComboBoxStyle read FStyle write SetComboBoxStyle;
property ItemHeight: integer read FItemHeight write FItemHeight;
property OnDrawItem: TDrawItemEvent read FOnDrawItem write FOnDrawItem;
property OnDrawText: TDCDrawItemEvent read FOnDrawText write FOnDrawText;
property OnMeasureItem: TMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
property DropDownWidth: integer read FDropDownWidth write FDropDownWidth;
procedure CreateWnd; override;
procedure SetText(ASelStart, ASelLen: integer); virtual;
property Items: TStrings read GetItems write SetItems;
property ItemIndex: integer read GetItemIndex;
property AllowGrayed: Boolean read GetAllowGrayed write SetAllowGrayed;
property OnSetText: TSetTextEvent read FOnSetText write FOnSetText;
property DropDownCount: Integer read FDropDownCount write FDropDownCount default 8;
public
procedure CreateParams(var Params: TCreateParams); override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char);override;
procedure KillFocus(var Value: boolean); override;
procedure Clear; override;
procedure ChoiceClick(Sender:TObject); override;
procedure UpdateItems;
property Canvas: TCanvas read GetCanvas;
property Checked[Index: Integer]: Boolean read GetChecked write SetChecked;
property ItemEnabled[Index: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
property State[Index: Integer]: TCheckBoxState read GetState write SetState;
end;
TDCListComboBox = class(TDCCustomListComboBox)
public
property ButtonEnabled;
published
property Alignment;
property DrawStyle;
property CheckGlyph;
property CheckTag;
property ItemHeight;
property DropDownWidth;
property OnDrawItem;
property OnDrawText;
property OnMeasureItem;
property Style;
property ShowCheckBox;
property Items;
property ItemIndex;
property AllowGrayed;
property OnSetText;
property DropDownCount;
end;
implementation
uses
DCResource, DCEditTools, DCPopupWindow;
type
TPrivateControl = class(TControl)
end;
{ TDCPopupCheckListBox }
procedure TDCPopupCheckListBox.AdjustNewHeight;
var
DC: HDC;
SaveFont: HFONT;
Metrics: TTextMetric;
begin
DC := GetDC(0);
SaveFont := SelectObject(DC, Font.Handle);
try
GetTextMetrics (DC, Metrics);
ItemHeight := Metrics.tmHeight + 3;
finally
SelectObject(DC, SaveFont);
ReleaseDC(0, DC);
end;
end;
procedure TDCPopupCheckListBox.BeginMoving(XCursor, YCursor: integer);
begin
ProcessMovingWindow(Self, XCursor, YCursor, FCursorMode, ItemHeight);
end;
procedure TDCPopupCheckListBox.CMMouseEnter(var Message: TMessage);
begin
inherited;
if Assigned(FButtons) then
FButtons.MouseDown := GetAsyncKeyState(VK_LBUTTON) < 0;
end;
procedure TDCPopupCheckListBox.CMMouseLeave(var Message: TMessage);
begin
inherited;
if Assigned(FButtons) then
FButtons.UpdateButtons( -1, -1, False, True);
end;
procedure TDCPopupCheckListBox.CMSetAlignment(var Message: TMessage);
begin
PopupAlignment := TWindowAlignment(Message.WParam);
end;
procedure TDCPopupCheckListBox.CNDrawItem(var Message: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Message.DrawItemStruct^ do
begin
if not UseRightToLeftAlignment then
rcItem.Left := rcItem.Left + GetCheckWidth
else
rcItem.Right := rcItem.Right - GetCheckWidth;
{$IFDEF DELPHI_V5UP}
State := TOwnerDrawState(LongRec(itemState).Lo);
{$ELSE}
State := TOwnerDrawState(WordRec(LongRec(itemState).Lo).Lo);
{$ENDIF}
Canvas.Lock;
try
Canvas.Handle := hDC;
Canvas.Font := Font;
Canvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then
begin
Canvas.Brush.Color := clHighlight;
Canvas.Font.Color := clHighlightText
end;
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State) else
Canvas.FillRect(rcItem);
finally
Canvas.Handle := 0;
Canvas.Unlock;
end;
end;
end;
constructor TDCPopupCheckListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FVisible := False;
ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable,
csAcceptsControls];
Visible := False;
Canvas.Brush.Style := bsClear;
FAlwaysVisible := True;
FOwner := TControl(AOwner);
Font := TPrivateControl(AOwner).Font;
SetRectEmpty(FWindowRect);
SetRectEmpty(FMargins);
FDropDownRows := 8;
AdjustNewHeight;
{Special ListBox properies}
FCursorMode := cmNone;
Style := lbOwnerDrawVariable;
FButtons := TDCEditButtons.Create(Self);
FButtons.AnchorStyle := asBL;
FButtons.Color := clBtnFace;
FButtons.OnlyClientRepaint := True;
FShowHeader := True;
end;
procedure TDCPopupCheckListBox.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST ;
AddBiDiModeExStyle(ExStyle);
end;
end;
procedure TDCPopupCheckListBox.CreateWnd;
var
LeftPos: integer;
AButton: TDCEditButton;
ALeft: integer;
begin
inherited CreateWnd;
if Parent <> nil then
begin
Windows.SetParent(Handle, 0);
CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
SetMargins;
FButtons.SetWndProc;
if FShowHeader then
begin
LeftPos := 4;
FButtons.Clear;
AButton := FButtons.AddButton;
with AButton do
begin
Name := '#Close';
Allignment := abCenter;
AnchorStyle := asBL;
Font := Self.Font;
Caption := LoadStr(RES_STRN_VAL_CLOSE);
SetBounds(Rect(LeftPos, Self.Height-br_FooterHeight-5,
50 + 5, br_FooterHeight+3));
DisableStyle := deNormal;
Style := stShadowFlat;
Enabled := True;
Visible := False;
Tag := 1;
OnClick := DoButtonClick;
OnDrawHint := DoDrawHint;
ALeft := Left+Width;
end;
AButton := FButtons.AddButton;
with AButton do
begin
Name := '#Sep_1';
Allignment := abImageTop;
AnchorStyle := asBL;
Font := Self.Font;
Glyph.LoadFromResourceName(HInstance, 'DC_DELIMITER');
SetBounds(Rect(ALeft, Self.Height-br_FooterHeight-5,
8, br_FooterHeight+3));
DisableStyle := deNormal;
Style := stNone;
Enabled := True;
Visible := False;
DrawText:= False;
Tag := -1;
OnDrawHint := DoDrawHint;
ALeft := Left+Width;
end;
AButton := FButtons.AddButton;
with AButton do
begin
Name := '#SelectAll';
Allignment := abCenter;
AnchorStyle := asBL;
Font := Self.Font;
Glyph.LoadFromResourceName(HInstance, 'DC_SELECTALL');
Comment := LoadStr(RES_STRN_HNT_SELALL);
SetBounds(Rect(ALeft, Self.Height-br_FooterHeight-5,
FMargins.Bottom-1, br_FooterHeight+3));
DisableStyle := deNormal;
Style := stShadowFlat;
Enabled := True;
Visible := False;
Tag := 2;
DrawText:= False;
OnClick := DoButtonClick;
OnDrawHint := DoDrawHint;
ALeft := Left+Width;
end;
AButton := FButtons.AddButton;
with AButton do
begin
Name := '#deSelectAll';
Allignment := abCenter;
AnchorStyle := asBL;
Font := Self.Font;
Glyph.LoadFromResourceName(HInstance, 'DC_DESELECTALL');
Comment := LoadStr(RES_STRN_HNT_DESALL);
SetBounds(Rect(ALeft, Self.Height-br_FooterHeight-5,
FMargins.Bottom-1, br_FooterHeight+3));
DisableStyle := deNormal;
Style := stShadowFlat;
Enabled := True;
Visible := False;
Tag := 3;
DrawText:= False;
OnClick := DoButtonClick;
OnDrawHint := DoDrawHint;
ALeft := Left+Width;
end;
AButton := FButtons.AddButton;
with AButton do
begin
Name := '#Comment';
Allignment := abLeft;
AnchorStyle := asBLR;
Font := Self.Font;
SetBounds(Rect(ALeft, Self.Height-br_FooterHeight-5,
Self.Width-FMargins.Right-ALeft-br_SizerWidth-2*FBorderSize-1, br_FooterHeight+3));
DisableStyle := deLite;
Style := stNone;
Enabled := False;
Visible := False;
Tag := -1;
end;
DoDrawHint(nil, 0);
end;
end;
end;
destructor TDCPopupCheckListBox.Destroy;
begin
FButtons.Free;
FButtons := nil;
inherited;
end;
procedure TDCPopupCheckListBox.DoButtonClick(Sender: TObject);
var
i: integer;
begin
if Assigned(FOnButtonClick) then FOnButtonClick(Sender);
case TDCEditButton(Sender).Tag of
1{Close}:
begin
FOwner.Perform(CM_POPUPBUTTONCLK, Integer(Sender), 0);
end;
2{SelectAll}:
begin
for i := 0 to Items.Count-1 do
{$IFDEF DELPHI_V5UP}
if ItemEnabled[i] then Checked[i] := True;
{$ELSE}
Checked[i] := True;
{$ENDIF}
end;
3{deSelectAll}:
begin
for i := 0 to Items.Count-1 do
{$IFDEF DELPHI_V5UP}
if ItemEnabled[i] then Checked[i] := False;
{$ELSE}
Checked[i] := False;
{$ENDIF}
end;
end;
end;
procedure TDCPopupCheckListBox.DoDrawHint(Sender: TObject; Mode: Integer);
var
Button: TDCEditButton;
begin
Button := FButtons.FindButton('#Comment');
if (Button <> nil) then
begin
if (Mode = 0) and Assigned(Sender) and (Sender is TDCEditButton) then
with TDCEditButton(Sender) do Button.Caption := Comment
else
Button.Caption := '';
Button.invalidate;
end;
end;
procedure TDCPopupCheckListBox.DrawClientRect;
var
DC: HDC;
R, R1, R2: TRect;
Rgn: HRGN;
begin
if not FShowHeader then Exit;
DC := GetWindowDC(Handle);
Rgn := 0;
try
GetWindowRect (Handle, R); OffsetRect (R, -R.Left, -R.Top);
R2 := R;
with FMargins do
begin
InflateRect(R2, -2, -2);
R2.Top := R2.Top + br_HeaderHeight;
R2.Bottom := R2.Bottom - br_FooterHeight;
end;
Rgn := CreateRectRgn(R2.Left, R2.Top, R2.Right, R2.Bottom);
SelectClipRgn(DC, Rgn);
R1 := Rect(FMargins.Left, FMargins.Top, R.Right-FMargins.Right, R.Bottom-FMargins.Bottom);
R1 := Rect(FMargins.Left, FMargins.Top, R.Right-FMargins.Right, R.Bottom-FMargins.Bottom);
InflateRect(R1, -1, -1);
DrawEdge(DC, R1, BDR_SUNKENOUTER, BF_TOPLEFT);
DrawEdge(DC, R1, BDR_SUNKENINNER, BF_BOTTOMRIGHT);
ExcludeClipRect(DC, R1.Left, R1.Top, R1.Right, R1.Bottom);
FillRect(DC, R, GetSysColorBrush(clWhite));
finally
ReleaseDC(Handle, DC);
if Rgn <> 0 then DeleteObject(Rgn)
end;
end;
procedure TDCPopupCheckListBox.DrawFooter;
var
DC: HDC;
R: TRect;
Bitmap: TBitmap;
begin
if not FShowHeader then Exit;
DC := GetWindowDC(Handle);
Bitmap := TBitmap.Create;
try
GetWindowRect (Handle, R); OffsetRect (R, -R.Left, -R.Top);
InflateRect(R, -2, -2);
Bitmap.LoadFromResourceName(HInstance, 'DC_BTNSIZE');
R.Top := R.Bottom - br_FooterHeight - 4;
FillRect(DC, R, GetSysColorBrush(COLOR_BTNFACE));
R.Left := R.Right-Bitmap.Width-2;
R.Top := R.Bottom-Bitmap.Height-2;
DrawTransparentBitmap(DC, Bitmap, R, False, Bitmap.Canvas.Pixels[0,0]);
finally
Bitmap.Free;
ReleaseDC(Handle, DC);
end;
end;
procedure TDCPopupCheckListBox.DrawHeader;
var
DC: HDC;
R: TRect;
begin
if not FShowHeader then Exit;
DC := GetWindowDC(Handle);
try
GetWindowRect (Handle, R); OffsetRect (R, -R.Left, -R.Top);
InflateRect(R, -2, -2);
R.Bottom := R.Top + br_HeaderHeight;
FillRect(DC, R, GetSysColorBrush(COLOR_BTNFACE));
R.Bottom := R.Bottom - 1;
DrawCaption(Handle, DC, R, DC_TEXT or DC_SMALLCAP or DC_ACTIVE or DC_GRADIENT);
finally
ReleaseDC(Handle, DC);
end;
end;
procedure TDCPopupCheckListBox.Hide;
begin
HideWindow(Handle);
FVisible := False;
end;
procedure TDCPopupCheckListBox.InvalidateButtons;
var
i, RightPos: integer;
Button: TDCEditButton;
Changed: boolean;
begin
RightPos := Width - br_SizerWidth - FBorderSize - FMargins.Left - 3;
Changed := False;
for i := 0 to FButtons.Count-1 do
begin
Button := FButtons.Buttons[i];
if (Button.Left + Button.Width) > RightPos then
begin
if Button.Visible then
begin
Button.Visible := False;
Changed := True;
end
end
else
if not Button.Visible then
begin
Button.Visible := True;
Changed := True;
end;
end;
if Changed then SendMessage(Self.Handle, WM_NCPAINT, 0, 0);
end;
procedure TDCPopupCheckListBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited;
case Key of
VK_LEFT :
begin
if ssCtrl in Shift then
SetBounds(Left-POPUP_MOVE_STEPX, Top, Width, Height);
end;
VK_RIGHT:
begin
if ssCtrl in Shift then
SetBounds(Left+POPUP_MOVE_STEPX, Top, Width, Height);
end;
VK_UP :
begin
if ssCtrl in Shift then
SetBounds(Left, Top-POPUP_MOVE_STEPY, Width, Height);
end;
VK_DOWN :
begin
if ssCtrl in Shift then
SetBounds(Left, Top+POPUP_MOVE_STEPY, Width, Height);
end;
end;
end;
procedure TDCPopupCheckListBox.RedrawBorder;
var
DC: HDC;
R: TRect;
ABrush: HBRUSH;
begin
DC := GetWindowDC(Handle);
try
GetWindowRect (Handle, R); OffsetRect (R, -R.Left, -R.Top);
case FPopupBorderStyle of
brNone:;
brSingle:
begin
ABrush := CreateSolidBrush(clBlack);
FrameRect( DC, R, ABrush);
DeleteObject(ABrush);
end;
brRaised:
begin
DrawEdge(DC, R, BDR_RAISEDOUTER, BF_RECT);
InflateRect(R, -1, -1);
DrawEdge(DC, R, BDR_RAISEDINNER, BF_RECT);
DrawHeader;
DrawClientRect;
DrawFooter;
end;
end;
finally
ReleaseDC(Handle, DC);
end;
end;
procedure TDCPopupCheckListBox.SetBounds(ALeft, ATop, AWidth,
AHeight: Integer);
begin
if AHeight < ItemHeight * 5 then AHeight := ItemHeight * 5;
if AWidth < 80 then AWidth := 80;
inherited;
FWindowRect := Rect(Left,Top,Left+Width,Top+Height);
end;
procedure TDCPopupCheckListBox.SetBoundsEx(ALeft, ATop, AWidth,
AHeight: Integer);
begin
FWindowRect := Rect(ALeft,ATop,ALeft+AWidth,aTop+AHeight);
if FVisible then Show;
end;
procedure TDCPopupCheckListBox.SetMargins;
begin
FMargins := Rect(4,4,4,2);
if not FShowHeader then Exit;
case FPopupBorderStyle of
brNone :;
brSingle:;
brRaised:
begin
// Margins.Properties
FMargins.Top := FMargins.Top + br_HeaderHeight;
FMargins.Bottom := FMargins.Bottom + br_FooterHeight + 4;
end;
end;
end;
procedure TDCPopupCheckListBox.SetParent(AParent: TWinControl);
begin
inherited;
if (AParent <> nil) and (AParent.Parent <> nil) and
(AParent is TDCCustomChoiceEdit)
then begin
Caption := TDCCustomChoiceEdit(AParent).DBObject.Caption;
end;
end;
procedure TDCPopupCheckListBox.SetPopupAlignment(Value: TWindowAlignment);
begin
if Value <> FPopupAlignment then
begin
FPopupAlignment := Value;
if Visible then Show;
end;
end;
procedure TDCPopupCheckListBox.SetPopupBorderStyle(
Value: TPopupBorderStyle);
begin
if FPopupBorderStyle <> Value then
begin
FPopupBorderStyle := Value;
case FPopupBorderStyle of
brNone :FBorderSize := 0;
brSingle:FBorderSize := 1;
brRaised:FBorderSize := 2;
end;
RecreateWnd;
end;
end;
procedure TDCPopupCheckListBox.SetShowHeader(const Value: boolean);
begin
FShowHeader := Value;
RecreateWnd;
end;
procedure TDCPopupCheckListBox.Show;
var
ItemsCount: integer;
begin
SetMargins;
if Items.Count < FDropDownRows then
ItemsCount := Items.Count
else
ItemsCount := FDropDownRows;
Height := ItemHeight * ItemsCount + 2*FBorderSize + FMargins.Top + FMargins.Bottom;
ShowWindow(Handle, FPopupAlignment, FWindowRect, FAlwaysVisible, Owner);
FVisible := True;
end;
procedure TDCPopupCheckListBox.WMFontChange(var Message: TWMFontChange);
var
i: integer;
begin
inherited;
AdjustNewHeight;
for i := 0 to FButtons.Count-1 do
FButtons.Buttons[i].Font := Font;
end;
procedure TDCPopupCheckListBox.WMMouseActivate(var Message: TWMActivate);
begin
inherited;
Message.Result := MA_NOACTIVATE;
SetWindowPos (Handle, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;
procedure TDCPopupCheckListBox.WMNCCalcSize(var Message: TWMNCCalcSize);
begin
case FPopupBorderStyle of
brNone :FBorderSize := 0;
brSingle:
begin
FBorderSize := 2;
InflateRect(Message.CalcSize_Params^.rgrc[0], -2, -2);
end;
brRaised:
begin
FBorderSize := 2;
InflateRect(Message.CalcSize_Params^.rgrc[0], -2, -2);
end;
end;
with Message.CalcSize_Params^.rgrc[0] do
begin
Top := Top + FMargins.Top;
Left := Left + FMargins.Left;
Bottom := Bottom - FMargins.Bottom;
Right := Right - FMargins.Right;
end;
inherited;
end;
procedure TDCPopupCheckListBox.WMNCHitTest(var Message: TWMNCHitTest);
var
R, WindowR: TRect;
BS: Integer;
Button: TDCEditButton;
function InCaptArea(XPos, YPos: integer): boolean;
begin
R := WindowR;
InflateRect(R, -BS, -BS);
R.Bottom := R.Top + FMargins.Top;
Result := PtInRect(R, Point(XPos, YPos));
end;
function InSizeArea(XPos, YPos: integer): boolean;
begin
R := WindowR;
InflateRect(R, -BS, -BS);
R.Top := R.Bottom - br_FooterHeight;
R.Left := R.Right - br_SizerWidth;
Result := PtInRect(R, Point(XPos, YPos));
end;
function InGridArea(XPos, YPos: integer): boolean;
begin
R := WindowR;
InflateRect(R, -BS, -BS);
R.Left := R.Left + FMargins.Left;
R.Top := R.Top + FMargins.Top;
R.Right := R.Right - FMargins.Right;
R.Bottom := R.Bottom - FMargins.Bottom;
Result := PtInRect(R, Point(XPos, YPos));
end;
function InButtonsArea(XPos, YPos: integer): boolean;
var
P: TPoint;
begin
P.X := XPos - Left;
P.Y := YPos - Top;
Result := FButtons.MouseInButtonArea(P.X, P.Y, Button);
R := WindowR;
InflateRect(R, -BS, -BS);
end;
function InFooterArea(XPos, YPos: integer): boolean;
begin
R := WindowR;
InflateRect(R, -BS, -BS);
R.Top := R.Bottom - br_FooterHeight;
Result := PtInRect(R, Point(XPos, YPos));
end;
begin
inherited;
if not FShowHeader then begin
FCursorMode := cmGrid;
Exit;
end;
FCursorMode := cmNone;
BS := FBorderSize;
GetWindowRect(Handle, WindowR);
with Message do
begin
if InCaptArea(XPos, YPos) then
begin
FCursorMode := cmMove;
Result := HTBORDER;
end;
if InFooterArea(XPos, YPos) then
begin
FCursorMode := cmFooter;
Result := HTBORDER;
end;
if InSizeArea(XPos, YPos) then
begin
FCursorMode := cmResize;
Result := HTSIZE;
end;
if InGridArea(XPos, YPos) then FCursorMode := cmGrid;
if InButtonsArea(XPos, YPos) then
begin
FCursorMode := cmButtons;
Result := HTBORDER;
end;
end;
end;
procedure TDCPopupCheckListBox.WMNCLButtonDown(
var Message: TWMNCLButtonDown);
begin
inherited;
with Message do
begin
case FCursorMode of
cmResize, cmMove: BeginMoving(XCursor, YCursor);
end;
end;
end;
procedure TDCPopupCheckListBox.WMNCPaint(var Message: TWMNCPaint);
begin
inherited;
RedrawBorder;
end;
procedure TDCPopupCheckListBox.WMPaint(var Message: TWMPaint);
begin
if Assigned(FButtons) then FButtons.UpdateDeviceRegion(Message.DC);
inherited;
if Assigned(FButtons) then InvalidateButtons;
end;
procedure TDCPopupCheckListBox.WMSetCursor(var Message: TWMSetCursor);
begin
case FCursorMode of
cmNone : SetCursor(Screen.Cursors[crArrow]);
cmResize : SetCursor(Screen.Cursors[crSizeNWSE]);
cmMove : SetCursor(Screen.Cursors[crArrow]);
cmButtons: SetCursor(Screen.Cursors[crArrow]);
cmFooter : SetCursor(Screen.Cursors[crArrow]);
cmGrid : inherited;
end;
end;
procedure TDCPopupCheckListBox.WMSize(var Message: TWMSize);
begin
inherited;
if Assigned(FButtons) then InvalidateButtons;
end;
{ TDCCustomListComboBox }
procedure TDCCustomListComboBox.CheckClick(Sender: TObject);
begin
inherited;
if NotEditControl then HideCaret(Handle);
end;
procedure TDCCustomListComboBox.ChoiceClick(Sender: TObject);
begin
if FListBoxVisible then
CloseUp(0, True)
else
Perform(CM_POPUPWINDOW, 1, 0);
end;
procedure TDCCustomListComboBox.Clear;
begin
Items.Clear;
end;
procedure TDCCustomListComboBox.CloseUp(State: Byte; bPerform: boolean);
begin
if FListBoxVisible then SetText(0, -1);
case State of
0: SelLength := 0;
1: FLastText := Text;
end;
inherited;
end;
procedure TDCCustomListComboBox.CMCancelMode(var Message: TCMCancelMode);
begin
if (Message.Sender <> Self) and
(Message.Sender <> FListBox) and
not FListBox.ContainsControl(Message.Sender) then
begin
inherited;
end;
end;
procedure TDCCustomListComboBox.CMEnter(var Message: TCMEnter);
begin
inherited;
PaintListItem(Focused);
end;
procedure TDCCustomListComboBox.CMPopupButtonClk(var Message: TMessage);
begin
case TDCEditButton(Message.WParam).Tag of
1{Close}: CloseUp(1, False);
end;
end;
procedure TDCCustomListComboBox.CMPopupWindow(var Message: TMessage);
begin
case Message.WParam of
0:
if FListBoxVisible then
begin
FListBoxVisible := False;
FListBox.Hide;
if BtnChoiceAssigned then ButtonChoice.ResetProperties;
ShowHint := FHintShow;
PaintListItem(Focused);
end;
1:
begin
PaintListItem(False);
FHintShow := ShowHint;
ShowHint := False;
with FListBox do
begin
Color := Self.Color;
Parent := Self;
PopupAlignment := wpBottomLeft;
DropDownRows := DropDownCount;
case DrawStyle of
FcsNormal,
fsNone : FListBox.PopupBorderStyle := brRaised;
fsSingle : FListBox.PopupBorderStyle := brRaised;
fsFlat : FListBox.PopupBorderStyle := brRaised;
end;
if FDropDownWidth = 0 then Width := Self.Width
else Width :=FDropDownWidth;
ItemHeight := FItemHeight;
SelectAll;
Show;
FListBoxVisible := True;
end
end;
end;
end;
constructor TDCCustomListComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FListBoxVisible := False;
FListBox := TDCPopupCheckListBox.Create(Self);
with FListBox do
begin
Parent := Self;
OnMeasureItem := ListMeasureItem;
OnDrawItem := ListDrawItem;
end;
ReadOnly := True;
FUpdateCount := 0;
FDropDownCount := 8;
end;
procedure TDCCustomListComboBox.CreateParams(var Params: TCreateParams);
begin
inherited;
if NotEditControl then
begin
with Params do
begin
Text := Name;
Style := WS_CHILD or WS_CLIPSIBLINGS;
AddBiDiModeExStyle(ExStyle);
if csAcceptsControls in ControlStyle then
begin
Style := Style or WS_CLIPCHILDREN;
ExStyle := ExStyle or WS_EX_CONTROLPARENT;
end;
if DrawStyle = fsNone then
ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
if DrawStyle = fsSingle then
Style := Style or WS_BORDER;
if not (csDesigning in ComponentState) and not Enabled then
Style := Style or WS_DISABLED;
if TabStop then Style := Style or WS_TABSTOP;
if Parent <> nil then
WndParent := Parent.Handle else
WndParent := ParentWindow;
WindowClass.style := CS_VREDRAW + CS_HREDRAW + CS_DBLCLKS;
WindowClass.lpfnWndProc := @DefWindowProc;
WindowClass.hCursor := LoadCursor(0, IDC_ARROW);
WindowClass.hbrBackground := 0;
WindowClass.hInstance := HInstance;
StrPCopy(WinClassName, ClassName);
end;
end
end;
procedure TDCCustomListComboBox.CreateWnd;
begin
inherited;
SetText(-1, 0);
end;
procedure TDCCustomListComboBox.DefineBtnChoiceStyle;
begin
if BtnChoiceAssigned then
begin
ButtonChoiceStyle := btsCombo;
ButtonStyle := esDropDown;
end;
end;
destructor TDCCustomListComboBox.Destroy;
begin
FListBox.Free;
inherited;
end;
procedure TDCCustomListComboBox.EMGetSel(var Message: TMessage);
begin
if FStyle = csDropDownList then
with Message do
begin
lParam := 0;
wParam := GetTextLen;
end
else
inherited
end;
procedure TDCCustomListComboBox.EMSetReadOnly(var Message: TMessage);
begin
Message.WParam := Integer(False);
end;
function TDCCustomListComboBox.GetAllowGrayed: Boolean;
begin
Result := FListBox.AllowGrayed
end;
function TDCCustomListComboBox.GetCanvas: TCanvas;
begin
if FListBoxVisible then
Result := FListBox.Canvas
else
Result := nil;
end;
function TDCCustomListComboBox.GetChecked(Index: Integer): Boolean;
begin
Result := FListBox.Checked[Index];
end;
function TDCCustomListComboBox.GetDropDownVisible: boolean;
begin
Result := FListBoxVisible;
end;
procedure TDCCustomListComboBox.GetHintOnError;
begin
inherited;
end;
function TDCCustomListComboBox.GetItemEnabled(Index: Integer): Boolean;
begin
{$IFDEF DELPHI_V5UP}
Result := FListBox.ItemEnabled[Index];
{$ELSE}
Result := True;
{$ENDIF}
end;
function TDCCustomListComboBox.GetItemIndex: integer;
begin
Result := FListBox.ItemIndex;
end;
function TDCCustomListComboBox.GetItems: TStrings;
begin
Result := FListBox.Items;
end;
function TDCCustomListComboBox.GetState(Index: Integer): TCheckBoxState;
begin
Result := FListBox.State[Index];
end;
procedure TDCCustomListComboBox.KeyDown(var Key: Word; Shift: TShiftState);
var
KeyDownEvent: TKeyEvent;
begin
KeyDownEvent := OnKeyDown;
if FListBoxVisible and (FListBox<>nil) then
case Key of
VK_PRIOR,
VK_NEXT ,
VK_UP ,
VK_DOWN :
begin
if Assigned(KeyDownEvent) then KeyDownEvent(Self, Key, Shift);
if (FListBox.ItemIndex = -1) and not(ssCtrl in Shift) then
FListBox.ItemIndex := 0
else
SendMessage(FListBox.Handle, WM_KEYDOWN, Key, 0);
Key := 0;
end;
end
else begin
if [ssAlt]*Shift = [ssAlt] then
begin
case Key of
VK_DOWN:
if FStyle <> csSimple then
begin
if Assigned(KeyDownEvent) then KeyDownEvent(Self, Key, Shift);
if Key <> 0 then ChoiceButtonDown;
Key := 0;
end;
end
end;
end;
if Key <> 0 then inherited;
end;
procedure TDCCustomListComboBox.KeyPress(var Key: Char);
begin
if FListBoxVisible and (FListBox<>nil) then
begin
case Key of
Char(VK_RETURN): begin CloseUp(1, True); Key := #0; end;
Char(VK_ESCAPE): begin CloseUp(0, True); Key := #0; end;
else begin
FListBox.KeyPress(Key);
Key := #0;
end;
end;
end
else begin
case Key of
Char(VK_ESCAPE): SetText(-1, 0);
end;
end;
inherited KeyPress(Key);
end;
procedure TDCCustomListComboBox.KillFocus(var Value: boolean);
begin
inherited KillFocus(Value);
end;
procedure TDCCustomListComboBox.ListDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
if Index < Items.Count then
begin
if Assigned(FOnDrawItem) then
FOnDrawItem(Control, Index, Rect, State)
else begin
Canvas.FillRect(Rect);
Canvas.TextOut(Rect.Left + 2, Rect.Top, Items[Index]);
end;
end;
end;
procedure TDCCustomListComboBox.ListMeasureItem(Control: TWinControl;
Index: Integer; var Height: Integer);
begin
if Assigned(FOnMeasureItem) then FOnMeasureItem(Control, Index, Height);
end;
procedure TDCCustomListComboBox.Loaded;
begin
inherited;
UpdateItems;
end;
function TDCCustomListComboBox.MinControlWidthBitmap: integer;
begin
if Style <> csDropDownList then
Result := inherited MinControlWidthBitmap
else
Result := 2;
end;
function TDCCustomListComboBox.NotEditControl: boolean;
begin
Result := FStyle = csDropDownList;
end;
procedure TDCCustomListComboBox.PaintListItem(bFocused: boolean);
const
Alignments: array[Boolean, TAlignment] of DWORD =
((DT_LEFT, DT_RIGHT, DT_CENTER),(DT_RIGHT, DT_LEFT, DT_CENTER));
var
DC: HDC;
R: TRect;
ACanvas: TCanvas;
begin
if not NotEditControl then Exit;
ACanvas := TControlCanvas.Create;
DC := GetWindowDC(Handle);
GetWindowRect (Handle, R); OffsetRect (R, -R.Left, -R.Top);
if PaintCheckGlyph then R.Left := R.Left + CheckGlyph.Width + 2;
if ButtonWidth > 0 then
begin
R.Right := R.Right - ButtonWidth;
if DrawStyle = fsFlat then R.Right := R.Right - 1
end;
case DrawStyle of
fsNone :
begin
InflateRect(R, -1, -1);
R.Left := R.Left -1;
end;
fsSingle :
InflateRect(R, -2, -2);
FcsNormal,
fsFlat :
InflateRect(R, -3, -3);
end;
ACanvas.Handle := DC;
ACanvas.Font := Font;
ACanvas.Brush.Color := Color;
InflateRect(R, 1, 1);
FillRect(ACanvas.Handle, R, ACanvas.Brush.Handle);
InflateRect(R, -1, -1);
if bFocused then
begin
ACanvas.Brush.Color := clHighlight;
ACanvas.Font.Color := clHighlightText;
end;
try
if DrawStyle = fsNone then R.Left := R.Left +1;
FillRect(ACanvas.Handle, R, ACanvas.Brush.Handle);
if bFocused then DrawFocusRect(ACanvas.Handle, R);
InflateRect(R, -1, -1);
SetBkMode(ACanvas.Handle, TRANSPARENT);
case DrawStyle of
FcsNormal,
fsFlat ,
fsNone : R.Top := R.Top -1;
end;
if Assigned(FOnDrawText) then
FOnDrawText(ACanvas, Self, ItemIndex, R, [])
else
DrawText(ACanvas.Handle, PChar(Text), Length(Text), R,
Alignments[UseRightToLeftAlignment, Alignment]);
finally
ReleaseDC(Handle, DC);
ACanvas.Handle := 0;
ACanvas.Free;
end;
end;
procedure TDCCustomListComboBox.SetAllowGrayed(const Value: Boolean);
begin
FListBox.AllowGrayed := Value;
end;
procedure TDCCustomListComboBox.SetChecked(Index: Integer;
const Value: Boolean);
begin
FListBox.Checked[Index] := Value;
UpdateItems;
if Style = csDropDownList then PaintListItem(Focused);
end;
procedure TDCCustomListComboBox.SetComboBoxStyle(Value: TComboBoxStyle);
begin
if FStyle <> Value then
begin
FStyle := Value;
case FStyle of
csDropDown:
ButtonExist := True;
csSimple:
ButtonExist := False;
csDropDownList:
begin
ButtonExist := True;
Text := ''
end;
csOwnerDrawFixed:
ButtonExist := True;
csOwnerDrawVariable:
ButtonExist := True;
end;
RecreateWnd;
SetText(-1, 0);
end;
end;
procedure TDCCustomListComboBox.SetItemEnabled(Index: Integer;
const Value: Boolean);
begin
{$IFDEF DELPHI_V5UP}
FListBox.ItemEnabled[Index] := Value;;
{$ENDIF}
end;
procedure TDCCustomListComboBox.SetItems(Value: TStrings);
begin
FListBox.Items.Assign(Value);
end;
procedure TDCCustomListComboBox.SetState(Index: Integer;
const Value: TCheckBoxState);
begin
FListBox.State[Index] := Value;
end;
procedure TDCCustomListComboBox.SetText(ASelStart, ASelLen: integer);
var
i: integer;
AText, BText: string;
begin
BText := Text;
AText := '';
for i := 0 to Items.Count-1 do
begin
if FListBox.Checked[i] then
if AText <> '' then
AText := AText + ', ' + Items[i]
else
AText := Items[i];
end;
if Assigned(FOnSetText) then FOnSetText(Self, AText);
Text := Format('[%s]', [AText]);
if not NotEditControl then SendMessage(Handle, EM_SETSEL, ASelLen, ASelStart);
if BText <> Text then Change;
end;
procedure TDCCustomListComboBox.UpdateItems;
begin
SetText(-1, 0);
end;
procedure TDCCustomListComboBox.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
if FStyle = csDropDownList then
Message.Result := 0
else
inherited;
end;
procedure TDCCustomListComboBox.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS or DLGC_WANTALLKEYS;
end;
procedure TDCCustomListComboBox.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
if Assigned(Items) then PaintListItem(False);
end;
procedure TDCCustomListComboBox.WMLButtonDblClk(
var Message: TWMLButtonDown);
begin
if not DisableButtons and (FStyle = csDropDownList) then
begin
Message.Result := $AE;
inherited WMLButtonDblClk(Message);
end
else inherited;
end;
procedure TDCCustomListComboBox.WMNCHitTest(var Message: TWMNCHitTest);
var
P: TPoint;
begin
inherited;
P := Self.ScreenToClient(Point(Message.XPos, Message.YPos));
if ShowCheckBox and Assigned(CheckGlyph) and (P.X < CheckGlyph.Width) and
((Width-CheckGlyph.Width) >= MinControlWidthBitmap) then
FInCheckArea := True
else
FInCheckArea := False;
if BtnChoiceAssigned and (P.X >= (Width - ButtonWidth - 2)) then
FInButtonArea := True
else
FInButtonArea := False;
inherited;
end;
procedure TDCCustomListComboBox.WMPaint(var Message: TWMPaint);
var
PS: TPaintStruct;
begin
if not NotEditControl then
inherited
else begin
BeginPaint(Handle, PS);
RedrawBorder(True, 0);
PaintListItem(Focused and not FListBoxVisible);
EndPaint(Handle, PS);
end;
end;
procedure TDCCustomListComboBox.WMSetCursor(var Message: TWMSetCursor);
begin
if NotEditControl then SetCursor(LoadCursor(0, IDC_ARROW)) else inherited;
end;
procedure TDCCustomListComboBox.WMSetFocus(var Message: TWMSetFocus);
begin
FLastText := Text;
inherited;
if NotEditControl then HideCaret(Handle);
end;
procedure TDCCustomListComboBox.WndProc(var Message: TMessage);
var
lFocused: boolean;
begin
lFocused := Focused;
inherited WndProc(Message);
if csDesigning in ComponentState then Exit;
case Message.Msg of
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
begin
if NotEditControl and not(FInButtonArea or FInCheckArea) then
begin
if not Focused then SetFocus;
if Focused then with ButtonChoice do
UpdateButtonState(Left+1, Top+1, True, False);
end;
if not NotEditControl and not lFocused then SelectAll;
end;
end;
end;
end.