这次记录的是有关子窗口控制(预定义的)的消息和部分相关API与标准(本人学的是Win程序设计第五版)有偏差,或哪里有不妥,欢迎大家给予斧正!
子窗口控制,说白了就是由父窗口的hwnd作为CreateWindow中的hWndParents参数,所穿件的一个字窗口,但这个子窗口有一个特性:当子窗口的状态发生改变时,会有消息通知父窗口,这就是一种当一个窗口收到某种重要消息二通知另一个窗口的一个方法的封装,这时子窗口就相当于父窗口的一个输入设备。
一般预定义的按钮中子窗口发送的消息是WM_COMMAND并且lParam为子窗口的hWnd,wParam的高字节是子窗口的通知码,低字节则是子窗口的窗口ID(在CreateWindow中有一个HMENU其中这个的值就是子窗口的窗口ID,并且只要知道窗口ID或者是hWnd,两者就可以通过GetWindowLong的GWL_ID来通过hWnd获取子窗口的ID,或者是通过GetDlgCtrlID也可以,同样的可以通过父窗口的hWnd和子窗口ID来通过GetDlgItem获取子窗口hWnd)
这个此窗口的创建方式如下:
CreateWindow(PTCHAR,
PTCHAR,
WS_CHILD | WS_VISIBLE | STYLE,
x,
y,
hwnd,
(HMENU)ID,
((LPCREATESTRUCT)lParam)->hInstance,
NULL)
其中要注意的是:STYLE用到的是下面的BS标识符替换窗口类型,ID则是窗口ID,自拟,实例句柄则需要借助一个特性:在CreateWindow时,会发送一个WM_CREATE消息,这个消息的lParam参数其实是一个指向CREATESTRUCT结构的指针,其中包含了一个实例句柄,当然也可以用GetWindowLong函数通过窗口实例来获取。
BS_(DEF)PUSHBUTTON,这个主要是拿来触发一个立即响应的动作,在用作子窗口控制的时候两者作用相同
这个按钮可以在父窗口内通过发送BM_SETSTATE,wParam为0或1来模拟按键被按下或是释放
这个东西就是那一个小勾勾,有四种类型:
SM_(AUTO)SETCHECK&SM_(AUTO)3STATE
上面那个不加AUTO的就需要我们在收到它返回的WM_COMMAND消息以后通过发送wParam为0和1的BM_STECHECK消息来控制这个小勾勾的显示(那个带了3的则有三种状态,0,1,2)与否。
同时也可以通过发送BM_GTECHECK来获取当前的状态。
这个按钮就是那个带了小点点的那种其类型为:
BS_(AUTO)RADIOBUTTON这里的非AUTO的显示小点点的方式同上。
BS_GROUPBOX
下面来看一个书上的例子程序对应一下
/*----------------------------------------
BTNLOOK.C -- Button Look Program
(c) Charles Petzold, 1998
----------------------------------------*/
#include
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:
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,
((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:
ScrollWindow(hwnd, 0, -cyChar, &rect, &rect);
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)));
ReleaseDC(hwnd, hdc);
ValidateRect(hwnd, &rect);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}