本文由BlueCoder編寫 轉載請說明出處:
http://blog.csdn.net/crocodile__/article/details/10273185
我的郵箱:[email protected] 歡迎大家和我交流編程心得
我的微博:BlueCoder_黎小華 歡迎光臨^_^
學習win32 API 編程,我們應該善於利用微軟給我們提供的一些輔助工具,例如大家都知道的MSDN、SPY++等等。
今天在講述之前呢,先給大家介紹一個很有用的工具——Control Spy——它的用途和SPY++有點兒類似,它能查看對應控件所屬的風格、能響應的消息以及響應的通知碼。
有了它,加上msdn,你基本上就能很快掌握這些控件的用法了——都是基於消息驅動來完成響應的工作
OK,先來講一下這個小工具的用法(包含個人的學習心得):
(1)在左邊子窗口中,選擇你想學習的控件,這裏我就選擇Button
(2)在中間子窗口中你就能預覽這個控件的樣式
(3)我們知道,這些控件其實本質上都是窗口,因此他們都可以用CreateWindow或者CreateWindowEx函數來創建
下面,我詳細講一下創建的過程(爲了幫助說明,我將以CreateWindow函數爲例,並貼出該函數的原型聲明)
HWND CreateWindow( LPCTSTR lpClassName, // registered class name LPCTSTR lpWindowName, // window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // menu handle or child identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // window-creation data );
我只列出需要注意的幾個特別參數的設法
1>窗口類的名稱lpClassName——微軟幫預設了對應控件所關聯的窗口類名稱——因此,你只需要將它設爲TEXT("控件的英文名稱")
例如,我這裏選擇按鈕Button,你就可以寫爲TEXT("button");如果選擇組合框ComboBox,就寫爲TEXT("combobox")
注:名稱不區分大小寫,因此你在創建主窗口的時候,就不能將主窗口的窗口類名稱設爲這些控件的名稱,免得覆蓋了微軟預設的控件窗口類名稱
2>窗口的風格dwStyle——這時剛剛提到的小工具就起作用了,你可以在它的子窗口Style中,查找對應的類型:
不過類型WS_CHILD是必須添加的,如果你想讓改控件一創建就可見,那麼就應該還加上WS_VISIBLE
3>父窗口hWndParent,由於這些控件都是子窗口,所以父窗口一定不能爲空,這個之情況而定
4>菜單句柄hMenu,這個需要設定爲控件的ID號(ID一般就是用宏定義的一些常量,例如:IDB_BUTTON 按鈕ID號)
爲了類型的匹配,你需要強制轉換一下類型:(HMENU)IDB_BUTTON
5>實例句柄hInstance,如果你是在主窗口的WM_CREATE消息中創建控件,那麼可以這樣設定:((LPCREATESTRUCT)lParam)->hInstance
(4)瞭解控件能響應的消息:
(5)你還可以操作,這個控件來看看它所響應的消息以及對應的通知碼
消息:
通知碼:
好了,這個小工具的大致使用方法就介紹到這裏,如果你還是不怎麼清楚它的用法,可以參見資源下載中提供的英文版幫助文檔
光說不練是假把式,還是用程序代碼來證明一切
昨天講了按鈕的創建以及使用方法,今天兒就講一下組合框的使用方法。
還是先來看看實現的效果:
可以看見,我還是使用WinXP以來微軟提供的新控件,畢竟要美觀些
***************************************************進入代碼階段******************************************************
先在頭文件做一些相應的聲明
//WINDOW_XP_STYLE.H
#include<windows.h>
//組合框的ID
#define IDCB_COMBOBOX_1 100
#define IDCB_COMBOBOX_2 101
#define IDCB_COMBOBOX_3 103
//組合框的個數
#define NUMS 3
//一些字符串數組,用於顯示
TCHAR* tchSmall[] = {TEXT("小美女"), TEXT("小帥哥"), TEXT("小可愛")};
TCHAR* tchBig[] = {TEXT("大美女"), TEXT("大帥哥"), TEXT("小頑皮")};
TCHAR* tchNone[] = {TEXT("漂亮"), TEXT("帥氣"), TEXT("可愛")};
//使用WinXP以來提供的心控件
#pragma comment(linker,"\"/manifestdependency:type='win32' "\
"name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' language='*'\"")
因爲大部分技術都是在前面博文中講述過的,這裏我就僅僅將完整代碼貼出來,內含一定的註釋,只要各位有一定的基礎,應該是能看懂的^_^
//ComboBox.c
#include"Window_Xp_Style.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
static TCHAR szAppName[] = TEXT("ComboBox View");//注意這裏不能寫爲ComboBox 因爲這樣會覆蓋微軟預設的控件窗口類名稱
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
int cxScreen, cyScreen;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
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 = szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
cxScreen = GetSystemMetrics(SM_CXSCREEN);
cyScreen = GetSystemMetrics(SM_CYSCREEN);
hwnd = CreateWindow(szAppName,
TEXT("ComboBox Demo"),
WS_OVERLAPPEDWINDOW,
cxScreen * 7 / 20,
cyScreen / 4,
cxScreen * 3 / 10,
cyScreen / 2,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hComboBox[NUMS];//組合框窗口句柄數組(有3個)
int iCombID[] = {IDCB_COMBOBOX_1, IDCB_COMBOBOX_2, IDCB_COMBOBOX_3};//組合框ID數組
HFONT hFont;//字體句柄
LOGFONT lf;
int i, xPos, yDiv;//循環變量、組合框x座標、y座標上的間距
switch(message)
{
case WM_CREATE:
//創建組合框
for(i=0; i<NUMS; i++)
{
hComboBox[i] = CreateWindow(TEXT("combobox"), TEXT(""),
WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SIMPLE,
0, 0, 0, 0, hwnd, (HMENU)iCombID[i],
((LPCREATESTRUCT)lParam)->hInstance, NULL);
}
//添加子項
for(i=0; i<NUMS; i++)
SendMessage(hComboBox[0], CB_ADDSTRING, 0, (LPARAM)tchSmall[i]);
for(i=0; i<NUMS; i++)
SendMessage(hComboBox[1], CB_ADDSTRING, 0, (LPARAM)tchBig[i]);
for(i=0; i<NUMS; i++)
SendMessage(hComboBox[2], CB_ADDSTRING, 0, (LPARAM)tchNone[i]);
//設置初始狀態選中的子項
for(i=0; i<NUMS; i++)
SendMessage(hComboBox[i], CB_SETCURSEL, (WPARAM)0, 0);
//創建字體
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = -10;
hFont = CreateFontIndirect(&lf);
//修改當前的字體
for(i=0; i<NUMS; i++)
SendMessage(hComboBox[i], WM_SETFONT, (WPARAM)hFont, 0);
return 0;
case WM_SIZE:
//隨着窗口大小的改變而移動組合框
xPos = (LOWORD(lParam) - 100) / 2;
yDiv = HIWORD(lParam) / (NUMS + 2);
for(i=0; i<NUMS; i++)
MoveWindow(hComboBox[i], xPos, yDiv * (i + 1), 100, 20, TRUE);
return 0;
//響應組合框子項選擇的消息
case WM_COMMAND:
//判斷控件的ID
switch(LOWORD(wParam))
{
case IDCB_COMBOBOX_1:
//判斷當前控件對應的通知碼
if(HIWORD(wParam) == CBN_SELENDOK)//選擇了組合框的子項
{
LRESULT index;
index = SendMessage(hComboBox[0], CB_GETCURSEL, 0, 0);
if(CB_ERR != index)
MessageBox(hwnd, tchSmall[(int)index], TEXT("提示"), MB_OK);
}
break;
case IDCB_COMBOBOX_2:
//判斷當前控件對應的通知碼
if(HIWORD(wParam) == CBN_SELENDOK)
{
LRESULT index;
index = SendMessage(hComboBox[1], CB_GETCURSEL, 0, 0);
if(CB_ERR != index)
MessageBox(hwnd, tchBig[(int)index], TEXT("提示"), MB_OK);
}
break;
case IDCB_COMBOBOX_3:
//判斷當前控件對應的通知碼
if(HIWORD(wParam) == CBN_SELENDOK)
{
LRESULT index;
index = SendMessage(hComboBox[2], CB_GETCURSEL, 0, 0);
if(CB_ERR != index)
MessageBox(hwnd, tchNone[(int)index], TEXT("提示"), MB_OK);
}
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}