我的一个朋友即将发布一个应用程序,并要求我为其创建一个启动器。我发现这是一个很好的借口,最终研究了 WinAPI,并认为即使在相对较小的时间窗口内,一个简单的启动器也很容易实现。
我错了。
我正在尝试创建一个带有 5 个按钮的启动器窗口,这些按钮可以启动不同的东西。目标是拥有透明按钮(尚未完成),其中包含较小的图像。仅当用户将鼠标悬停在较大的按钮区域上时才应显示图像。
图像为 .png 格式。我正在使用 GDI+ 并使用http://www.codeproject.com/Articles/3537/Loading-JPG-PNG-resources-using-GDI从资源中加载 PNG 文件。
我正在使用 MouseTrackEvents 来跟踪鼠标,并且我还对按钮进行了子类化。问题是我不知道应该如何处理 WM_MOUSELEAVE 消息。我不知道如何擦除我绘制的图像。如果我必须将 ht_img 保存为变量并稍后引用它,我不知道如何。
这是我到目前为止所拥有的。此示例从资源 IDB_Website2 加载 .png。显示图像有效(尽管目前它一直在一遍又一遍地渲染):
WndProc:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
GDI gdi;
switch (Msg)
{
case WM_CREATE:
{
HWND hwndButton = CreateWindow(TEXT("button"), NULL,
WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
80, 10, 100, 50,
hWnd, (HMENU) HT_BUTTON1, NULL, NULL);
HTButton = (WNDPROC) SetWindowLong(hwndButton, GWL_WNDPROC, (LONG) ButtonProc);
}
...
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
gdi.InitList(hInst, hdc);
EndPaint(hWnd, &ps);
break;
Buttonproc(子类按钮):
LRESULT CALLBACK ButtonProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
MouseTrackEvents MouseTrack;
GDI gdi;
HDC odc = GetDC(GetParent(hWnd));
switch(Msg)
{
case WM_MOUSEMOVE:
MouseTrack.OnMouseMove(hWnd);
break;
case WM_MOUSEHOVER:
gdi.Create(IDB_Website2, _T("PNG"), hInst, odc, 62, 347, 200, 40, true);
MouseTrack.Reset(hWnd);
break;
case WM_MOUSELEAVE:
MouseTrack.Reset(hWnd);
break;
}
return CallWindowProc (HTButton, hWnd, Msg, wParam, lParam);
}
类 GDI 的创建图形方法:
void Create(UINT menuid, LPCTSTR pType, HMODULE hInst, HDC hdc, int x, int y, int w, int h)
{
Graphics grpx(hdc);
ht_img = new CGdiPlusBitmapResource();
ht_img -> Load(menuid, pType, hInst);
grpx.DrawImage(*ht_img, x, y, w, h);
delete ht_img;
}
到目前为止,这是一个相当大的挑战!这很有趣,尽管有时会让人有些发狂。:-) 对于我应该如何进行的任何建议,我将不胜感激。
编辑:回答阿德里安
我尝试更改我的 Buttonproc,但图像似乎没有被渲染。这是我所做的:
LRESULT CALLBACK ButtonProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
MouseTrackEvents MouseTrack;
GDI gdi;
HDC odc = GetDC(GetParent(hWnd));
PAINTSTRUCT ps;
int result;
switch(Msg)
{
case WM_MOUSEMOVE:
MouseTrack.OnMouseMove(hWnd);
break;
case WM_MOUSEHOVER:
hovering = true;
break;
case WM_MOUSELEAVE:
hovering = false;
MouseTrack.Reset(hWnd);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
result = CallWindowProc(HTButton, hWnd, Msg, wParam, lParam);
if (hovering == true) {
gdi.Create(IDB_Play2, _T("PNG"), hInst, hdc, 62, 100, 200, 40);
}
EndPaint(hWnd, &ps);
return result;
}
return CallWindowProc (HTButton, hWnd, Msg, wParam, lParam);
}