曾經做過一個最簡單的 Windows 程式: 建立一個 Delphi 控制台程式, 貼入以下代碼, 即可運行.
program Project1;uses Windows;begin MessageBox(0,PChar('Ok!'),PChar('Title'),0);end.
程式碼分析: 系統函數 MessageBox 即可產生一個訊息視窗; 因為這個函數來自 Windows 單元, 需要 uses Windows;
同樣的道理, 我們也可以使用 ShellAPI 單元下的 ShellAbout 調用一個關於視窗:
program Project1;uses ShellAPI;begin ShellAbout(0, '萬一的 Delphi 部落格', 'Copyright: 萬一', 0);end.
但這都是 Windows 固定模式和固定功能的視窗, 如果建立一個普通的視窗呢?
暫且拋棄使用 Forms.TForm 類的想法, 讓一切從頭開始, 也就是從 Windows API 開始.
現在我們能夠想到的代碼應該是這樣:
program Project1;begin //建立視窗 CreateWindow //顯示視窗 ShowWindowend.
認識 ShowWindow 函數:
ShowWindow( hWnd: HWND; {要顯示的視窗的控制代碼} nCmdShow: Integer {選項, 參加下表}): BOOL;//uCmdShow 參數可選值:SW_HIDE = 0; {隱藏, 並且工作列也沒有最小化表徵圖}SW_SHOWNORMAL = 1; {用最近的大小和位置顯示, 啟用}SW_NORMAL = 1; {同 SW_SHOWNORMAL}SW_SHOWMINIMIZED = 2; {最小化, 啟用}SW_SHOWMAXIMIZED = 3; {最大化, 啟用}SW_MAXIMIZE = 3; {同 SW_SHOWMAXIMIZED}SW_SHOWNOACTIVATE = 4; {用最近的大小和位置顯示, 不啟用}SW_SHOW = 5; {同 SW_SHOWNORMAL}SW_MINIMIZE = 6; {最小化, 不啟用}SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}SW_SHOWNA = 8; {同 SW_SHOWNOACTIVATE}SW_RESTORE = 9; {同 SW_SHOWNORMAL}SW_SHOWDEFAULT = 10; {同 SW_SHOWNORMAL}SW_MAX = 10; {同 SW_SHOWNORMAL}
認識 CreateWindow 函數:
CreateWindow( lpClassName: PChar; {視窗類別的名字} lpWindowName: PChar; {視窗標題} dwStyle: DWORD; {視窗樣式, 參加下表} X,Y: Integer; {位置; 預設的X,Y可以指定為: Integer(CW_USEDEFAULT)} nWidth,nHeight: Integer;{大小; 預設的寬度、高度可以指定為: Integer(CW_USEDEFAULT)}} hWndParent: HWND; {父視窗控制代碼} hMenu: HMENU; {主菜單控制代碼} hInstance: HINST; {模組執行個體控制代碼, 也就是當前 exe 的控制代碼} lpParam: Pointer {附加參數, 建立多重文件介面時才用到, 一般設為 nil}): HWND; {返回所建立的視窗的控制代碼}//dwStyle 視窗樣式參數可選值:WS_OVERLAPPED = 0; {重疊式視窗, 應帶標題列和邊框}WS_POPUP = DWORD($80000000); {彈出式視窗, 不能與 WS_CHILD 一起使用}WS_CHILD = $40000000; {子視窗, 不能與 WS_POPUP 一起使用}WS_MINIMIZE = $20000000; {已最小化的視窗}WS_VISIBLE = $10000000; {初始時可見}WS_DISABLED = $8000000; {禁止輸入}WS_CLIPSIBLINGS = $4000000; {裁剪子視窗, 也就是子視窗重繪不影響重疊的其他子視窗, 應與 WS_CHILD 一起使用}WS_CLIPCHILDREN = $2000000; {在父視窗中繪圖時繞開子視窗地區, 建立父視窗是使用}WS_MAXIMIZE = $1000000; {已最大化的視窗}WS_CAPTION = $C00000; {有標題列}WS_BORDER = $800000; {有細線邊框}WS_DLGFRAME = $400000; {對話方塊視窗}WS_VSCROLL = $200000; {有垂直捲軸}WS_HSCROLL = $100000; {有水平捲軸}WS_SYSMENU = $80000; {帶系統標題列, 須同時指定 WS_CAPTION}WS_THICKFRAME = $40000; {頻寬邊框, 寬邊框用於改變視窗大小}WS_GROUP = $20000; {能用方向鍵轉移焦點}WS_TABSTOP = $10000; {能用 TAB 轉移焦點}WS_MINIMIZEBOX = $20000; {有最小化按鈕}WS_MAXIMIZEBOX = $10000; {有最大化按鈕}WS_TILED = WS_OVERLAPPED;WS_ICONIC = WS_MINIMIZE;WS_SIZEBOX = WS_THICKFRAME;WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_THICKFRAME or WS_MINIMIZEBOX or WS_MAXIMIZEBOX);WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW;WS_POPUPWINDOW = (WS_POPUP or WS_BORDER or WS_SYSMENU);WS_CHILDWINDOW = (WS_CHILD);//另外還有一些擴充樣式:WS_EX_DLGMODALFRAME = 1; {指定雙邊界視窗; 藉此指定 WS_CAPTION 建立標題列}WS_EX_NOPARENTNOTIFY = 4; {在視窗建立或取消時不向父視窗發送 WM_PARENTNOTIFY 訊息}WS_EX_TOPMOST = 8; {在所有非最頂層視窗的上面}WS_EX_ACCEPTFILES = $10; {可接受拖放檔案}WS_EX_TRANSPARENT = $20; {透明樣式, 在同屬視窗已重畫時該視窗才可重畫}WS_EX_MDICHILD = $40; {建立一個 MDI 子視窗}WS_EX_TOOLWINDOW = $80; {工具視窗}WS_EX_WINDOWEDGE = $100; {帶立體的邊框}WS_EX_CLIENTEDGE = $200; {帶陰影的邊界}WS_EX_CONTEXTHELP = $400; {標題包含一個問號標誌, 不能與 WS_MAXIMIZEBOX 和 WS_MINIMIZEBOX 同時使用}WS_EX_RIGHT = $1000; {視窗具有靠右對齊屬性}WS_EX_LEFT = 0; {視窗具有靠左對齊屬性, WS_EX_LEFT 是預設設定}WS_EX_RTLREADING = $2000; {視窗文本從右至左}WS_EX_LTRREADING = 0; {視窗文本從左至右, WS_EX_LTRREADING 是預設設定}WS_EX_LEFTSCROLLBAR = $4000; {垂直捲軸在左邊界, 只用於特殊語言環境}WS_EX_RIGHTSCROLLBAR = 0; {垂直捲軸在右邊界, WS_EX_RIGHTSCROLLBAR 是預設設定}WS_EX_CONTROLPARENT = $10000; {允許使用者使用 Tab 鍵在視窗的子視窗間搜尋}WS_EX_STATICEDGE = $20000; {視窗不可用時建立一個三維邊界}WS_EX_APPWINDOW = $40000; {當視窗可見時, 將一個頂層視窗放置到任務條上}WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE); {立體邊框並帶陰影}WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST); {立體邊框、工具條視窗樣式、在頂層}WS_EX_LAYERED = $00080000; {分層或透明視窗, 該樣式可使用混合特效}WS_EX_NOINHERITLAYOUT = $00100000; {子視窗不繼承父視窗的布局}WS_EX_LAYOUTRTL = $00400000; {從右至左的布局}WS_EX_COMPOSITED = $02000000; {用雙緩衝從下到上繪製視窗的所有子孫}WS_EX_NOACTIVATE = $08000000; {處於頂層但不啟用}
分析:
首先要用 CreateWindow 建立視窗, 才能用 ShowWindow 顯示視窗; 因為 ShowWindow 需要 CreateWindow 返回的控制代碼.
在 CreateWindow 的參數中, 位置與大小與視窗標題無須多說;
父視窗與菜單, 暫時都不需要, 先可置為 0;
程式執行個體的控制代碼, Delphi 已經為我們準備好了: HInstance; (參見原來的說明)
視窗樣式在前面的例子中我們使用了: WS_OVERLAPPEDWINDOW, 它代表幾種特點的組合, 表示了常規視窗.
CreateWindow 還有一個重要參數(第一個參數 lpClassName): 視窗類別的名字.
Windows 要求我們要登記並註冊一個視窗類別以後, 才可以用 CreateWindow 建立視窗!
另附控制項樣式參考:
ES_LEFT = 0; {靠左對齊}ES_CENTER = 1; {置中}ES_RIGHT = 2; {靠右對齊}ES_MULTILINE = 4; {多行}ES_UPPERCASE = 8; {全大寫}ES_LOWERCASE = $10; {全小寫}ES_PASSWORD = $20; {掩碼字元}ES_AUTOVSCROLL = $40; {自動垂直滾動}ES_AUTOHSCROLL = $80; {自動水平滾動}ES_NOHIDESEL = $100; {始終顯示選中部分}ES_OEMCONVERT = $400; {允許 ANSI 和 OEM 互相轉換}ES_READONLY = $800; {唯讀}ES_WANTRETURN = $1000; {可接受斷行符號換行}ES_NUMBER = $2000; {只接受數字輸入}