- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
为了在标题栏上绘制图标,我引用了this MSDN article并使用 DWM API 通过调用 DwmExtendFrameIntoClientArea 创建我的自定义客户区。
我的代码:
CMainFrame::CMainFrame()
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
BOOL fDwmEnabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&fDwmEnabled)))
TRACE0("DWM is enabled\n");
TCHAR szLogoPath[MAX_PATH];
GetModuleFileName ( GetModuleHandle(NULL), szLogoPath, _countof(szLogoPath) );
PathRemoveFileSpec ( szLogoPath );
PathAppend ( szLogoPath, _T("lena.bmp") );
m_pLogoImage = m_pLogoImage->FromFile ( CT2CW(szLogoPath) );
if(NULL == m_pLogoImage)
TRACE0("load image fail\n");
}
void CMainFrame::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
int xFrame = 2;
int yFrame = 2;
int nTHight = 30;
NCCALCSIZE_PARAMS * p;
RECT * rc;
RECT aRect;
RECT bRect;
RECT acRect;
p = (NCCALCSIZE_PARAMS *)lpncsp;
CopyRect(&bRect,&p->rgrc[1]);
CopyRect(&aRect,&p->rgrc[0]);
acRect.left = aRect.left + xFrame;
acRect.top = aRect.top - nTHight;
acRect.right = aRect.right - xFrame;
acRect.bottom = aRect.bottom - yFrame;
CopyRect(&p->rgrc[0],&acRect);
CopyRect(&p->rgrc[1],&aRect);
CopyRect(&p->rgrc[2],&bRect);
CFrameWnd::OnNcCalcSize(TRUE, lpncsp);
}
LRESULT CMainFrame::OnNcHitTest(CPoint p)
{
BOOL dwm_enabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled)))
{
LRESULT result = 0;
if (!DwmDefWindowProc(m_hWnd, WM_NCHITTEST, 0, MAKELPARAM(p.x, p.y), &result))
result = HitTestNCA(m_hWnd, p);
if (result == HTNOWHERE && GetForegroundWindow() != this)
{
return HTCAPTION;
}
return result;
}
return CWnd::OnNcHitTest(p);
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if(cs.hMenu!=NULL)
{
::DestroyMenu(cs.hMenu);
cs.hMenu = NULL ;
}
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style = WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_OVERLAPPED| WS_SYSMENU | WS_THICKFRAME;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
return TRUE;
}
void CMainFrame::OnActivate(UINT nState,CWnd* pWndOther,BOOL bMinimized )
{
CFrameWnd::OnActivate(nState,pWndOther,bMinimized);
BOOL fDwmEnabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&fDwmEnabled)))
{
if(nState == WA_ACTIVE )
{
MARGINS margins = {-1};
/*margins.cyTopHeight = 30;
margins.cxLeftWidth = 0;
margins.cxRightWidth = 0;
margins.cyBottomHeight = 0;*/
HRESULT hr = DwmExtendFrameIntoClientArea(m_hWnd, &margins);
if (!SUCCEEDED(hr))
TRACE0("Failed in DwmExtendFrameIntoClientArea\n");
}
}
}
void CMainFrame::OnNcPaint()
{
CFrameWnd::OnPaint();
CDC* dc = GetWindowDC();
RECT rcClient;
GetWindowRect(&rcClient);
dc->FillSolidRect(0,0,RECTWIDTH(rcClient),RECTHEIGHT(rcClient),RGB(255,0,0));
CPaintDC gdc(this); // device context for painting
Graphics gr(gdc.m_hDC);
gr.DrawImage ( m_pLogoImage, 0, 0 );
ReleaseDC(dc);
}
但是,我的窗口在Windows 10下出现了另一个未知的标题标题栏。
我发现未知的标题是由 cs.style 中的 WS_THICKFRAME 引起的。如果我删除 WS_THICKFRAME,未知的阳 ionic 栏将消失,但我无法调整窗口边框的大小。此外,我的程序无法再捕获自定义标题栏上的最小值、最大值和关闭按钮消息。我想删除未知的标题栏而没有任何副作用。谁能给我一个好的解决方案或建议?
最好的问候,
最佳答案
当使用DwmExtendFrameIntoClientArea
时,意味着框架被扩展到客户区。它不再位于非客户区。所以不需要覆盖OnNcPaint
,你可以在OnPaint
void CMainFrame::OnPaint()
{
CPaintDC dc(this);
//paint titlebar area (this used to be the non-client area)
CRect rc;
GetClientRect(&rc);
rc.bottom = titlebar_height;
CDC memdc;
memdc.CreateCompatibleDC(&dc);
BITMAPINFOHEADER bmpInfoHeader = {
sizeof(BITMAPINFOHEADER), rc.Width(), -rc.Height(), 1, 32 };
HBITMAP hbitmap = CreateDIBSection(
dc, (BITMAPINFO*)(&bmpInfoHeader), DIB_RGB_COLORS, NULL, NULL, 0);
auto oldbitmap = memdc.SelectObject(hbitmap);
dc.BitBlt(0, 0, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
memdc.SelectObject(oldbitmap);
DeleteObject(hbitmap);
//begin normal paint
//The new client area begins below titlebar_height which we define earlier
GetClientRect(&rc);
rc.top = titlebar_height;
dc.FillSolidRect(&rc, RGB(0, 0, 255));
Gdiplus::Image *image = Gdiplus::Image::FromFile(L"file.jpg");
Gdiplus::Graphics gr(dc);
gr.DrawImage(image, 0, 0);
delete image;
}
使用成员变量CRect m_border
来跟踪边框的粗细。您可以使用 AdjustWindowRectEx
找到边框的粗细。
void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
titlebar_height = 100;
//find border thickness
if (GetWindowLongPtr(m_hWnd, GWL_STYLE) & WS_THICKFRAME)
{
m_border = { 0,0,0,0 };
AdjustWindowRectEx(&m_border, GetWindowLongPtr(m_hWnd,
GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
m_border.left = abs(m_border.left);
m_border.top = abs(m_border.top);
}
else if (GetWindowLongPtr(m_hWnd, GWL_STYLE) & WS_BORDER)
{
m_border = { 1,1,1,1 };
}
else
{
m_border = { 0,0,0,0 };
}
//Extend frame in to client area
MARGINS margins = { 0 };
margins.cyTopHeight = titlebar_height; //<<=== *** edited
DwmExtendFrameIntoClientArea(m_hWnd, &margins);
SetWindowPos(NULL, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
m_border
例如 {7,7,7,7}
;
允许 Windows 在左、右、下边框上绘制。上边框是唯一改变的
void CMainFrame::OnNcCalcSize(BOOL validate, NCCALCSIZE_PARAMS FAR* lpncsp)
{
if (validate)
{
lpncsp->rgrc[0].left += m_border.left;
lpncsp->rgrc[0].right -= m_border.right;
lpncsp->rgrc[0].bottom -= m_border.bottom;
}
else
{
CFrameWnd::OnNcCalcSize(validate, lpncsp);
}
}
关于c++ - 在 Windows 10 上使用 DWM API 的 Aero 字幕标题栏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40017484/
我正在使用 OpenGL 进行渲染。我的东西是沙盒的,所以我使用 CreateDesktop() 来防止粉碎攻击。但是,无论出于何种原因创建新桌面时都没有 Aero 组合(尽管默认桌面有)并且尝试使用
使用 Aero 主题时,是否有样式的资源名称,我可以 Hook 以实现与标准 Win7 应用程序相同的外观: 换句话说,是否已经有众所周知的 TextBlocks(和其他控件)样式名称可以让我获得与上
我想弄清楚在 Vista 或 Win7 中使用 Aero 主题时如何在窗口的标题栏上绘制自定义按钮。我需要在不更改原始代码的情况下将其应用于许多不同的应用程序,因此这将在一个 Hook 过程中。由于无
有谁知道是否有 API 以编程方式禁用/启用特定的 Windows 视觉效果,例如“启用透明玻璃”或“启用 Aero Peek”? 我所指的效果是那些配置在:系统/高级系统首选项/高级(选项卡)/性能
使用 GDI+ 在玻璃上绘制文本: graphics.DrawString(s, Length(s), font, MakePointF(x, y), brush); 您会注意到启用 ClearTyp
有人有关于 7 或 Vista 上的 Delphi 和 Windows Aero 的好资源吗? 我们即将将 Windows 7 添加到我们的公司,并希望确保我们的内部应用程序尽可能适应。 使用 Del
我一直在尝试在 Delphi 2010 中使用 Aero 来找到一个好看的设计。人们看到的一个明显的用途是玻璃框架被扩展以包括屏幕底部的“确定”/“取消”按钮。我注意到,这在 Delphi 2010
使用 GDI+ 绘制各种颜色: brush = new SolidBrush(color); graphics.FillRectangle(brush, x, y, width, height); 您
Raymond Chen 已确认 there is no publicly documented way去做这个。有谁知道undocumented solution ? 最佳答案 我也有同样的问题,并
我正在开发一个适用于 Windows(XP、Vista、7、8)的窗口(非全屏)OpenGL 应用程序,其中 VSync 和 GPU 帧排队会导致非常明显(且严重)的输入延迟。我使用 wglSwapB
我使用 WPF 制作了一个非常漂亮的 Windows 8 风格界面。结果已经比我希望的要好得多,但我想知道以下几点: 是否可以通过某种方式检索用户设置的当前窗口颜色?您知道,您可以在右键单击桌面时设置
第一次绘制时,绘制不正确。但是,当我最小化框架并恢复它时,它被正确绘制。 我该如何解决这个问题?我尝试过 repaint()。 这是代码 import javax.swing.JComponent;
我正在寻找一种将自定义控件绘制到对话框的客户端和非客户端区域的方法。大致就是下面的白色区域 我使用了 DwmExtendFrameIntoClientArea 并且我设法通过在整个窗口上扩展客户区来获
我已经使用 DWM API 通过调用 DwmExtendFrameIntoClientArea 创建了一个 Aero 玻璃窗。 void CMainFrame::OnActivate(UINT nSt
我有一个应用程序,我已经使用 C++/Win32 制作了一段时间,当我创建我的第一个对话框时,当我没有启用 aero 或我没有使用 windows 7/8 时,它显示得很奇怪。 这是它的截图: 这是我
我正在尝试在 Qt5.6.0 中制作一个无边框窗口,具有 aero-snap 功能。一切正常,除了当我最大化窗口时:它太大了。 我的屏幕分辨率是 2560x1440,所以窗口的大小应该是 2560x1
我遇到 Aero Snap 无法与我正在处理的应用程序(Windows 桌面、 native C++ 应用程序)一起工作的问题,我对发生的事情有点困惑,因为它似乎应该可以正常工作,开箱即用。 我在一个
我有一个使用 MFC 创建的模态对话框。当它出现时,Aero 主题会为出现的新窗口执行淡入过渡。在我的特殊情况下,我会立即从一个对话框切换到另一个对话框,淡入淡出的效果让人分心。有没有一种方法可以禁用
好的,所以我已经按照文档一直到最小的细节,当我尝试调试和运行 (F5) 时,它一直给我以下错误: PInvokeStackImbalance was detected Message: A call
我到处查看如何在我的程序中使用 Aero。我找不到任何可以在您自己的窗口后面预览窗口的 C 函数,例如文件资源管理器或任何主流浏览器在其标题栏上所做的那样。 有些程序通过添加看起来像 Windows
我是一名优秀的程序员,十分优秀!