子窗口的應用——翻轉窗口

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

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

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

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




在windows程序中,子窗口的應用很常見,基本上大部分窗口都有其指定的子窗口,這些子窗口統統受其父窗口的管理,各自實現相應的功能

 

老規矩,先簡述今天的實例程序所實現的功能:

在父窗口中先繪製一張位圖,然後在其之上創建36個子窗口,點擊子窗口隱藏,點擊改子窗口占據父窗口的區域就重新顯示該子窗口。

 

比較好玩兒,可以拼出很多好看的圖形,來看看效果吧:

 

 

 

 

OK,賞析完了,就來具體研究一下它的實現細節……

 

在看代碼細節之前,先來學習一個函數:

BOOL MoveWindow(
  HWND hWnd,      // handle to window
  int X,          // horizontal position
  int Y,          // vertical position
  int nWidth,     // width
  int nHeight,    // height
  BOOL bRepaint   // repaint option
);

這個函數可用於移動一個窗口,同時改變窗口的size(大小),在創建子窗口中能用到

 

閱讀代碼細節:

(1)父窗口和子窗口類的註冊

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;
}

wndclass.lpfnWndProc	= ChildWndProc;
wndclass.hIcon			= NULL;
wndclass.lpszClassName	= szChildName;

//註冊子窗口類
RegisterClass(&wndclass);

 

(2)由於這裏的子窗口都是做同樣一件事——響應鼠標左鍵消息,隱藏自己,因此我們只需要一個回調函數

你可能會有一個疑慮:

程序怎麼知道我們點擊的是哪一個子窗口呢?

問得好。不過你可能忘記了一點,windows是如何管理、定位在它上面運行的所有程序(窗口)呢?

這裏子窗口的定位和其它窗口(包括父窗口)都是由windows來統一確定,無需我們的父窗口來操心

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);		//父窗口回調函數
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);	//子窗口回調函數

 

(3)在父窗口的WM_CREATE消息中獲取位圖信息和創建子窗口

a)在WM_PAINT消息中貼位圖,這個我就不再贅述了,不熟悉的朋友可以查看我之前寫的關於Bitmap位圖應用的博文

b)創建子窗口

用一個for循環

/*        創建子窗口        */
for(i=0; i<DIVISIONS; i++)
	for(j=0; j<DIVISIONS; j++)
		hwndChild[i][j] = CreateWindow(szChildName, NULL, 
										WS_CHILD | WS_VISIBLE,
										0, 0, 0, 0,
										hwnd, NULL, hInstance, NULL);

因爲在CREATE消息中我們還不能確定父窗口客戶區大小,所以還需要在WM_SIZE消息中移動一下創建的子窗口

case WM_SIZE:
	//確定父窗口客戶區大小
	cxClient = LOWORD(lParam);
	cyClient = HIWORD(lParam);

	//確定子窗口大小
	cxChild = cxClient / DIVISIONS;
	cyChild = cyClient / DIVISIONS;

	/*        移動子窗口      */
	for(i=0; i<DIVISIONS; i++)
		for(j=0; j<DIVISIONS; j++)
			MoveWindow(hwndChild[i][j], i * (cxChild + 1), j * (cyChild + 1),//加1是爲了讓子窗口之間有一個明顯的間隙
						cxChild, cyChild, TRUE);
	return 0;

(4)在父窗口的左鍵按下消息中顯示子窗口

/*
	因爲在子窗口中通過鼠標消息隱藏,這時父窗口的該區域就可見,
	因此我們可以讓父窗口通過鼠標消息顯示子窗口
*/
case WM_LBUTTONDOWN:
	{
		int xMouse, yMouse;
		xMouse = LOWORD(lParam);
		yMouse = HIWORD(lParam);

		for(i=0; i<DIVISIONS; i++)
			for(j=0; j<DIVISIONS; j++)
				//如果鼠標點擊位置在子窗口上,就顯示
				if((xMouse >= i * cxChild && xMouse < (i+1) * cxChild)
					&& (yMouse >= j * cyChild && yMouse < (j+1) * cyChild))
				{
					ShowWindow(hwndChild[i][j], SW_SHOW);
					return 0;
				}
	}
	return 0;


 

(5)子窗口的回調函數

//子窗口回調函數
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
	//點擊子窗口時隱藏
	case WM_LBUTTONDOWN:
		ShowWindow(hwnd, SW_HIDE);
		return 0;
	}
	return DefWindowProc (hwnd, message, wParam, lParam);
}

 

 

以上就是今天的內容,歡迎各位的品讀^_^……

 

點擊下載源代碼以及相關資源
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章