基于SDK的win32程式架構一般總是由兩個基本函數組成:一個是入口函數WinMain,它包含了整個架構的運作代碼;另一個是使用者定義的視窗過程函數SDKWndProc(名稱可以在程式中自動定義),用來接收 和處理各種不同的消息。
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK SDKWndProc (HWND, UINT, WPARAM, LPARAM); // 視窗過程
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd ; // 視窗句柄
MSG msg ; // 消息
WNDCLASS wndclass ; // 視窗類
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = SDKWndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject ( WHITE_BRUSH ) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = "SDKWin"; // 視窗類名
if (!RegisterClass (&wndclass)) // 注冊視窗
{
MessageBox (NULL, "視窗注冊失敗!", "HelloWin", 0) ;
return 0 ;
}
// 建立視窗
hwnd = CreateWindow ("SDKWin", // 視窗類名
"實驗2 Windows程式設計基礎", // 視窗标題
WS_OVERLAPPEDWINDOW, // 視窗樣式
CW_USEDEFAULT, // 視窗最初的 x 位置
CW_USEDEFAULT, // 視窗最初的 y 位置
400, // 視窗最初的 x 大小
320, // 視窗最初的 y 大小
NULL, // 父視窗句柄
NULL, // 視窗菜單句柄
hInstance, // 應用程式執行個體句柄
NULL) ; // 建立視窗的參數
ShowWindow (hwnd, nCmdShow) ; // 顯示視窗
UpdateWindow (hwnd) ; // 更新視窗,包括視窗的客戶區
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ; // 轉換某些鍵盤消息
DispatchMessage (&msg) ; // 将消息發送給視窗過程,這裡是WndProc
}
return msg.wParam ;
}
LRESULT CALLBACK SDKWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndHint, hwndRes, hwndEdit, hwndBtn;
HFONT hFont;
switch (message)
{
case WM_CREATE: hFont = (HFONT)GetStockObject ( DEFAULT_GUI_FONT );
hwndHint = CreateWindow("STATIC", "輸入半徑: ",
WS_CHILD | WS_VISIBLE | SS_SIMPLE,
20, 20, 100, 20, hwnd, NULL, NULL, NULL );
hwndEdit = CreateWindow("EDIT", NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER,
20, 40, 100, 20, hwnd, NULL, NULL, NULL );
hwndBtn = CreateWindow("BUTTON", "圓面積",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
140, 40, 80, 20, hwnd, NULL, NULL, NULL );
hwndRes = CreateWindow("STATIC", NULL,
WS_CHILD | WS_VISIBLE | SS_SIMPLE,
20, 70, 180, 20, hwnd, NULL, NULL, NULL );
SendMessage(hwndHint, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
SendMessage(hwndBtn, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
SendMessage(hwndRes, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
break;
case WM_COMMAND: // 指令消息,控件産生的通知代碼在wParam的高字中
if (((HWND)lParam == hwndBtn )&&( HIWORD(wParam) == BN_CLICKED ))
{
char strEdit[80];
// 擷取編輯框控件的内容,并将其轉換成float數值
if ( GetWindowText( hwndEdit, strEdit, 80) > 0 ) // 擷取編輯框内容
{
float fRes = (float)atof( strEdit );
if ( fRes > 0.0f )
{
sprintf( strEdit, "圓面積為: %f", 3.14 * fRes * fRes );
SetWindowText( hwndRes, strEdit );
} else
MessageBox( hwnd, "圓半徑輸入無效!", "注意", 0 );
} else
MessageBox( hwnd, "請輸入圓的半徑!", "注意", 0 );
}
break;
case WM_DESTROY: // 當視窗關閉時産生的消息
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ; // 執行預設的消息處理
}
在CALLBACK SDKWndProc 中,這樣就建立了兩個靜态控件、一個編輯框和一個按鈕。需要說明的是:
- 将hwndHint\hwndRes\hwndEdit和hwndButton視窗句柄定義成static的目的是使其成為全局變量,當SDKWndPro第一次調用建立後,就會一直有效。用CreateWindow函數建立視窗時,若指定的是預定義的視窗名BUTTON、COMBOBOX、EDIT、LISTBOX、SCROLLBAR和STATIC,則建立的是按鈕、組合框、編輯框、清單框、滾動條和講台空間等視窗。由于這些空間視窗必須是主視窗的子視窗,是以為其指定的風格中一定要有WS_CHILD和WS_VISIBLE,同時指定父視窗句柄為主視窗句柄hwnd。
- 各空間的字型可通過SendMessage函數并指定WM_SETFONT消息來更改。DEFAULT_GUI_FONT是擷取系統消息對話框和菜單中的預設字型。