#include <windows.h>
#include <fstream>
#define ID_SMALLER 1
#define ID_LARGER 2
#define BTN_WIDTH (8*cxChar)
#define BTN_HEIGHT (4*cyChar)
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
static TCHAR szAppName[] = TEXT("ownerbtn");
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 windwos NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(
szAppName,
TEXT("ownerbtn"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
hInst = hInstance;
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 std::ofstream of{"E:/test/zdc.txt"};
static HWND hwndSmall, hwndLarge;
static int cxChar, cyChar, cxClient, cyClient;
int cx, cy;
LPDRAWITEMSTRUCT pdis;
POINT pt[3];
RECT rect;
switch (message)
{
case WM_CREATE:
of << "WM_CREATE" << std::endl;
cxChar = LOWORD(GetDialogBaseUnits());
cyChar = HIWORD(GetDialogBaseUnits());
hwndSmall = CreateWindow(TEXT("button"), TEXT(""),
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
0, 0, BTN_WIDTH, BTN_HEIGHT,
hwnd, (HMENU)ID_SMALLER, hInst, NULL);
hwndLarge = 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:
of << "WM_SIZE" << std::endl;
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
MoveWindow(hwndSmall, cxClient/2-3*BTN_WIDTH/2, cyClient/2-BTN_HEIGHT/2, BTN_WIDTH, BTN_HEIGHT, TRUE);
MoveWindow(hwndLarge, cxClient/2+BTN_WIDTH/2, cyClient/2-BTN_HEIGHT/2, BTN_WIDTH, BTN_HEIGHT, TRUE);
return 0;
case WM_COMMAND:
of << "WM_COMMAND" << "\t";
GetWindowRect(hwnd, &rect);
switch (wParam)
{
case ID_SMALLER:
of << "ID_SMALLER" << std::endl;
rect.left += cxClient/20;
rect.right -= cxClient/20;
rect.top += cyClient/20;
rect.bottom -= cyClient/20;
break;
case ID_LARGER:
of << "ID_LARGER" << std::endl;
rect.left -= cxClient/20;
rect.right += cxClient/20;
rect.top -= cyClient/20;
rect.bottom += cyClient/20;
break;
}
MoveWindow(hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
return 0;
case WM_DRAWITEM:
of << "WM_DRAWITEM" << "\t";
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:
of << "ID_SMALLER" << std::endl;
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 = 3*cx/8; pt[0].y = 7*cy/8;
pt[1].x = 5*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 = 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 = 1*cx/8; pt[0].y = 3*cy/8;
pt[1].x = 1*cx/8; pt[1].y = 5*cy/8;
pt[2].x = 3*cx/8; pt[2].y = 4*cy/8;
Triangle(pdis->hDC, pt);
break;
case ID_LARGER:
of << "ID_LARGER" << std::endl;
pt[0].x = 3*cx/8; pt[0].y = 3*cy/8;
pt[1].x = 5*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 = 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 = 5*cx/8; pt[0].y = 3*cy/8;
pt[1].x = 5*cx/8; pt[1].y = 5*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 = 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;
}
if (pdis->itemState & ODS_SELECTED)
InvertRect(pdis->hDC, &pdis->rcItem);
if (pdis->itemState & ODS_FOCUS)
{
pdis->rcItem.left += cx/16;
pdis->rcItem.right -= cx/16;
pdis->rcItem.top += cy/16;
pdis->rcItem.bottom -= cy/16;
DrawFocusRect(pdis->hDC, &pdis->rcItem);
}
return 0;
case WM_DESTROY:
of.close();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
测试点击按钮后产生的消息如下:WM_COMMAND->WM_SIZE->WM_DRAWITEM ID_SMALLER->WM_DRAWITEM ID_LARGER。