程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Windows 編程[3] - 學習窗體生成的過程三

Windows 編程[3] - 學習窗體生成的過程三

編輯:Delphi

根據前面的理論, 一個窗口生成的框架應該是這個樣子:

program Project1;

uses Windows; {前面提到的函數都來自 Windows 單元}

var
 hWnd   : THandle;  {聲明窗口句柄}
 MyWndClass: TWndClass; {聲明一個窗口類型}
begin
  //在這裡設置 MyWndClass 的參數(譬如窗口圖標、光標和畫刷等等), 包括指定 "類名"

  {然後注冊}
  RegisterClass(MyWndClass);
  {建立並返回句柄}
  hWnd := CreateWindow(類名, 標題, 樣式, X,Y, 寬,高, 0, 0, HInstance, nil);
  {顯示}
  ShowWindow(hWnd, SW_SHOWNORMAL);
end.

  這個窗口類型 TWndClass 其實是一個結構, 是 tagWNDCLASSA 結構的重命名.

{tagWNDCLASSA 結構:}
tagWNDCLASSA = packed record
 style: UINT;       {窗口風格, 見下表}
 lpfnWndProc: TFNWndProc; {窗口回調函數的指針, 後面要詳細分析}
 cbClsExtra: Integer;   {為窗口類分配的額外空間, 一般為 0}
 cbWndExtra: Integer;   {為窗口實例分配的額外空間, 一般為 0}
 hInstance: HINST;     {窗口所在程序實例的句柄, 就是 HInstance}
 hIcon: HICON;       {指定窗口圖標, 一般用 LoadIcon 加載; 不指定可設為 0}
 hCursor: HCURSOR;     {指定窗口光標, 一般用 LoadCursor 加載; 不指定可設為 0}
 hbrBackground: HBRUSH;  {指定窗口背景畫刷, 這需要用 GetStockObject 函數檢索; 也可以直接指定系統顏色}
 lpszMenuName: PAnsiChar; {菜單資源名稱; 一般置為 nil, 表示窗口沒有默認菜單}
 lpszClassName: PAnsiChar; {給該窗口類命名; CreateWindow 函數將使用這個名稱}
end;

//窗口風格參數 style 可選值:
CS_VREDRAW     = DWord(1); {窗口高度變化時將被重繪}
CS_HREDRAW     = DWord(2); {窗口寬度變化時將被重繪}
CS_KEYCVTWINDOW  = 4;    {}
CS_DBLCLKS     = 8;    {不忽略鼠標雙擊的消息}
CS_OWNDC      = $20;   {給用該類建立的每一個窗口分配獨立的設備 DC}
CS_CLASSDC     = $40;   {讓屬於該類的所有窗口共享一個設備 DC}
CS_PARENTDC    = $80;   {允許窗口的子窗口繼承一些共同特性}
CS_NOKEYCVT    = $100;   {}
CS_NOCLOSE     = $200;   {禁用系統菜單的 Close命令,同時窗口沒有關閉按鈕}
CS_SAVEBITS    = $800;   {當窗口被覆蓋時, 用位圖緩存被覆蓋區, 從而避免 WM_PAINT 消息, 一般用於菜單或對話框}
CS_BYTEALIGNCLIENT = $1000;  {通過字節對齊, 增強客戶區的繪制性能}
CS_BYTEALIGNWINDOW = $2000;  {通過字節對齊, 增強窗口的繪制性能}
CS_GLOBALCLASS   = $4000;  {全局窗口類, 一般用於 DLL; 沒有此選項, 窗口類和窗口建立函數中指定的實例句柄須相同}

//關於窗口背景畫刷:
{系統預定義了一些畫刷, 需要用 GetStockObject 根據指定的常數檢索;}
{但 GetStockObject 返回的句柄有可能是畫刷、畫筆、調色板或系統字體的句柄,}
{所以還需要把 GetStockObject 返回的句柄進行類型轉換, 譬如: HBRUSH(GetStockObject(常數))}
//下面是 GetStockObject 函數參數的可選值:
WHITE_BRUSH     = 0;
LTGRAY_BRUSH    = 1;
GRAY_BRUSH     = 2;
DKGRAY_BRUSH    = 3;
BLACK_BRUSH     = 4;
NULL_BRUSH     = 5;
HOLLOW_BRUSH    = NULL_BRUSH;
WHITE_PEN      = 6;
BLACK_PEN      = 7;
NULL_PEN      = 8;
OEM_FIXED_FONT   = 10;
ANSI_FIXED_FONT   = 11;
ANSI_VAR_FONT    = 12;
SYSTEM_FONT     = 13;
DEVICE_DEFAULT_FONT = 14;
DEFAULT_PALETTE   = 15;
SYSTEM_FIXED_FONT  = $10;
DEFAULT_GUI_FONT  = 17;
DC_BRUSH      = 18;
DC_PEN       = 19;
STOCK_LAST     = 19;

{另外背景畫刷還可以使用 Windows 定義系統顏色常量, 譬如: HBRUSH(COLOR_WINDOW + 1) }
COLOR_SCROLLBAR        = 0;
COLOR_BACKGROUND       = 1;
COLOR_ACTIVECAPTION      = 2;
COLOR_INACTIVECAPTION     = 3;
COLOR_MENU          = 4;
COLOR_WINDOW         = 5;
COLOR_WINDOWFRAME       = 6;
COLOR_MENUTEXT        = 7;
COLOR_WINDOWTEXT       = 8;
COLOR_CAPTIONTEXT       = 9;
COLOR_ACTIVEBORDER      = 10;
COLOR_INACTIVEBORDER     = 11;
COLOR_APPWORKSPACE      = 12;
COLOR_HIGHLIGHT        = 13;
COLOR_HIGHLIGHTTEXT      = 14;
COLOR_BTNFACE         = 15;
COLOR_BTNSHADOW        = $10;
COLOR_GRAYTEXT        = 17;
COLOR_BTNTEXT         = 18;
COLOR_INACTIVECAPTIONTEXT   = 19;
COLOR_BTNHIGHLIGHT      = 20;
COLOR_3DDKSHADOW       = 21;
COLOR_3DLIGHT         = 22;
COLOR_INFOTEXT        = 23;
COLOR_INFOBK         = 24;
COLOR_HOTLIGHT        = 26;
COLOR_GRADIENTACTIVECAPTION  = 27;
COLOR_GRADIENTINACTIVECAPTION = 28;
COLOR_MENUHILIGHT       = 29;
COLOR_MENUBAR         = 30;
COLOR_ENDCOLORS        = COLOR_MENUBAR;
COLOR_DESKTOP         = COLOR_BACKGROUND;
COLOR_3DFACE         = COLOR_BTNFACE;
COLOR_3DSHADOW        = COLOR_BTNSHADOW;
COLOR_3DHIGHLIGHT       = COLOR_BTNHIGHLIGHT;
COLOR_3DHILIGHT        = COLOR_BTNHIGHLIGHT;
COLOR_BTNHILIGHT       = COLOR_BTNHIGHLIGHT;

 整理一下思路:

  要顯示一個窗口, 需要先建立一個窗口;

  要建立一個窗口, 需要先注冊一個窗口類型;

  注冊前需要給窗口類型指定種種特性, 這些特性裡面, 最重要的就是指定"窗口的回調函數"!

  此回調函數必須要按照 Windows 指定的格式(只有函數名和參數名可變):

function WndProc(wnd: HWND; msg: UINT; wParam: Integer; lParam: Integer): Integer; stdcall;
begin
 ...
end;

  在該回調函數中, 要處理發送到窗口的所有消息;

  但消息非常非常多, 不可能都做處理, 不需要的消息都要通過 DefWindowProc 函數做默認處理.

  DefWindowProc 函數的參數和回調函數的參數一直, 並返回回調函數需要的返回值.

  譬如我們只處理 WM_DESTROY 消息:

function WndProc(wnd: HWND; msg: UINT; wParam: Integer; lParam: Integer): Integer; stdcall;
begin
 if msg = WM_DESTROY then
  ...
 else
  Result := DefWindowProc(wnd, msg, wParam, lParam);
end;

  


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved