program Project1;
uses
Windows, Messages;
{回調函數; 其中要處理的消息很多, 最好用 case 語句}
function WndProc(wnd: HWND; msg: UINT; wParam: Integer; lParam: Integer): Integer; stdcall;
begin
Result := 0;
case msg of
WM_DESTROY: PostQuitMessage(0); {收到 WM_DESTROY 後, 發送 WM_QUIT 消息指示退出}
else
{其他消息交 DefWindowProc 處理; DefWindowProc 會返回回調函數需要的返回值}
Result := DefWindowProc(wnd, msg, wParam, lParam);
end;
end;
{登記與注冊窗口類的函數}
function RegMyWndClass: Boolean;
var
MyWndClass: TWndClass;
begin
{指定窗口類型}
MyWndClass.style := CS_HREDRAW or CS_VREDRAW; {改變大小時重繪}
MyWndClass.lpfnWndProc := @WndProc; {回調函數指針}
MyWndClass.cbClsExtra := 0; {沒有額外的窗口類信息}
MyWndClass.cbWndExtra := 0; {沒有額外的窗口信息}
MyWndClass.hInstance := HInstance; {程序實例句柄}
MyWndClass.hIcon := 0; {沒指定圖標}
MyWndClass.hCursor := LoadCursor(0, IDC_ARROW); {選用了系統提供的指針}
MyWndClass.hbrBackground := HBRUSH(COLOR_BTNFACE + 1); {背景色使用 Windows 默認的按鈕顏色}
MyWndClass.lpszMenuName := nil; {不指定默認菜單}
MyWndClass.lpszClassName := 'MyWindowClass'; {給窗口類型命名}
Result := RegisterClass(MyWndClass) <> 0; {注冊窗口類型}
end;
{主程序}
var
hWnd: THandle;
Msg : TMsg;
begin
{調用登記與注冊窗口的函數}
if not RegMyWndClass then
begin
MessageBox(0, '窗口類注冊失敗!', '提示', MB_OK + MB_ICONERROR);
Exit;
end;
{建立窗口並返回句柄; 既然有 CreateWindowEx 就不使用 CreateWindow 了}
hWnd := CreateWindowEx(0, {不使用擴展風格}
'MyWindowClass', {窗口類型名}
'新窗口', {標題}
WS_OVERLAPPEDWINDOW, {窗口的常規樣式}
Integer(CW_USEDEFAULT), {默認水平位置}
Integer(CW_USEDEFAULT), {默認垂直位置}
Integer(CW_USEDEFAULT), {默認寬度}
Integer(CW_USEDEFAULT), {默認高度}
0, {無父窗口}
0, {無主菜單}
HInstance, {實例句柄}
nil {無附加信息}
);
if hWnd = 0 then {如果窗口建立失敗}
begin
MessageBox(0, '窗口建立失敗!', '提示', MB_OK + MB_ICONERROR);
Exit;
end;
{顯示窗口與更新窗口}
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
{消息循環; GetMessage 在收到 WM_QUIT 消息時會返回 False, 從而終止循環}
while(GetMessage(Msg, 0, 0, 0)) do
begin
TranslateMessage(Msg); {需要對部分鍵盤消息的再處理}
DispatchMessage(Msg); {將消息發送給回調函數}
end;
Halt(Msg.wParam); {沒有了消息循環程序自然會退出; 加上這句, 程序會根據退出碼主動退出}
end.