1.前言
经过了之前的四篇文章,我们单独实现了对菜单栏,标题栏,按钮,列表的美化。
在这个篇幅中,笔者会把这些整合到一个项目中,实现一个完整的美化效果。
并且还增加了,最大化,最小化,界面的自适应。
2.效果展示
视频运行效果
3.所有的源码链接,笔者使用的是vs2022
1.美化按钮的Demo
https://download.csdn.net/download/dz131lsq/88992781
2.列表美化的Demo
https://download.csdn.net/download/dz131lsq/88992914
3.标题栏美化的Demo
https://download.csdn.net/download/dz131lsq/88999950
4.菜单栏美化的Demo
https://download.csdn.net/download/dz131lsq/89000223
5.完整的项目包括了对菜单栏,按钮,列表,标题的美化
做了最大化,最小化的自适应。
https://download.csdn.net/download/dz131lsq/89000649
4.按钮的美化
主要是封装好了mybutton.h,mybutton.cpp。两个文件。然后对按钮进行重绘
使用图片贴图对按钮进行美化。
核心代码
cpp
CMyButton m_button_start;
CMyButton m_button_stop;
//启动按钮绘制
GetClientRect(&rtBtnClo);
rtBtnClo.left = rtBtnClo.right - 800;
m_button_start.SetImagePath(_T(".\\res\\start.png"), _T(".\\res\\start.png"), _T(".\\res\\start.png"));
m_button_start.InitMyButton(rtBtnClo.left, 60, 55, 24, true);
//停止按钮绘制
GetClientRect(&rtBtnClo);
rtBtnClo.left = rtBtnClo.right - 600;
m_button_stop.SetImagePath(_T(".\\res\\stop.png"), _T(".\\res\\stop.png"), _T(".\\res\\stop.png"));
m_button_stop.InitMyButton(rtBtnClo.left, 60, 55, 24, true);
详细过程可以查看这篇文章
MFC界面美化第三篇----自绘按钮(重绘按钮)-CSDN博客
5.列表的美化
封装好了列表类,主要有8个文件。对列表进行重绘。
主要注意事项,
修改我们的原始list的属性,方便我们后续重绘
边框:true
静态边缘:false
视图:Reporte
无滚动:true
详细过程可以查看这篇文章
MFC界面美化第四篇----自绘list列表(重绘列表)-CSDN博客
6.标题栏的美化
为了对标题栏进行重绘,我们要把mfc原始的标题栏去除,然后再mfc上重新绘制一块区域作为标题栏。然后再重新绘制好对应的最大化,最小化按钮。
详细过程查看这篇文章。
MFC界面美化---自绘标题栏_mfc如何做出漂亮的界面-CSDN博客
7.菜单栏的美化
核心是因为我们把原始的菜单删除了。现在要选择一块区域,写上文字。比如,文件,菜单,帮助,作为我们新的菜单。当我们点击这个菜单区域的时候,会弹出选项。
MenuEx.h MenuEx.cpp 是封装好的重绘菜单栏的文件。需要注意的是使用了hook.让重绘的时候进入我们的函数。
C++ MFC 界面美化------自绘菜单栏_mfc界面美化-CSDN博客
8.关于控件最大化,最小化 的时候的自适应问题。
主要再onsize()函数里面进行处理
对应的相关代码
cpp
CDialogEx::OnSize(nType, cx, cy);
int dlgitem[2] = { IDC_LIST1 };
for (int i = 0; i < 2; i++)//因为是多个控件,所以这里用了循环
{
CWnd* pWnd = GetDlgItem(dlgitem[i]);
//判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = rect.left * cx / m_wndRect.Width();//调整控件大小
rect.right = rect.right * cx / m_wndRect.Width();
rect.top = rect.top * cy / m_wndRect.Height();
rect.bottom = rect.bottom * cy / m_wndRect.Height();
pWnd->MoveWindow(rect);//设置控件大小
}
}
//重新获得窗口尺寸
GetClientRect(&m_wndRect);
//开始重新绘制
//m_btnStart.SetImagePath(_T(".\\res\\firing_button.png"), _T(".\\res\\firing_button_press.png"), _T(".\\res\\firing_button_hover.png"));
//m_btnStart.InitMyButton(11, 70, 70, 28, true);
CWnd* pWnd = GetDlgItem(IDC_BUTTON4);
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
m_button_start.ReleaseImg();
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = m_wndRect.right * 0.0098;
rect.top = m_wndRect.bottom * 0.1176;
rect.right = rect.left + 70;
rect.bottom = rect.top + 28;
//pWnd->MoveWindow(rect);//设置控件大小
m_button_start.SetImagePath(_T(".\\res\\start.png"), _T(".\\res\\start.png"), _T(".\\res\\start.png"));
m_button_start.InitMyButton(rect.left, rect.top, 55, 24, true);
}
//停止按钮重新绘制
pWnd = GetDlgItem(IDC_BUTTON5);
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
m_button_stop.ReleaseImg();
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = m_wndRect.right * 0.0811;
rect.top = m_wndRect.bottom * 0.1176;
rect.right = rect.left + 70;
rect.bottom = rect.top + 28;
m_button_stop.SetImagePath(_T(".\\res\\stop.png"), _T(".\\res\\stop.png"), _T(".\\res\\stop.png"));
m_button_stop.InitMyButton(rect.left, rect.top, 55, 24, true);
}
//退出按钮重新绘制
pWnd = GetDlgItem(IDC_BUTTON3);
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
m_btnExit.ReleaseImg();
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = m_wndRect.right - 20;
rect.top = 5;
rect.right = rect.left + 16;
rect.bottom = rect.top + 16;
m_btnExit.SetImagePath(_T(".\\res\\icon_popup_off.png"), _T(".\\res\\icon_popup_off.png"), _T(".\\res\\icon_popup_off.png"));
m_btnExit.InitMyButton(rect.left, rect.top, 16, 16, true);
}
//最大化按钮重新绘制
pWnd = GetDlgItem(IDC_BUTTON1);
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
m_btnMax.ReleaseImg();
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = m_wndRect.right - 50;
rect.top = 5;
rect.right = rect.left + 16;
rect.bottom = rect.top + 16;
m_btnMax.SetImagePath(_T(".\\res\\icon_square.png"), _T(".\\res\\icon_square.png"), _T(".\\res\\icon_square.png"));
m_btnMax.InitMyButton(rect.left, rect.top, 16, 16, true);
}
//最小化按钮重新绘制
pWnd = GetDlgItem(IDC_BUTTON2);
if (pWnd && nType != 1 && m_wndRect.Width() && m_wndRect.Height())
{
m_btnMin.ReleaseImg();
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
rect.left = m_wndRect.right - 80;
rect.top = 5;
rect.right = rect.left + 16;
rect.bottom = rect.top + 16;
m_btnMin.SetImagePath(_T(".\\res\\icon_minimiz.png"), _T(".\\res\\icon_minimiz.png"), _T(".\\res\\icon_minimiz.png"));
m_btnMin.InitMyButton(rect.left, rect.top, 16, 16, true);
}
Invalidate();
9.关于界面上所有的颜色
1.菜单栏的颜色
OnPaint()中这段代码决定了菜单栏的颜色
cpp
dc.FillSolidRect(rect, RGB(45, 51, 60));
dc.SetBkMode(TRANSPARENT);
2.界面主体的颜色。
OnCtlColor()中这段代码决定了界面主体的颜色
cpp
switch (nCtlColor)
{
case CTLCOLOR_DLG:
HBRUSH aBrush;
aBrush = CreateSolidBrush(RGB(30, 34, 39));
hbr = aBrush;
break;
}
3.列表的颜色
HeaderCtrlEx.cpp中这段代码决定了列表的标题头的颜色
OnNMCustomdraw()函数
cpp
GetClientRect(&rect);
//pDC->FillSolidRect(&rect, RGB(215, 235, 226));
pDC->FillSolidRect(&rect, RGB(30, 34, 39));
*pResult = CDRF_NOTIFYITEMDRAW;
4.ListCtrlComboEx.cpp文件中这段代码决定了列表的主体颜色
DrawItem 函数
cpp
if(bSelected)
{
pDC->SetBkColor(RGB(30, 34, 39));
pDC->SetTextColor(RGB(255,255,255)/*::GetSysColor(COLOR_HIGHLIGHTTEXT)*//*GetTableItemColor(nItem, item.iSubItem)*/);
color = RGB(30, 34, 39);
}
else
{
pDC->SetBkColor(RGB(30, 34, 39));
pDC->SetTextColor(RGB(255,255,255)/*::GetSysColor(COLOR_WINDOWTEXT)*//*GetTableItemColor(nItem, item.iSubItem)*/);
}
5.弹出菜单的颜色
由函数来设置
cpp
// 设置边框颜色
void SetBorderColor(COLORREF clr) { m_clrBorder = clr; }