1.MessageBox类实现
// 头文件 #pragma once // CMessageBox dialog class CMessageBox : public CDialogEx { DECLARE_DYNAMIC(CMessageBox) public: CMessageBox(CWnd* pParent = NULL); // standard constructor virtual ~CMessageBox(); // Dialog Data #ifdef AFX_DESIGN_TIME enum { IDD = IDD_MSG_BOX }; #endif enum MessageType { Pass, Fail, Normal, Custom }; void ShowMessage(const CString& strMsg, MessageType type = MessageType::Normal, bool bDoModal = false); void CMessageBox::SetMessageInfo(const CString& msg, COLORREF backgroudColor = RGB(255, 255, 255), COLORREF fontColor = RGB(0, 0, 0), DWORD fontSize = 700, const CString& fontFormat = _T("宋体")); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support DECLARE_MESSAGE_MAP() public: afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); virtual void OnOK(); private: CString m_strMsg; COLORREF m_bkColor; COLORREF m_fontColor; DWORD m_fontSize; CString m_fontFormat; public: virtual BOOL OnInitDialog(); }; // 实现.cpp // MessageBox.cpp : implementation file // #include "stdafx.h" #include "CMessageBox.h" #include "MessageBox.h" #include "afxdialogex.h" // CMessageBox dialog IMPLEMENT_DYNAMIC(CMessageBox, CDialogEx) CMessageBox::CMessageBox(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_MSG_BOX, pParent) , m_strMsg(_T("")) , m_bkColor(RGB(255, 255, 255)) , m_fontColor(RGB(0, 0, 0)) , m_fontFormat(_T("宋体")) , m_fontSize(700) { } CMessageBox::~CMessageBox() { } void CMessageBox::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CMessageBox, CDialogEx) ON_WM_PAINT() ON_WM_LBUTTONDOWN() // ON_WM_CLOSE() END_MESSAGE_MAP() // CMessageBox message handlers // Repaint Event void CMessageBox::OnPaint() { // device context for painting CPaintDC dc(this); // TODO: Add your message handler code here // Do not call CDialogEx::OnPaint() for painting messages CRect rect; GetClientRect(&rect); // 获取客户区尺寸 // 背景画刷 CBrush brush(m_bkColor); // 前景字体 CFont font; font.CreatePointFont(m_fontSize, m_fontFormat); // 将画刷和字体选入设备描述表 dc.SelectObject(&font); dc.SelectObject(&brush); // 设置背景透明 dc.SetBkMode(TRANSPARENT); // 设置文本颜色 dc.SetTextColor(m_fontColor); // 填充背景 dc.FillRect(rect, &brush); // 绘制文字信息(水平垂直居中,单行显示) dc.DrawText(m_strMsg, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } // Left button clicked void CMessageBox::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default this->OnCancel(); CDialogEx::OnLButtonDown(nFlags, point); } void CMessageBox::OnOK() { // TODO: Add your specialized code here and/or call the base class return; } void CMessageBox::SetMessageInfo(const CString& msg, COLORREF backgroudColor /*= RGB(0, 0, 255)*/, COLORREF fontColor /*= RGB(0, 0, 0)*/, DWORD fontSize /*= 700*/, const CString& fontFormat /*= _T("宋体")*/) { if (!msg.IsEmpty()) { m_strMsg = msg; } if (backgroudColor >= 0x00000000 && backgroudColor <= 0x00FFFFFF) { m_bkColor = backgroudColor; } if (fontColor >= 0x00000000 && fontColor <= 0x00FFFFFF) { m_fontColor = fontColor; } if (fontSize >= 0) { m_fontSize = fontSize; } if (!fontFormat.IsEmpty()) { m_fontFormat = fontFormat; } } // 模态和非模态模式显示信息,非模态显示必须保证在窗口关闭之前窗口对象的生命周期(窗口对象析构时会释放窗口资源) void CMessageBox::ShowMessage(const CString& strMsg, MessageType type /*= MessageType::Normal*/, bool bDoModal/*= false*/) { switch (type) { case CMessageBox::Pass: SetMessageInfo(strMsg, RGB(0, 255, 0)); break; case CMessageBox::Fail: SetMessageInfo(strMsg, RGB(255, 0, 0)); break; case CMessageBox::Normal: SetMessageInfo(strMsg); break; default: break; } // 模态和非模态模式 if (bDoModal) { DoModal(); } else { static int i = 0; // 第一次显示时创建窗口,不能创建 if (i == 0) { this->Create(IDD_MSG_BOX, NULL); } this->ShowWindow(SW_SHOW); // 按照窗口预先设定的尺寸显示 i++; } } BOOL CMessageBox::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: Add extra initialization here //设置窗口大小,样式 int cx = GetSystemMetrics(SM_CXSCREEN); int cy = GetSystemMetrics(SM_CYSCREEN); int iXpos = 0; int iYpos = cy / 2 - cy / 6; // 置顶窗口 SetWindowPos(&CWnd::wndTopMost, iXpos, iYpos, cx, cy / 3, SWP_NOOWNERZORDER); // SWP_NOZORDER | SWP_NOOWNERZORDER // 设置窗口分层属性 ::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) | WS_EX_LAYERED); // 设置分层窗口的不透明度, 透明度由alpha参数指定 SetLayeredWindowAttributes(0, 150, LWA_ALPHA); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
2.使用
// CMessageBoxDlg.cpp : implementation file // #include "stdafx.h" #include "CMessageBox.h" #include "CMessageBoxDlg.h" #include "afxdialogex.h" #include "MessageBox.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CAboutDlg dialog used for App About class CAboutDlg : public CDialogEx { public: CAboutDlg(); // Dialog Data #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CCMessageBoxDlg dialog CCMessageBoxDlg::CCMessageBoxDlg(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_CMESSAGEBOX_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CCMessageBoxDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CCMessageBoxDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BTN_PASS, &CCMessageBoxDlg::OnBnClickedBtnPass) ON_BN_CLICKED(IDC_BTN_FAIL, &CCMessageBoxDlg::OnBnClickedBtnFail) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BTN_NORMAL, &CCMessageBoxDlg::OnBnClickedBtnNormal) ON_BN_CLICKED(IDC_BTN_CUSTOM, &CCMessageBoxDlg::OnBnClickedBtnCustom) END_MESSAGE_MAP() // CCMessageBoxDlg message handlers BOOL CCMessageBoxDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. 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); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here if (m_msgBox == nullptr) m_msgBox = new CMessageBox(this); return TRUE; // return TRUE unless you set the focus to a control } void CCMessageBoxDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CCMessageBoxDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CCMessageBoxDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CCMessageBoxDlg::OnBnClickedBtnPass() { // TODO: Add your control notification handler code here if (m_msgBox) { m_msgBox->ShowMessage(_T("测试OK"), CMessageBox::MessageType::Pass); } TRACE(" --------------------------------------------------------------"); } void CCMessageBoxDlg::OnBnClickedBtnFail() { // TODO: Add your control notification handler code here if (m_msgBox) { m_msgBox->ShowMessage(_T("测试Fail"), CMessageBox::MessageType::Fail); } TRACE(" --------------------------------------------------------------"); } void CCMessageBoxDlg::OnOK() { // TODO: Add your specialized code here and/or call the base class return; } void CCMessageBoxDlg::OnCancel() { // TODO: Add your specialized code here and/or call the base class return; } void CCMessageBoxDlg::OnClose() { // TODO: Add your message handler code here and/or call default if (m_msgBox != nullptr) { m_msgBox->DestroyWindow(); delete m_msgBox; } CDialogEx::OnCancel(); //CDialogEx::OnClose(); } void CCMessageBoxDlg::OnBnClickedBtnNormal() { // 模态调用 CMessageBox box; box.ShowMessage(_T("正常..."), CMessageBox::MessageType::Normal, true); } void CCMessageBoxDlg::OnBnClickedBtnCustom() { // TODO: Add your control notification handler code here // 模态调用 CMessageBox box; box.SetMessageInfo(_T("测试中..."), RGB(255, 255, 0)); box.ShowMessage(_T(""), CMessageBox::MessageType::Custom, true); }
3.效果图