API之子窗口创建 (转)
子窗口的創建非常非常重要
步驟:1、新建窗口類,在窗口類中指名對應的自定義的窗口過程。窗口類類名要唯一,它?????
?????????是各窗口類相互區別的標識。注意,類名或為靜態變量,或為全局變量,因為程
?????????序隨時都用他們。
??????2、創建窗體時,指定其風格之一為WS_CHILD,?指定其父窗口句柄,得到父窗體實
?????????例句柄,并賦給子窗體。
??????3、在主窗體的create消息中,創建0尺寸的子窗體,主窗體的size消息中,利用
????????movewindow函數,重設窗體大小,重置窗體位置。
實例為CTRL002,CTRL003
實例CTRL001單擊按鈕顯示對應文字
子窗口向父窗口發送消息
CreateWindow呼叫使用下面這些參數:
| Class?name(類別名稱) Window?text(窗口文字) Window?style(窗口樣式) x?position(x位置) y?position(y位置) Width(寬度) Height(高度) Parent?window(父窗口) Child?window?ID(子窗口ID) Instance?handle(執行實體句柄 )Extra?parameters(附加參數) | TEXT?("button") button[i].szText WS_CHILD|WS_VISIBLE|button[i].iStyle cxChar cyChar?*?(1?+?2?*?i) 20?*?xChar 7?*?cyChar?/?4 hwnd (HMENU)i ((LPCREATESTRUCT)?lParam)?->?hInstance NULL |
?
?
說明:從WM_COMMAND區別出單擊了哪個按鈕。通過子窗口的ID號來區分。每個子窗口在創建時,就已經分配了一個唯一的ID號。ID號包含在WM_COMMAND消息中wParam的低字節位。用LOWORD()宏來獲取ID。
??????“用鼠標單擊按鈕時,子窗口控制就向其父窗口發送一個WM_COMMAND消息。...捕獲WM_COMMAND消息....”
???????“LOWORD(wParam)???子窗口ID
?????????HIWORD(wParam)????通知碼
?????????lParam??????????????子窗口句柄”
?
[cpp] view plaincopyprint?- //定義一個按鈕類型結構體,方便創建按鈕,提高代碼復用率 ??
- struct??
- {??
- ?????int?????iStyle?;??
- ?????TCHAR?*?szText?;??
- }??
- button[]?=??
- {??
- ?????BS_PUSHBUTTON,??????TEXT?("PUSHBUTTON"),??
- ?????BS_DEFPUSHBUTTON,???TEXT?("DEFPUSHBUTTON"),??
- ?????BS_CHECKBOX,????????TEXT?("CHECKBOX"),???
- ?????BS_AUTOCHECKBOX,????TEXT?("AUTOCHECKBOX"),??
- ?????BS_RADIOBUTTON,?????TEXT?("RADIOBUTTON"),??
- ?????BS_3STATE,??????????TEXT?("3STATE"),??
- ?????BS_AUTO3STATE,??????TEXT?("AUTO3STATE"),??
- ?????BS_GROUPBOX,????????TEXT?("GROUPBOX"),??
- ?????BS_AUTORADIOBUTTON,?TEXT?("AUTORADIO"),??
- ?????BS_OWNERDRAW,???????TEXT?("OWNERDRAW")??
- }?;??
- #define?NUM?(sizeof?button?/?sizeof?button[0]) ??
- LRESULT?CALLBACK?WndProc?(HWND,?UINT,?WPARAM,?LPARAM)?;??
- int?WINAPI?WinMain?(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,??
- ????????????????????PSTR?szCmdLine,?int?iCmdShow)??
- {??
- ?????static?TCHAR?szAppName[]?=?TEXT?("BtnLook")?;??
- ?????HWND?????????hwnd?;??
- ?????MSG??????????msg?;??
- ?????WNDCLASS?????wndclass?;??
- ???????
- ?????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?;??
- ?????}??
- ???????
- ?????hwnd?=?CreateWindow?(szAppName,?TEXT?("Button?Look"),??
- ??????????????????????????WS_OVERLAPPEDWINDOW,??
- ??????????????????????????CW_USEDEFAULT,?CW_USEDEFAULT,??
- ??????????????????????????CW_USEDEFAULT,?CW_USEDEFAULT,??
- ??????????????????????????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??hwndButton[NUM]?;//句柄是一個數值,所以可以定義成數組形式 ??
- ?????static?int???cxChar,?cyChar?;??
- ??????
- ?????int?iLength=0;??
- ?????int??????????i?;??
- ??????
- ???????
- ?????HDC??????????hdc?;??
- ?????PAINTSTRUCT??ps?;??
- ???????
- ???????
- ?????switch?(message)??
- ?????{??
- ?????case?WM_CREATE?:??
- ??????????cxChar?=?LOWORD?(GetDialogBaseUnits?())?;??
- ??????????cyChar?=?HIWORD?(GetDialogBaseUnits?())?;??
- ????????????
- //得用?button[]?,簡化創建一系列按鈕過程,這就是編輯的藝術 ??
- ??????????for?(i?=?0?;?i?<?NUM-1?;?i++)??
- ???????????????hwndButton[i]?=?CreateWindow?(?TEXT("button"),???
- ???????????????????????????????????button[i].szText,??
- ???????????????????????????????????WS_CHILD?|?WS_VISIBLE?|?button[i].iStyle,??
- ???????????????????????????????????cxChar,?cyChar?*?(1?+?2?*?i),??
- ???????????????????????????????????20?*?cxChar,?7?*?cyChar?/?4,??
- ???????????????????????????????????hwnd,?(HMENU)?i,??
- ???????????????????????????????????((LPCREATESTRUCT)?lParam)->hInstance,?NULL)?;??
- ???????????????????????????????????//((HMENU)?i),為子窗口指定唯一的ID號。按鈕是子窗口的一種。該參數通常用于指定程序的菜單,因此子窗口ID必須被強制轉換為HMENU ??
- ??????
- ????????????/*?hwndButton[9]?=?CreateWindow?(?TEXT("button"),??
- ???????????????????????????????????button[9].szText,?
- ???????????????????????????????????WS_CHILD?|?WS_VISIBLE?|?button[9].iStyle,?
- ???????????????????????????????????cxChar,?cyChar?*?(1?+?2?*?9),?
- ???????????????????????????????????20?*?cxChar,?7?*?cyChar?/?4,?
- ???????????????????????????????????hwnd,?(HMENU)?9,?
- ???????????????????????????????????((LPCREATESTRUCT)?lParam)->hInstance,?NULL)?;?
- ?????????????*這種按鈕,會不斷地觸發WM_COMMAND消息,不斷地調用WM_COMMAND中的InvalidateRect,?
- ??????????????使客戶區不斷更新,出現閃爍現象。?
- ????????????*/??
- ??????????return?0?;??
- ?????case?WM_PAINT?:??
- ??????????//InvalidateRect?(hwnd,?&rect,?TRUE)?; ??
- ????????????
- ??????????hdc?=?BeginPaint?(hwnd,?&ps)?;??
- ??????????//為舉例方便起見,將窗口ID號數值大小順序設定成自定義按鈕結構體的順序 ??
- ??????????TextOut(hdc,300,200,button[iFlag].szText,lstrlen(button[iFlag].szText));??
- ??????????EndPaint?(hwnd,?&ps)?;??
- ??????????return?0?;??
- ?????case?WM_DRAWITEM?:??
- ?????case?WM_COMMAND?:??
- ????????????
- ??????????hdc?=?GetDC?(hwnd)?;??
- ??????????//得到子窗口的ID號 ??
- ??????????iFlag=LOWORD(wParam);//LOWORD=LOW?WORD,HIWORD=HIGH?WORD ??
- ????????????
- ??????????ReleaseDC?(hwnd,?hdc)?;??
- ??????????InvalidateRect?(hwnd,?NULL,?TRUE)?;//使客戶區失效,發出WM_PAINT消息,導致重繪發生 ??
- ??????????return?0;??
- ?????case?WM_DESTROY?:??
- ??????????PostQuitMessage?(0)?;??
- ??????????return?0?;??
- ?????}??
- ?????return?DefWindowProc?(hwnd,?message,?wParam,?lParam)?;??
- }??
#include <windows.h> int iFlag=1;//記錄被單擊按鈕的ID //定義一個按鈕類型結構體,方便創建按鈕,提高代碼復用率 struct { int iStyle ; TCHAR * szText ; } button[] = { BS_PUSHBUTTON, TEXT ("PUSHBUTTON"), BS_DEFPUSHBUTTON, TEXT ("DEFPUSHBUTTON"), BS_CHECKBOX, TEXT ("CHECKBOX"), BS_AUTOCHECKBOX, TEXT ("AUTOCHECKBOX"), BS_RADIOBUTTON, TEXT ("RADIOBUTTON"), BS_3STATE, TEXT ("3STATE"), BS_AUTO3STATE, TEXT ("AUTO3STATE"), BS_GROUPBOX, TEXT ("GROUPBOX"), BS_AUTORADIOBUTTON, TEXT ("AUTORADIO"), BS_OWNERDRAW, TEXT ("OWNERDRAW") } ; #define NUM (sizeof button / sizeof button[0]) LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("BtnLook") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; 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 ; } hwnd = CreateWindow (szAppName, TEXT ("Button Look"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 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 hwndButton[NUM] ;//句柄是一個數值,所以可以定義成數組形式 static int cxChar, cyChar ; int iLength=0; int i ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE : cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; //得用 button[] ,簡化創建一系列按鈕過程,這就是編輯的藝術 for (i = 0 ; i < NUM-1 ; i++) hwndButton[i] = CreateWindow ( TEXT("button"), button[i].szText, WS_CHILD | WS_VISIBLE | button[i].iStyle, cxChar, cyChar * (1 + 2 * i), 20 * cxChar, 7 * cyChar / 4, hwnd, (HMENU) i, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; //((HMENU) i),為子窗口指定唯一的ID號。按鈕是子窗口的一種。該參數通常用于指定程序的菜單,因此子窗口ID必須被強制轉換為HMENU /* hwndButton[9] = CreateWindow ( TEXT("button"), button[9].szText, WS_CHILD | WS_VISIBLE | button[9].iStyle, cxChar, cyChar * (1 + 2 * 9), 20 * cxChar, 7 * cyChar / 4, hwnd, (HMENU) 9, ((LPCREATESTRUCT) lParam)->hInstance, NULL) ; *這種按鈕,會不斷地觸發WM_COMMAND消息,不斷地調用WM_COMMAND中的InvalidateRect, 使客戶區不斷更新,出現閃爍現象。 */ return 0 ; case WM_PAINT : //InvalidateRect (hwnd, &rect, TRUE) ; hdc = BeginPaint (hwnd, &ps) ; //為舉例方便起見,將窗口ID號數值大小順序設定成自定義按鈕結構體的順序 TextOut(hdc,300,200,button[iFlag].szText,lstrlen(button[iFlag].szText)); EndPaint (hwnd, &ps) ; return 0 ; case WM_DRAWITEM : case WM_COMMAND : hdc = GetDC (hwnd) ; //得到子窗口的ID號 iFlag=LOWORD(wParam);//LOWORD=LOW WORD,HIWORD=HIGH WORD ReleaseDC (hwnd, hdc) ; InvalidateRect (hwnd, NULL, TRUE) ;//使客戶區失效,發出WM_PAINT消息,導致重繪發生 return 0; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
?
?
?
實例CTRL002?利用多個靜態窗體繪制棋盤
說明:1、窗體類別必需是static類,否則程序不能生成靜態窗體
??????2、利用GetWindowLong得到窗體實例句柄
??????3、HWND是數值類型,可以定義成數組
??????4、創建子窗體時,將大小設為0,以便重置
??????4、利用movewidow(...)函數重置靜態子窗體位置
?
[cpp] view plaincopyprint?#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; 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 = CreateSolidBrush (0) ;//將背景色設成黑色 wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, // window class name TEXT ("Chess"), // window caption WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME & ~ WS_MINIMIZEBOX //去除max、minbox,禁止改變窗體大小 , // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters 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 hwndRect[32]; HINSTANCE hinstance; int iw,ik,im,cxClient, cyClient ;//不能將它們定義在switch中 switch (message) { case WM_CREATE: hinstance=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); //得到程序的實例 //窗體類別必需是static類,否則程序不能生成靜態窗體。 for(iw=0;iw<32;iw++) { hwndRect[iw]=CreateWindow(TEXT("STATIC"),NULL, WS_CHILD|WS_VISIBLE|SS_WHITERECT, //將static 窗體背景色設成白色,好像只能設成黑/白彩色 0,0,0,0, hwnd,(HMENU)iw, hinstance, NULL ); } MoveWindow(hwnd,0,0,300,300,TRUE); return 0 ; case WM_SIZE: //MoveWindow(hwnd,0,0,400,400,TRUE); cxClient = LOWORD (lParam) ;//得到客戶區寬度 cyClient = HIWORD (lParam) ;//得到客戶區高度 //SetRect(&rcColor,icxClient/2,0,icxClient,icyClient); /* //歸納法 for(ik=0;ik<4;ik++) //for(im=0;im<4;im++) MoveWindow (hwndRect[ik], (0%2+ik)*cxClient/4, 0, cxClient/8, cyClient/8, TRUE) ; for(ik=0;ik<4;ik++) MoveWindow (hwndRect[ik+4], (1%2)*cxClient/8+ik*cxClient/4, cyClient/8, cxClient/8, cyClient/8, TRUE) ; */ MoveWindow(hwnd,200,100,300,300,TRUE); for(ik=0;ik<4;ik++) for(im=0;im<8;im++) MoveWindow (hwndRect[ik+4*im], (im%2)*cxClient/8+ik*cxClient/4, im*cyClient/8, cxClient/8, cyClient/8, TRUE) ; return 0; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
?
?
運行結果如下圖
?
[cpp] view plaincopyprint?轉載于:https://www.cnblogs.com/Fightingbirds/archive/2013/01/03/2843407.html
總結
以上是生活随笔為你收集整理的API之子窗口创建 (转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GNU ARM 汇编指令[转载]
- 下一篇: iOS开发 plist字段列表,很全