程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 為Windows窗口標題欄添加新按鈕

為Windows窗口標題欄添加新按鈕

編輯:C語言基礎知識

  對於我們熟悉的標准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.
  
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved