| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025 |
- 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;
- procedure ChangeScale(M, D: Integer); 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;
- procedure TTBEditItem.ChangeScale(M, D: Integer);
- begin
- inherited;
- EditWidth := MulDiv(EditWidth, M, D);
- 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.
|