标签:
9.4.1 滚动条控件
(1)窗口滚动条与滚动条控件的比较
|
窗口滚动条 |
滚动条控件 |
消息 |
发送WM_VSCROLL、WM_HSCROLL消息。不发送WM_COMMAND消息。wParam参数的意义是一样的。lParam:当消息来自窗口滚动条时为NULL,来自滚动条控件时为滚动条的句柄。 |
|
宽度或高度 |
固定大小 //水平滚动条高度 GetSysMetrics(SM_CYHSCROLL); //垂直滚动条宽度 GetSysMetrics(SM_CYVSCROLL) |
1、大小、位置均可设定; 2、在CreateWindow或MoveWindow函数中指定,大小可自定义。 |
窗口样式 |
WS_VSCROLL:垂直滚动条(在窗口右侧) WS_HSCROLL:水平滚动条(在窗口下方) |
可用滚动条样式和尺寸 SBS_VERT、SBS_HORZ、 S SBS_TOPALIGN、 BS_BOTTOMALIGN、SBS_LEFTALIGN、SBS_RIGHTALIGN等。 |
调用函数 的参数 |
SetScrollInfo(hwnd,SB_VERT, &si,bRedraw); |
SetScrollInfo(hwndScroll,SB_CTL, &si,bRedraw); |
(2)滚动条的颜色
①滚动条两端的按钮及滑块:COLOR_BTNFACE、COLOR_BTNHILIGHT、COLOR_BTNSHADOW、COLOR_BTNTEXT(给小箭头用)、COLOR_DKSHADOW及COLOR_BTNLIGHT
②两端按钮之间的大片区域:COLOR_BTNFACE、COLOR_BTNHIGHLIGHT的某种组合。
9.4.2 COLORS1程序
(1)窗口子类化
①用自定义窗口过程(ScrollProc)替换Windows的内部窗口过程
OldScroll[i]=(WNDPROC)SetWindowLong(hwndScroll[i], GWL_WNDPROC, (LONG)ScrollProc);
②调用旧的滚动条窗口过程
CallWindowProc(OldScroll[id],hwnd, message, wParam, lParam);
(2)主窗口背景着色
①准备好背景画刷:新建画刷→存入窗口类结构→删除旧画刷
DeleteObject((HBRUSH)
SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG)
CreateSolidBrush(RGB(color[0],color[1], color[2]))));
②终止程序时清除画刷
DeleteObject((HBRUSH)
SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG)GetStockObject(WHITE_BRUSH)));
(3)滚动条和静态文本着色
①3个滚动条背景色:hBrush[i] = CreateSolidBrush(crPrim[i]);
②在WM_CTLCOLORSCROLLBAR中return (LRESULT)hBrush[i],返回画刷,即可着色。
③静态文本在WM_CTLCOLORSTATIC中通过SetBkColor和SetTextColor为文本着色。
【Color1程序】
/*------------------------------------------------------------ COLORS1.C -- Colors Using Scroll Bars (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT ScrollProc(HWND, UINT, WPARAM, LPARAM); int idFocus; //当前选中的滚动条 WNDPROC OldScroll[3]; //原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 = (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, // window class name TEXT("Color Scroll1"), // window caption WS_OVERLAPPEDWINDOW, // 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 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; static TCHAR* szColorLabel[] = { TEXT("Red"), TEXT("Green"), TEXT("Blue") }; TCHAR szBuffer[10]; static int cxChar, cyChar; HINSTANCE hInstance; static RECT rcColor; static int color[3]; //三个滚动条当前的颜色值 int i, cxClient, cyClient; switch (message) { case WM_CREATE: //hInstance = ((LPCREATESTRUCT)lParam)->hInstance; hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE); //创建一个白色矩形区,用来放置控件,窗口ID为9. hwndRect = CreateWindow(TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_WHITERECT, 0, 0, 0, 0, hwnd, (HMENU)9, hInstance, NULL); for (int i = 0; i< 3; i++) { //创建三个滚动条,范围0-255,ID分别为0,1.2 hwndScroll[i] = CreateWindow(TEXT("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_VERT, //垂直,可接受Tab键 0, 0, 0, 0, hwnd, (HMENU)i, hInstance, NULL); SetScrollRange(hwndScroll[i], SB_CTL, 0, 255, FALSE); SetScrollPos(hwndScroll[i], SB_CTL, 0, FALSE); //3个颜色名称为"Red"、"Green"、"Blue"的标签,ID分别为3,4,5 hwndLabel[i] = CreateWindow(TEXT("static"), szColorLabel[i], WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU)(i + 3), hInstance, NULL); //3种颜色值的标签,ID分别为6,7,8 hwndValue[i] = CreateWindow(TEXT("static"), TEXT("0"), WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU)(i + 6), hInstance, NULL); //3个滚动条的背景画刷 hBrush[i] = CreateSolidBrush(crPrim[i]); OldScroll[i] = (WNDPROC)SetWindowLong(hwndScroll[i], GWL_WNDPROC, (LONG)ScrollProc); } hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT)); cxChar = LOWORD(GetDialogBaseUnits()); 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 (int i = 0; i < 3; i++) { //设置滚动条在主窗口大小和位置:宽cxClient/14,高cyClient -4*cyChar; MoveWindow(hwndScroll[i], (2 * i + 1)*cxClient / 14, 2 * cyChar, cxClient / 14, cyClient - 4 * cyChar, TRUE); MoveWindow(hwndLabel[i], (2 * i + 1)*cxClient / 14, cyChar / 2, cxClient / 14, cyChar, TRUE); MoveWindow(hwndValue[i], (2 * i + 1)*cxClient / 14, cyClient - 3 * cyChar / 2, cxClient / 14, cyChar, TRUE); } SetFocus(hwnd); return 0; case WM_VSCROLL: //获取子窗口ID i = GetWindowLong((HWND)lParam, GWL_ID); switch (LOWORD(wParam)) { case SB_PAGEDOWN: //每次增长16; color[i] += 16; break; case SB_PAGEUP: color[i] -= 16; break; case SB_LINEDOWN: color[i] += 1; break; case SB_LINEUP: 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; } color[i] = max(0, min(255, color[i])); SetScrollPos(hwndScroll[i], SB_CTL, color[i], TRUE); wsprintf(szBuffer, TEXT("%i"), color[i]); //%i与%d相同 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: //wParam:DC,lParam:滚动条句柄 i = GetWindowLong((HWND)lParam, GWL_ID); return (LRESULT)hBrush[i]; //须返回画刷句柄 case WM_CTLCOLORSTATIC://wParam:DC,lParam:静态类文本的句柄 i = GetWindowLong((HWND)lParam, GWL_ID); if (i >= 3 && i <= 8) { SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNHIGHLIGHT)); SetTextColor((HDC)wParam, crPrim[i % 3]); return (LRESULT)hBrushStatic; } break; case WM_SYSCOLORCHANGE: DeleteObject(hBrushStatic); hBrushStatic = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT)); return 0; case WM_SETFOCUS: SetFocus(hwndScroll[idFocus]); return 0; case WM_DESTROY: //将主窗口画刷设为白色 DeleteObject((HBRUSH) SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(WHITE_BRUSH))); DeleteObject(hBrushStatic); for (int i = 0; i < 3; i++) DeleteObject(hBrush[i]); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } //窗口子类化 LRESULT ScrollProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int id = GetWindowLong(hwnd, GWL_ID);//获子窗口ID switch (message) { case WM_KEYDOWN: if (wParam == VK_TAB) { SetFocus(GetDlgItem(GetParent(hwnd), (id + 1) % 3)); } break; case WM_SETFOCUS: idFocus = id; break; } //调用子窗口旧的窗口过程 return CallWindowProc(OldScroll[id], hwnd, message, wParam, lParam); }
9.5.1 编辑类的样式
样式 |
说明 |
ES_LEFT |
文本对齐方式 |
ES_RIGHT |
|
ES_CENTER |
|
ES_MULTILINE |
多行编辑控件 |
ES_AUTOHSCROLL |
默认会自动文本,加这后不会自动换行,要按回车键。 |
ES_AUTOVSCROLL |
垂直滚动条 |
ES_NOHIDESEL |
失去焦,选中时仍高亮显示 |
9.5.2 编辑控件的通知消息:WM_COMMAND
参数 |
含义 |
|
lParam |
子窗口句柄 |
|
wParam |
LOWORD(wParam):子窗口ID |
|
HIWORD(wParam):通知码 |
EN_SETFOCUS:得到焦点 EN_KILLFOCUS:失去焦点 EN_CHANGE: 内容改变 EN_UPDATE: 内容己变化 EN_ERRSPACE: 没有空间了 EN_MAXTEXT: 输入超过最大长度 EN_HSCROLL: 水平滚动条被单击 EN_VSCROLL: 垂直滚动条被单击 |
9.5.3 使用编辑控件
①SetWindowText:输入文本
②GetWindowText:读取文本
③GetWindowTextLength:获得文本长度
9.5.4 传递消息给编辑控件
操作 |
消息 |
复制、剪切、 清除、粘贴 |
SendMessage(hwndEdit,WM_COPY,0,0); SendMessage(hwndEdit,WM_CUT,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); |
获得行数 |
iCount = SendMessage(hwndEdit,EM_LINECOUNT,0,0); |
编辑缓冲区起点到指定行的位移量 |
iOffset = SendMessage(hwndEdit,EM_LINELENGTH,iLine,0); //如果iLine =-1,则返回插入符号所在行的位移量。 |
获到某行的长度 |
iLength = SendMessage(hwndEdit,EM_LINELENGTH,iLine,0); |
复制一行到缓冲区 |
iLength = SendMessage(hwndEdit,EM_GETLINE,iLine,(LPARAM)szBuffer |
【PopPad1程序】
/*------------------------------------------------------------ POPPAD1.C -- Popup Editor using child window edit box (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #define ID_EDIT 1 static TCHAR szAppName[] = TEXT("PopPad1"); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { 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, // window class name TEXT("edit"), // window caption WS_OVERLAPPEDWINDOW, // 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 hwndEdit; switch (message) { case WM_CREATE: hwndEdit = CreateWindow(TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, (HMENU)ID_EDIT, ((LPCREATESTRUCT)lParam)->hInstance, NULL); return 0; case WM_SETFOCUS: SetFocus(hwndEdit); return 0; case WM_COMMAND: if (LOWORD(wParam) == ID_EDIT) { if (HIWORD(wParam) == EN_ERRSPACE || HIWORD(wParam) == EN_MAXTEXT) { MessageBox(hwnd, TEXT("Edit Control out of space."), szAppName, MB_OK | MB_ICONSTOP); } } return 0; case WM_SIZE: MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
键盘操作 |
单选列表框 |
多选列表框 |
空格键 |
选择光标所在项 |
切换选中状态 |
方向键 |
移动光标和当前的选择 |
取消以前所选,并移动光标和选中项 |
翻页键 |
移动光标,但不移动选择项 |
|
字母键 |
移动和选择以该字母开头的第一项 |
|
Ctrl+方向 |
移动光标,但不移动选中项 |
|
Shift+方向 |
|
扩展选中项 |
9.6.1 列表框的样式
样式 |
含义 |
LBS_NOTIFY |
默认的列表框样式不能发送WM_COMMAND到父窗口,须指定该样式才行 |
LBS_SORT |
排序 |
LBS_MULTIPLESEL |
多选 |
LBS_NOREDRAW |
新增项目默认不会自我更新,可在WM_SETREDRAW中设置 |
LBS_STANDARD |
标准列表框:LBS_NOTIFY|LBS_SORT|WS_VSCROLL|WS_BORDER |
★设定列表框的宽度:最长字符串长度+滚动条的宽度
★设定列表框的高度:1个字符的高度*视图中项目的数量
9.6.2 向列表框中添加字符串
操作 |
SendMessage: 返回值——LB_ERRSPACE或LB_ERR或LB_OKAY |
在列表框最后增加一项 |
(hwndList,LB_ADDSTRING,0,(LPARAM)szString); //如果LBS_SORT则会插到顺序后相应的位置。 |
插入到指定位置 |
hwndList,LB_INSERTSTRING,iIndex,(LPARAM)szString) //当iIndex=-1时,会被添加到最底部。 |
删除索引位置处的一个字符串 |
(hwndList,LB_DELETESTRING,iIndex,0); |
清除所有项目 |
(hwndList,LB_RESETCONTENT,iIndex,0); |
开关控件重绘标志 |
(hwndList,WM_SETREDRAW,FALSE,0); (hwndList,WM_SETREDRAW,TRUE,0); |
9.6.3 项目的选择和提取
(1)获取列表框项目数量:iCount=SendMessage(hwndList,LB_GETCOUNT,0,0)
(1)单选列表框
单选列表框操作 |
相应代码 |
突出选择某项 |
SendMessage(hwndList,LB_SETCURSEL,iIndex,0); //lParam为-1时,取消选中所有项 |
根据起始字符选择一项 |
SendMessage(hwndList,LB_SELECTSTRING,iIndex, (LPARAM)szSerchString); //如果参数iIndex=-1,那么从顶端开始查找。 //返回值:被选中的索引或没有匹配时为LB_ERR |
获取当前选中项的索引 |
iIndex = SendMessage(hwndList,LB_GETCURSEL,0,0) |
获取某项字符串长度 |
iLength = SendMessage(hwndList,LB_GETTEXTLEN,iIndex,0) |
读取项目到缓冲区 |
iLength =SendMessage(hwndList,LB_GETTEXT,iIndex, (LPARAM)szBuffer); |
(3)多选列表框(不能使用LB_SETCURSEL,LB_GETCURSEL或LB_SELECTSTRING)
操作 |
相应代码 |
设置某项选择状态 (不影响其他项) |
SendMessage(hwndList,LB_SETSEL,wParam,iIndex); //wParam非零时,选中并高亮该项,为0时取消选择 //lParam是-1时,在选择和取消所有项之间切换 |
检查选择状态 |
iSelect = SendMessage(hwndList,LB_GETSEL,iIndex,0); //iSelect非零,表示选中。为零时,未选中 |
9.6.4 接收来自列表框的消息
参数 |
含义 |
|
lParam |
子窗口句柄 |
|
wParam |
LOWORD(wParam):子窗口ID |
|
HIWORD(wParam):通知码 |
LBN_ERRSPACE: 空间不够 LBN_SELCHANGE:当前选择发生变化 LBN_DBLCLK: 双击 LBN_SELCANCEL:取消选择 LBN_SETFOCUS: 得到焦点 LBN_KILLFOCUS:失去焦点 |
【ENVIRON.C程序】
(1)环境变量格式
(2)获取和释放环境变量块GetEnvironmentStrings、FreeEnvironmentStrings
(3)获取环境变量 GetEnvironmentVariable
效果图:
/*------------------------------------------------------------ ENVIRON.C -- Environment List Box (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #define ID_LIST 1 #define ID_TEXT 2 LRESULT 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, // window class name TEXT("Environment List Box"), // window caption WS_OVERLAPPEDWINDOW, // 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; } void FillListBox(HWND hwndList) { TCHAR *pVarBlock, *pVarCurr, *pVarBeg, *pVarEnd, *pVarName; int iLength; //获得环境变量的指针 pVarCurr = pVarBlock = GetEnvironmentStrings(); while (*pVarCurr) { if (*pVarCurr != ‘=‘) //跳过无意义的“=::=::\”或"=E:=E:\ABC\"格式的字符串 { pVarBeg = pVarCurr; //变量名的开始位置。注意环境变量的格式varName=value while (*pVarCurr++ != ‘=‘); //扫描到‘=’号 pVarEnd = pVarCurr - 1; //pVarCurr指向‘=‘号 iLength = pVarEnd - pVarBeg; //变量名的长度 //分配内存给变量名 pVarName = calloc(iLength + 1, sizeof(TCHAR)); //变量名加个‘\0‘结束,所以iLength+1 CopyMemory(pVarName, pVarBeg, iLength*sizeof(TCHAR)); pVarName[iLength] = ‘\0‘; //变量名以‘\0‘结束 //将变量名加入到列表框中,并释放内存 SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)pVarName); free(pVarName); } while (*pVarCurr++ != ‘\0‘); //找字符串的结束符‘\0‘,并把指针移向下一行开始。 } FreeEnvironmentStrings(pVarBlock); } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hwndList, hwndText; int cxChar, cyChar; int iLength, iIndex; TCHAR *pVarName, *pVarValue; switch (message) { case WM_CREATE: cxChar = LOWORD(GetDialogBaseUnits()); cyChar = HIWORD(GetDialogBaseUnits()); //创建列表框 hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD, cxChar, cyChar * 3, cxChar * 35 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 15, 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); FillListBox(hwndList); return 0; case WM_COMMAND: if (LOWORD(wParam) == ID_LIST &&HIWORD(wParam) == LBN_SELCHANGE) { //获取列表框的中变量名称 iIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0); //获得当前选中项索引 iLength = SendMessage(hwndList, LB_GETTEXTLEN, iIndex, 0) + 1;//获得文本长度 pVarName = calloc(iLength, sizeof(TCHAR)); //calloc初始化元素为0 SendMessage(hwndList, LB_GETTEXT, iIndex, (LPARAM)pVarName); //获取变量名称 //获取环境变量名称 iLength = GetEnvironmentVariable(pVarName, NULL, 0); //获得变量值的数据长度,含‘\0‘ pVarValue = calloc(iLength, sizeof(TCHAR)); GetEnvironmentVariable(pVarName, pVarValue, iLength);//获得变量的值 //将变量的值显示在文本框中 SetWindowText(hwndText, pVarValue); free(pVarValue); free(pVarName); } return 0; case WM_SETFOCUS: SetFocus(hwndList); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
(1)文件属性代码iAttr——下列数值的组合的(最后两个位于高字节)
iAttr |
属性 |
DDL_READWRITE (0x0000) |
普通文件 |
DDL_READONLY (0x0001) |
只读文件 |
DDL_HIDDEN (0x0002) |
隐藏文件 |
DDL_SYSTEM (0x0004) |
系统文件 |
DDL_DIRECTORY (0x0010) |
子目录 |
DDL_ARCHIVE (0x0020) |
设置了存档位的文件 |
DDL_DRIVES (0x4000) |
包括驱动器字符,如形如“[-C-]” |
DDL_EXCLUSIVE (0x8000) |
只搜索指定值 |
①前缀DDL:Dialog directory list(对话框目录列表)
②如果最高位被设置,则只列出具有某种标志的文件:
如只列出自上次备份以来所有被修改过的文件——DDL_EXCLUSIVE|DDL_ARCHIVE
(2)文件列表的排序:(要使用LBS_SORT样式)
文件列表排序 |
说明 |
①先列出满足文件限定条件的所有文件名称 |
|
②再列子目录名称 |
A、第一个子目录[..]:用于返回上一级目录,如果己经是根目录没有这东西。 B、其他子目录[SUBDIR] C、该项是可选的 |
③最后磁盘驱动器清单 |
A、驱动器清单,形如:[-A-] B、该项也是可选的 |
9.6.6 Windows的HEAD程序
(1)窗口子类化
在ListProc中捕捉WM_KEYDOWN消息,发现VK_RETURN则发送WM_COMMAND(带LBN_DBLCKL)通知码的消息给父窗口。
(2)获取当前目录或设置当前目录
GetCurrentDirectory(MAX_PATH + 1, szBuffer);//当前目录
SetCurrentDirectory(szBuffer);//将当前目录设置为指定的目录
(3)打开文件和关闭文件:
打开文件:HANDLE hFile =CreateFile(…);
读取文件:ReadFile(hFile, buffer, nNumberOfBytesToRead, lpNumberOfBytesRead,NULL);
关闭文件:CloseFile(hFile);
效果图
/*------------------------------------------------------------ HEAD.C -- Displays beginning (head) of file (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #define ID_LIST 1 #define ID_TEXT 2 #define MAXREAD 8192 #define DIRATTR (DDL_READWRITE|DDL_READONLY|DDL_HIDDEN|DDL_SYSTEM|\ DDL_DIRECTORY | DDL_ARCHIVE | DDL_DRIVES) #define DTFLAG (DT_WORDBREAK|DT_EXPANDTABS|DT_NOCLIP|DT_NOPREFIX) WNDPROC OldList; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ListProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("head"); 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_BTNFACE + 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, // window class name TEXT("head"), // window caption WS_OVERLAPPEDWINDOW, // 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) { HDC hdc; PAINTSTRUCT ps; static RECT rect; //在客户区指定的地方显示文件的内容 int i, cxChar, cyChar; static HWND hwndList, hwndText; static TCHAR szFile[MAX_PATH + 1]; //保存选中的文件名 TCHAR szBuffer[MAX_PATH + 1]; static BYTE buffer[MAXREAD]; static BOOL bValidFile; HANDLE hFile; switch (message) { case WM_CREATE: cxChar = LOWORD(GetDialogBaseUnits()); cyChar = HIWORD(GetDialogBaseUnits()); rect.top = 3 * cyChar; rect.left = 25 * cxChar; hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD, cxChar, 3 * cyChar, cxChar * 20 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 20, hwnd, (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL ); GetCurrentDirectory(MAX_PATH + 1, szBuffer); //当前目录 hwndText = CreateWindow(TEXT("static"), szBuffer, WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT, cxChar, cyChar, cxChar * MAX_PATH, cyChar, hwnd, (HMENU)ID_TEXT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL ); OldList = (WNDPROC)SetWindowLong(hwndList, GWL_WNDPROC, (LONG)ListProc); SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM)TEXT("*.*")); return 0; case WM_SIZE: rect.right = LOWORD(lParam); rect.bottom = HIWORD(lParam); return 0; case WM_SETFOCUS: SetFocus(hwndList); return 0; case WM_COMMAND: if (LOWORD(wParam) == ID_LIST && HIWORD(wParam) == LBN_DBLCLK) { //判断是否选中项目 if (LB_ERR == (i = SendMessage(hwndList, LB_GETCURSEL, 0, 0))) break; //获取选中项的文本 SendMessage(hwndList, LB_GETTEXT, i, (LPARAM)szBuffer); //打开文件 hFile = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE != hFile) //选中项为文件 { CloseHandle(hFile); bValidFile = TRUE; lstrcpy(szFile, szBuffer); //保存选中项的文件名 //将文件及路径显示在文本框中 GetCurrentDirectory(MAX_PATH + 1, szBuffer); if (szBuffer[lstrlen(szBuffer) - 1] != ‘\\‘) { lstrcat(szBuffer, TEXT("\\")); //最未尾加个“\” } SetWindowText(hwndText, lstrcat(szBuffer, szFile)); } else { //选中项为目录或驱动器 //1、上级目录:[..] //2、子目录如:[SubDir] //3、驱动器符:[-c-] bValidFile = FALSE; //判断是否目录 szBuffer[lstrlen(szBuffer) - 1] = ‘\0‘; //变成szBuffer变成[SubDir,加个\0 if (!SetCurrentDirectory(szBuffer + 1)) //SubDir加上当前目录为新路径。失败,说明选中的是驱动器 { szBuffer[3] = ‘:‘; //变成[-c:] szBuffer[4] = ‘\0‘;//变成[-c: SetCurrentDirectory(szBuffer + 2); //将当前路径设为驱动器符,如c: } //转到子目录或选中的驱动器的根目录下,获取当前路径。 GetCurrentDirectory(MAX_PATH + 1, szBuffer); //显示当前路径 SetWindowText(hwndText, szBuffer); //清空列表框 SendMessage(hwndList, LB_RESETCONTENT, 0, 0); //显示当前目录下的文件及子目录等信息 SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM)TEXT("*.*")); } InvalidateRect(hwnd, NULL, TRUE); } return 0; case WM_PAINT: if (!bValidFile) break; //这里不做任何事,交给DefWindowProc处理 //打开文件 hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) //打开文件失败 { bValidFile = FALSE; break; } //读取文件内容 ReadFile(hFile, buffer, MAXREAD, &i, NULL); CloseHandle(hFile); //显示读取到的内容,i为读取文本到buffer中的字节总数 hdc = BeginPaint(hwnd, &ps); SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); SetBkColor(hdc, GetSysColor(COLOR_BTNFACE)); //假定是ASCII字符的文件 DrawTextA(hdc, buffer, i, &rect, DTFLAG); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK ListProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_KEYDOWN && wParam == VK_RETURN) { SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(ID_LIST, LBN_DBLCLK), (LPARAM)hwnd); } return CallWindowProc(OldList, hwnd, message, wParam, lParam); }
第9章 子窗口控件_9.4-9.6滚动条类、编辑框类、列表框类
标签:
原文地址:http://www.cnblogs.com/5iedu/p/4658962.html