怎么自己画菜单啊?

kbsoft 2011-06-30 09:44:37
不想用CMENU实现绘制菜单功能,主要思路说说?

或者有源码参考
...全文
154 点赞 收藏 9
写回复
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
alexmayer 2011-08-26
Mark党到此一游!
回复
见习学术士 2011-06-30

DrawTitleBar(CDC *pDC)
{
if (!m_hWnd) return;

CRect rtWnd, rtButtons, rtClient;
GetWindowRect(&rtWnd); //整个Window的相对于屏幕的矩形
GetClientRect(&rtClient);
//取得整个Title bar的矩形
//m_rtTitle.left = GetSystemMetrics(SM_CXFRAME) ;
//m_rtTitle.top = GetSystemMetrics(SM_CYFRAME) ;
//m_rtTitle.right = rtWnd.right-rtWnd.left-GetSystemMetrics(SM_CYFRAME) ;
//m_rtTitle.bottom = m_rtTitle.top + GetSystemMetrics(SM_CYCAPTION);
m_rtTitle.left = 0;
m_rtTitle.top = 0;
m_rtTitle.right = rtWnd.Width();
m_rtTitle.bottom = rtWnd.Height();

//重画BODER
//CBrush BrushBorder(RGB(38, 57, 115));
CBrush BrushBorder(RGB(81, 164, 222));
CBrush* pOldBrush = pDC->SelectObject(&BrushBorder);

CPoint point;
//填充顶部框架
point.x = rtWnd.Width() ;
point.y = GetSystemMetrics(SM_CYFRAME) ;
//pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
//填充左侧框架
point.x = GetSystemMetrics(SM_CXFRAME);
point.y = rtWnd.Height();
pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
//填充底部框架
point.x = rtWnd.Width();
point.y = GetSystemMetrics(SM_CYFRAME);
pDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY);
//填充右侧框架
point.x = GetSystemMetrics(SM_CXFRAME);
point.y = rtWnd.Height();
pDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY);

pDC->SelectObject(pOldBrush);

//重画Title Bar

CEnBitmap bmp;
CString strFile = CUtilityEx::GetBasePath() + "images\\bgtitle.bmp";
bmp.LoadImage(CUtilityEx::GetBasePath() + "images\\bgtitle.bmp");

//准备画XP风格按钮
CEnBitmap* pBitmap = new CEnBitmap;
CBitmap* pOldBitmap;
BITMAP bmpInfo;
CDC* pDisplayMemDC=new CDC;
pDisplayMemDC->CreateCompatibleDC(pDC);

//平铺标题
if( m_rtTitle.Height() > 602 )
pBitmap->LoadImage(CUtility::GetBasePath() + "images\\bgtitle_xp.bmp");
else
pBitmap->LoadImage(CUtility::GetBasePath() + "images\\bgtitle.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
pDC->BitBlt(m_rtTitle.left, m_rtTitle.top, m_rtTitle.Width(), m_rtTitle.Height(), pDisplayMemDC, 0, 0, SRCCOPY);
pDisplayMemDC->SelectObject(pOldBitmap);
pBitmap->DeleteObject();
}

CRect rcBoder;
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\border.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
rcBoder.left = 0;
rcBoder.top = GetSystemMetrics(SM_CYCAPTION);
rcBoder.right = rtWnd.Width();
rcBoder.bottom = rtWnd.Height();
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
//画左边框
pDC->BitBlt(rcBoder.left, rcBoder.top, rcBoder.Width(), rcBoder.Height(), pDisplayMemDC, 0, 0, SRCCOPY);
//画右边框
rcBoder.left = rtWnd.Width() - GetSystemMetrics(SM_CXFRAME);
pDC->BitBlt(rcBoder.left, rcBoder.top, rcBoder.Width(), rcBoder.Height(), pDisplayMemDC, 0, 0, SRCCOPY);
pDisplayMemDC->SelectObject(pOldBitmap);
pBitmap->DeleteObject();
//描边
//CPen penBlack(PS_SOLID, 1,RGB(10,36,106));
//CPen* pOldPen = pDC->SelectObject(&penBlack);
//pDC->MoveTo(0 ,0);
//pDC->LineTo(rtWnd.right-rtWnd.left,0);
//pDC->LineTo(rtWnd.right-rtWnd.left,rtWnd.Height());
//pDC->LineTo(0,rtWnd.Height());
//pDC->LineTo(0,0);
//pDC->SelectObject(pOldPen);

}


//重画图标
m_rtIcon.left = rtClient.left + 5;
m_rtIcon.top = GetSystemMetrics(SM_CYFRAME);
m_rtIcon.right = m_rtIcon.left + 16;
m_rtIcon.bottom = m_rtIcon.top + 16;

//pDC->DrawIcon(m_rtIcon.left, m_rtIcon.top, AfxGetApp()->LoadIcon(IDR_MAINFRAME));
::DrawIconEx(pDC->m_hDC, m_rtIcon.left, m_rtIcon.top, AfxGetApp()->LoadIcon(IDR_MAINFRAME),
m_rtIcon.Width() + 2, m_rtIcon.Height() + 2, 0, NULL, DI_NORMAL);
m_rtIcon.OffsetRect(rtWnd.TopLeft());



//重画关闭button
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\exit_nor.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
rtButtons.left = m_rtTitle.right - bmpInfo.bmWidth - 4;
rtButtons.top = m_rtTitle.top + 1;
rtButtons.right = rtButtons.left + bmpInfo.bmWidth;
rtButtons.bottom = rtButtons.top + bmpInfo.bmHeight;


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
if (IsZoomed())
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\res_norm.bmp");
else
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\max_norm.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
rtButtons.right = rtButtons.left - 1;
rtButtons.left = rtButtons.right - bmpInfo.bmWidth;

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
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\min_norm.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
rtButtons.right = rtButtons.left - 1;
rtButtons.left = rtButtons.right - bmpInfo.bmWidth;
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
pBitmap->LoadImage(CUtilityEx::GetBasePath() + "images\\hel_norm.bmp");
if( pBitmap->GetSafeHandle() )
{
pBitmap->GetBitmap(&bmpInfo);
rtButtons.right = rtButtons.left - 1;
rtButtons.left = rtButtons.right - bmpInfo.bmWidth;
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();
}



CFont titleFont;
if( !titleFont.GetSafeHandle() )
{
VERIFY(titleFont.CreateFont(
14, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
GB2312_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("宋体")));
}


CFont *OldFont;
OldFont = pDC->SelectObject(&titleFont);
char szFullPath[MAX_PATH] = "";
::GetModuleFileName(NULL, szFullPath, MAX_PATH);
string strVersion = CUtility::GetVersion(szFullPath);
//重画caption
int nOldMode=pDC->SetBkMode(TRANSPARENT);
COLORREF clOldText=pDC->SetTextColor(RGB(0, 0, 0));
m_rtTitle.right-=GetSystemMetrics(SM_CYSMICON);
m_rtTitle.left += 25;
m_rtTitle.top += 7;
//pDC->SetTextColor(RGB(255, 255, 255));
pDC->SetTextColor(RGB(10, 36, 106));
CString strTitle;
strTitle.Format("XXXXXX %s",strVersion.c_str());
pDC->DrawText((LPCTSTR)strTitle,-1, &m_rtTitle, DT_LEFT);
pDC->SetBkMode(nOldMode);
pDC->SetTextColor(clOldText);

pDC->SelectObject(OldFont);
ReleaseDC(pDisplayMemDC);
if(pDisplayMemDC) delete pDisplayMemDC;
if(pBitmap) delete pBitmap;
}
回复
simoreg 2011-06-30
菜单项可以通过自绘来完成
菜单条,自己在客户区或非客户区画,响应鼠标消息,如WM_MOUSEMOVE时高亮显示,WM_LBURRONDOWN弹出菜单
回复
kbsoft 2011-06-30
我主要想模仿傲游浏览器那种收藏栏的item可以拖动到子菜单的效果,用CMenu的话,TrackPopup总是会阻塞系统消息,导致无法响应拖拽功能
回复
快乐鹦鹉 2011-06-30
那就不是传统的菜单的概念了.菜单控制确实感觉接口开放的不够.在一些船用的系统中,基本上都不用系统自带的菜单功能,看效果就像一些dialogbar,在其上用控件来形成菜单和工具条的效果。
回复
kbsoft 2011-06-30
CMenuEx我看过,也是基于HMENU的吧?
回复
yeah2000 2011-06-30
http://www.codeproject.com/KB/menus/CMenuEx.aspx
回复
yeah2000 2011-06-30
网上找一下 CMenuEx 类,自己根据需要来修改
回复
shenyi0106 2011-06-30
提供一个思路(仅仅是思路哈):
可以用一个窗体来代替菜单的背景,然后用按钮来代替各个菜单项,可以根据菜单项来定制窗体大小,还可以定制背景,定制菜单项背景。

仅仅是思路,不知是否可行
回复
发动态
发帖子
界面
创建于2007-09-28

1.5w+

社区成员

VC/MFC 界面
申请成为版主
社区公告
暂无公告