Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Not able to run message boxes Collapse All
Subject Author Date
lester oidka Jun 7, 2006 - 9:39 AM

Because you wrote me that Prof-uis doesn’t have Message Boxes, I’ve realized I’ll make my own. I’d like to show the message box from a static function, but it always fails - HWND of new window is set to 0x0000000. I am able to create the dialog from any other class but from a static function it never works...
example:
CExtMessageBox::Show(this, _T("some text"), _T("caption"), MB_YESNO); - doesn`t work

but

CExtMessageBox mb2(this, _T("hhhhhhhhhh12356,\nasdg"), _T("kepsn"), MB_OK | MB_ICONEXCLAMATION);
mb2.DoModal(); - works just fine when called from another function - like another dialog or so

------------------------------------------------------------------------------------------------------------------------------------------------------------
next code is my first version of message box:
(... if anyone would like to to copy this - no problem... by the way the icons are not shown yet)

resource.rc - dialog with 2 static boxes and 3 buttons

IDD_MESSAGEBOX_CUSTOM DIALOGEX 0, 0, 188, 87
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CLIPCHILDREN |
WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "",ID_BTN_2,65,66,54,14
PUSHBUTTON "",ID_BTN_3,127,66,54,14
LTEXT "aaa",IDC_MESSAGE,39,7,142,50,SS_WORDELLIPSIS
PUSHBUTTON "",ID_BTN_1,7,66,54,14
LTEXT "",IDC_ICONPLACE,7,7,27,43
END

------------------------------------------------------------------ header file
#pragma once

#define MBS_ABORT _T("PA™eruA?it")
#define MBS_OK _T("Ok")
#define MBS_CANCEL _T("ZruA?it")
#define MBS_RETRY _T("Opakovat")
#define MBS_IGNORE _T("Ignorovat")
#define MBS_YES _T("Ano")
#define MBS_NO _T("Ne")
#define MBS_ERROR _T("Chyba")

int ExtMessageBox(CWnd * pParent, LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK);

// CExtMessageBox dialog

class CExtMessageBox : public CExtResizableDialog
{
    DECLARE_DYNAMIC(CExtMessageBox)

private:
    CExtMessageBox(CWnd* pParent = NULL, LPCTSTR lpszText = NULL, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK); // standard constructor
    virtual ~CExtMessageBox();

public:
// Dialog Data
    enum { IDD = IDD_MESSAGEBOX_CUSTOM };

    static int Show(CWnd * pParent, LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType);

protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

    DECLARE_MESSAGE_MAP()
protected:
    CExtButton m_cButton1, m_cButton2, m_cButton3;
    CExtButton m_cIcon;
    CExtLabel m_cMessage;

    void DesignView();

    int m_iUsedButtonCount; /// count of used buttons - e.g. 2 for MB_YESNO

    CString m_sMessage; /// message to display
    CString m_sLabel; /// label of a message box window
    UINT m_uFlags; /// flags which user passed when called the function

protected:
    afx_msg void OnBnClickedBtn1();
    afx_msg void OnBnClickedBtn2();
    afx_msg void OnBnClickedBtn3();
};

-------------------------------------------------------------- source file
// ExtMessageBox.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "ExtMessageBox.h"
#include ".\extmessagebox.h"

#define PADDING 7

/// public function - shows a message box and returns it’s value
int CExtMessageBox::Show(CWnd * pParent, LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
{
    CExtMessageBox mb(pParent, lpszText, lpszCaption, nType);
    if (!mb.GetSafeHwnd())
        return -1;
    else return mb.DoModal();
}


// CExtMessageBox dialog

IMPLEMENT_DYNAMIC(CExtMessageBox, CExtResizableDialog)
CExtMessageBox::CExtMessageBox(CWnd* pParent, LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
    : CExtResizableDialog (CExtMessageBox::IDD, pParent)
{
    this->m_sMessage = lpszText; /// message to display
    this->m_sLabel = (lpszCaption == NULL)? MBS_ERROR : lpszCaption; /// label of a message box window
    this->m_uFlags = nType; /// flags which user passed when called the function
}

CExtMessageBox::~CExtMessageBox()
{
}

void CExtMessageBox::DoDataExchange(CDataExchange* pDX)
{
    CExtResizableDialog::DoDataExchange(pDX);

    DDX_Control(pDX, ID_BTN_1, m_cButton1);
    DDX_Control(pDX, ID_BTN_2, m_cButton2);
    DDX_Control(pDX, ID_BTN_3, m_cButton3);

    DDX_Control(pDX, IDC_MESSAGE, m_cMessage);
    DDX_Control(pDX, IDC_ICONPLACE, m_cIcon);

    DesignView();
}

void CExtMessageBox::DesignView()
{
    this->m_cButton1.ShowWindow(true);
    this->m_cButton2.ShowWindow(true);
    this->m_cButton3.ShowWindow(true);

    /// set window title
    this->SetWindowText(m_sLabel);

    /// now parse the dialog type
    /// message box is one of:
    /// MB_ABORTRETRYIGNORE The message box contains three pushbuttons: Abort, Retry, and Ignore.
/// MB_OK The message box contains one pushbutton: OK.
/// MB_OKCANCEL The message box contains two pushbuttons: OK and Cancel.
/// MB_RETRYCANCEL The message box contains two pushbuttons: Retry and Cancel.
/// MB_YESNO The message box contains two pushbuttons: Yes and No.
/// MB_YESNOCANCEL The message box contains three pushbuttons: Yes, No, and Cancel.
    if (this->m_uFlags & MB_ABORTRETRYIGNORE)
    {
        this->m_iUsedButtonCount = 3;
        this->m_cButton1.SetWindowText(MBS_ABORT);
        this->m_cButton2.SetWindowText(MBS_RETRY);
        this->m_cButton3.SetWindowText(MBS_IGNORE);
    }
    else if (this->m_uFlags & MB_OKCANCEL)
    {
        this->m_cButton1.SetWindowText(MBS_OK);        
        this->m_cButton2.SetWindowText(MBS_CANCEL);
        this->m_cButton3.ShowWindow(false);
        this->m_cButton3.EnableWindow(false);

        this->m_iUsedButtonCount = 2;
    }
    else if (this->m_uFlags & MB_RETRYCANCEL)
    {
        this->m_cButton1.SetWindowText(MBS_RETRY);
        this->m_cButton2.SetWindowText(MBS_CANCEL);
        this->m_cButton3.ShowWindow(false);
        this->m_cButton3.EnableWindow(false);

        this->m_iUsedButtonCount = 2;
    }
    else if (this->m_uFlags & MB_YESNO)
    {
        this->m_cButton1.SetWindowText(MBS_YES);
        this->m_cButton2.SetWindowText(MBS_NO);
        this->m_cButton3.ShowWindow(false);
        this->m_cButton3.EnableWindow(false);

        this->m_iUsedButtonCount = 2;
    }
    else if (this->m_uFlags & MB_YESNOCANCEL)
    {
        this->m_cButton1.SetWindowText(MBS_YES);
        this->m_cButton2.SetWindowText(MBS_NO);
        this->m_cButton3.SetWindowText(MBS_CANCEL);

        this->m_iUsedButtonCount = 3;
    }
    else // let’s say its MB_OK
    {
        this->m_cButton1.SetWindowText(MBS_OK);
        this->m_cButton2.ShowWindow(false);
        this->m_cButton3.ShowWindow(false);
        this->m_cButton2.EnableWindow(false);
        this->m_cButton3.EnableWindow(false);

        this->m_iUsedButtonCount = 1;
    }

    /// now let’s set the icon - if any
// MB_ICONEXCLAMATION An exclamation-point icon appears in the message box.
// MB_ICONINFORMATION An icon consisting of an "i" in a circle appears in the message box.
// MB_ICONQUESTION A question-mark icon appears in the message box.
// MB_ICONSTOP A stop-sign icon appears in the message box.
    bool bIconUsed = false;

    if (this->m_uFlags & MB_ICONEXCLAMATION)
    {
        bIconUsed = true;
        this->m_cIcon.SetIcon(IDI_EXCLAMATION, 0, 0, 0,32, 32);
    }
else if (this->m_uFlags |MB_ICONINFORMATION)
    {
        this->m_cIcon.SetIcon(IDI_INFORMATION, 0, 0, 0, 32, 32);
        bIconUsed = true;
    }
else if (this->m_uFlags |MB_ICONQUESTION)
    {
        this->m_cIcon.SetIcon(IDI_QUESTION, 0, 0, 0,32, 32);
        bIconUsed = true;
    }
else if (this->m_uFlags |MB_ICONSTOP)
    {
        this->m_cIcon.SetIcon(IDI_ERROR, 0, 0, 0, 32, 32);
        bIconUsed = true;
    }

    if (!bIconUsed) this->m_cIcon.ShowWindow(SW_HIDE);
    else this->m_cIcon.ShowWindow(SW_SHOW);

    /// now we have buttons and the icon set
    /// let’s find the length of a longest line in the string
    CSize maxLen(0,0);
    CSize tmpLen(0,0);
    CString tmpLine;
    int lines = 0;
    int i = 0;
    long strlen = this->m_sMessage.GetLength();
    CPaintDC dc (this);
    
    while (i < strlen)
    {
        lines ++;
        while (this->m_sMessage[i] != ’\n’ && i < strlen)
        {
            tmpLine.AppendChar(m_sMessage[i]);            
            i++;
        }
        i++;

        GetTextExtentPoint(dc.GetSafeHdc(), tmpLine, tmpLine.GetLength(), & tmpLen);

        if (tmpLen.cx > maxLen.cx) maxLen.cx = tmpLen.cx;
        tmpLine = _T("");
        tmpLen.cx = 0;
    }

    TEXTMETRIC metric;
    GetTextMetrics(dc.GetSafeHdc(), & metric);

    /// now we know we have to resize static to fit the text
    if (bIconUsed)
    {
        int iconWidth = GetSystemMetrics(SM_CXICON);
        int iconHeight = GetSystemMetrics(SM_CYICON);

        this->m_cIcon.SetWindowPos(NULL, PADDING, PADDING, PADDING + iconWidth, PADDING + iconHeight, SWP_SHOWWINDOW);    
        this->m_cMessage.SetWindowPos(NULL, 3 * PADDING + iconWidth, PADDING, maxLen.cx, lines * metric.tmHeight, SWP_SHOWWINDOW);
    }
    else
    {
        this->m_cMessage.SetWindowPos(NULL, PADDING, PADDING, maxLen.cx, lines * metric.tmHeight, SWP_SHOWWINDOW);
    }
    this->m_cMessage.SetWindowText(m_sMessage);

    /// and set the window size
    CRect winRect;
    this->GetWindowRect( & winRect);
    CRect messageRect;
    this->m_cMessage.GetWindowRect( & messageRect);
    CRect iconRect;
    this->m_cIcon.GetWindowRect( & iconRect);

    CRect btnSize;
    this->m_cButton1.GetWindowRect(btnSize);
    int buttonWidth = btnSize.Width();
    int buttonHeight = btnSize.Height();

    int winWidth = ((messageRect.right - winRect.left + PADDING) > (buttonWidth * m_iUsedButtonCount + PADDING * (m_iUsedButtonCount + 1)))? (messageRect.right - winRect.left + PADDING) : (buttonWidth * (m_iUsedButtonCount + 1) + PADDING * (m_iUsedButtonCount + 1));
    int winHeight = (iconRect.Height() > messageRect.Height()) ? (iconRect.bottom - winRect.top + 2*PADDING + buttonHeight) : (messageRect.bottom - winRect.top + 2*PADDING + buttonHeight);

    this->SetWindowPos(NULL, winRect.left, winRect.top, winWidth, winHeight, SWP_SHOWWINDOW);

    /// finally position the buttons
    this->GetClientRect( & winRect);

    int buttonTop = winRect.Height() - PADDING - buttonHeight;
    int windowCenter = winRect.Width() / 2;

    switch (m_iUsedButtonCount)
    {
    case 1: /// one button -> in center of a message box
        {
            BOOL b = m_cButton1.SetWindowPos (NULL,
                windowCenter - buttonWidth / 2,
                buttonTop, buttonWidth, buttonHeight, SWP_SHOWWINDOW);
        }
        break;

    case 2: /// two buttons
        {
            m_cButton1.SetWindowPos (NULL,
                windowCenter - buttonWidth - PADDING/2,
                buttonTop, buttonWidth, buttonHeight, SWP_SHOWWINDOW);

            m_cButton2.SetWindowPos (NULL,
                windowCenter + PADDING/2, buttonTop,
                buttonWidth, buttonHeight, SWP_SHOWWINDOW);
        }
        break;

    case 3:
        {
            m_cButton1.SetWindowPos (NULL,
                windowCenter - buttonWidth - buttonWidth / 2 - PADDING,
                buttonTop, buttonWidth, buttonHeight, SWP_SHOWWINDOW);

            m_cButton2.SetWindowPos (NULL,
                windowCenter - buttonWidth / 2,
                buttonTop, buttonWidth, buttonHeight, SWP_SHOWWINDOW);

            m_cButton3.SetWindowPos (NULL,
                windowCenter + buttonWidth / 2 + PADDING,
                buttonTop, buttonWidth, buttonHeight, SWP_SHOWWINDOW);
        }
        break;
    }

}

BEGIN_MESSAGE_MAP(CExtMessageBox, CExtResizableDialog)
    ON_BN_CLICKED(ID_BTN_1, OnBnClickedBtn1)
    ON_BN_CLICKED(ID_BTN_2, OnBnClickedBtn2)
    ON_BN_CLICKED(ID_BTN_3, OnBnClickedBtn3)
END_MESSAGE_MAP()


// CExtMessageBox message handlers

void CExtMessageBox::OnBnClickedBtn1()
{
    if (this->m_uFlags & MB_ABORTRETRYIGNORE)
    {
        this->EndDialog(IDABORT);
    }
    else if (this->m_uFlags & MB_OKCANCEL)
    {
        this->EndDialog(IDOK);
    }
    else if (this->m_uFlags & MB_RETRYCANCEL)
    {
        this->EndDialog(IDRETRY);
    }
    else if (this->m_uFlags & MB_YESNO)
    {
        this->EndDialog(IDYES);
    }
    else if (this->m_uFlags & MB_YESNOCANCEL)
    {
        this->EndDialog(IDYES);
    }
    else // let’s say its MB_OK
    {
        this->EndDialog(IDOK);
    }
}

void CExtMessageBox::OnBnClickedBtn2()
{
        if (this->m_uFlags & MB_ABORTRETRYIGNORE)
    {
        this->EndDialog(IDRETRY);
    }
    else if (this->m_uFlags & MB_OKCANCEL)
    {    
        this->EndDialog(IDCANCEL);
    }
    else if (this->m_uFlags & MB_RETRYCANCEL)
    {
        this->EndDialog(IDCANCEL);
    }
    else if (this->m_uFlags & MB_YESNO)
    {
        this->EndDialog(IDNO);
    }
    else if (this->m_uFlags & MB_YESNOCANCEL)
    {
        this->EndDialog(IDNO);
    }
}

void CExtMessageBox::OnBnClickedBtn3()
{
    if (this->m_uFlags & MB_ABORTRETRYIGNORE)
    {
        this->EndDialog(IDIGNORE);
    }
    else if (this->m_uFlags & MB_YESNOCANCEL)
    {
        this->EndDialog(IDCANCEL);
    }
}

Technical Support Jun 7, 2006 - 11:06 AM

We do not see problems in the source code you provided. We think there must be some resource identifier conflict in your project. Would you create a simple project, insert it into your current Workspace/Solution, copy message box dialog resources and source code into the new project? Please ensure the problem persists in the new project and send it to us.