前段时间由于工作原因,一直没有更新博客,今天,继续讲解如何用MFC做漂亮界面,前几次我们讲了如何美化窗口背景,如何美化标题,如何美化按钮,今天我们用以前学过的知识来一起做一个登录界面,这个登录界面的效果图如下:
分析
当我们看到这个界面的时候,先不要忙着去做,先要分析一下哪些是代码做的,哪些不是代码做的,这样就可以减少工作量。大家试试看,分析一下哪些是留在背景上的,不需要我们去做?没错,一共有5个部分是留在背景上的,分别如下:
第一个是老虎,这个不用多说。
第二个是账号,因为这个是美术字,加了特效,代码没法实现。
第三个是密码,同上。
第四个是账号输入框,因为这个框的边框加了特效,所以要留下。
第五个是密码输入框,同上。
美化窗口背景
创建一个对话框项目,命名为LoginTigger,去掉取消按钮和确定按钮,并且修改对话框的Border为None,然后在函数OnInitDialog中修改窗口尺寸为背景图片尺寸。具体如下:
BOOL CLoginTiggerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
//这个是我们自己加的
MoveWindow(0, 0, 300, 400);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
然后,编译代码,效果如下:
下面我们显示背景图片到窗口中,就完成了美化背景,首先在我们的对话框的头文件中增加一个CBrush变量,变量名是m_bkBrush,它代表我们的背景图片,在OnInitDialog中加载背景图片Tigger.png,具体如下:
BOOL CLoginTiggerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
//这个是我们自己加的
MoveWindow(0, 0, 300, 400);
//加载背景图片
CString strBmpPath = _T(".\\res\\Tigger.png");
CImage img;
img.Load(strBmpPath);
CBitmap bmpTmp;
bmpTmp.Attach(img.Detach());
m_bkBrush.CreatePatternBrush(&bmpTmp);
return TRUE;
}
然后添加WM_CTLCOLOR响应函数,不懂得可以翻阅一下前面的文章,具体如下:
HBRUSH CLoginTiggerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
if (pWnd == this)
{
return m_bkBrush;
}
return hbr;
}
编译,运行效果如下:
至此,美化背景完成,是不是很简单。
添加标题
我们首先创建一个CCaption类,继承自CStatic,然后添加成员函数HBRUSH CtlColor(CDC* pDC, UINT nCtlColor),不懂得可以翻阅前面的文章,具体如下:
HBRUSH CCaption::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
CFont font;
LOGFONT lf;
if (!pDC)
return NULL;
//创建一个空画刷,返回这个画刷可以让静态控件的背景透明
HBRUSH hr = (HBRUSH)GetStockObject(NULL_BRUSH);
//让文字的背景透明
pDC->SetBkMode(TRANSPARENT);
//设置文字的颜色为白色
pDC->SetTextColor(RGB(255, 255, 255));
::ZeroMemory(&lf, sizeof(lf));
//设置逻辑字体的高度
lf.lfHeight = 24;
//设置逻辑字体为粗体字
lf.lfWeight = FW_BOLD;
//设置字体为宋体
::lstrcpy(lf.lfFaceName, _T("宋体"));
//用逻辑字体创建一个CFont对象
font.CreateFontIndirect(&lf);
//应用字体
pDC->SelectObject(&font);
return hr;
}
然后再添