本文介绍了使用 BM_SETIMAGE 和 SetWindowRgn 的圆形按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个圆形按钮.到目前为止,这是我的流程:

创建 BS_BITMAP 样式按钮:

Create BS_BITMAP style button:

hButton = CreateWindow(L"button",L"Label",WS_CHILD|WS_VISIBLE|BS_BITMAP,
               122,363,65,65,hWnd,(HMENU)BUTTON_ID,NULL,NULL);

使用 LoadImage 加载位图.位图是一个正方形,但我只想在中心显示圆形(稍后会详细介绍):

Load bitmap with LoadImage. The bitmap is a square, but I only want to display the circle in the center (more on this later):

buttonImage = (HBITMAP)LoadImage(hInstance,L"button.bmp",IMAGE_BITMAP,65,65,
               LR_LOADFROMFILE|LR_CREATEDIBSECTION);

设置按钮的图像:

SendMessage(hButton,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)buttonImage);

为了仅显示圆圈,我使用以下内容:

In order to display just the circle, I use the following:

hButtonRgn = CreateEllipticRgn(0,0,65,65);
SetWindowRgn(hButton,hButtonRgn,TRUE);

请注意,我全局定义了 hButtonRgn 并且不再使用它,因为 SetWindowRgn 的 MSDN 文档指出系统拥有区域句柄 hRgn 指定的区域".

Note that I define hButtonRgn globally and don't use it again, as the MSDN documentation for SetWindowRgn states that "the system owns the region specified by the region handle hRgn".

问题来了:

该按钮最初仅显示为一个圆圈.但是,在单击并按住时,会出现完整的方形位图,圆圈周围有空白区域.然而,发布后,只有圆圈再次出现.

The button initially appears as only a circle. On being clicked and held, though, the full square bitmap appears, with white space surrounding the circle. However, upon release, only the circle appears again.

这是我尝试的解决方案:

点击按钮后,在按钮周围重新绘制主窗口.然后,在主窗口的 WndProc 中,我执行以下操作:

As soon as the button is clicked, repaint the main window around the button. Within the main window's WndProc, then, I do the following:

case WM_PARENTNOTIFY:
    if ((int)wParam == WM_LBUTTONDOWN)
    {
        PAINTSTRUCT ps;
        BeginPaint(hWnd, &ps);
        pRenderTarget->BeginDraw();
        // paint the background surrounding the button in another function
        pRenderTarget->EndDraw();
        EndPaint(hWnd, &ps);
    }

然而,这没有明显的影响.释放鼠标后按钮显示为圆形,按住鼠标时显示为正方形.

However, this has no discernible effect. The button appears circular after releasing the mouse, but appears as a square when the mouse is being held down.

对我哪里出错有什么想法吗?

Any ideas on where I've gone wrong?

推荐答案

您的重绘例程不正确.BeginPaint() 应该只用于响应 WM_PAINT 消息 - 它告诉您某些东西很脏并且需要重新绘制.你想要做的是触发那个机制,你这样做的方法是使用 InvalidateRect() 来标记父窗口的适当区域以进行重绘.

Your redraw routine is incorrect. BeginPaint() should only be used in response to a WM_PAINT message - it tells you that something is dirty and needs repainting. What you want to do is trigger that mechanism, and the way you do that is to use InvalidateRect() to mark the appropriate area of the parent window for redraw.

即使这确实对您有所改善,我认为您最终会出现闪烁,这可能是不可接受的.您可以研究的另一种机制是让按钮所有者绘制,因为这样您就可以在同一步骤中将其绘制为圆形(并使父窗口无效).

Even if this does improve things for you I think you'll end up with flickering which will probably be unacceptable. Another mechanism you could investigate is making the button owner draw, because then you can just draw it as a circle (and invalidate the parent window) in the same step.

这篇关于使用 BM_SETIMAGE 和 SetWindowRgn 的圆形按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 14:44