如何 自画标题栏,但 保留原来的MENU??

专制的网站 2012-11-28 03:06:50
光看标题,估计不清楚,我举个例子:
vs08-->新建项目-->Windows 应用程序-->完成,如下图:


然后,想自画 标题栏,但是 保留原来的MENU。
我在“LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)”中添加了对消息 WM_NCCREATE 和 WM_NCCALCSIZE的处理,在WM_NCCALCSIZE中分配了一个区域用于画标题栏,如下代码:

switch (message)
{
case WM_NCCREATE:
{
long dwStyle = GetWindowLong(hWnd, GWL_STYLE);
if (WS_DLGFRAME == (dwStyle & WS_DLGFRAME))
{
dwStyle &= ~WS_DLGFRAME;
}
SetWindowLong(hWnd, GWL_STYLE, dwStyle);

return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_NCCALCSIZE:
{
if (!IsIconic(hWnd))
{
RECT* p = (RECT*)lParam;
p->top += 50;//GetSystemMetrics(SM_CYCAPTION);;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}

然后运行代码,发现 MENU 出现在窗口的最上方,如何把 MENU 放到下面点的位置啊??如图:

问题:
如上图所示,③处是我分配的非客户区的区域,MENU出现在非客户区的顶端(即 ①处),这样很不好,我想把MENU弄到下面去点,弄到 客户区的顶端(②处) 或者弄到 非客户区(③处)的最底端。

请问如何实现?????
...全文
365 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2013-06-09
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
向立天 2013-04-13
  • 打赏
  • 举报
回复
引用 21 楼 okmnjizc 的回复:
暂不想结
好的
专制的网站 2013-04-13
  • 打赏
  • 举报
回复
引用 20 楼 xianglitian 的回复:
...

暂不想结
专制的网站 2012-12-01
  • 打赏
  • 举报
回复
引用 16 楼 schlafenhamster 的回复:
给你一段绘标题栏的代码: void CTitleSelfDrawDlg::OnNcPaint() { ……
貌似 原来的 标题有时会出现啊... 比如我显示 一个 MessageBox时...
schlafenhamster 2012-12-01
  • 打赏
  • 举报
回复
给你一段绘标题栏的代码: void CTitleSelfDrawDlg::OnNcPaint() { //CDialog::OnNcPaint(); //return; if(m_bOsXP) // {// xp CRect rcWin; int barHeight=GetSystemMetrics(SM_CYCAPTION);// 0x1A = 26 GetWindowRect(&rcWin); // exclude title bar HRGN hRgnWin=::CreateRectRgnIndirect(rcWin); // CRect rcTitle; rcTitle.SetRect(0,0,rcWin.Width(),barHeight); rcTitle.DeflateRect(3,0);// w-6 rcTitle.OffsetRect(0,3); // down 3 CRgn RgnTitle; RgnTitle.CreateRectRgnIndirect(rcTitle); // int ret=::CombineRgn(hRgnWin,hRgnWin,(HRGN)RgnTitle,RGN_XOR);//3=COMPLEXREGION // if (ret==3) afxDump << "COMPLEX REGION\n"; // let dlg draw DefWindowProc(WM_NCPAINT,(WPARAM)hRgnWin,0); DeleteObject(hRgnWin); // create title CDC *pDC=GetWindowDC(); pDC->SelectClipRgn(&RgnTitle); if(m_bActive) {// rect pDC->FillSolidRect(&rcTitle,RGB(255,128,128)); // round pDC->SetPixel(rcTitle.left,rcTitle.top,RGB(8,85,222)); pDC->SetPixel(rcTitle.left+1,rcTitle.top,RGB(8,85,222)); pDC->SetPixel(rcTitle.left,rcTitle.top+1,RGB(8,85,222)); } else { pDC->FillSolidRect(&rcTitle,RGB(196,196,196)); // round pDC->SetPixel(rcTitle.left,rcTitle.top,RGB(8,85,222)); pDC->SetPixel(rcTitle.left+1,rcTitle.top,RGB(8,85,222)); pDC->SetPixel(rcTitle.left,rcTitle.top+1,RGB(8,85,222)); } // draw icon //HICON hIcon=GetIcon(FALSE);// or use m_hIcon ::DrawIconEx(pDC->m_hDC,rcTitle.left+(barHeight-16)/2,rcTitle.top+(barHeight-16)/2,m_hIcon,16,16,0,0,DI_NORMAL); // drw title pDC->TextOut(rcTitle.left + barHeight-16 + 18,rcTitle.top+(barHeight-16)/2,"TitleSelfDraw"); // draw sysmenu bmp HDC hMemDC=CreateCompatibleDC(pDC->m_hDC); HBITMAP oldbmp; if(m_bActive) { oldbmp=(HBITMAP)SelectObject(hMemDC,m_hBmp); } else { oldbmp=(HBITMAP)SelectObject(hMemDC,m_hBmp1); } // // ::BitBlt(pDC->m_hDC,rcTitle.right-77,rcTitle.top, rcTitle.right,rcTitle.bottom, hMemDC,0,0, SRCCOPY); SelectObject(hMemDC,oldbmp); // DeleteDC(hMemDC); ReleaseDC(pDC); DeleteObject(RgnTitle); } else {// win2000;
schlafenhamster 2012-12-01
  • 打赏
  • 举报
回复
再试试: // win2000; CRect rcWin; GetWindowRect(&rcWin); // exclude title bar rcWin.top += m_frmHeight + 3;// border=3 // need rgn HRGN hRgnWin=::CreateRectRgnIndirect(rcWin); // let dlg draw , DefWindowProc(WM_NCPAINT,(WPARAM)hRgnWin,0); DeleteObject(hRgnWin); // CDC *pDC=GetWindowDC(); // create title CRect rcTitle; rcTitle.SetRect(0,0,rcWin.Width(),m_frmHeight+3); CRgn RgnTitle; RgnTitle.CreateRectRgnIndirect(rcTitle); pDC->SelectClipRgn(&RgnTitle); rcWin.OffsetRect(-rcWin.left,-rcWin.top); // draw the lost borders pDC->Draw3dRect(0,0,rcWin.Width() ,rcWin.Height() ,RGB(97,108,173),RGB(97,108,173)); pDC->Draw3dRect(1,1,rcWin.Width()-2,rcWin.Height()-1,RGB(97,108,173),RGB(97,108,173)); pDC->Draw3dRect(2,2,rcWin.Width()-4,rcWin.Height()-1,RGB(97,108,173),RGB(97,108,173)); // real caption rcTitle.DeflateRect(3,0); rcTitle.OffsetRect(0,3); rcTitle.bottom -= 3;// // have to make round if(m_bActive) {// rect pDC->FillSolidRect(&rcTitle,RGB(255,128,128)); } else { pDC->FillSolidRect(&rcTitle,RGB(196,196,196)); } // draw icon ::DrawIconEx(pDC->m_hDC,rcTitle.left+(m_frmHeight-16)/2,rcTitle.top+(m_frmHeight-16)/2,m_hIcon,16,16,0,0,DI_NORMAL); // drw title pDC->TextOut(rcTitle.left + m_frmHeight-16 + 18,rcTitle.top+(m_frmHeight-16)/2,"haha"); // draw sysmenu bmp HDC hMemDC=CreateCompatibleDC(pDC->m_hDC); HBITMAP oldbmp; if(m_bActive) { // afxDump << "True\n" ; oldbmp=(HBITMAP)SelectObject(hMemDC,m_hBmp);//m_hBmp2); } else { // afxDump << "False\n" ; oldbmp=(HBITMAP)SelectObject(hMemDC,m_hBmp1);//m_hBmp3); } // ::BitBlt(pDC->m_hDC,rcTitle.right-77,rcTitle.top, rcTitle.right,rcTitle.bottom, hMemDC,0,0, SRCCOPY); SelectObject(hMemDC,oldbmp); // DeleteDC(hMemDC); ReleaseDC(pDC); DeleteObject(RgnTitle); }
schlafenhamster 2012-12-01
  • 打赏
  • 举报
回复
那3个按钮可以 这样: UINT CTitleSelfDrawDlg::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default UINT ret = CDialog::OnNcHitTest(point); if((ret==HTMAXBUTTON ) || (ret==HTMINBUTTON) || (ret==HTCLOSE)) return HTCAPTION; return ret; }
专制的网站 2012-11-30
  • 打赏
  • 举报
回复
引用 14 楼 zhllxt 的回复:
我都没搞清你到底是要画标题栏还是要画菜单。要是只需要画标题栏,你可以不处理OnCaclSize啊,直接绘制标题栏,菜单完全不管它不就行了。
这个 貌似会变成:系统画一遍 标题栏,然后我再画一遍 标题栏 吧??然后 很闪烁?? 或者 我没理解正确这种方式?能给个这个方式的链接么?
zhllxt 2012-11-30
  • 打赏
  • 举报
回复
我都没搞清你到底是要画标题栏还是要画菜单。要是只需要画标题栏,你可以不处理OnCaclSize啊,直接绘制标题栏,菜单完全不管它不就行了。
schlafenhamster 2012-11-29
  • 打赏
  • 举报
回复
1.菜单一定在 非客户区 NC 。 2.没有办法 移动 非客户区。 3.没有办法 把 菜单 放客户区 (SetMenu) 总是 把 菜单 放 非客户区 4.可以使用 ToolBar 5.可以使用 POPUP menu
专制的网站 2012-11-29
  • 打赏
  • 举报
回复
引用 4 楼 schlafenhamster 的回复:
返回时,该结构应该包含窗口客户区的屏幕坐标。
是啊~ 我不是 这样“p->top += 50;”了么,我在数据返回给os之前把客户区变矮了50了啊,上面那个50高度的区域就是非客户区啊。(或着,是我理解错了?? 如果理解错误请指点,谢谢) 但是,现在的MENU不是在非客户区的顶端么,我是要把MENU的位置给弄下来点,我的非客户区的顶端是想用来画标题的。
schlafenhamster 2012-11-29
  • 打赏
  • 举报
回复
·lParam wParam为TRUE时,lParam指向一个NCCALCSIZE_PARAMS结构。该结构包含应用程序可用于计算客户区新的大小和位置的信息。 wParam为FALSE时,lParam指向一个RECT结构。进入时,该结构包含了建议的窗口矩形。返回时,该结构应该包含窗口客户区的屏幕坐标。
专制的网站 2012-11-29
  • 打赏
  • 举报
回复
UP 一下 还有谁来指点下??
gz_qmc 2012-11-29
  • 打赏
  • 举报
回复
话说你百度:"对话框如何添加菜单",奇迹就会出现
傻X 2012-11-29
  • 打赏
  • 举报
回复
之后为啥会有MenuBar和Toolbar就是有这个原因呀
CCDDzclxy 2012-11-29
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
你是把 客户区 下拉了 50; 但这个 50, 还 是不属于 非客户区。 相当于你把 客户区 挖掉了 一块,这块成了 透明区。
哦~~ 这么说就只能 隐藏原来的MENU ,用自画等方式来自己弄MENU了...
schlafenhamster 2012-11-29
  • 打赏
  • 举报
回复
你是把 客户区 下拉了 50; 但这个 50, 还 是不属于 非客户区。 相当于你把 客户区 挖掉了 一块,这块成了 透明区。
CCDDzclxy 2012-11-29
  • 打赏
  • 举报
回复
引用 8 楼 VisualEleven 的回复:
Menu你可以用按钮嘛~
我的意思是 ,如果能把 那个MENU弄下面去点的话,就不用自己再用BUTTON啊,popupmenu啊的来模拟了嘛,主要是想方便...
Eleven 2012-11-29
  • 打赏
  • 举报
回复
Menu你可以用按钮嘛~
专制的网站 2012-11-29
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
1.菜单一定在 非客户区 NC 。 2.没有办法 移动 非客户区。 3.没有办法 把 菜单 放客户区 (SetMenu) 总是 把 菜单 放 非客户区 4.可以使用 ToolBar 5.可以使用 POPUP menu
“菜单一定在 非客户区 NC ” ,那能不能不要让MENU在NC的顶部,放到NC的底部行不行?? 如果不行的话,就只能用变通的方式,先“wcex.lpszMenuName=NULL”,然后自画菜单??
加载更多回复(2)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧