學習目的 學習創建, 使用Windows標准控件(按鈕, 滾動條, 靜態控件, 列表框, 編輯框, 組合框); 學習使用子窗口控件操作函數(EnableWindow, MoveWindow, SetWindowText, GetWindowText, DestroyWindow). 編寫程序: 設計窗口應用程序, 分別包含按鈕, 滾動條, 靜態控件, 列表框, 編輯框, 組合框.等標准控件. 1. 創建按鈕控件 創建子窗口時指定窗口類為button.代碼如下: //創建按鈕 CreateWindow("button",//必須為:button "向上滾動",//按鈕上顯示的字符 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 35, rt.top+10, 120, 60, hWnd, (HMENU)IDB_ONE, ((LPCREATESTRUCT)lParam)->hInstance,NULL);
2.創建滾動條控件 在創建窗口函數的第三個參數中添加WS_HSCROLL,WS_VSCROLL分別添加垂直和水平滾動條,代碼如下: hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
3. 創建靜態控件 創建子窗口時指定窗口類為static.代碼如下: //創建靜態控件 CreateWindow("static","這是靜態控件",WS_VISIBLE|WS_CHILD, 200,rt.top+20,100,50, hWnd,NULL,((LPCREATESTRUCT)lParam)->hInstance,NULL); 4. 創建列表框控件 創建子窗口時指定窗口類為listbox.代碼如下: //創建列表框 hWndList=CreateWindow("listbox",NULL,LBS_NOTIFY|WS_CHILD | WS_VISIBLE | LBS_STANDARD, 200,(rt.bottom+rt.top)/2-100,200,200, hWnd,NULL,((LPCREATESTRUCT)lParam)->hInstance,NULL); SendMessage (hWndList, LB_ADDSTRING, 0, (LPARAM) "我是列表框") ; 5. 創建編輯框控件 創建子窗口時指定窗口類為edit.代碼如下: //創建編輯框 CreateWindow ("edit","這是編輯框,\r\n這是編輯框,\r\n這是編輯框,這是編輯框,這是編輯框,這是編輯框,這是編輯框,這是編輯框,\r\n這是編輯框,\r\n這是編輯框,\r\n這是編輯框,\r\n這是編輯框", WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 200, rt.bottom-120, 220, 100, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;
6. 創建組合框控件 創建子窗口時指定窗口類為combobox.代碼如下: //創建組合框 hWndComboBox=CreateWindow("combobox", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, rt.right -300, 20, 200, 400, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); SendMessage(hWndComboBox,CB_ADDSTRING,0,(LPARAM)"我是列表框"); for (i=0;i<=50;i++) { char temp[10]; SendMessage(hWndComboBox,CB_ADDSTRING,0,(LPARAM)itoa(i,temp,10)); } 7. 滾動條的事件處理 在WM_VSCROLL中處理滾動條的消息,代碼如下 case WM_VSCROLL: switch (LOWORD (wParam)) { case SB_LINEUP: iVscrollPos -= 1 ; break ;
case SB_LINEDOWN: iVscrollPos += 1 ; break ;
case SB_PAGEUP: iVscrollPos -= cyClient / cyChar ; break ;
case SB_PAGEDOWN: iVscrollPos += cyClient / cyChar ; break ;
case SB_THUMBPOSITION: iVscrollPos = HIWORD (wParam) ; break ;
default : break ; } iVscrollPos = max (0, min (iVscrollPos, NUMLINES-1)) ; if (iVscrollPos != GetScrollPos (hWnd, SB_VERT)) { SetScrollPos (hWnd, SB_VERT, iVscrollPos, TRUE) ; InvalidateRect (hWnd, NULL, TRUE) ; } break; 8. 按鈕控件的事件處理 同主窗口菜單一樣,在WM_COMMAND中處理按鈕控件的消息,代碼如下
case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_EXIT: DestroyWindow(hWnd); break;
case IDB_ONE: iVscrollPos++; //MessageBox(hWnd, "您點擊了第一個按鈕。", "提示", MB_OK | MB_ICONINFORMATION); break; case IDB_TWO: iVscrollPos--; //MessageBox(hWnd, "您點擊了第二個按鈕。", "提示", MB_OK |MB_ICONINFORMATION); break; case IDB_THREE: itoa(iVscrollPos, szList, 10); //SendMessage (hWndList, LB_RESETCONTENT, 0, 0) ; SendMessage (hWndList, LB_INSERTSTRING, -1, (LPARAM) szList) ; //MessageBox(hWnd, "這個按鈕沒有功能。", "提示", MB_OK |MB_ICONINFORMATION); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } 9. 向列表框和組合框中添加數據條目 向相應控件發送消息來向其中添加數據,代碼如下 //向列表框中添加數據 SendMessage (hWndList, LB_ADDSTRING, 0, (LPARAM) "我是列表框") ; //向組合框中添加數據 SendMessage(hWndComboBox,CB_ADDSTRING,0,(LPARAM)"我是組合框");
10.啟用、禁用窗口控件 使用EnableWindow()函數啟用與禁用窗口控件,具體代碼如下: case IDB_ENWIN: if(IsCbBoxEnable==true) { EnableWindow(hWndComboBox,false); IsCbBoxEnable=false; SetWindowText(GetDlgItem(hWnd,IDB_ENWIN),"啟用組合框->"); } else { EnableWindow(hWndComboBox,true); IsCbBoxEnable=true; SetWindowText(GetDlgItem(hWnd,IDB_ENWIN),"禁用組合框->"); } break; 11.調整控件位置與大小 使用MoveWindow()函數調整控件位置與大小,具體代碼如下: case IDB_MOVWIN: GetWindowRect(hWndComboBox, &CbBoxRECT); MoveWindow( hWndComboBox,750,CbBoxRECT.top,CbBoxRECT.right-CbBoxRECT.left+30, 400, true ); break; 12.控件文字的設置與獲取 使用GetWindowText()函數與SetWindowText()函數獲取與設置控件文字,具體代碼如下: case IDB_GETWINTEXT: TCHAR editString[MAX_LOADSTRING]; //GetWindowText(hWndEdit,editString,MAX_LOADSTRING); GetWindowText(hWndComboBox,editString,MAX_LOADSTRING); SetWindowText(GetDlgItem(hWnd,IDB_GETWINTEXT),editString); break; 13.銷毀控件 使用DestroyWindow()函數獲取與設置控件文字,具體代碼如下: case IDB_DESWIN: DestroyWindow(hWndComboBox); break;
14. 繪制窗口 在WM_PAINT中繪制窗口,通過改變視口坐標來達到滾動的效果,代碼如下 case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... RECT rt; GetClientRect(hWnd, &rt); SetMapMode(hdc,MM_ANISOTROPIC); SetViewportOrgEx(hdc,0,rt.bottom -iVscrollPos*5 ,NULL); DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); TextOut(hdc,300,500,szHello, strlen(szHello));
EndPaint(hWnd, &ps); break; 編譯並調試程序 |
程序運行結果運行結果如下圖:
程序運行初始狀態
操作滾動條或點擊按鈕使文字滾動,打開組合框
禁用組合框
啟用並移動組合框,改變組合框寬度
改變組合框文字,獲取組合框當前文字並顯示在按鈕上
銷毀組合框,再次獲取組合框文字,此時為空
本次只處理了垂直滾動條的事件響應,水平滾動條事件處理方式與此相同,操作重復,暫未做處理。 在Windows中,控件其實也是窗口,可以像處理窗口一樣處理控件。 做完本次實驗感覺Windows中使用純代碼創建控件的方式不是很方便,習慣了Windows在可視化環境下以所見即所得方式創建控件,win32這種方式實在是不適應。而且不能理解的是為什么win32對話框窗口中可以使用可視化方式創建控件,在主窗口中卻不能使用這種方式。 |