標籤:
為Windows視窗標題列添加新按鈕
對於我們熟悉的標準windows視窗來講,標題列上一般包含有3個按鈕,即最大化按鈕,最小化按鈕和關閉按鈕。你想不想在Windows的視窗標題列上添加一個新的自訂按鈕,滿足你的個人化需求,從而也使自己的視窗更具特色呢?
下面我們就討論一下在delphi中如何給視窗的標題列上添加新的按鈕。
一、實現起來要定義以下過程:
1、 定義DrawCaptButton過程,這個過程的功能是在指定的位置畫出按鈕。
在過程中要使用win32函數GetSystemMetrics得到視窗的大小和標題按鈕的大小;使用delphi函數Bounds定義一個矩形,這個矩形就是新按鈕的位置;再定義一個小的矩形,這個矩形是為了填寫文本;最後就調用delphi中比較有用的函數drawbuttonface把按鈕畫出來。
2、 每次我們對視窗進行操作,例如,最大化操作或最小化操作,新按鈕就會消失,為瞭解決這個問題,我們對所有的訊息要進行處理,給每個訊息編寫一個過程對按鈕進行重畫。
A、定義WMNCPaint(var Msg:TWMNCPaint)過程,處理訊息WM_NCPaint。
B、定義WMNCActivate(var Msg :TWMNCActivate)過程,處理訊息WM_NCACTIVATE。
C、定義WMSetText(var Msg:TWMSetText)過程,處理訊息WM_SETTEXT。
D、定義WMNCHitTest(var Msg :TWMNCHitTest)過程,處理訊息WM_NCHITTEST。
E、定義WMNCLButtonDown(var Msg : TWMNCLButtonDown)過程,處理訊息WM_NCLBUTTONDOWN。
二、 具體的來源程式如下:
我們結合來源程式來講述過程的實現,從中可以看出程式對win32函數的調用,以及drawbuttonface函數的使用方法。
unit Main;
interface
uses
Windows, Buttons, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormResize(Sender: TObject);
private
CaptionBtn : TRect;
procedure DrawCaptButton;
procedure WMNCPaint(var Msg : TWMNCPaint); message WM_NCPaint;
procedure WMNCActivate(var Msg : TWMNCActivate); message WM_NCACTIVATE;
procedure WMSetText(var Msg : TWMSetText); message WM_SETTEXT;
procedure WMNCHitTest(var Msg : TWMNCHitTest); message WM_NCHITTEST;
procedure WMNCLButtonDown(var Msg : TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
const
htCaptionBtn = htSizeLast + 1;
{$R *.DFM}
procedure TForm1.DrawCaptButton;
file://drawcapbuttton過程的具體實現
var
xFrame,
yFrame,
xSize,
ySize : Integer;
R : TRect;
begin
xFrame := GetSystemMetrics(SM_CXFRAME);
yFrame := GetSystemMetrics(SM_CYFRAME);
file://把視窗的寬度置於變數xFrame,把視窗的高度置於變數yFrame
xSize:= GetSystemMetrics(SM_CXSIZE);
ySize:= GetSystemMetrics(SM_CYSIZE);
// 把標題列按鈕的寬度置於變數xSize,把標題列按鈕的高度置於變數ySize
CaptionBtn := Bounds(Width - xFrame - 4*xSize + 2,
yFrame + 2, xSize - 2, ySize - 4);
file://定義出新的標題按鈕的位置,值放在變數CaptionBtn中
Canvas.Handle := GetWindowDC(Self.Handle);
file://得到視窗的控制代碼
Canvas.Font.Name := ‘Symbol‘;
Canvas.Font.Color := clBlue;
Canvas.Font.Style := [fsBold];
Canvas.Pen.Color := clYellow;
Canvas.Brush.Color := clBtnFace;
file://定義畫布的字型、畫筆、刷子等屬性
try
DrawButtonFace(Canvas, CaptionBtn, 1, bsAutoDetect, False, False, False);
file://在畫布上畫出定義的按鈕
R := Bounds(Width - xFrame - 4 * xSize + 2,
yFrame + 3, xSize - 6, ySize - 7);
file://在新按鈕上畫出一個小矩形
with CaptionBtn do
Canvas.TextRect(R, R.Left + 2, R.Top - 1, ‘W‘);
file://在上面畫出的小矩形上填寫一個字元‘w‘字元
finally
ReleaseDC(Self.Handle, Canvas.Handle);
Canvas.Handle := 0;
file://容錯處理,如果出現異常,把控制代碼釋放掉
end;
end;
procedure TForm1.WMNCPaint(var Msg : TWMNCPaint);
//WMNCPaint過程的具體實現,該過程在繪製視窗時被調用
begin
inherited;//繼承預設的訊息處理常式
DrawCaptButton;//對按鈕進行重畫
end;
procedure TForm1. (var Msg : TWMNCActivate);
// WMNCActivate過程與WMNCPaint過程實現方法相同,該過程在視窗的非客戶區要更改為啟用狀態或非啟用狀態時被調用
begin
inherited;
DrawCaptButton;
end;
procedure TForm1.WMSetText(var Msg : TWMSetText);
// WMSetText過程與WMNCPaint過程實現方法相同,該過程在設定視窗的文本時被調用
begin
inherited;
DrawCaptButton;
end;
procedure TForm1.WMNCHitTest(var Msg : TWMNCHitTest);
file:// WMNCHitTest過程與WMNCPaint過程實現方法相同,該過程在游標移動或滑鼠按鍵被按下或滑鼠按鍵被釋放時調用
begin
inherited;
with Msg do
if PtInRect(CaptionBtn, Point(XPos - Left, YPos - Top)) then
Result := htCaptionBtn;//判斷滑鼠所在位置是否在新按鈕的矩形範圍內,如果在返回新按鈕的標識值
end;
procedure TForm1.WMNCLButtonDown(var Msg : TWMNCLButtonDown);
// WMNCLButtonDown過程與WMNCPaint過程實現方法相同,當游標處於視窗非客戶區範圍內滑鼠左鍵被按下時調用該過程
begin
inherited;
if (Msg.HitTest = htCaptionBtn) then
ShowMessage(‘你點擊的是標題列上的新按鈕‘);
file://判斷被點擊的是否是新按鈕,如果是顯示上面的資訊,在這裡你可以按你的需要編寫程式碼
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Perform(WM_NCACTIVATE, Word(Active), 0);
file://如果視窗大小改變則重畫標題列
end;
end.
為Windows視窗標題列添加新按鈕