📄 mydialogs.pas
字号:
{*******************************************************}
{ }
{ Borland Delphi Visual Component Library }
{ }
{ Copyright (c) 1995-2001 Borland Software Corporation }
{ }
{*******************************************************}
unit myDialogs;
{$R-,T-,H+,X+}
interface
uses Windows, Messages, SysUtils, CommDlg, Classes, Graphics, Controls,
Forms, StdCtrls, Printers;
const
{ Maximum number of custom colors in color dialog }
MaxCustomColors = 16;
type
{ TCommonDialog }
TCommonDialog = class(TComponent)
private
FCtl3D: Boolean;
FDefWndProc: Pointer;
FHelpContext: THelpContext;
FHandle: HWnd;
FObjectInstance: Pointer;
FTemplate: PChar;
FOnClose: TNotifyEvent;
FOnShow: TNotifyEvent;
procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY;
procedure WMInitDialog(var Message: TWMInitDialog); message WM_INITDIALOG;
procedure WMNCDestroy(var Message: TWMNCDestroy); message WM_NCDESTROY;
procedure MainWndProc(var Message: TMessage);
protected
procedure DoClose; dynamic;
procedure DoShow; dynamic;
procedure WndProc(var Message: TMessage); virtual;
function MessageHook(var Msg: TMessage): Boolean; virtual;
function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; virtual;
property Template: PChar read FTemplate write FTemplate;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Execute: Boolean; virtual; abstract;
procedure DefaultHandler(var Message); override;
property Handle: HWnd read FHandle;
published
property Ctl3D: Boolean read FCtl3D write FCtl3D default True;
property HelpContext: THelpContext read FHelpContext write FHelpContext default 0;
property OnClose: TNotifyEvent read FOnClose write FOnClose;
property OnShow: TNotifyEvent read FOnShow write FOnShow;
end;
{ TOpenDialog }
TOpenOption = (ofReadOnly, ofOverwritePrompt, ofHideReadOnly,
ofNoChangeDir, ofShowHelp, ofNoValidate, ofAllowMultiSelect,
ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofCreatePrompt,
ofShareAware, ofNoReadOnlyReturn, ofNoTestFileCreate, ofNoNetworkButton,
ofNoLongNames, ofOldStyleDialog, ofNoDereferenceLinks, ofEnableIncludeNotify,
ofEnableSizing, ofDontAddToRecent, ofForceShowHidden);
TOpenOptions = set of TOpenOption;
TOpenOptionEx = (ofExNoPlacesBar);
TOpenOptionsEx = set of TOpenOptionEx;
TFileEditStyle = (fsEdit, fsComboBox);
TOFNotifyEx = type CommDlg.TOFNotifyEx;
{$NODEFINE TOFNotifyEx}
TIncludeItemEvent = procedure (const OFN: TOFNotifyEx; var Include: Boolean) of object;
TOpenDialog = class(TCommonDialog)
private
FHistoryList: TStrings;
FOptions: TOpenOptions;
FFilter: string;
FFilterIndex: Integer;
FCurrentFilterIndex: Integer;
FInitialDir: string;
FTitle: string;
FDefaultExt: string;
FFileName: TFileName;
FFiles: TStrings;
FFileEditStyle: TFileEditStyle;
FOnSelectionChange: TNotifyEvent;
FOnFolderChange: TNotifyEvent;
FOnTypeChange: TNotifyEvent;
FOnCanClose: TCloseQueryEvent;
FOnIncludeItem: TIncludeItemEvent;
FOptionsEx: TOpenOptionsEx;
function GetFileName: TFileName;
function GetFilterIndex: Integer;
procedure ReadFileEditStyle(Reader: TReader);
procedure SetHistoryList(Value: TStrings);
procedure SetInitialDir(const Value: string);
protected
function CanClose(var OpenFileName: TOpenFileName): Boolean;
function DoCanClose: Boolean; dynamic;
function DoExecute(Func: Pointer): Bool;
procedure DoSelectionChange; dynamic;
procedure DoFolderChange; dynamic;
procedure DoTypeChange; dynamic;
procedure DoIncludeItem(const OFN: TOFNotifyEx; var Include: Boolean); dynamic;
procedure DefineProperties(Filer: TFiler); override;
procedure GetFileNames(var OpenFileName: TOpenFileName);
function GetStaticRect: TRect; virtual;
procedure WndProc(var Message: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Execute: Boolean; override;
property FileEditStyle: TFileEditStyle read FFileEditStyle write FFileEditStyle;
property Files: TStrings read FFiles;
property HistoryList: TStrings read FHistoryList write SetHistoryList;
published
property DefaultExt: string read FDefaultExt write FDefaultExt;
property FileName: TFileName read GetFileName write FFileName;
property Filter: string read FFilter write FFilter;
property FilterIndex: Integer read GetFilterIndex write FFilterIndex default 1;
property InitialDir: string read FInitialDir write SetInitialDir;
property Options: TOpenOptions read FOptions write FOptions default [ofHideReadOnly, ofEnableSizing];
property OptionsEx: TOpenOptionsEx read FOptionsEx write FOptionsEx default [];
property Title: string read FTitle write FTitle;
property OnCanClose: TCloseQueryEvent read FOnCanClose write FOnCanClose;
property OnFolderChange: TNotifyEvent read FOnFolderChange write FOnFolderChange;
property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
property OnTypeChange: TNotifyEvent read FOnTypeChange write FOnTypeChange;
property OnIncludeItem: TIncludeItemEvent read FOnIncludeItem write FOnIncludeItem;
end;
{ TSaveDialog }
TSaveDialog = class(TOpenDialog)
function Execute: Boolean; override;
end;
{ TColorDialog }
TColorDialogOption = (cdFullOpen, cdPreventFullOpen, cdShowHelp,
cdSolidColor, cdAnyColor);
TColorDialogOptions = set of TColorDialogOption;
TCustomColors = array[0..MaxCustomColors - 1] of Longint;
TColorDialog = class(TCommonDialog)
private
FColor: TColor;
FOptions: TColorDialogOptions;
FCustomColors: TStrings;
procedure SetCustomColors(Value: TStrings);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Execute: Boolean; override;
published
property Color: TColor read FColor write FColor default clBlack;
property Ctl3D default False;
property CustomColors: TStrings read FCustomColors write SetCustomColors;
property Options: TColorDialogOptions read FOptions write FOptions default [];
end;
{ TFontDialog }
TFontDialogOption = (fdAnsiOnly, fdTrueTypeOnly, fdEffects,
fdFixedPitchOnly, fdForceFontExist, fdNoFaceSel, fdNoOEMFonts,
fdNoSimulations, fdNoSizeSel, fdNoStyleSel, fdNoVectorFonts,
fdShowHelp, fdWysiwyg, fdLimitSize, fdScalableOnly, fdApplyButton);
TFontDialogOptions = set of TFontDialogOption;
TFontDialogDevice = (fdScreen, fdPrinter, fdBoth);
TFDApplyEvent = procedure(Sender: TObject; Wnd: HWND) of object;
TFontDialog = class(TCommonDialog)
private
FFont: TFont;
FDevice: TFontDialogDevice;
FOptions: TFontDialogOptions;
FOnApply: TFDApplyEvent;
FMinFontSize: Integer;
FMaxFontSize: Integer;
FFontCharsetModified: Boolean;
FFontColorModified: Boolean;
procedure DoApply(Wnd: HWND);
procedure SetFont(Value: TFont);
procedure UpdateFromLogFont(const LogFont: TLogFont);
protected
procedure Apply(Wnd: HWND); dynamic;
procedure WndProc(var Message: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Execute: Boolean; override;
published
property Font: TFont read FFont write SetFont;
property Device: TFontDialogDevice read FDevice write FDevice default fdScreen;
property MinFontSize: Integer read FMinFontSize write FMinFontSize;
property MaxFontSize: Integer read FMaxFontSize write FMaxFontSize;
property Options: TFontDialogOptions read FOptions write FOptions default [fdEffects];
property OnApply: TFDApplyEvent read FOnApply write FOnApply;
end;
{ TPrinterSetupDialog }
TPrinterSetupDialog = class(TCommonDialog)
public
function Execute: Boolean; override;
end;
{ TPrintDialog }
TPrintRange = (prAllPages, prSelection, prPageNums);
TPrintDialogOption = (poPrintToFile, poPageNums, poSelection, poWarning,
poHelp, poDisablePrintToFile);
TPrintDialogOptions = set of TPrintDialogOption;
TPrintDialog = class(TCommonDialog)
private
FFromPage: Integer;
FToPage: Integer;
FCollate: Boolean;
FOptions: TPrintDialogOptions;
FPrintToFile: Boolean;
FPrintRange: TPrintRange;
FMinPage: Integer;
FMaxPage: Integer;
FCopies: Integer;
procedure SetNumCopies(Value: Integer);
public
function Execute: Boolean; override;
published
property Collate: Boolean read FCollate write FCollate default False;
property Copies: Integer read FCopies write SetNumCopies default 0;
property FromPage: Integer read FFromPage write FFromPage default 0;
property MinPage: Integer read FMinPage write FMinPage default 0;
property MaxPage: Integer read FMaxPage write FMaxPage default 0;
property Options: TPrintDialogOptions read FOptions write FOptions default [];
property PrintToFile: Boolean read FPrintToFile write FPrintToFile default False;
property PrintRange: TPrintRange read FPrintRange write FPrintRange default prAllPages;
property ToPage: Integer read FToPage write FToPage default 0;
end;
{ TFindDialog }
TFindOption = (frDown, frFindNext, frHideMatchCase, frHideWholeWord,
frHideUpDown, frMatchCase, frDisableMatchCase, frDisableUpDown,
frDisableWholeWord, frReplace, frReplaceAll, frWholeWord, frShowHelp);
TFindOptions = set of TFindOption;
TFindReplaceFunc = function(var FindReplace: TFindReplace): HWnd stdcall;
TFindDialog = class(TCommonDialog)
private
FOptions: TFindOptions;
FPosition: TPoint;
FFindReplaceFunc: TFindReplaceFunc;
FRedirector: TWinControl;
FOnFind: TNotifyEvent;
FOnReplace: TNotifyEvent;
FFindHandle: HWnd;
FFindReplace: TFindReplace;
FFindText: array[0..255] of Char;
FReplaceText: array[0..255] of Char;
function GetFindText: string;
function GetLeft: Integer;
function GetPosition: TPoint;
function GetReplaceText: string;
function GetTop: Integer;
procedure SetFindText(const Value: string);
procedure SetLeft(Value: Integer);
procedure SetPosition(const Value: TPoint);
procedure SetReplaceText(const Value: string);
procedure SetTop(Value: Integer);
property ReplaceText: string read GetReplaceText write SetReplaceText;
property OnReplace: TNotifyEvent read FOnReplace write FOnReplace;
protected
function MessageHook(var Msg: TMessage): Boolean; override;
procedure Find; dynamic;
procedure Replace; dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure CloseDialog;
function Execute: Boolean; override;
property Left: Integer read GetLeft write SetLeft;
property Position: TPoint read GetPosition write SetPosition;
property Top: Integer read GetTop write SetTop;
published
property FindText: string read GetFindText write SetFindText;
property Options: TFindOptions read FOptions write FOptions default [frDown];
property OnFind: TNotifyEvent read FOnFind write FOnFind;
end;
{ TReplaceDialog }
TReplaceDialog = class(TFindDialog)
public
constructor Create(AOwner: TComponent); override;
published
property ReplaceText;
property OnReplace;
end;
{ Message dialog }
type
TMsgDlgType = (mtWarning, mtError, mtInformation, mtConfirmation, mtCustom);
TMsgDlgBtn = (mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore,
mbAll, mbNoToAll, mbYesToAll, mbHelp);
TMsgDlgButtons = set of TMsgDlgBtn;
const
mbYesNoCancel = [mbYes, mbNo, mbCancel];
mbYesAllNoAllCancel = [mbYes, mbYesToAll, mbNo, mbNoToAll, mbCancel];
mbOKCancel = [mbOK, mbCancel];
mbAbortRetryIgnore = [mbAbort, mbRetry, mbIgnore];
mbAbortIgnore = [mbAbort, mbIgnore];
function CreateMessageDialog(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons): TForm;
function MessageDlg(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer;
function MessageDlgPos(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Integer;
function MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
const HelpFileName: string): Integer;
procedure ShowMessage(const Msg: string);
procedure ShowMessageFmt(const Msg: string; Params: array of const);
procedure ShowMessagePos(const Msg: string; X, Y: Integer);
{ Input dialog }
function InputBox(const ACaption, APrompt, ADefault: string): string;
function InputQuery(const ACaption, APrompt: string;
var Value: string): Boolean;
function PromptForFileName(var AFileName: string; const AFilter: string = '';
const ADefaultExt: string = ''; const ATitle: string = '';
const AInitialDir: string = ''; SaveDialog: Boolean = False): Boolean;
{ Win98 and Win2k will default to the "My Documents" folder if the InitialDir
property is empty and no files of the filtered type are contained in the
current directory. Set this flag to True to force TOpenDialog and descendents
to always open in the current directory when InitialDir is empty. (Same
behavior as setting InitialDir to '.') }
var
ForceCurrentDirectory: Boolean = False;
implementation
uses
ExtCtrls, myConsts, Dlgs, Math;
{ Private globals }
var
CreationControl: TCommonDialog = nil;
HelpMsg: Cardinal;
FindMsg: Cardinal;
WndProcPtrAtom: TAtom = 0;
{ Center the given window on the screen }
procedure CenterWindow(Wnd: HWnd);
var
Rect: TRect;
Monitor: TMonitor;
begin
GetWindowRect(Wnd, Rect);
if Application.MainForm <> nil then
begin
if Assigned(Screen.ActiveForm) then
Monitor := Screen.ActiveForm.Monitor
else
Monitor := Application.MainForm.Monitor;
end
else
Monitor := Screen.Monitors[0];
SetWindowPos(Wnd, 0,
Monitor.Left + ((Monitor.Width - Rect.Right + Rect.Left) div 2),
Monitor.Top + ((Monitor.Height - Rect.Bottom + Rect.Top) div 3),
0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
end;
{ Generic dialog hook. Centers the dialog on the screen in response to
the WM_INITDIALOG message }
function DialogHook(Wnd: HWnd; Msg: UINT; WParam: WPARAM; LParam: LPARAM): UINT; stdcall;
begin
Result := 0;
if Msg = WM_INITDIALOG then
begin
CenterWindow(Wnd);
CreationControl.FHandle := Wnd;
CreationControl.FDefWndProc := Pointer(SetWindowLong(Wnd, GWL_WNDPROC,
Longint(CreationControl.FObjectInstance)));
CallWindowProc(CreationControl.FObjectInstance, Wnd, Msg, WParam, LParam);
CreationControl := nil;
end;
end;
{ TCommonDialog }
constructor TCommonDialog.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCtl3D := True;
FObjectInstance := Classes.MakeObjectInstance(MainWndProc);
end;
destructor TCommonDialog.Destroy;
begin
if FObjectInstance <> nil then Classes.FreeObjectInstance(FObjectInstance);
inherited Destroy;
end;
function TCommonDialog.MessageHook(var Msg: TMessage): Boolean;
begin
Result := False;
if (Msg.Msg = HelpMsg) and (FHelpContext <> 0) then
begin
Application.HelpContext(FHelpContext);
Result := True;
end;
end;
procedure TCommonDialog.DefaultHandler(var Message);
begin
if FHandle <> 0 then
with TMessage(Message) do
Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam)
else inherited DefaultHandler(Message);
end;
procedure TCommonDialog.MainWndProc(var Message: TMessage);
begin
try
WndProc(Message);
except
Application.HandleException(Self);
end;
end;
procedure TCommonDialog.WndProc(var Message: TMessage);
begin
Dispatch(Message);
end;
procedure TCommonDialog.WMDestroy(var Message: TWMDestroy);
begin
inherited;
DoClose;
end;
procedure TCommonDialog.WMInitDialog(var Message: TWMInitDialog);
begin
{ Called only by non-explorer style dialogs }
DoShow;
{ Prevent any further processing }
Message.Result := 0;
end;
procedure TCommonDialog.WMNCDestroy(var Message: TWMNCDestroy);
begin
inherited;
FHandle := 0;
end;
function TCommonDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
type
TDialogFunc = function(var DialogData): Bool stdcall;
var
ActiveWindow: HWnd;
WindowList: Pointer;
FPUControlWord: Word;
FocusState: TFocusState;
begin
ActiveWindow := GetActiveWindow;
WindowList := DisableTaskWindows(0);
FocusState := SaveFocusState;
try
Application.HookMainWindow(MessageHook);
asm
// Avoid FPU control word change in NETRAP.dll, NETAPI32.dll, etc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -