__win32控件(2)__教你自學掌握所有控件的玩法

本文由BlueCoder編寫   轉載請說明出處:

http://blog.csdn.net/crocodile__/article/details/10273185

我的郵箱:[email protected]    歡迎大家和我交流編程心得

我的微博:BlueCoder_黎小華    歡迎光臨^_^




學習win32 API 編程,我們應該善於利用微軟給我們提供的一些輔助工具,例如大家都知道的MSDN、SPY++等等。

今天在講述之前呢,先給大家介紹一個很有用的工具——Control Spy——它的用途和SPY++有點兒類似,它能查看對應控件所屬的風格、能響應的消息以及響應的通知碼。

有了它,加上msdn,你基本上就能很快掌握這些控件的用法了——都是基於消息驅動來完成響應的工作

(點擊下載Control Spy小工具)

 

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);
}
發佈了39 篇原創文章 · 獲贊 29 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章