如何在Delphi中創建一個不帶標題欄而且可以改變大 小的窗體?
或許你會說,“把窗體的 BorderStyle 屬性設為 bsNone不就可以了?”這種做法雖然可以去掉窗體的標題 欄,但是你卻不能在程序運行時改變窗體的大小了。通過對 Delphi的分析,筆者找到了一種比較簡單的解決方法。首先 我們應該澄清Delphi不僅僅是Object Pascal——它也非常 有效地封裝了 Windows API。Windows 中每一個窗口都 是使用 CreateWindow 或者 CreateWindowEx 創建的。 CreateWindow 能創建一個標准樣式的 Windows 窗口; CreateWindowEx 與前者類似,不過你可以指定並創建特 定的窗口樣式。在 Delphi 中一個窗體的創建,其實是對 CreateWindowEx 函數的調用,也就是說,窗體 Form 的 Create方法封裝了 CreateWindowEx函數,而且在Create 方法運行時會通過Form的另外一個方法CreateParams來獲 取 CreateWindowEx 的參數。我們說 CreateParams 是 Form 類的一個方法,也就意味著可以對它進行重載,通 過重載來修改窗體類型以滿足程序特殊的需要。例如要去 掉窗體的標題欄,就可以通過修改 TCreateParams結構中 的 DWord Style 字段來實現,這個結構將被作為參數創 遞給 CreateWindowEx。下面給出了具體的實現代碼,請 仔細閱讀,緊接著我們還要作進一步的討論。
unit NoCap; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure CreateParams(var Params: TCreateParams); override;
// 重載
procedure WMNCHitTest(var Msg: TWMNcHitTest); message
WM_NCHITTEST; // 消息
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
Style := (Style or WS_POPUP) and (not WS_DLGFRAME);
end;
procedure TForm1.WMNCHitTest(var Msg: TWMNcHitTest);
begin
inherited;
if (msg.Result = htClIEnt) then
msg.Result := htCaption;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
close;
end;
end.
請注意,我在TForm1.CreateParams過程中把窗體的 Style 設置成 Style := (Style or WS_POPUP) and (not WS_DLGFRAME),其中 or WS_POPUP 意味著把這個 窗體設置成一個可修改尺寸的窗體,and (not WS_DLGFRAME)表示不要產生一個帶標題欄的標准窗 體,從而把標題欄去掉。
那麼 WMNCHitTest 函數在這裡起到一個什麼作用 呢?通常來講,可以通過用鼠標拖動標題欄的方法來移動窗 體的位置;如果去掉了標題欄,也就同時失去了對窗體的控 制權。那麼通過WM _NCHITTEST消息的捕獲就可以改 變鼠標的缺省行為,這樣一來就可以在沒有標題欄的情況下 移動窗體的位置了。關於消息使用的相關資料比較多,大家 可以自行查閱更詳細的用法。程序運行時如下圖所示,可以 看到窗體沒有標題欄,但是使用鼠標可以修改窗體的尺寸並 且在窗體的任一區域按住鼠標都可以實現窗體的拖動。
通過上面的討論,我們解決了無標題窗體的制作、窗體 的拖動和尺寸改變這三個問題,希望對大家的軟件開發能有 所幫助。