如何在非客户区绘图?

发布于 2024-07-04 16:47:36 字数 62 浏览 11 评论 0原文

我希望能够在窗口的非客户区域中的菜单栏右侧进行一些绘图。

使用 C++/MFC 这可能吗?

I'd like to be able to do some drawing to the right of the menu bar, in the nonclient area of a window.

Is this possible, using C++ / MFC?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

余生共白头 2024-07-11 16:47:36

如果您只想在菜单栏中添加某些内容,也许将其添加为右对齐菜单项会更容易/更干净。 这样它也可以与不同的 Windows 主题等一起使用。

If you just want something in the menu bar, maybe it is easier/cleaner to add it as a right-aligned menu item. This way it'll also work with different Windows themes, etc.

贪了杯 2024-07-11 16:47:36

Charlie 通过 WM_NCPAINT 找到了答案。 如果您使用 MFC,代码将如下所示:

// in the message map
ON_WM_NCPAINT()

// ...

void CMainFrame::OnNcPaint()
{
   // still want the menu to be drawn, so trigger default handler first
   Default();

   // get menu bar bounds
   MENUBARINFO menuInfo = {sizeof(MENUBARINFO)};
   if ( GetMenuBarInfo(OBJID_MENU, 0, &menuInfo) )
   {
      CRect windowBounds;
      GetWindowRect(&windowBounds);
      CRect menuBounds(menuInfo.rcBar);
      menuBounds.OffsetRect(-windowBounds.TopLeft());

      // horrible, horrible icon-drawing code. Don't use this. Seriously.
      CWindowDC dc(this);
      HICON appIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
      ::DrawIconEx(dc, menuBounds.right-18, menuBounds.top+2, appIcon, 0,0, 0, NULL, DI_NORMAL);
      ::DestroyIcon(appIcon);
   }
}

Charlie hit on the answer with WM_NCPAINT. If you're using MFC, the code would look something like this:

// in the message map
ON_WM_NCPAINT()

// ...

void CMainFrame::OnNcPaint()
{
   // still want the menu to be drawn, so trigger default handler first
   Default();

   // get menu bar bounds
   MENUBARINFO menuInfo = {sizeof(MENUBARINFO)};
   if ( GetMenuBarInfo(OBJID_MENU, 0, &menuInfo) )
   {
      CRect windowBounds;
      GetWindowRect(&windowBounds);
      CRect menuBounds(menuInfo.rcBar);
      menuBounds.OffsetRect(-windowBounds.TopLeft());

      // horrible, horrible icon-drawing code. Don't use this. Seriously.
      CWindowDC dc(this);
      HICON appIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
      ::DrawIconEx(dc, menuBounds.right-18, menuBounds.top+2, appIcon, 0,0, 0, NULL, DI_NORMAL);
      ::DestroyIcon(appIcon);
   }
}
琴流音 2024-07-11 16:47:36

为了在非客户区绘制,需要获取“窗口”DC(而不是“客户”DC),并在“窗口”DC中绘制。

In order to draw in the non-client area, you need to get the "window" DC (rather than "client" DC), and draw in the "window" DC.

日暮斜阳 2024-07-11 16:47:36

您应该尝试处理 WM_NCPAINT。 这与普通的 WM_PAINT 消息类似,但处理整个窗口,而不仅仅是客户区。 WM_NCPAINT 上的 MSDN 文档提供了以下示例代码:

case WM_NCPAINT:
{
 HDC hdc;
 hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
 // Paint into this DC
 ReleaseDC(hwnd, hdc);
}

该代码旨在用在应用程序的消息循环中,该消息循环使用大型“switch”语句进行规范组织。

正如 Shog 的 MFC 示例中所述,请确保调用默认版本,在本示例中这意味着调用 DefWindowProc。

You should try handling WM_NCPAINT. This is similar to a normal WM_PAINT message, but deals with the entire window, rather than just the client area. The MSDN documents on WM_NCPAINT provide the following sample code:

case WM_NCPAINT:
{
 HDC hdc;
 hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
 // Paint into this DC
 ReleaseDC(hwnd, hdc);
}

This code is intended to be used in the message loop of your applicaton, which is canonically organized using a large 'switch' statement.

As noted in the MFC example from Shog, make sure to call the default version, which in this example would mean a call to DefWindowProc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文