windows程序设计——子视窗控制项
来源:互联网 发布:c语言格式控制符 编辑:程序博客网 时间:2024/06/07 09:44
我们以一个窗口作为消息处理的主体,除了鼠标、键盘、定时器外,窗口中的子窗口发送的消息也可作为一种输入。当子窗口的自身处理消息,在必要时给父窗口发送消息,相当于父窗口的的高阶输入设备,这个称为"子视窗控制项"。常见的有:按钮、核取方块、编辑方块、清单方块、下拉式清单方块、字串标签和卷动列等,windows为这些基本项目都编写了默认的处理代码,我们只需要在主窗口中获取并处理(WM_COMMAND)消息就好了。
按钮是一类子视窗,使用方法如下:
/*---------------------------------------- BTNLOOK.C -- Button Look Program (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>//定义按钮的风格和文本信息结构,并初始化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 RECT rect ; static TCHAR szTop[] = TEXT ("message wParam lParam"), szUnd[] = TEXT ("_______ ______ ______"), szFormat[] = TEXT ("%-16s%04X-%04X %04X-%04X"), szBuffer[50] ; static int cxChar, cyChar ; HDC hdc ; PAINTSTRUCT ps ; int i ; switch (message) { case WM_CREATE : //创建窗口的时候建立子窗体(各种风格的按钮) // 获取字体大小,函数GetDialogBaseUnits只在对话框中起作用正常窗体还用的GetTextMetrics cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; //创建按钮 for (i = 0 ; i < NUM ; 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, //子视窗ID ((LPCREATESTRUCT) lParam)->hInstance, //程序句柄 NULL) ; return 0 ; case WM_SIZE : //窗口大小改变 //设置文字输出区域 rect.left = 24 * cxChar ; rect.top = 2 * cyChar ; rect.right = LOWORD (lParam) ; rect.bottom = HIWORD (lParam) ; return 0 ; case WM_PAINT : //绘图输出消息列表的表头 InvalidateRect (hwnd, &rect, TRUE) ; hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; SetBkMode (hdc, TRANSPARENT) ; TextOut (hdc, 24 * cxChar, cyChar, szTop, lstrlen (szTop)) ; TextOut (hdc, 24 * cxChar, cyChar, szUnd, lstrlen (szUnd)) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DRAWITEM : //子窗口自绘消息 case WM_COMMAND : //响应子视窗消息 //令窗口在rect中向上滚动cyChar ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ; //获取dc,并选入SYSTEM_FIXED_FONT字体 hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; //在最后一行输出消息类型和参数 TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1), szBuffer, wsprintf (szBuffer, szFormat, message == WM_DRAWITEM ? TEXT ("WM_DRAWITEM") : TEXT ("WM_COMMAND"), HIWORD (wParam), LOWORD (wParam), HIWORD (lParam), LOWORD (lParam))) ; //释放DC,并刷新界面 ReleaseDC (hwnd, hdc) ; ValidateRect (hwnd, &rect) ; break ; case WM_DESTROY : //销毁窗口 PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}子视窗想父窗口发送WM_COMMAND消息,结果如下:
通知码说明如下:
而父窗口也可以向子窗口发送信息,来控制或获得子窗口,消息如下:
父窗口中通常使用下列方法来控制子窗口:
//通过句柄获取idid = GetWindowLong (hwndChild, GWL_ID) ;id = GetDlgCtrlID (hwndChild) ;//通过id获取句柄hwndChild = GetDlgItem (hwndParent, id) ;//模拟按下按钮和不再按下SendMessage (hwndButton, BM_SETSTATE, 1, 0) ;SendMessage (hwndButton, BM_SETSTATE, 0, 0) ;//发送选中和不再选中信息(单选,复选)SendMessage (hwndButton, BM_SETCHECK, 1, 0) ;SendMessage (hwndButton, BM_SETCHECK, 0, 0) ;//获取是否选中iCheck = (int) SendMessage (hwndButton, BM_GETCHECK, 0, 0) ;//获得和设置子窗口的文本信息SetWindowText (hwnd, pszString) ;iLength = GetWindowText (hwnd, pszBuffer, iMaxLength) ;iLength = GetWindowTextLength (hwnd) ;//设置和获得是否可见ShowWindow (hwndChild, SW_SHOWNORMAL) ;ShowWindow (hwndChild, SW_HIDE) ;IsWindowVisible (hwndChild) ;//设置和获得是否可用EnableWindow (hwndChild, FALSE) ;EnableWindow (hwndChild, TRUE) ;IsWindowEnabled (hwndChild) ;//设置焦点SetFocus (hwnd) ;//设置背景和文字颜色SetBkColor (hdc, GetSysColor (COLOR_BTNFACE)) ;SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;虽然没什么用处但是可以通过响应WM_CTLCOLORBTN消息来改变背景和文字的颜色,更通常的做法是使用BS_OWNERDRAW风格的按钮在drawitem中自己绘制:
/*--------------------------------------------- OWNDRAW.C -- Owner-Draw Button Demo Program (c) Charles Petzold, 1998 ---------------------------------------------*/#include <windows.h>//定义两个窗口ID#define ID_SMALLER 1#define ID_LARGER 2//按钮宽高为字体的宽高8倍和4倍#define BTN_WIDTH (8 * cxChar)#define BTN_HEIGHT (4 * cyChar)LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;HINSTANCE hInst ;//建立框架int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("OwnDraw") ; MSG msg ; HWND hwnd ; WNDCLASS wndclass ; hInst = hInstance ; 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 = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Owner-Draw Button Demo"), 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 ;}//画黑色三角形void Triangle (HDC hdc, POINT pt[]){ SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ; Polygon (hdc, pt, 3) ; SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HWND hwndSmaller, hwndLarger ; static int cxClient, cyClient, cxChar, cyChar ; int cx, cy ; LPDRAWITEMSTRUCT pdis ; POINT pt[3] ; RECT rc ; switch (message) { case WM_CREATE : //字体宽高 cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; // 创建两个BS_OWNERDRAW风格的按钮 hwndSmaller = CreateWindow (TEXT ("button"), TEXT (""), WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 0, 0, BTN_WIDTH, BTN_HEIGHT, hwnd, (HMENU) ID_SMALLER, hInst, NULL) ; hwndLarger = CreateWindow (TEXT ("button"), TEXT (""), WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 0, 0, BTN_WIDTH, BTN_HEIGHT, hwnd, (HMENU) ID_LARGER, hInst, NULL) ; return 0 ; case WM_SIZE : //获取窗体大小 cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; // 把按钮设置到最中心 MoveWindow (hwndSmaller, cxClient / 2 - 3 * BTN_WIDTH / 2, cyClient / 2 - BTN_HEIGHT / 2, BTN_WIDTH, BTN_HEIGHT, TRUE) ; MoveWindow (hwndLarger, cxClient / 2 + BTN_WIDTH / 2, cyClient / 2 - BTN_HEIGHT / 2, BTN_WIDTH, BTN_HEIGHT, TRUE) ; return 0 ; case WM_COMMAND : GetWindowRect (hwnd, &rc) ; // 判断点击的是那个窗口来决定放大还是缩小 switch (wParam) { case ID_SMALLER : rc.left += cxClient / 20 ; rc.right -= cxClient / 20 ; rc.top += cyClient / 20 ; rc.bottom -= cyClient / 20 ; break ; case ID_LARGER : rc.left -= cxClient / 20 ; rc.right += cxClient / 20 ; rc.top -= cyClient / 20 ; rc.bottom += cyClient / 20 ; break ; } //改变窗口大小 MoveWindow (hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE) ; return 0 ; case WM_DRAWITEM : //BS_OWNERDRAW风格的自绘消息 pdis = (LPDRAWITEMSTRUCT) lParam ; //填充背景和画边框 FillRect (pdis->hDC, &pdis->rcItem, (HBRUSH) GetStockObject (WHITE_BRUSH)) ; FrameRect (pdis->hDC, &pdis->rcItem, (HBRUSH) GetStockObject (BLACK_BRUSH)) ; //获取子窗口的宽度 cx = pdis->rcItem.right - pdis->rcItem.left ; cy = pdis->rcItem.bottom - pdis->rcItem.top ; switch (pdis->CtlID) { case ID_SMALLER : //若是缩小按钮 pt[0].x = 3 * cx / 8 ; pt[0].y = 1 * cy / 8 ; pt[1].x = 5 * cx / 8 ; pt[1].y = 1 * cy / 8 ; pt[2].x = 4 * cx / 8 ; pt[2].y = 3 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 7 * cx / 8 ; pt[0].y = 3 * cy / 8 ; pt[1].x = 7 * cx / 8 ; pt[1].y = 5 * cy / 8 ; pt[2].x = 5 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 5 * cx / 8 ; pt[0].y = 7 * cy / 8 ; pt[1].x = 3 * cx / 8 ; pt[1].y = 7 * cy / 8 ; pt[2].x = 4 * cx / 8 ; pt[2].y = 5 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 1 * cx / 8 ; pt[0].y = 5 * cy / 8 ; pt[1].x = 1 * cx / 8 ; pt[1].y = 3 * cy / 8 ; pt[2].x = 3 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC, pt) ; break ; case ID_LARGER : //若是放大按钮 pt[0].x = 5 * cx / 8 ; pt[0].y = 3 * cy / 8 ; pt[1].x = 3 * cx / 8 ; pt[1].y = 3 * cy / 8 ; pt[2].x = 4 * cx / 8 ; pt[2].y = 1 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 5 * cx / 8 ; pt[0].y = 5 * cy / 8 ; pt[1].x = 5 * cx / 8 ; pt[1].y = 3 * cy / 8 ; pt[2].x = 7 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 3 * cx / 8 ; pt[0].y = 5 * cy / 8 ; pt[1].x = 5 * cx / 8 ; pt[1].y = 5 * cy / 8 ; pt[2].x = 4 * cx / 8 ; pt[2].y = 7 * cy / 8 ; Triangle (pdis->hDC, pt) ; pt[0].x = 3 * cx / 8 ; pt[0].y = 3 * cy / 8 ; pt[1].x = 3 * cx / 8 ; pt[1].y = 5 * cy / 8 ; pt[2].x = 1 * cx / 8 ; pt[2].y = 4 * cy / 8 ; Triangle (pdis->hDC, pt) ; break ; } // Invert the rectangle if the button is selected //判断是否按下,若按下则整个按钮设为反色 if (pdis->itemState & ODS_SELECTED) InvertRect (pdis->hDC, &pdis->rcItem) ; // Draw a focus rectangle if the button has the focus // 判断是否有焦点,若有焦点则画焦点矩形 if (pdis->itemState & ODS_FOCUS) { pdis->rcItem.left += cx / 16 ; pdis->rcItem.top += cy / 16 ; pdis->rcItem.right -= cx / 16 ; pdis->rcItem.bottom -= cy / 16 ; DrawFocusRect (pdis->hDC, &pdis->rcItem) ; } return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}除了自绘还可以通过SetWindowLong函数来子类化对象:
/*---------------------------------------- COLORS1.C -- Colors Using Scroll Bars (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>//声明窗口处理函数和滚动条消息的处理函数LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;LRESULT CALLBACK ScrollProc (HWND, UINT, WPARAM, LPARAM) ;//被设为焦点的子窗id,和原先的滚动条回调函数int idFocus ;WNDPROC OldScroll[3] ;//建立框架int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("Colors1") ; 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, TEXT ("Color Scroll"), 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 COLORREF crPrim[3] = { RGB (255, 0, 0), RGB (0, 255, 0), RGB (0, 0, 255) } ; //三原色 static HBRUSH hBrush[3], hBrushStatic ; //三个画刷 static HWND hwndScroll[3], hwndLabel[3], hwndValue[3], hwndRect ; //滚动条,title,值,方块的子窗口句柄 static int color[3], cyChar ; static RECT rcColor ; static TCHAR * szColorLabel[] = { TEXT ("Red"), TEXT ("Green"), TEXT ("Blue") } ; HINSTANCE hInstance ; int i, cxClient, cyClient ; TCHAR szBuffer[10] ; switch (message) { case WM_CREATE : //创建窗口 hInstance = (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE) ; // Create the white-rectangle window against which the // scroll bars will be positioned. The child window ID is 9. //创建一个SS_WHITERECT空白的static子窗口 hwndRect = CreateWindow (TEXT ("static"), NULL, WS_CHILD | WS_VISIBLE | SS_WHITERECT, 0, 0, 0, 0, hwnd, (HMENU) 9, hInstance, NULL) ; for (i = 0 ; i < 3 ; i++) { // The three scroll bars have IDs 0, 1, and 2, with // scroll bar ranges from 0 through 255. //创建三个SBS_VERT竖立的滚动条 hwndScroll[i] = CreateWindow (TEXT ("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_VERT, 0, 0, 0, 0, hwnd, (HMENU) i, hInstance, NULL) ; //设置范围和初始值 SetScrollRange (hwndScroll[i], SB_CTL, 0, 255, FALSE) ; SetScrollPos (hwndScroll[i], SB_CTL, 0, FALSE) ; // The three color-name labels have IDs 3, 4, and 5, // and text strings "Red", "Green", and "Blue". //创建三个static子控件作为说明 hwndLabel [i] = CreateWindow (TEXT ("static"), szColorLabel[i], WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU) (i + 3), hInstance, NULL) ; // The three color-value text fields have IDs 6, 7, // and 8, and initial text strings of "0". //创建三个static显示各自滚动条所表示的RGB值 hwndValue [i] = CreateWindow (TEXT ("static"), TEXT ("0"), WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU) (i + 6), hInstance, NULL) ; //将滚动条的处理函数设置为ScrollProc,并将原先的处理函数保存到OldScroll中 OldScroll[i] = (WNDPROC) SetWindowLong (hwndScroll[i], GWL_WNDPROC, (LONG) ScrollProc) ; //创建三个原色的画刷 hBrush[i] = CreateSolidBrush (crPrim[i]) ; } //创建画刷 hBrushStatic = CreateSolidBrush ( GetSysColor (COLOR_BTNHIGHLIGHT)) ; //字体高度 cyChar = HIWORD (GetDialogBaseUnits ()) ; return 0 ; case WM_SIZE : //窗口大小改变时重设子控件位置 cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; SetRect (&rcColor, cxClient / 2, 0, cxClient, cyClient) ; MoveWindow (hwndRect, 0, 0, cxClient / 2, cyClient, TRUE) ; for (i = 0 ; i < 3 ; i++) { MoveWindow (hwndScroll[i], (2 * i + 1) * cxClient / 14, 2 * cyChar, cxClient / 14, cyClient - 4 * cyChar, TRUE) ; MoveWindow (hwndLabel[i], (4 * i + 1) * cxClient / 28, cyChar / 2, cxClient / 7, cyChar, TRUE) ; MoveWindow (hwndValue[i], (4 * i + 1) * cxClient / 28, cyClient - 3 * cyChar / 2, cxClient / 7, cyChar, TRUE) ; } SetFocus (hwnd) ; return 0 ; case WM_SETFOCUS ://将焦点设置为某个滚动条 SetFocus (hwndScroll[idFocus]) ; return 0 ; case WM_VSCROLL : //当滚动条滚动时 //获取子控件id i = GetWindowLong ((HWND) lParam, GWL_ID) ; //计算滚动条的值 switch (LOWORD (wParam)) { case SB_PAGEDOWN : color[i] += 15 ; // fall through case SB_LINEDOWN : color[i] = min (255, color[i] + 1) ; break ; case SB_PAGEUP : color[i] -= 15 ; // fall through case SB_LINEUP : color[i] = max (0, color[i] - 1) ; break ; case SB_TOP : color[i] = 0 ; break ; case SB_BOTTOM : color[i] = 255 ; break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : color[i] = HIWORD (wParam) ; break ; default : break ; } //设置滚动条位置,并设置static的文本信息 SetScrollPos (hwndScroll[i], SB_CTL, color[i], TRUE) ; wsprintf (szBuffer, TEXT ("%i"), color[i]) ; SetWindowText (hwndValue[i], szBuffer) ; //重设方块的背景画刷 DeleteObject ((HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) CreateSolidBrush (RGB (color[0], color[1], color[2])))) ; InvalidateRect (hwnd, &rcColor, TRUE) ; return 0 ; case WM_CTLCOLORSCROLLBAR : //画滚动条时返回滚动条的背景画刷 i = GetWindowLong ((HWND) lParam, GWL_ID) ; return (LRESULT) hBrush[i] ; case WM_CTLCOLORSTATIC : //标题和值static控件的文本和背景颜色 i = GetWindowLong ((HWND) lParam, GWL_ID) ; if (i >= 3 && i <= 8) // static text controls { SetTextColor ((HDC) wParam, crPrim[i % 3]) ; SetBkColor ((HDC) wParam, GetSysColor (COLOR_BTNHIGHLIGHT)); return (LRESULT) hBrushStatic ; } break ; case WM_SYSCOLORCHANGE : //系统颜色更改时 DeleteObject (hBrushStatic) ; hBrushStatic = CreateSolidBrush (GetSysColor (COLOR_BTNHIGHLIGHT)) ; return 0 ; case WM_DESTROY : //窗口销毁时清理创建的object DeleteObject ((HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) GetStockObject (WHITE_BRUSH))) ; for (i = 0 ; i < 3 ; i++) DeleteObject (hBrush[i]) ; DeleteObject (hBrushStatic) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;} LRESULT CALLBACK ScrollProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ int id = GetWindowLong (hwnd, GWL_ID) ; //通过键盘来改变焦点 switch (message) { case WM_KEYDOWN : if (wParam == VK_TAB) SetFocus (GetDlgItem (GetParent (hwnd), (id + (GetKeyState (VK_SHIFT) < 0 ? 2 : 1)) % 3)) ; break ; case WM_SETFOCUS : idFocus = id ; break ; } return CallWindowProc (OldScroll[id], hwnd, message, wParam, lParam) ;}与static子窗口不同,edit是可以让用户编辑文本信息的控件。edit给父窗口的控件发送的消息说明如下:
而父窗口通过如下接口控制edit:
//剪切,复制,删除,黏贴SendMessage (hwndEdit, WM_CUT, 0, 0) ;SendMessage (hwndEdit, WM_COPY, 0, 0) ;SendMessage (hwndEdit, WM_CLEAR, 0, 0) ;SendMessage (hwndEdit, WM_PASTE, 0, 0) ;//获取和设置选择区域SendMessage (hwndEdit, EM_GETSEL, (WPARAM) &iStart, (LPARAM) &iEnd) ;SendMessage (hwndEdit, EM_SETSEL, iStart, iEnd) ;//替换文字SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) szString) ;//取得行数iCount = SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0) ;//取得光标对于行头的编译量iOffset = SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0) ;//取得当前行的长度iLength = SendMessage (hwndEdit, EM_LINELENGTH, iLine, 0) ;//取得获取当前行到缓冲区iLength = SendMessage (hwndEdit, EM_GETLINE, iLine, (LPARAM) szBuffer) ;listbox也是一个常用的控件:
/*---------------------------------------- ENVIRON.C -- Environment List Box (c) Charles Petzold, 1998 ----------------------------------------*/#include <windows.h>#define ID_LIST 1#define ID_TEXT 2LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;//主函数建立框架int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("Environ") ; 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) (COLOR_WINDOW + 1) ; 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 ("Environment List Box"), 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 ;}//填充listboxvoid FillListBox (HWND hwndList) { int iLength ; TCHAR * pVarBlock, * pVarBeg, * pVarEnd, * pVarName ; // 获取环境变量 pVarBlock = GetEnvironmentStrings () ; // Get pointer to environment block // 拆分字符串 while (*pVarBlock) { if (*pVarBlock != '=') // Skip variable names beginning with '=' { pVarBeg = pVarBlock ; // Beginning of variable name while (*pVarBlock++ != '=') ; // Scan until '=' pVarEnd = pVarBlock - 1 ; // Points to '=' sign iLength = pVarEnd - pVarBeg ; // Length of variable name // Allocate memory for the variable name and terminating // zero. Copy the variable name and append a zero. pVarName = calloc (iLength + 1, sizeof (TCHAR)) ; CopyMemory (pVarName, pVarBeg, iLength * sizeof (TCHAR)) ; pVarName[iLength] = '\0' ; // Put the variable name in the list box and free memory. // 添加到listbox中 SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) pVarName) ; free (pVarName) ; } while (*pVarBlock++ != '\0') ; // Scan until terminating zero } FreeEnvironmentStrings (pVarBlock) ;}LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HWND hwndList, hwndText ; int iIndex, iLength, cxChar, cyChar ; TCHAR * pVarName, * pVarValue ; switch (message) { case WM_CREATE : cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; // Create listbox and static text windows. hwndList = CreateWindow (TEXT ("listbox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD, cxChar, cyChar * 3, cxChar * 16 + GetSystemMetrics (SM_CXVSCROLL), cyChar * 5, hwnd, (HMENU) ID_LIST, (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ; hwndText = CreateWindow (TEXT ("static"), NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, cxChar, cyChar, GetSystemMetrics (SM_CXSCREEN), cyChar, hwnd, (HMENU) ID_TEXT, (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ; //填充listbox FillListBox (hwndList) ; return 0 ; case WM_SETFOCUS : SetFocus (hwndList) ; return 0 ; case WM_COMMAND : if (LOWORD (wParam) == ID_LIST && HIWORD (wParam) == LBN_SELCHANGE) { // Get current selection. // 获取选中行,选中行的文本长度,根据长度申请内存,获取选中行的文本 iIndex = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ; iLength = SendMessage (hwndList, LB_GETTEXTLEN, iIndex, 0) + 1 ; pVarName = calloc (iLength, sizeof (TCHAR)) ; SendMessage (hwndList, LB_GETTEXT, iIndex, (LPARAM) pVarName) ; // Get environment string. // 获取环境变量内容 iLength = GetEnvironmentVariable (pVarName, NULL, 0) ; pVarValue = calloc (iLength, sizeof (TCHAR)) ; GetEnvironmentVariable (pVarName, pVarValue, iLength) ; // Show it in window. SetWindowText (hwndText, pVarValue) ; free (pVarName) ; free (pVarValue) ; } return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
阅读全文
0 0
- windows程序设计——子视窗控制项
- windows程序设计——视窗和讯息
- Windows程式开发设计指南(九)子视窗控制项
- WINDOWS程序设计示例:创建视窗
- 9a 子视窗控制项--按钮类别
- 基于Visual C#的Windows API 程序设计——控制你的Windows系统
- 子窗口控件 -windows程序设计
- 子窗口控件 -windows程序设计
- 子窗口控件 -windows程序设计
- Windows程序设计-子窗口控件
- Python初学——窗口视窗Tkinter
- Python初学——窗口视窗Tkinter
- 《Windows程序设计》——字符集
- windows程序设计——CreateProcess()
- Windows程序设计——GetObject
- windows程序设计——键盘
- windows程序设计——鼠标
- windows程序设计——计时器
- WEB分页打印和打印模式的页边距缩放
- ES学习笔记(1)---部署篇
- YaMi美食项目感想
- Google关于大数据的三篇著名论文 中文版
- 对Java中线程安全Synchronized的深入理解和运用
- windows程序设计——子视窗控制项
- windows下配置python的easyGUI
- Autotools基本使用
- maven详细安装配置入门教程
- vue2整个项目中,数据请求显示loading图
- web项目通过Session监听器控制在线人数以及同一用户异地登陆限制
- d3饼状图布局
- uva题目笔记——字符串
- linux下view编辑文件时Found a swap file by the name