/***********************************************************************/ /* Copyright (C) 2002 Definitive Solutions, Inc. All Rights Reserved. */ /* THIS COMPUTER PROGRAM IS PROPRIETARY AND CONFIDENTIAL TO DEFINITIVE */ /* SOLUTIONS, INC. AND ITS LICENSORS AND CONTAINS TRADE SECRETS OF */ /* DEFINITIVE SOLUTIONS, INC. THAT ARE PROVIDED PURSUANT TO A WRITTEN */ /* AGREEMENT CONTAINING RESTRICTIONS ON USE AND DISCLOSURE. ANY USE, */ /* REPRODUCTION, OR TRANSFER EXCEPT AS PROVIDED IN SUCH AGREEMENT */ /* IS STRICTLY PROHIBITED. */ /***********************************************************************/ #include "stdafx.h" #include "MyMessageBox.h" #include "MyRegistry.h" #include "MyButtonResource.h" #include "MyApp.h" #include "MyLog.h" #include "Generic.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // MyMessageBox dialog // Constructor. (No "Always" support.) MyMessageBox::MyMessageBox(UINT uiText, CWnd* pParent /* = NULL */ , UINT uiHeadline /* = 0U */ , UINT uiStyle /* = MB_OK */ , UINT uiDetailsID /* = 0U */ ) : MyDialog(MyMessageBox::IDD, "MyMessageBox", MYMESSAGEBOX_REGPLACEMENTSKEY_, pParent) , m_uiText(uiText) , m_uiHeadline(uiHeadline) , m_uiStyle(uiStyle) , m_uiDetailsID(uiDetailsID) , m_sFile("") , m_nLine(-1) , m_editText(MYMESSAGEBOX_REGPLACEMENTSKEY_) { CommonConstruct(); m_sText = Generic::LoadString(uiText); } // Constructor. (No "Always" support.) MyMessageBox::MyMessageBox(const CString& sText, CWnd* pParent /* = NULL */ , UINT uiHeadline /* = 0U */ , UINT uiStyle /* = MB_OK */ , UINT uiDetailsID /* = 0U */ ) : MyDialog(MyMessageBox::IDD, "MyMessageBox", MYMESSAGEBOX_REGPLACEMENTSKEY_, pParent) , m_uiHeadline(uiHeadline) , m_uiStyle(uiStyle) , m_uiDetailsID(uiDetailsID) , m_sFile("") , m_nLine(-1) , m_editText(MYMESSAGEBOX_REGPLACEMENTSKEY_) { CommonConstruct(); m_sText = sText; } // "Always" support. MyMessageBox::MyMessageBox(UINT uiText, const CString& sFile, int nLine, CWnd* pParent /* = NULL */ , UINT uiHeadline /* = 0U */ , UINT uiStyle /* = MB_OK */ , UINT uiDetailsID /* = 0U */ ) : MyDialog(MyMessageBox::IDD, "MyMessageBox", MYMESSAGEBOX_REGPLACEMENTSKEY_, pParent) , m_uiHeadline(uiHeadline) , m_uiStyle(uiStyle) , m_uiDetailsID(uiDetailsID) , m_sFile(sFile) , m_nLine(nLine) , m_editText(MYMESSAGEBOX_REGPLACEMENTSKEY_) { CommonConstruct(); m_sText = Generic::LoadString(uiText); } // "Always" support. MyMessageBox::MyMessageBox(const CString& sText, const CString& sFile, int nLine, CWnd* pParent /* = NULL */ , UINT uiHeadline /* = 0U */ , UINT uiStyle /* = MB_OK */ , UINT uiDetailsID /* = 0U */ ) : MyDialog(MyMessageBox::IDD, "MyMessageBox", MYMESSAGEBOX_REGPLACEMENTSKEY_, pParent) , m_uiHeadline(uiHeadline) , m_uiStyle(uiStyle) , m_uiDetailsID(uiDetailsID) , m_sFile(sFile) , m_nLine(nLine) , m_editText(MYMESSAGEBOX_REGPLACEMENTSKEY_) { CommonConstruct(); m_sText = sText; } // ClassWizard hates it when you have AFX_DATA_INIT in more than one place! void MyMessageBox::CommonConstruct() { VALIDATE; //{{AFX_DATA_INIT(MyMessageBox) m_sText = _T(""); m_bAlways = TRUE; //}}AFX_DATA_INIT } // void MyMessageBox::DoDataExchange(CDataExchange* pDX) { MyDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(MyMessageBox) DDX_Control(pDX, IDC_EDIT_MYMESSAGEBOX_TEXT, m_editText); DDX_Control(pDX, IDCANCEL, m_buttonCancel); DDX_Control(pDX, IDOK, m_buttonOk); DDX_Control(pDX, IDC_BUTTON_MYMESSAGEBOX_DETAILS, m_buttonDetails); DDX_Control(pDX, IDC_STATIC_MYMESSAGEBOX_HEADLINE, m_staticHeadline); DDX_Control(pDX, IDC_CHECK_MYMESSAGEBOX_ALWAYS, m_checkAlways); DDX_Text(pDX, IDC_EDIT_MYMESSAGEBOX_TEXT, m_sText); DDX_Check(pDX, IDC_CHECK_MYMESSAGEBOX_ALWAYS, m_bAlways); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(MyMessageBox, MyDialog) //{{AFX_MSG_MAP(MyMessageBox) ON_BN_CLICKED(IDC_BUTTON_MYMESSAGEBOX_DETAILS, OnButtonDetails) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // MyMessageBox message handlers // Handle WM_INITIDIALOG. BOOL MyMessageBox::OnInitDialog() { VALIDATE; MyDialog::OnInitDialog(); ::MessageBeep(m_uiStyle); // Handle the Details button. if (0U == m_uiDetailsID) { m_buttonDetails.ShowWindow(SW_HIDE); } else { m_buttonDetails.SetIcon(IDI_MYMESSAGEBOX, 16, 16); } // Set icons on other buttons. IMPORTANT! These cannot be owner-drawn // buttons, because (stupidly) Microsoft won't let a button have both // BS_OWNERDRAW and BS_DEFPUSHBUTTON styles. //m_buttonOk.SetIcon(IDI_MYBUTTON_OK, 16, 16); //m_buttonCancel.SetIcon(IDI_MYBUTTON_CANCEL, 16, 16); // Handle the Cancel button. BYTE byButtonMask(0x0F); // 00001111 _ASSERTE(MB_YESNO != (byButtonMask & m_uiStyle) && "Not supported - use MB_OK or MB_OKCANCEL instead."); _ASSERTE(MB_YESNOCANCEL != (byButtonMask & m_uiStyle) && "Not supported - use MB_OK or MB_OKCANCEL instead."); _ASSERTE(MB_ABORTRETRYIGNORE != (byButtonMask & m_uiStyle) && "Not supported - use MB_OK or MB_OKCANCEL instead."); _ASSERTE(MB_RETRYCANCEL != (byButtonMask & m_uiStyle) && "Not supported - use MB_OK or MB_OKCANCEL instead."); if (MB_OK == (byButtonMask & m_uiStyle)) { GetDlgItem(IDCANCEL)->ShowWindow(SW_HIDE); } // Hide the "Always" checkbox if this is not in Always-mode. if (-1 == m_nLine) { m_checkAlways.ShowWindow(SW_HIDE); } // Set the font on the headline. m_staticHeadline.SetFontSize(14); m_staticHeadline.SetFontBold(); m_staticHeadline.SetBkColor(RGB_WHITE); // Set the icons, and the title text. HICON hIcon(NULL); CString sTitle; BYTE byIconMask(0xF0); // 11110000 if (MB_ICONSTOP == (byIconMask & m_uiStyle)) { m_staticHeadline.SetBkColor(RGB_RED); hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_ERROR)); sTitle = Generic::LoadString(IDS_MYMESSAGEBOX_WORD_ERROR); } else if (MB_ICONQUESTION == (byIconMask & m_uiStyle)) { m_staticHeadline.SetBkColor(RGB_WHITE); hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION)); sTitle = Generic::LoadString(IDS_MYMESSAGEBOX_WORD_QUESTION); } else if (MB_ICONEXCLAMATION == (byIconMask & m_uiStyle)) { m_staticHeadline.SetBkColor(RGB_YELLOW); hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_EXCLAMATION)); sTitle = Generic::LoadString(IDS_MYMESSAGEBOX_WORD_IMPORTANT); } else if (MB_ICONASTERISK == (byIconMask & m_uiStyle)) { hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_ASTERISK)); sTitle = Generic::LoadString(IDS_MYMESSAGEBOX_WORD_INFORMATION); } else { // Default if none requested. hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_INFORMATION)); sTitle = Generic::LoadString(IDS_MYMESSAGEBOX_WORD_INFORMATION); } // Change the dialog box's title bar text. if (! sTitle.IsEmpty()) { CString sTitleBar; GetWindowText(sTitleBar); sTitle += sTitleBar; SetWindowText(sTitle); } // Set the dialog box icon. if (hIcon) { SetIcon(hIcon, /* bBigIcon */ false); } else { _ASSERTE(! "Error"); DOMYLOGST(API_FAILURE), "::LoadIcon", ::GetLastError(), Generic::GetSysErrorString()); } // Replace any "\n" strings with real CR-LF's. m_sText.Replace("\n", "\r\n"); // Set the headline text, if any was requested. CString sHeadline(sTitle); if (m_uiHeadline) { sHeadline = Generic::LoadString(m_uiHeadline); sHeadline.Replace("\n", "\r\n"); } m_staticHeadline.SetWindowText(sHeadline); // Update the controls. UpdateData(false); // Set the default button. if (MB_DEFBUTTON2 & m_uiStyle) { m_buttonOk.SetButtonStyle(BS_PUSHBUTTON); SetDefID(IDCANCEL); m_buttonCancel.SetButtonStyle(BS_DEFPUSHBUTTON); m_buttonCancel.SetFocus(); } else { m_buttonCancel.SetButtonStyle(BS_PUSHBUTTON); SetDefID(IDOK); m_buttonOk.SetButtonStyle(BS_DEFPUSHBUTTON); m_buttonOk.SetFocus(); } // The only time I've ever used this! return FALSE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } // User wants more details. void MyMessageBox::OnButtonDetails() { VALIDATE; CString sText(Generic::LoadString(m_uiDetailsID)); CString sCaption(Generic::LoadString(IDS_MYMESSAGEBOX_DETAILS_HEADLINE)); MessageBox(sText, sCaption); } // Pop the message box (or maybe not, in "Always" mode. /* virtual */ int MyMessageBox::DoModal() { VALIDATE; // If not in Always-mode, just pop the dialog box and let the user pick. if (-1 == m_nLine) { return CDialog::DoModal(); } else { // In Always mode, we have to check the Registry to see if we should // show the dialog - we default to 'yes'. _ASSERTE(! m_sFile.IsEmpty()); bool bShow(true); MyRegistry reg(HKEY_CURRENT_USER, MYMESSAGEBOX_REGALWAYSKEY_, /* bCreate */ true); if (reg.IsOpen()) { CString sValue; sValue.Format("%s_%d_%s", Generic::TitleFromPath(m_sFile), m_nLine, MYMESSAGEBOX_VERSION_); // If the value isn't there, the user hasn't made a choice yet, // so just to be safe we set this to true (probably not necessary, // but...). if (! reg.ReadValueBool(sValue, bShow)) { bShow = true; } } // Now we either pop the dialog... if (bShow) { return CDialog::DoModal(); } else { // ... or we simply return the OK value. Note this implies that // message boxes should be written such that going into Always mode // requires that OK be the right answer. return IDOK; } } } // User clicked the OK button. /* virtual */ void MyMessageBox::OnOK() { VALIDATE; // Set the Registry state. UpdateData(true); MyRegistry reg(HKEY_CURRENT_USER, MYMESSAGEBOX_REGALWAYSKEY_, /* bCreate */ true); CString sValue; sValue.Format("%s_%d_%s", Generic::TitleFromPath(m_sFile), m_nLine, MYMESSAGEBOX_VERSION_); reg.SaveValueBool(sValue, m_bAlways); // Done. CDialog::OnOK(); }