第9章子窗口控件
1.静态类(static),静态子窗口控件,它不接收鼠标或键盘输入,也不会向其父窗口发送WM_COMMAND消息
下面6个静态窗口样式:
“RECT”静态样式 | “FRAME”静态样式 |
---|---|
SS_BLACKRECT | SS_BLACKFRAME |
SS_GRAYRECT | SS_GRAYFRAME |
SS_WHITERECT | SS_WHITEFRAME |
样式中的“BLACK”,“GRAY”,“WHITE”基于系统颜色
静态控件 | 系统颜色 |
---|---|
BLACK | COLOR_3DDKSHADOW |
GRAY | COLOR_BTNSHADOW |
WHITE | COLOR_BTNHIGHLIGHT |
上面6个静态窗口样式,只是简单地在子窗口的客户区画一个矩形或框架,会忽略CreateWindow的窗口文本字段。
还有两个样式为:SS_ICON和SS_USERITEM。
2.滚动条类(scrollbar)
滚动条子控件不发送WM_COMMAND消息到父窗口,它们就像窗口滚动条一样发送WM_VSCROLL和WM_HSCROLL消息。如何lParam为0,则它是窗口滚动条;如果等于滚动条窗口句柄,就说明它是滚动条控件。wParam参数对于窗口滚动条和滚动条控件是一样的。
设置滚动条控件的范围和位置:
SetScrollRange(hwndScroll,SB_CTL,iMin,iMax,bRedraw);
SetScrollPos(hwndScroll,SB_CTL,iPos,bRedraw);
SetScrollInfo(hwndScroll,SB_CTL,&si,bRedraw);
重定位子控件的过程处理函数:
OldScroll = (WNDPROC)SetWindowLong(hwndScroll, GWL_WNDPROC, (LONG)ScrollProc);
LRESULT CALLBACK ScrollProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int id = GetWindowLong(hwnd, GWL_ID);
switch (message)
{
case WM_SETFOCUS:
break;
}
return CallWindowProc(OldScroll, hwnd, message, wParam, lParam);
}
创建新画刷,把句柄存入到窗口类结构中,然后删除旧的画刷:
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.编辑类(edit)
样式 | 说明 |
---|---|
ES_LEFT | 文本左对齐 |
ES_RIGHT | 文本右对齐 |
ES_CENTER | 文本居中对齐 |
ES_MULTILINE | 支持多行 |
ES_AUTOHSCROLL | 自动水平滚动 |
ES_AUTOVSCROLL | 自动垂直滚动 |
WS_BORDER | 添加边框 |
WS_HSCROLL | 添加水平滚动条 |
WS_VSCROLL | 添加垂直滚动条 |
ES_NOHIDESEL | 失去焦点后选择部分保持高亮 |
4.编辑控件的通知消息
编辑控件能向父窗口发WM_COMMAND消息
通知码 | 说明 |
---|---|
EN_SETFOCUS | 得到输入焦点 |
EN_KILLFOCUS | 失去输入焦点 |
EN_CHANGE | 内容将变化 |
EN_UPDATE | 内容已变化 |
EN_ERRSPACE | 没有空间了 |
EN_MAXTEXT | 没有空间完成插入了 |
EN_HSCROLL | 水平滚动条被单击了 |
EN_VSCROLL | 垂直滚动条被单击了 |
5.传递给编辑控件的消息
消息 | 说明 |
---|---|
SendMessage(hwndEdit,WM_CUT,0,0) | 剪切当前选择的内容 |
SendMessage(hwndEdit,WM_COPY,0,0) | 复制当前选择的内容 |
SendMessage(hwndEdit,WM_CLEAR,0,0) | 删除当前选择的内容 |
SendMessage(hwndEdit,WN_PASTE,0,0) | 黏贴内容到当前位置 |
SendMessage(hwndEdit,EM_GETSEL,(WPARAM)&iStart,(LPARAM)&iEnd) | 获得选择文本的初始位置和终止位置 |
SendMessage(hwndEdit,EM_SETSEL,iStart,iEnd) | 选择iStart到iEnd的文本 |
SendMessage(hwndEdit,EM_REPLACESEL,0,(LPARAM)szString) | 取代当前选择的内容 |
iCount=SendMessage(hwndEdit,EM_GETLINECOUNT,0,0) | 得到编辑器的行数 |
iOffset=SendMessage(hwndEdit,EN_LINEINDEX,iLine,0) | 获得从编辑缓冲区的起点到这行的位移量,行从0开始计数,如果iLine为-1,则返回插入符号所在行的位移量 |
iLength=SendMessage(hwndEdit,EM_LINELENGTH,iLine,0) | 得到某个行的长度 |
iLength=SendMessage(hwndEdit,EM_GETLINE,iLine,(LPARAM)szBuffer) | 得到行的内容 |
6.获取系统环境变量
#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("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;
}
void FillListBox(HWND hwndList)
{
int iLength;
TCHAR *pVarBlock=nullptr, *pVarBeg= nullptr, *pVarEnd= nullptr, *pVarName= nullptr;
TCHAR *pVarOrigin;
pVarBlock = GetEnvironmentStrings();
pVarOrigin = pVarBlock;
while (*pVarBlock)
{
if (*pVarBlock != '=')
{
pVarBeg = pVarBlock;
while (*pVarBlock++ != '=');
pVarEnd = pVarBlock - 1;
iLength = pVarEnd - pVarBeg;
pVarName = (TCHAR *)calloc(iLength + 1, sizeof(TCHAR));
CopyMemory(pVarName, pVarBeg, iLength*sizeof(TCHAR));
pVarName[iLength] = '\0';
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)pVarName);
free(pVarName);
}
while (*pVarBlock++ != '\0');
}
FreeEnvironmentStrings(pVarOrigin);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndList, hwndText;
int iIndex, iLength, cxChar, cyChar;
TCHAR *pVarName = nullptr, *pVarValue = nullptr;
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 * 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);
FillListBox(hwndList);
return 0;
case WM_SETFOCUS:
SetFocus(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 = (TCHAR*)calloc(iLength, sizeof(TCHAR));
SendMessage(hwndList, LB_GETTEXT, iIndex, (LPARAM)pVarName);
iLength = GetEnvironmentVariable(pVarName, NULL, 0);
pVarValue = (TCHAR*)calloc(iLength, sizeof(TCHAR));
GetEnvironmentVariable(pVarName, pVarValue, iLength);
SetWindowText(hwndText, pVarValue);
free(pVarName);
free(pVarValue);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}