📄 tooledit.pas
字号:
var
DC: HDC;
SaveFont: HFont;
SysMetrics, Metrics: TTextMetric;
begin
DC := GetDC(0);
try
GetTextMetrics(DC, SysMetrics);
SaveFont := SelectObject(DC, Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
finally
ReleaseDC(0, DC);
end;
Result := Min(SysMetrics.tmHeight, Metrics.tmHeight);
end;
function TCustomComboEdit.GetMinHeight: Integer;
var
I: Integer;
begin
I := GetTextHeight;
Result := I + GetSystemMetrics(SM_CYBORDER) * 4 +
1 {$IFNDEF WIN32} + (I div 4) {$ENDIF};
end;
procedure TCustomComboEdit.UpdatePopupVisible;
begin
FPopupVisible := (FPopup <> nil) and FPopup.Visible;
end;
function TCustomComboEdit.GetPopupVisible: Boolean;
begin
Result := (FPopup <> nil) and FPopupVisible;
end;
procedure TCustomComboEdit.CMFontChanged(var Message: TMessage);
begin
inherited;
if HandleAllocated then SetEditRect;
end;
procedure TCustomComboEdit.CMEnabledChanged(var Message: TMessage);
begin
inherited;
FButton.Enabled := Enabled;
end;
procedure TCustomComboEdit.CMCancelMode(var Message: TCMCancelMode);
begin
if (Message.Sender <> Self) and (Message.Sender <> FPopup) and
(Message.Sender <> FButton) and ((FPopup <> nil) and
not FPopup.ContainsControl(Message.Sender)) then
PopupCloseUp(FPopup, False);
end;
procedure TCustomComboEdit.CMEnter(var Message: TMessage);
begin
if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
inherited;
end;
procedure TCustomComboEdit.CNCtlColor(var Message: TMessage);
var
TextColor: Longint;
begin
inherited;
if NewStyleControls then begin
TextColor := ColorToRGB(Font.Color);
if not Enabled and (ColorToRGB(Color) <> ColorToRGB(clGrayText)) then
TextColor := ColorToRGB(clGrayText);
SetTextColor(Message.WParam, TextColor);
end;
end;
procedure TCustomComboEdit.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
FFocused := False;
PopupCloseUp(FPopup, False);
end;
procedure TCustomComboEdit.WMSetFocus(var Message: TMessage);
begin
inherited;
FFocused := True;
SetShowCaret;
end;
{$IFDEF RX_D4}
procedure TCustomComboEdit.CMBiDiModeChanged(var Message: TMessage);
begin
inherited;
if FPopup <> nil then FPopup.BiDiMode := BiDiMode;
end;
{$ENDIF}
procedure TCustomComboEdit.SetShowCaret;
const
CaretWidth: array[Boolean] of Byte = (1, 2);
begin
CreateCaret(Handle, 0, CaretWidth[fsBold in Font.Style], GetTextHeight);
ShowCaret(Handle);
end;
procedure TCustomComboEdit.EditButtonClick(Sender: TObject);
begin
if (not FReadOnly) or AlwaysEnable then ButtonClick;
end;
procedure TCustomComboEdit.DoClick;
begin
EditButtonClick(Self);
end;
procedure TCustomComboEdit.ButtonClick;
begin
if Assigned(FOnButtonClick) then FOnButtonClick(Self);
if FPopup <> nil then begin
if FPopupVisible then PopupCloseUp(FPopup, True) else PopupDropDown(True);
end;
end;
procedure TCustomComboEdit.SelectAll;
begin
if DirectInput then inherited SelectAll;
end;
function TCustomComboEdit.GetDirectInput: Boolean;
begin
Result := FDirectInput;
end;
procedure TCustomComboEdit.SetDirectInput(Value: Boolean);
begin
inherited ReadOnly := not Value or FReadOnly;
FDirectInput := Value;
end;
procedure TCustomComboEdit.WMPaste(var Message: TWMPaste);
begin
if not FDirectInput or ReadOnly then Exit;
inherited;
end;
procedure TCustomComboEdit.WMCut(var Message: TWMCut);
begin
if not FDirectInput or ReadOnly then Exit;
inherited;
end;
function TCustomComboEdit.GetReadOnly: Boolean;
begin
Result := FReadOnly;
end;
procedure TCustomComboEdit.SetReadOnly(Value: Boolean);
begin
if Value <> FReadOnly then begin
FReadOnly := Value;
inherited ReadOnly := Value or not FDirectInput;
end;
end;
procedure TCustomComboEdit.SetAlignment(Value: TAlignment);
begin
if FAlignment <> Value then begin
FAlignment := Value;
RecreateWnd;
end;
end;
function TCustomComboEdit.BtnWidthStored: Boolean;
begin
if (FGlyphKind = gkDefault) and (Glyph <> nil) then
Result := ButtonWidth <> Max(Glyph.Width div FButton.NumGlyphs + 6,
DefEditBtnWidth)
else if FGlyphKind = gkDropDown then
Result := ButtonWidth <> GetSystemMetrics(SM_CXVSCROLL)
{$IFNDEF WIN32} + 1{$ENDIF}
else Result := ButtonWidth <> DefEditBtnWidth;
end;
function TCustomComboEdit.IsCustomGlyph: Boolean;
begin
Result := FGlyphKind = gkCustom;
end;
procedure TCustomComboEdit.SetGlyphKind(Value: TGlyphKind);
begin
if FGlyphKind <> Value then begin
FGlyphKind := Value;
if (FGlyphKind = gkCustom) and (csReading in ComponentState) then begin
Glyph := nil;
end;
RecreateGlyph;
if (FGlyphKind = gkDefault) and (Glyph <> nil) then
ButtonWidth := Max(Glyph.Width div FButton.NumGlyphs + 6, FButton.Width)
else if FGlyphKind = gkDropDown then begin
ButtonWidth := GetSystemMetrics(SM_CXVSCROLL){$IFNDEF WIN32} + 1{$ENDIF};
with FButton do
ControlStyle := ControlStyle + [csFixedWidth];
end;
end;
end;
function TCustomComboEdit.GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap;
begin
Result := nil;
end;
procedure TCustomComboEdit.RecreateGlyph;
function CreateEllipsisGlyph: TBitmap;
var
W, G, I: Integer;
begin
Result := TBitmap.Create;
with Result do
try
Monochrome := True;
Width := Max(1, FButton.Width - 6);
Height := 4;
W := 2;
G := (Result.Width - 3 * W) div 2;
if G <= 0 then G := 1;
if G > 3 then G := 3;
I := (Width - 3 * W - 2 * G) div 2;
PatBlt(Canvas.Handle, I, 1, W, W, BLACKNESS);
PatBlt(Canvas.Handle, I + G + W, 1, W, W, BLACKNESS);
PatBlt(Canvas.Handle, I + 2 * G + 2 * W, 1, W, W, BLACKNESS);
except
Free;
raise;
end;
end;
var
NewGlyph: TBitmap;
DestroyNeeded: Boolean;
begin
case FGlyphKind of
gkDefault:
begin
DestroyNeeded := False;
NewGlyph := GetDefaultBitmap(DestroyNeeded);
try
FButton.Glyph.Assign(NewGlyph);
NumGlyphs := FDefNumGlyphs;
finally
if DestroyNeeded then NewGlyph.Destroy;
end;
end;
gkDropDown:
begin
FButton.Glyph.Handle := LoadBitmap(0, PChar(32738));
NumGlyphs := 1;
end;
gkEllipsis:
begin
NewGlyph := CreateEllipsisGlyph;
try
FButton.Glyph := NewGlyph;
NumGlyphs := 1;
finally
NewGlyph.Destroy;
end;
end;
end;
end;
const
FileBitmap: TBitmap = nil;
DateBitmap: TBitmap = nil;
{ TFileDirEdit }
constructor TFileDirEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
OEMConvert := True;
{$IFNDEF WIN32}
MaxLength := MaxFileLength;
{$ENDIF}
ControlState := ControlState + [csCreating];
try
GlyphKind := gkDefault; { force update }
finally
ControlState := ControlState - [csCreating];
end;
end;
function TFileDirEdit.GetDefaultBitmap(var DestroyNeeded: Boolean): TBitmap;
begin
DestroyNeeded := False;
if FileBitmap = nil then begin
FileBitmap := TBitmap.Create;
FileBitmap.Handle := LoadBitmap(hInstance, sFileBmp);
end;
Result := FileBitmap;
end;
procedure TFileDirEdit.DoBeforeDialog(var FileName: string;
var Action: Boolean);
begin
if Assigned(FOnBeforeDialog) then FOnBeforeDialog(Self, FileName, Action);
end;
procedure TFileDirEdit.DoAfterDialog(var FileName: string;
var Action: Boolean);
begin
if Assigned(FOnAfterDialog) then FOnAfterDialog(Self, FileName, Action);
end;
procedure TFileDirEdit.CreateHandle;
begin
inherited CreateHandle;
if FAcceptFiles then SetDragAccept(True);
end;
procedure TFileDirEdit.DestroyWindowHandle;
begin
SetDragAccept(False);
inherited DestroyWindowHandle;
end;
procedure TFileDirEdit.SetDragAccept(Value: Boolean);
begin
if not (csDesigning in ComponentState) and (Handle <> 0) then
DragAcceptFiles(Handle, Value);
end;
procedure TFileDirEdit.SetAcceptFiles(Value: Boolean);
begin
if FAcceptFiles <> Value then begin
SetDragAccept(Value);
FAcceptFiles := Value;
end;
end;
procedure TFileDirEdit.DisableSysErrors;
begin
FErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX or SEM_FAILCRITICALERRORS);
end;
procedure TFileDirEdit.EnableSysErrors;
begin
SetErrorMode(FErrMode);
FErrMode := 0;
end;
procedure TFileDirEdit.WMDropFiles(var Msg: TWMDropFiles);
var
AFileName: array[0..255] of Char;
I, Num: Cardinal;
begin
Msg.Result := 0;
try
{$IFDEF WIN32}
Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
{$ELSE}
Num := DragQueryFile(Msg.Drop, $FFFF, nil, 0);
{$ENDIF}
if Num > 0 then begin
ClearFileList;
for I := 0 to Num - 1 do begin
DragQueryFile(Msg.Drop, I, PChar(@AFileName), Pred(SizeOf(AFileName)));
ReceptFileDir(StrPas(AFileName));
if not FMultipleDirs then Break;
end;
if Assigned(FOnDropFiles) then FOnDropFiles(Self);
end;
finally
DragFinish(Msg.Drop);
end;
end;
procedure TFileDirEdit.ClearFileList;
begin
end;
{ TFilenameEdit }
function ClipFilename(const FileName: string): string;
var
Params: string;
begin
if FileExists(FileName) then Result := FileName
else SplitCommandLine(FileName, Result, Params);
end;
function ExtFilename(const FileName: string): string;
begin
if (Pos(' ', FileName) > 0) and (FileName[1] <> '"') then
Result := Format('"%s"', [FileName])
else Result := FileName;
end;
constructor TFilenameEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
CreateEditDialog;
end;
procedure TFilenameEdit.CreateEditDialog;
var
NewDialog: TOpenDialog;
begin
case FDialogKind of
dkOpen: NewDialog := TOpenDialog.Create(Self);
{$IFDEF RX_D3}
dkOpenPicture: NewDialog := TOpenPictureDialog.Create(Self);
dkSavePicture: NewDialog := TSavePictureDialog.Create(Self);
{$ENDIF}
else {dkSave} NewDialog := TSaveDialog.Create(Self);
end;
try
if FDialog <> nil then begin
with NewDialog do begin
DefaultExt := FDialog.DefaultExt;
FileEditStyle := FDialog.FileEditStyle;
FileName := FDialog.FileName;
Filter := FDialog.Filter;
FilterIndex := FDialog.FilterIndex;
InitialDir := FDialog.InitialDir;
HistoryList := FDialog.HistoryList;
Files.Assign(FDialog.Files);
Options := FDialog.Options;
Title := FDialog.Title;
end;
FDialog.Free;
end
else begin
NewDialog.Title := LoadStr(SBrowse);
NewDialog.Filter := LoadStr(SDefaultFilter);
NewDialog.Options := [ofHideReadOnly];
end;
finally
FDialog := NewDialog;
end;
end;
function TFilenameEdit.IsCustomTitle: Boolean;
begin
Result := CompareStr(LoadStr(SBrowse), FDialog.Title) <> 0;
end;
function TFilenameEdit.IsCustomFilter: Boolean;
begin
Result := CompareStr(LoadStr(SDefaultFilter), FDialog.Filter) <> 0;
end;
procedure TFilenameEdit.ButtonClick;
var
Temp: string;
Action: Boolean;
begin
inherited ButtonClick;
Temp := inherited Text;
Action := True;
Temp := ClipFilename(Temp);
DoBeforeDialog(Temp, Action);
if not Action then Exit;
if ValidFileName(Temp) then
try
if DirExists(ExtractFilePath(Temp)) then
SetInitialDir(ExtractFilePath(Temp));
if (ExtractFileName(Temp) = '') or
not ValidFileName(ExtractFileName(Temp)) then Temp := '';
FDialog.FileName := Temp;
except
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -