失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > mfc标题栏重绘

mfc标题栏重绘

时间:2019-12-24 21:05:17

相关推荐

mfc标题栏重绘

1.mfc对话框

1.1 保留原标题栏

1.如果需要加高标题栏(用于贴图等),就要调用OnNcCalcSize追加部分空间(非客户区间):

[cpp]view plaincopyvoidCMy082302Dlg::OnNcCalcSize(BOOLbCalcValidRects,NCCALCSIZE_PARAMSFAR*lpncsp) { lpncsp->rgrc[0].top+=25;//尺度自己把握 //lpncsp->rgrc[0].bottom-=100;//类似增加底边栏,此例无用 CDialog::OnNcCalcSize(bCalcValidRects,lpncsp); }

2.添加绘制标题栏函数DrawTitleBar():

[cpp]view plaincopyvoidCMy082302Dlg::DrawTitleBar(CDC*pDC) { if(m_hWnd) { CBrushBrush(RGB(0,100,255)); CBrush*pOldBrush=pDC->SelectObject(&Brush); CRectrtWnd,rtTitle,rtButtons; GetWindowRect(&rtWnd); //取得标题栏的位置 rtTitle.left=GetSystemMetrics(SM_CXFRAME); rtTitle.top=GetSystemMetrics(SM_CYFRAME); rtTitle.right=rtWnd.right-rtWnd.left-GetSystemMetrics(SM_CXFRAME); rtTitle.bottom=rtTitle.top+GetSystemMetrics(SM_CYSIZE); CPointpoint; //填充顶部框架 point.x=rtWnd.Width(); point.y=GetSystemMetrics(SM_CYSIZE)+GetSystemMetrics(SM_CYFRAME)+20; pDC->PatBlt(0,0,point.x,point.y,PATCOPY); //填充左侧框架 point.x=GetSystemMetrics(SM_CXFRAME)+1; point.y=rtWnd.Height(); pDC->PatBlt(0,0,point.x,point.y,PATCOPY); //填充底部框架 point.x=rtWnd.Width(); point.y=GetSystemMetrics(SM_CYFRAME)+1; pDC->PatBlt(0,rtWnd.Height()-point.y,point.x,point.y,PATCOPY); //填充右侧框架 point.x=GetSystemMetrics(SM_CXFRAME)+1; point.y=rtWnd.Height(); pDC->PatBlt(rtWnd.Width()-point.x,0,point.x,point.y,PATCOPY); pDC->SelectObject(pOldBrush); //重画图标 m_rtIcon.left=rtWnd.Width()-135; m_rtIcon.top=GetSystemMetrics(SM_CYFRAME); m_rtIcon.right=m_rtIcon.left+32; m_rtIcon.bottom=m_rtIcon.top+32; ::DrawIconEx(pDC->m_hDC,m_rtIcon.left,m_rtIcon.top,m_hIcon, m_rtIcon.Width(),m_rtIcon.Height(),0,NULL,DI_NORMAL); m_rtIcon.OffsetRect(rtWnd.TopLeft()); //准备画XP风格按钮 CBitmap*pBitmap=newCBitmap; CBitmap*pOldBitmap; CDC*pDisplayMemDC=newCDC; pDisplayMemDC->CreateCompatibleDC(pDC); //重画关闭button rtButtons.left=rtTitle.right-19; rtButtons.top=rtTitle.top; rtButtons.right=rtButtons.left+19; rtButtons.bottom=rtButtons.top+19; pBitmap->LoadBitmap(IDB_EXIT_NORMAL); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButtons.left,rtButtons.top,rtButtons.Width(),rtButtons.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); m_rtButtExit=rtButtons; m_rtButtExit.OffsetRect(rtWnd.TopLeft()); pBitmap->DeleteObject(); //重画最大化/恢复button rtButtons.right=rtButtons.left-3; rtButtons.left=rtButtons.right-19; if(IsZoomed()) pBitmap->LoadBitmap(IDB_RESTORE_NORMAL); else pBitmap->LoadBitmap(IDB_MAX_NORMAL); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButtons.left,rtButtons.top,rtButtons.Width(),rtButtons.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); m_rtButtMax=rtButtons; m_rtButtMax.OffsetRect(rtWnd.TopLeft()); pBitmap->DeleteObject(); //重画最小化button rtButtons.right=rtButtons.left-3; rtButtons.left=rtButtons.right-19; pBitmap->LoadBitmap(IDB_MIN_NORMAL); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButtons.left,rtButtons.top,rtButtons.Width(),rtButtons.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); m_rtButtMin=rtButtons; m_rtButtMin.OffsetRect(rtWnd.TopLeft()); pBitmap->DeleteObject(); //重画帮助button rtButtons.right=rtButtons.left-3; rtButtons.left=rtButtons.right-19; pBitmap->LoadBitmap(IDB_HELP_NORMAL); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButtons.left,rtButtons.top,rtButtons.Width(),rtButtons.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); m_rtButtHelp=rtButtons; m_rtButtHelp.OffsetRect(rtWnd.TopLeft()); pBitmap->DeleteObject(); //贴图 point.x=rtWnd.Width(); point.y=GetSystemMetrics(SM_CYSIZE)+GetSystemMetrics(SM_CYFRAME)+20; pBitmap->LoadBitmap(IDB_BITMAP1); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(0,0,point.x,point.y,pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //拉伸图片 //pDC->StretchBlt(x,y,nW,nH,&memDc,0,0, //bm.bmWidth,bm.bmHeight,SRCCOPY); //重写标题文字 intnOldMode=pDC->SetBkMode(TRANSPARENT); COLORREFclOldText=pDC->SetTextColor(RGB(255,255,255)); pDC->SelectStockObject(SYSTEM_FIXED_FONT); rtTitle.left+=2; rtTitle.top+=GetSystemMetrics(SM_CYSIZE); rtTitle.bottom=rtTitle.top+30; CStringm_strTitle; GetWindowText(m_strTitle); pDC->DrawText(m_strTitle,&rtTitle,DT_LEFT); pDC->SetBkMode(nOldMode); pDC->SetTextColor(clOldText); ReleaseDC(pDisplayMemDC); deletepDisplayMemDC; deletepBitmap; } }

3.按钮响应,消息发送/拦截等(系统消息函数)

[cpp]view plaincopyLRESULTCMy082302Dlg::DefWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam) { LRESULTlrst=CDialog::DefWindowProc(message,wParam,lParam); if(!::IsWindow(m_hWnd)) returnlrst; if(message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE||message==WM_NOTIFY) { CDC*pWinDC=GetWindowDC(); if(pWinDC) DrawTitleBar(pWinDC); ReleaseDC(pWinDC); } returnlrst; } voidCMy082302Dlg::OnNcLButtonDown(UINTnHitTest,CPointpoint) { //检测各按钮是否按到 if(m_rtButtHelp.PtInRect(point)) SendMessage(WM_HELP); elseif(m_rtButtExit.PtInRect(point)) SendMessage(WM_CLOSE); elseif(m_rtButtMin.PtInRect(point)) SendMessage(WM_SYSCOMMAND,SC_MINIMIZE,MAKELPARAM(point.x,point.y)); elseif(m_rtButtMax.PtInRect(point)) { if(IsZoomed()) SendMessage(WM_SYSCOMMAND,SC_RESTORE,MAKELPARAM(point.x,point.y)); else { SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,MAKELPARAM(point.x,point.y)); Invalidate(); } } elseif(!IsZoomed()) Default(); } voidCMy082302Dlg::OnNcMouseMove(UINTnHitTest,CPointpoint) { CDC*pDC=GetWindowDC(); CDC*pDisplayMemDC=newCDC; pDisplayMemDC->CreateCompatibleDC(pDC); CBitmap*pBitmap=newCBitmap; CBitmap*pOldBitmap; CRectrtWnd,rtButton; if(pDC) { GetWindowRect(&rtWnd); //关闭button if(m_rtButtExit.PtInRect(point)) pBitmap->LoadBitmap(IDB_EXIT_FOCUS); else pBitmap->LoadBitmap(IDB_EXIT_NORMAL); rtButton=m_rtButtExit; rtButton.OffsetRect(-rtWnd.left,-rtWnd.top); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButton.left,rtButton.top,rtButton.Width(),rtButton.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //最大化/恢复button if(m_rtButtMax.PtInRect(point)) { if(IsZoomed()) pBitmap->LoadBitmap(IDB_RESTORE_FOCUS); else pBitmap->LoadBitmap(IDB_MAX_FOCUS); } else { if(IsZoomed()) pBitmap->LoadBitmap(IDB_RESTORE_NORMAL); else pBitmap->LoadBitmap(IDB_MAX_NORMAL); } rtButton=m_rtButtMax; rtButton.OffsetRect(-rtWnd.left,-rtWnd.top); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButton.left,rtButton.top,rtButton.Width(),rtButton.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //最小化button if(m_rtButtMin.PtInRect(point)) pBitmap->LoadBitmap(IDB_MIN_FOCUS); else pBitmap->LoadBitmap(IDB_MIN_NORMAL); rtButton=m_rtButtMin; rtButton.OffsetRect(-rtWnd.left,-rtWnd.top); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButton.left,rtButton.top,rtButton.Width(),rtButton.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //帮助button if(m_rtButtHelp.PtInRect(point)) pBitmap->LoadBitmap(IDB_HELP_FOCUS); else pBitmap->LoadBitmap(IDB_HELP_NORMAL); rtButton=m_rtButtHelp; rtButton.OffsetRect(-rtWnd.left,-rtWnd.top); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButton.left,rtButton.top,rtButton.Width(),rtButton.Height(),pDisplayMemDC,0,0,SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); } ReleaseDC(pDisplayMemDC); ReleaseDC(pDC); deletepDisplayMemDC; deletepBitmap; CDialog::OnNcMouseMove(nHitTest,point); }

1.2 去除原标题栏

1.去除窗口标题风格

2.添加响应按钮(最大化、最小化等)

3.贴图(可借助众所周知的BitButtonNL类 )处理

4.添加可供窗口拖移消息欺骗:

[cpp]view plaincopyvoidCMy082302Dlg::OnLButtonDown(UINTnFlags,CPointpoint) { //处理移动 if(point.y<26) PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y)); CDialog::OnLButtonDown(nFlags,point); }

2、mfc单/多文档

2.1 保留原标题栏

方法同1.1

问题:1) 禁用cs.style&=~WS_SYSMENU;(为了去除原标题栏按钮) ,但这导致邮件菜单不可用。

2) 不名操作闪烁(个别特殊操作,基本不会)

3)1.1中的第1步如果单/多文档绘制了菜单,会出现菜单夹中问题。如需菜单建议菜单重绘或bcg界面库工程

2.2 去除原标题栏

由于2.1中的问题1和2,再加上去除标题栏所导致的非客户区自绘按钮消息无法响应以及窗口无法拖动等情况,我们必须用OnNcHitTest改变新增加空间(1.1中第1步)为HTCAPTION属性。

1.去除标题栏 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){} 添加:

[cpp]view plaincopyModifyStyle(WS_CAPTION,WS_DLGFRAME,SWP_FRAMECHANGED);

2.同1.1中1.2.3步。1步不可缺省哦

3. OnNcHitTest返回HTCAPTION:

[cpp]view plaincopyUINTCMainFrame::OnNcHitTest(CPointpoint) { RECTrectWindows,rectClient; this->GetWindowRect(&rectWindows); this->GetClientRect(&rectClient); if(point.y>rectWindows.top&&point.y<rectWindows.top+25) { returnHTCAPTION;//标题栏形式 } else { returnCFrameWnd::OnNcHitTest(point); } }

如果觉得《mfc标题栏重绘》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。