Win32 API自绘按钮
程序员文章站
2022-07-05 13:00:11
...
WinMain.c
#include <windows.h>
HINSTANCE hInst;
WNDPROC OldBtnProc;
BOOL bMouseHover;
HBRUSH hBrush1;
HBRUSH hBrush2;
HBRUSH hBrush3;
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
LRESULT CALLBACK NewBtnProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow
)
{
hInst = hInstance;
bMouseHover = FALSE;
WNDCLASS wndcls;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = GetStockObject(GRAY_BRUSH);
wndcls.hCursor = LoadCursor(NULL,IDC_ARROW);
wndcls.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WindowProc;
wndcls.lpszClassName = TEXT("MainWnd");
wndcls.lpszMenuName = NULL;
wndcls.style = CS_VREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd = CreateWindow(TEXT("MainWnd"),TEXT("MainWnd"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
static HWND hBtn;
DRAWITEMSTRUCT* pdis;
switch (uMsg)
{
case WM_CREATE:
hBrush1 = CreateSolidBrush(RGB(0, 255, 0));
hBrush2 = CreateSolidBrush(RGB(255, 0, 0));
hBrush3 = CreateSolidBrush(RGB(0, 0, 255));
hBtn = CreateWindow(TEXT("BUTTON"), TEXT("按钮1"), WS_CHILD |WS_VISIBLE| BS_OWNERDRAW, 50, 50, 200, 100, hwnd,
123, hInst, NULL);
OldBtnProc = SetWindowLong(hBtn,GWL_WNDPROC, NewBtnProc);
SetFocus(hBtn);
return 0;
case WM_DRAWITEM:
pdis = (LPDRAWITEMSTRUCT)lParam;
if (GetCapture() == hBtn)
{
if (pdis->itemState & ODS_SELECTED)//如果鼠标选中按钮
{
FillRect(pdis->hDC, &pdis->rcItem, hBrush3);//蓝色
}
else
{
FillRect(pdis->hDC, &pdis->rcItem, hBrush2);//初始按钮样式:红色
}
}
else
{
if (bMouseHover)//鼠标悬停
{
FillRect(pdis->hDC, &pdis->rcItem, hBrush1);//初始按钮样式:绿色
}
else
{
FillRect(pdis->hDC, &pdis->rcItem, hBrush2);//初始按钮样式:红色
}
}
if (pdis->itemState & ODS_FOCUS)//如果按钮获得焦点
{
DrawFocusRect(pdis->hDC, &pdis->rcItem);
}
return 0;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 123:
//MessageBox(hwnd,TEXT("按钮"),0,0);
break;
}
return 0;
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
LRESULT CALLBACK NewBtnProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_MOUSEMOVE://注意,只要当鼠标位于窗口内,即使没有移动,也会产生WM_MOUSEMOVE消息
{
if (!bMouseHover)
{
bMouseHover = TRUE;//特别注意:这条语句不能放在TrackMouseEvent函数调用之后
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
}
break;
}
//可以用于显示ToolTip提示框
case WM_MOUSEHOVER:
break;
case WM_MOUSELEAVE:
bMouseHover = FALSE;
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
break;
}
return CallWindowProc(OldBtnProc,hwnd,uMsg,wParam,lParam);
}