| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018 |
- unit TB2ExtItems;
- {
- Toolbar2000
- Copyright (C) 1998-2005 by Jordan Russell
- All rights reserved.
- The contents of this file are subject to the "Toolbar2000 License"; you may
- not use or distribute this file except in compliance with the
- "Toolbar2000 License". A copy of the "Toolbar2000 License" may be found in
- TB2k-LICENSE.txt or at:
- http://www.jrsoftware.org/files/tb2k/TB2k-LICENSE.txt
- Alternatively, the contents of this file may be used under the terms of the
- GNU General Public License (the "GPL"), in which case the provisions of the
- GPL are applicable instead of those in the "Toolbar2000 License". A copy of
- the GPL may be found in GPL-LICENSE.txt or at:
- http://www.jrsoftware.org/files/tb2k/GPL-LICENSE.txt
- If you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- "Toolbar2000 License", indicate your decision by deleting the provisions
- above and replace them with the notice and other provisions required by the
- GPL. If you do not delete the provisions above, a recipient may use your
- version of this file under either the "Toolbar2000 License" or the GPL.
- $jrsoftware: tb2k/Source/TB2ExtItems.pas,v 1.63 2005/07/04 02:49:52 jr Exp $
- }
- interface
- {$I TB2Ver.inc}
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, CommCtrl, Menus, ActnList,
- TB2Item;
- type
- TTBEditItemOption = (tboUseEditWhenVertical);
- TTBEditItemOptions = set of TTBEditItemOption;
- const
- EditItemDefaultEditOptions = [];
- EditItemDefaultEditWidth = 64;
- { Change reasons for TTBEditItem.Text property }
- tcrSetProperty = 0; // direct assignment to TTBEditItem.Text property
- tcrActionLink = 1; // change comes from an action link
- tcrEditControl = 2; // change is caused by typing in edit area
- type
- TTBEditItem = class;
- TTBEditItemViewer = class;
- TTBAcceptTextEvent = procedure(Sender: TObject; var NewText: String;
- var Accept: Boolean) of object;
- TTBBeginEditEvent = procedure(Sender: TTBEditItem; Viewer: TTBEditItemViewer;
- EditControl: TEdit) of object;
- TTBEditAction = class(TAction)
- private
- FEditOptions: TTBEditItemOptions;
- FEditCaption: String;
- FEditWidth: Integer;
- FOnAcceptText: TTBAcceptTextEvent;
- FText: String;
- procedure SetEditCaption(Value: String);
- procedure SetEditOptions(Value: TTBEditItemOptions);
- procedure SetEditWidth(Value: Integer);
- procedure SetOnAcceptText(Value: TTBAcceptTextEvent);
- procedure SetText(Value: String);
- public
- constructor Create(AOwner: TComponent); override;
- published
- property EditCaption: String read FEditCaption write SetEditCaption;
- property EditOptions: TTBEditItemOptions read FEditOptions write SetEditOptions default EditItemDefaultEditOptions;
- property EditWidth: Integer read FEditWidth write SetEditWidth default EditItemDefaultEditWidth;
- property Text: String read FText write SetText;
- property OnAcceptText: TTBAcceptTextEvent read FOnAcceptText write SetOnAcceptText;
- end;
- TTBEditItemActionLink = class(TTBCustomItemActionLink)
- protected
- procedure AssignClient(AClient: TObject); override;
- function IsEditCaptionLinked: Boolean; virtual;
- function IsEditOptionsLinked: Boolean; virtual;
- function IsEditWidthLinked: Boolean; virtual;
- function IsOnAcceptTextLinked: Boolean; virtual;
- function IsTextLinked: Boolean; virtual;
- procedure SetEditCaption(const Value: String); virtual;
- procedure SetEditOptions(Value: TTBEditItemOptions); virtual;
- procedure SetEditWidth(const Value: Integer); virtual;
- procedure SetOnAcceptText(Value: TTBAcceptTextEvent); virtual;
- procedure SetText(const Value: String); virtual;
- end;
- TTBEditItem = class(TTBCustomItem)
- private
- FCharCase: TEditCharCase;
- FEditCaption: String;
- FEditOptions: TTBEditItemOptions;
- FEditWidth: Integer;
- FExtendedAccept: Boolean;
- FMaxLength: Integer;
- FOnAcceptText: TTBAcceptTextEvent;
- FOnBeginEdit: TTBBeginEditEvent;
- FText: String;
- function IsEditCaptionStored: Boolean;
- function IsEditOptionsStored: Boolean;
- function IsEditWidthStored: Boolean;
- function IsTextStored: Boolean;
- procedure SetCharCase(Value: TEditCharCase);
- procedure SetEditCaption(Value: String);
- procedure SetEditOptions(Value: TTBEditItemOptions);
- procedure SetEditWidth(Value: Integer);
- procedure SetMaxLength(Value: Integer);
- procedure SetText(Value: String);
- protected
- procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
- function DoAcceptText(var NewText: string): Boolean; virtual;
- procedure DoBeginEdit(Viewer: TTBEditItemViewer); virtual;
- procedure DoTextChanging(const OldText: String; var NewText: String; Reason: Integer); virtual;
- procedure DoTextChanged(Reason: Integer); virtual;
- function GetActionLinkClass: TTBCustomItemActionLinkClass; override;
- function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
- function NeedToRecreateViewer(AViewer: TTBItemViewer): Boolean; override;
- property ExtendedAccept: Boolean read FExtendedAccept write FExtendedAccept default False;
- procedure SetTextEx(Value: String; Reason: Integer);
- public
- constructor Create(AOwner: TComponent); override;
- procedure Clear;
- procedure Click; override;
- published
- property Action;
- property AutoCheck;
- property Caption;
- property CharCase: TEditCharCase read FCharCase write SetCharCase default ecNormal;
- property Checked;
- property DisplayMode;
- property EditCaption: String read FEditCaption write SetEditCaption stored IsEditCaptionStored;
- property EditOptions: TTBEditItemOptions read FEditOptions write SetEditOptions stored IsEditOptionsStored;
- property EditWidth: Integer read FEditWidth write SetEditWidth stored IsEditWidthStored;
- property MaxLength: Integer read FMaxLength write SetMaxLength default 0;
- property Enabled;
- property GroupIndex;
- property HelpContext;
- { MP }
- property HelpKeyword;
- property Hint;
- property ImageIndex;
- property RadioItem;
- property ShortCut;
- property Text: String read FText write SetText stored IsTextStored;
- property Visible;
- property OnAcceptText: TTBAcceptTextEvent read FOnAcceptText write FOnAcceptText;
- property OnBeginEdit: TTBBeginEditEvent read FOnBeginEdit write FOnBeginEdit;
- property OnClick;
- property OnSelect;
- end;
- TEditClass = class of TEdit;
- TTBEditItemViewer = class(TTBItemViewer)
- private
- FEditControl: TEdit;
- FEditControlStatus: set of (ecsContinueLoop, ecsAccept, ecsClose);
- function EditLoop(const CapHandle: HWND): Boolean;
- procedure EditWndProc(var Message: TMessage);
- procedure MouseBeginEdit;
- protected
- procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer);
- override;
- function CaptionShown: Boolean; override;
- function DoExecute: Boolean; override;
- function GetAccRole: Integer; override;
- function GetAccValue(var Value: WideString): Boolean; override;
- function GetCaptionText: String; override;
- procedure GetCursor(const Pt: TPoint; var ACursor: HCURSOR); override;
- function GetEditControlClass: TEditClass; virtual;
- procedure GetEditRect(var R: TRect); virtual;
- procedure MouseDown(Shift: TShiftState; X, Y: Integer;
- var MouseDownOnMenu: Boolean); override;
- procedure MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean); override;
- procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect;
- IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
- function UsesSameWidth: Boolean; override;
- public
- property EditControl: TEdit read FEditControl;
- end;
- {$IFNDEF MPEXCLUDE}
- { TTBVisibilityToggleItem }
- TTBVisibilityToggleItem = class(TTBCustomItem)
- private
- FControl: TControl;
- procedure SetControl(Value: TControl);
- procedure UpdateProps;
- protected
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- procedure Click; override;
- procedure InitiateAction; override;
- published
- property Caption;
- property Control: TControl read FControl write SetControl;
- property DisplayMode;
- property Enabled;
- property HelpContext;
- { MP }
- property HelpKeyword;
- property Hint;
- property ImageIndex;
- property Images;
- property InheritOptions;
- property MaskOptions;
- property Options;
- property ShortCut;
- property Visible;
- property OnClick;
- property OnSelect;
- end;
- {$ENDIF}
- implementation
- uses
- TB2Common, TB2Consts;
- const
- EditMenuTextMargin = 3;
- EditMenuMidWidth = 4;
- type
- TControlAccess = class(TControl);
- TEditAccess = class(TEdit);
- { TTBEditAction }
- constructor TTBEditAction.Create(AOwner: TComponent);
- begin
- inherited;
- FEditOptions := EditItemDefaultEditOptions;
- FEditWidth := EditItemDefaultEditWidth;
- DisableIfNoHandler := False;
- end;
- procedure TTBEditAction.SetEditCaption(Value: String);
- var
- I: Integer;
- begin
- if FEditCaption <> Value then begin
- for I := 0 to ClientCount - 1 do
- if TBasicActionLink(Clients[I]) is TTBEditItemActionLink then
- TTBEditItemActionLink(Clients[I]).SetEditCaption(Value);
- FEditCaption := Value;
- Change;
- end;
- end;
- procedure TTBEditAction.SetEditOptions(Value: TTBEditItemOptions);
- var
- I: Integer;
- begin
- if FEditOptions <> Value then begin
- for I := 0 to ClientCount - 1 do
- if TBasicActionLink(Clients[I]) is TTBEditItemActionLink then
- TTBEditItemActionLink(Clients[I]).SetEditOptions(Value);
- FEditOptions := Value;
- Change;
- end;
- end;
- procedure TTBEditAction.SetEditWidth(Value: Integer);
- var
- I: Integer;
- begin
- if FEditWidth <> Value then begin
- for I := 0 to ClientCount - 1 do
- if TBasicActionLink(Clients[I]) is TTBEditItemActionLink then
- TTBEditItemActionLink(Clients[I]).SetEditWidth(Value);
- FEditWidth := Value;
- Change;
- end;
- end;
- procedure TTBEditAction.SetOnAcceptText(Value: TTBAcceptTextEvent);
- var
- I: Integer;
- begin
- if not MethodsEqual(TMethod(FOnAcceptText), TMethod(Value)) then begin
- for I := 0 to ClientCount - 1 do
- if TBasicActionLink(Clients[I]) is TTBEditItemActionLink then
- TTBEditItemActionLink(Clients[I]).SetOnAcceptText(Value);
- FOnAcceptText := Value;
- Change;
- end;
- end;
- procedure TTBEditAction.SetText(Value: String);
- var
- I: Integer;
- begin
- if FText <> Value then begin
- for I := 0 to ClientCount - 1 do
- if TBasicActionLink(Clients[I]) is TTBEditItemActionLink then
- TTBEditItemActionLink(Clients[I]).SetText(Value);
- FText := Value;
- Change;
- end;
- end;
- { TTBEditItemActionLink }
- procedure TTBEditItemActionLink.AssignClient(AClient: TObject);
- begin
- FClient := AClient as TTBEditItem;
- end;
- function TTBEditItemActionLink.IsEditCaptionLinked: Boolean;
- begin
- if Action is TTBEditAction then
- Result := TTBEditItem(FClient).EditCaption = TTBEditAction(Action).EditCaption
- else
- Result := False;
- end;
- function TTBEditItemActionLink.IsEditOptionsLinked: Boolean;
- begin
- if Action is TTBEditAction then
- Result := TTBEditItem(FClient).EditOptions = TTBEditAction(Action).EditOptions
- else
- Result := False;
- end;
- function TTBEditItemActionLink.IsEditWidthLinked: Boolean;
- begin
- if Action is TTBEditAction then
- Result := TTBEditItem(FClient).EditWidth = TTBEditAction(Action).EditWidth
- else
- Result := False;
- end;
- function TTBEditItemActionLink.IsOnAcceptTextLinked: Boolean;
- begin
- if Action is TTBEditAction then
- Result := MethodsEqual(TMethod(TTBEditItem(FClient).OnAcceptText),
- TMethod(TTBEditAction(Action).OnAcceptText))
- else
- Result := False;
- end;
- function TTBEditItemActionLink.IsTextLinked: Boolean;
- begin
- if Action is TTBEditAction then
- Result := TTBEditItem(FClient).Text = TTBEditAction(Action).Text
- else
- Result := False;
- end;
- procedure TTBEditItemActionLink.SetEditCaption(const Value: String);
- begin
- if IsEditCaptionLinked then TTBEditItem(FClient).EditCaption := Value;
- end;
- procedure TTBEditItemActionLink.SetEditOptions(Value: TTBEditItemOptions);
- begin
- if IsEditOptionsLinked then TTBEditItem(FClient).EditOptions := Value;
- end;
- procedure TTBEditItemActionLink.SetEditWidth(const Value: Integer);
- begin
- if IsEditWidthLinked then TTBEditItem(FClient).EditWidth := Value;
- end;
- procedure TTBEditItemActionLink.SetOnAcceptText(Value: TTBAcceptTextEvent);
- begin
- if IsOnAcceptTextLinked then TTBEditItem(FClient).OnAcceptText := Value;
- end;
- procedure TTBEditItemActionLink.SetText(const Value: String);
- begin
- if IsTextLinked then TTBEditItem(FClient).SetTextEx(Value , tcrActionLink);
- end;
- { TTBEditItem }
- constructor TTBEditItem.Create(AOwner: TComponent);
- begin
- inherited;
- FEditOptions := EditItemDefaultEditOptions;
- FEditWidth := EditItemDefaultEditWidth;
- end;
- procedure TTBEditItem.ActionChange(Sender: TObject; CheckDefaults: Boolean);
- begin
- inherited;
- if Action is TTBEditAction then
- with TTBEditAction(Sender) do
- begin
- if not CheckDefaults or (Self.EditCaption = '') then
- Self.EditCaption := EditCaption;
- if not CheckDefaults or (Self.EditOptions = []) then
- Self.EditOptions := EditOptions;
- if not CheckDefaults or (Self.Text = '') then
- Self.SetTextEx(Text, tcrActionLink);
- if not CheckDefaults or not Assigned(Self.OnAcceptText) then
- Self.OnAcceptText := OnAcceptText;
- end;
- end;
- function TTBEditItem.GetActionLinkClass: TTBCustomItemActionLinkClass;
- begin
- Result := TTBEditItemActionLink;
- end;
- function TTBEditItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
- begin
- if not(tboUseEditWhenVertical in EditOptions) and
- (AView.Orientation = tbvoVertical) then
- Result := inherited GetItemViewerClass(AView)
- else
- Result := TTBEditItemViewer;
- end;
- function TTBEditItem.NeedToRecreateViewer(AViewer: TTBItemViewer): Boolean;
- begin
- Result := GetItemViewerClass(AViewer.View) <> AViewer.ClassType;
- end;
- procedure TTBEditItem.Clear;
- begin
- Text := '';
- end;
- procedure TTBEditItem.Click;
- begin
- inherited;
- end;
- procedure TTBEditItem.DoBeginEdit(Viewer: TTBEditItemViewer);
- begin
- if Assigned(FOnBeginEdit) then
- FOnBeginEdit(Self, Viewer, Viewer.EditControl);
- end;
- function TTBEditItem.IsEditOptionsStored: Boolean;
- begin
- Result := (EditOptions <> EditItemDefaultEditOptions) and
- ((ActionLink = nil) or not(ActionLink is TTBEditItemActionLink) or
- not TTBEditItemActionLink(ActionLink).IsEditOptionsLinked);
- end;
- function TTBEditItem.IsEditCaptionStored: Boolean;
- begin
- Result := (ActionLink = nil) or not(ActionLink is TTBEditItemActionLink) or
- not TTBEditItemActionLink(ActionLink).IsEditCaptionLinked;
- end;
- function TTBEditItem.IsEditWidthStored: Boolean;
- begin
- Result := (EditWidth <> EditItemDefaultEditWidth) and
- ((ActionLink = nil) or not(ActionLink is TTBEditItemActionLink) or
- not TTBEditItemActionLink(ActionLink).IsEditWidthLinked);
- end;
- function TTBEditItem.IsTextStored: Boolean;
- begin
- Result := (ActionLink = nil) or not(ActionLink is TTBEditItemActionLink) or
- not TTBEditItemActionLink(ActionLink).IsTextLinked;
- end;
- procedure TTBEditItem.SetCharCase(Value: TEditCharCase);
- begin
- if FCharCase <> Value then begin
- FCharCase := Value;
- Text := Text; { update case }
- end;
- end;
- procedure TTBEditItem.SetEditOptions(Value: TTBEditItemOptions);
- begin
- if FEditOptions <> Value then begin
- FEditOptions := Value;
- Change(True);
- end;
- end;
- procedure TTBEditItem.SetEditCaption(Value: String);
- begin
- if FEditCaption <> Value then begin
- FEditCaption := Value;
- Change(True);
- end;
- end;
- procedure TTBEditItem.SetEditWidth(Value: Integer);
- begin
- if FEditWidth <> Value then begin
- FEditWidth := Value;
- Change(True);
- end;
- end;
- procedure TTBEditItem.SetMaxLength(Value: Integer);
- begin
- if FMaxLength <> Value then begin
- FMaxLength := Value;
- Change(False);
- end;
- end;
- function TTBEditItem.DoAcceptText(var NewText: string): Boolean;
- begin
- Result := True;
- if Assigned(FOnAcceptText) then FOnAcceptText(Self, NewText, Result);
- end;
- procedure TTBEditItem.DoTextChanging(const OldText: String; var NewText: String; Reason: Integer);
- begin
- case FCharCase of
- ecUpperCase: NewText := AnsiUpperCase(NewText);
- ecLowerCase: NewText := AnsiLowerCase(NewText);
- end;
- end;
- procedure TTBEditItem.DoTextChanged(Reason: Integer);
- begin
- end;
- procedure TTBEditItem.SetText(Value: String);
- begin
- DoTextChanging(FText, Value, tcrSetProperty);
- if FText <> Value then begin
- FText := Value;
- Change(False);
- DoTextChanged(tcrSetProperty);
- end;
- end;
- procedure TTBEditItem.SetTextEx(Value: String; Reason: Integer);
- begin
- DoTextChanging(FText, Value, Reason);
- if FText <> Value then begin
- FText := Value;
- Change(False);
- DoTextChanged(Reason);
- end;
- end;
- { TTBEditItemViewer }
- procedure TTBEditItemViewer.EditWndProc(var Message: TMessage);
- var
- Item: TTBEditItem;
- procedure AcceptText;
- var
- S: String;
- begin
- S := FEditControl.Text;
- if Item.DoAcceptText(S) then Item.SetTextEx(S, tcrEditControl);
- end;
- begin
- Item := TTBEditItem(Self.Item);
- if FEditControl = nil then
- Exit;
- if Message.Msg = WM_CHAR then
- case TWMChar(Message).CharCode of
- VK_TAB: begin
- FEditControlStatus := [ecsAccept];
- AcceptText;
- Exit;
- end;
- VK_RETURN: begin
- FEditControlStatus := [ecsAccept, ecsClose];
- AcceptText;
- Exit;
- end;
- VK_ESCAPE: begin
- FEditControlStatus := [];
- Exit;
- end;
- end;
- TEditAccess(FEditControl).WndProc(Message);
- if Message.Msg = WM_KILLFOCUS then begin
- { Someone has stolen the focus from us, so 'cancel mode'. (We have to
- handle WM_KILLFOCUS in addition to the upstream WM_CANCELMODE handling
- since we don't always hold the mouse capture.) }
- View.CancelMode;
- FEditControlStatus := [ecsClose];
- end;
- end;
- function TTBEditItemViewer.GetEditControlClass: TEditClass;
- begin
- Result := TEdit;
- end;
- procedure TTBEditItemViewer.GetEditRect(var R: TRect);
- var
- Item: TTBEditItem;
- DC: HDC;
- begin
- Item := TTBEditItem(Self.Item);
- DC := GetDC(0);
- try
- SelectObject(DC, View.GetFont.Handle);
- R := BoundsRect;
- if not View.IsToolbar and (Item.EditCaption <> '') then begin
- Inc(R.Left, GetTextWidth(DC, Item.EditCaption, True) +
- EditMenuMidWidth + EditMenuTextMargin * 2);
- end;
- finally
- ReleaseDC(0, DC);
- end;
- end;
- procedure TTBEditItemViewer.CalcSize(const Canvas: TCanvas;
- var AWidth, AHeight: Integer);
- var
- Item: TTBEditItem;
- DC: HDC;
- TextHeight, MinHeight: Integer;
- begin
- Item := TTBEditItem(Self.Item);
- DC := Canvas.Handle;
- TextHeight := GetTextHeight(DC);
- AWidth := Item.FEditWidth;
- AHeight := TextHeight;
- if not IsToolbarStyle and (Item.EditCaption <> '') then begin
- Inc(AWidth, GetTextWidth(DC, Item.EditCaption, True) + EditMenuMidWidth +
- EditMenuTextMargin * 2);
- end;
- MinHeight := AHeight + (EditMenuTextMargin * 2) + 1;
- if not IsToolbarStyle then
- Inc(AHeight, DivRoundUp(AHeight, 4));
- if AHeight < MinHeight then
- AHeight := MinHeight;
- end;
- function TTBEditItemViewer.CaptionShown: Boolean;
- begin
- Result := not IsToolbarStyle and inherited CaptionShown;
- end;
- function TTBEditItemViewer.GetCaptionText: String;
- begin
- Result := TTBEditItem(Item).EditCaption;
- end;
- procedure TTBEditItemViewer.Paint(const Canvas: TCanvas;
- const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean);
- const
- FillColors: array[Boolean] of TColor = (clBtnFace, clWindow);
- TextColors: array[Boolean] of TColor = (clGrayText, clWindowText);
- var
- Item: TTBEditItem;
- S: String;
- R: TRect;
- W: Integer;
- begin
- Item := TTBEditItem(Self.Item);
- R := ClientAreaRect;
- { Caption }
- if not IsToolbarStyle and (Item.EditCaption <> '') then begin
- S := Item.EditCaption;
- W := GetTextWidth(Canvas.Handle, S, True) + EditMenuTextMargin * 2;
- R.Right := R.Left + W;
- if IsSelected then
- Canvas.FillRect(R);
- Inc(R.Left, EditMenuTextMargin);
- DrawItemCaption(Canvas, R, S, UseDisabledShadow, DT_SINGLELINE or
- DT_LEFT or DT_VCENTER);
- R := ClientAreaRect;
- Inc(R.Left, W + EditMenuMidWidth);
- end;
- { Border }
- if IsSelected and Item.Enabled then
- DrawEdge(Canvas.Handle, R, BDR_SUNKENOUTER, BF_RECT);
- InflateRect(R, -1, -1);
- Canvas.Brush.Color := FillColors[not Item.Enabled];
- Canvas.FrameRect(R);
- InflateRect(R, -1, -1);
- { Fill }
- Canvas.Brush.Color := FillColors[Item.Enabled];
- Canvas.FillRect(R);
- InflateRect(R, -1, -1);
- { Text }
- if Item.Text <> '' then begin
- S := Item.Text;
- Canvas.Brush.Style := bsClear; { speed optimization }
- Canvas.Font.Color := TextColors[Item.Enabled];
- DrawText(Canvas.Handle, PChar(S), Length(S), R, DT_SINGLELINE or DT_NOPREFIX);
- end;
- end;
- procedure TTBEditItemViewer.GetCursor(const Pt: TPoint; var ACursor: HCURSOR);
- var
- R: TRect;
- begin
- if not Item.Enabled then
- Exit;
- GetEditRect(R);
- OffsetRect(R, -BoundsRect.Left, -BoundsRect.Top);
- InflateRect(R, -2, -2);
- if PtInRect(R, Pt) then
- ACursor := LoadCursor(0, IDC_IBEAM);
- end;
- function TTBEditItemViewer.EditLoop(const CapHandle: HWND): Boolean;
- procedure ControlMessageLoop;
- function PointInWindow(const Wnd: HWND; const P: TPoint): Boolean;
- var
- W: HWND;
- begin
- Result := False;
- W := WindowFromPoint(P);
- if W = 0 then Exit;
- if W = Wnd then
- Result := True
- else
- if IsChild(Wnd, W) then
- Result := True;
- end;
- function ContinueLoop: Boolean;
- begin
- Result := (ecsContinueLoop in FEditControlStatus) and
- not View.IsModalEnding and FEditControl.Focused and Item.Enabled;
- { Note: View.IsModalEnding is checked since TTBView.CancelMode doesn't
- destroy popup windows; it merely hides them and calls EndModal. So if
- IsModalEnding returns True we can infer that CancelMode was likely
- called. }
- end;
- var
- Msg: TMsg;
- IsKeypadDigit: Boolean;
- V: Integer;
- begin
- try
- while ContinueLoop do begin
- { Examine the next message before popping it out of the queue }
- if not PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then begin
- WaitMessage;
- Continue;
- end;
- case Msg.message of
- WM_SYSKEYDOWN: begin
- { Exit immediately if Alt+[key] or F10 are pressed, but not
- Alt+Shift, Alt+`, or Alt+[keypad digit] }
- if (Msg.wParam <> VK_MENU) and (Msg.wParam <> VK_SHIFT) and
- (Msg.wParam <> VK_HANJA) then begin
- IsKeypadDigit := False;
- { This detect digits regardless of whether Num Lock is on: }
- if Lo(LongRec(Msg.lParam).Hi) <> 0 then
- for V := VK_NUMPAD0 to VK_NUMPAD9 do
- if MapVirtualKey(V, 0) = Lo(LongRec(Msg.lParam).Hi) then begin
- IsKeypadDigit := True;
- Break;
- end;
- if not IsKeypadDigit then begin
- FEditControlStatus := [ecsClose];
- Exit;
- end;
- end;
- end;
- WM_SYSKEYUP: begin
- { Exit when Alt is released by itself }
- if Msg.wParam = VK_MENU then begin
- FEditControlStatus := [ecsClose];
- Exit;
- end;
- end;
- WM_LBUTTONDOWN, WM_LBUTTONDBLCLK,
- WM_RBUTTONDOWN, WM_RBUTTONDBLCLK,
- WM_MBUTTONDOWN, WM_MBUTTONDBLCLK,
- WM_NCLBUTTONDOWN, WM_NCLBUTTONDBLCLK,
- WM_NCRBUTTONDOWN, WM_NCRBUTTONDBLCLK,
- WM_NCMBUTTONDOWN, WM_NCMBUTTONDBLCLK: begin
- { If a mouse click outside the edit control is in the queue,
- exit and let the upstream message loop deal with it }
- if Msg.hwnd <> FEditControl.Handle then
- Exit;
- end;
- WM_MOUSEMOVE, WM_NCMOUSEMOVE: begin
- if GetCapture = CapHandle then begin
- if PointInWindow(FEditControl.Handle, Msg.pt) then
- ReleaseCapture;
- end
- else if GetCapture = 0 then begin
- if not PointInWindow(FEditControl.Handle, Msg.pt) then
- SetCapture(CapHandle);
- end;
- if GetCapture = CapHandle then
- SetCursor(LoadCursor(0, IDC_ARROW));
- end;
- end;
- { Now pop the message out of the queue }
- if not PeekMessage(Msg, 0, Msg.message, Msg.message, PM_REMOVE or PM_NOYIELD) then
- Continue;
- if ((Msg.message >= WM_MOUSEFIRST) and (Msg.message <= WM_MOUSELAST)) and
- (Msg.hwnd = CapHandle) then
- { discard, so that the selection doesn't get changed }
- else begin
- TranslateMessage(Msg);
- DispatchMessage(Msg);
- end;
- end;
- finally
- { Make sure there are no outstanding WM_*CHAR messages }
- RemoveMessages(WM_CHAR, WM_DEADCHAR);
- RemoveMessages(WM_SYSCHAR, WM_SYSDEADCHAR);
- end;
- end;
- var
- Item: TTBEditItem;
- R: TRect;
- ActiveWnd, FocusWnd: HWND;
- S: string;
- begin
- Item := TTBEditItem(Self.Item);
- GetEditRect(R);
- if IsRectEmpty(R) then begin
- Result := False;
- Exit;
- end;
- ActiveWnd := GetActiveWindow;
- FocusWnd := GetFocus;
- { Create the edit control }
- InflateRect(R, -3, -4);
- //View.FreeNotification (Self);
- FEditControl := GetEditControlClass.Create(nil);
- try
- FEditControl.Name := Format('%s_edit_control_%p', [ClassName,
- Pointer(FEditControl)]);
- FEditControl.Visible := False;
- FEditControl.BorderStyle := bsNone;
- FEditControl.AutoSize := False;
- FEditControl.Font.Assign(View.GetFont);
- FEditControl.Text := Item.Text;
- FEditControl.CharCase := Item.FCharCase;
- FEditControl.MaxLength := Item.FMaxLength;
- FEditControl.BoundsRect := R;
- FEditControl.WindowProc := EditWndProc;
- FEditControl.ParentWindow := View.Window.Handle;
- FEditControl.SelectAll;
- Item.DoBeginEdit(Self);
- FEditControl.Visible := True;
- FEditControl.SetFocus;
- if GetActiveWindow <> ActiveWnd then
- { don't gray out title bar of old active window }
- SendMessage(ActiveWnd, WM_NCACTIVATE, 1, 0)
- else
- ActiveWnd := 0;
- FEditControlStatus := [ecsContinueLoop];
- ControlMessageLoop;
- finally
- S := FEditControl.Text;
- FreeAndNil(FEditControl);
- end;
- with TTBEditItem(Item) do
- if (FEditControlStatus = [ecsContinueLoop]) and ExtendedAccept then
- if DoAcceptText(S) then SetTextEx(S, tcrEditControl);
- { ensure the area underneath the edit control is repainted immediately }
- View.Window.Update;
- { If app is still active, set focus to previous control and restore capture
- to CapHandle if another control hasn't taken it }
- if GetActiveWindow <> 0 then begin
- SetFocus(FocusWnd);
- if GetCapture = 0 then
- SetCapture(CapHandle);
- end;
- if ActiveWnd <> 0 then
- SendMessage(ActiveWnd, WM_NCACTIVATE, Ord(GetActiveWindow = ActiveWnd), 0);
- { The SetFocus call above can change the Z order of windows. If the parent
- window is a popup window, reassert its topmostness. }
- if View.Window is TTBPopupWindow then
- SetWindowPos(View.Window.Handle, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
- { Send an MSAA "focus" event now that we're returning to the regular modal loop }
- View.NotifyFocusEvent;
- Result := ecsClose in FEditControlStatus;
- if not Result and (GetCapture = CapHandle) then begin
- if ecsAccept in FEditControlStatus then
- { if we are accepting but not closing, Tab must have been pressed }
- View.Selected := View.NextSelectable(View.Selected,
- GetKeyState(VK_SHIFT) >= 0);
- end;
- end;
- function TTBEditItemViewer.DoExecute: Boolean;
- begin
- { Close any delay-close popup menus before entering the edit loop }
- View.CancelChildPopups;
- Result := False;
- if EditLoop(View.GetCaptureWnd) then begin
- View.EndModal;
- if ecsAccept in FEditControlStatus then
- Result := True;
- end;
- end;
- procedure TTBEditItemViewer.MouseBeginEdit;
- begin
- if Item.Enabled then
- Execute(True)
- else begin
- if (View.ParentView = nil) and not View.IsPopup then
- View.EndModal;
- end;
- end;
- procedure TTBEditItemViewer.MouseDown(Shift: TShiftState; X, Y: Integer;
- var MouseDownOnMenu: Boolean);
- begin
- if IsPtInButtonPart(X, Y) then { for TBX... }
- MouseBeginEdit
- else
- inherited;
- end;
- procedure TTBEditItemViewer.MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean);
- begin
- if IsPtInButtonPart(X, Y) then { for TBX... }
- MouseBeginEdit
- else
- inherited;
- end;
- function TTBEditItemViewer.UsesSameWidth: Boolean;
- begin
- Result := False;
- end;
- function TTBEditItemViewer.GetAccRole: Integer;
- const
- ROLE_SYSTEM_TEXT = $2a; { from OleAcc.h }
- begin
- Result := ROLE_SYSTEM_TEXT;
- end;
- function TTBEditItemViewer.GetAccValue(var Value: WideString): Boolean;
- begin
- Value := TTBEditItem(Item).Text;
- Result := True;
- end;
- {$IFNDEF MPEXCLUDE}
- { TTBToolbarVisibilityItem }
- procedure TTBVisibilityToggleItem.Click;
- begin
- if Assigned(FControl) then
- FControl.Visible := not FControl.Visible;
- inherited;
- end;
- procedure TTBVisibilityToggleItem.InitiateAction;
- begin
- UpdateProps;
- end;
- procedure TTBVisibilityToggleItem.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited;
- if (Operation = opRemove) and (AComponent = FControl) then
- Control := nil;
- end;
- procedure TTBVisibilityToggleItem.SetControl(Value: TControl);
- begin
- if FControl <> Value then begin
- FControl := Value;
- if Assigned(Value) then begin
- Value.FreeNotification(Self);
- if (Caption = '') and not(csLoading in ComponentState) then
- Caption := TControlAccess(Value).Caption;
- end;
- UpdateProps;
- end;
- end;
- procedure TTBVisibilityToggleItem.UpdateProps;
- begin
- if (ComponentState * [csDesigning, csLoading, csDestroying] = []) then
- Checked := Assigned(FControl) and FControl.Visible;
- end;
- {$ENDIF}
- end.
|