MFC: диалоговое окно не отображается после нажатия клавиши - PullRequest
0 голосов
/ 21 мая 2011

спасибо за ваше время заранее.

Очень плохо знаком с MFC и пытается завершить проект CS до воскресенья. Мы должны создать простую программу, которая отображает полигоны в сетке. Прямоугольники работают отлично, но когда я начинаю добавлять треугольники, я не могу понять, почему диалоговое окно треугольника отказывается отображаться. Вот некоторый код:

CEquilDialog.h:

 #include <afxwin.h>

class CEquilDialog : public CDialog {
public:
    CEquilDialog();
    afx_msg void OnOK();
    afx_msg void OnCancel();
    int m_nSideLength;
    COLORREF m_Color;
private:
    DECLARE_MESSAGE_MAP()
};

CEquilDialog.cpp:

#include "CEquilDialog.h"
#include "CEquilateralIds.h"

const int TEXT_MAX = 20;

CEquilDialog::CEquilDialog() : CDialog("Equilateral Traingle") {
    m_nSideLength = 0;
}

afx_msg void CEquilDialog::OnOK() {
    char editText[TEXT_MAX + 1];
    CEdit* SideLengthEdit = (CEdit* )(GetDlgItem(IDC_SideLength));
    SideLengthEdit->GetWindowText(editText,TEXT_MAX);
    m_nSideLength = atoi(editText);
    if (m_nSideLength <= 0) {
        EndDialog(!IDOK);
        return;
    }
    int color = GetCheckedRadioButton(IDC_Red, IDC_Blue);
    switch(color) {
        case IDC_Red:
            m_Color = RGB(255,0,0);
            break;
        case IDC_Yellow:
            m_Color = RGB(255,255,0);
            break;
        case IDC_Blue:
            m_Color = RGB(0,0,255);
            break;
        default:
            m_Color = RGB(255,255,255);
    }
    EndDialog(IDOK);
}
afx_msg void CEquilDialog::OnCancel() {
    m_nSideLength = 0;
    EndDialog(!IDOK);
}   

BEGIN_MESSAGE_MAP(CEquilDialog, CDialog)
    ON_COMMAND(IDC_OK, OnOK)
    ON_COMMAND(IDC_Cancel, OnCancel)
END_MESSAGE_MAP()

CEquilateralIds.h

#define IDC_OK          2000
#define IDC_Cancel      2011
#define IDC_SideLength  2012
#define IDC_Red         2013
#define IDC_Yellow      2014
#define IDC_Blue        2015

Equilib.rc (файл ресурсов)

#include <afxres.h>
#include "CEquilateralIds.h"

Equilateral DIALOG 50,50,150,150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Create Triangle"
{
    LTEXT "Enter Side Length", IDC_STATIC, 10, 5, 50, 8
    EDITTEXT IDC_SideLength, 25, 15, 60, 16
    GROUPBOX "Select color", IDC_STATIC, 10, 70, 60+15, 50
    AUTORADIOBUTTON "Red", IDC_Red, 25, 80, 50, 16, WS_GROUP
    AUTORADIOBUTTON "Yellow", IDC_Yellow, 25, 91, 50, 16
    AUTORADIOBUTTON "Blue", IDC_Blue, 25, 102, 50, 16
    PUSHBUTTON "OK", IDC_OK, 10, 125, 30, 15, NOT WS_TABSTOP
    PUSHBUTTON "Cancel", IDC_Cancel, 10+60+15, 125, 30, 15, NOT WS_TABSTOP
}

Весь этот код идентичен моим прямоугольным файлам (те же файлы, только с прямоугольником вместо equil, также с высотой и шириной вместо просто SideLength) - и вот CShapesWin.cpp (где диалоговое окно вызывается):

#include <afxwin.h>
#include "CShapesWin.h"
#include "CRectDialog.h"
#include "CEquilDialog.h"
#include "CRectangleIds.h"
#include "CEquilateralIds.h"

CShapesWin::CShapesWin() {
    Create(NULL, "DrawShapes");
}

afx_msg void CShapesWin::OnPaint() {
    CPaintDC dc(this);
    CRect rect;
    GetClientRect(&rect);
    m_doc.Paint(dc, rect);
}

afx_msg void CShapesWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
    CRectDialog rectDialog;
    CEquilDialog equilDialog;
    switch(nChar) {
        case 38: // Up arrow
        case 40: // Down arrow
            // Pop up a dialog box and get the response
            if (rectDialog.DoModal() == IDOK) {
                if (m_doc.Add(new CRectangle(rectDialog.m_nHeight, 
                    rectDialog.m_nWidth, rectDialog.m_Color)) == TRUE) {
                        Invalidate(TRUE);
                }
            }
            break;
        case 39: // Right arrow
        case 37: // Left arrow
            if (equilDialog.DoModal() == IDOK) {
                if (m_doc.Add(new CEquilateral(equilDialog.m_nSideLength, 
                    equilDialog.m_Color)) == TRUE) {
                        Invalidate(TRUE);
                }
            }
            else {
                MessageBox("Whoops, no dialoge box... :(");
            }
            break;
        default:
            MessageBox("Key not recognized");
    }
}

BEGIN_MESSAGE_MAP(CShapesWin, CFrameWnd)
    ON_WM_PAINT()
    ON_WM_KEYDOWN()
END_MESSAGE_MAP()

При отладке я видел, как вызывается попытка вызова equilDialog.DoModel (), но она происходит каждый раз, в то время как мой rect.Dialog.DoModel () никогда не завершается .... Я полностью потерян, если любой мог бы помочь, я был бы так благодарен!

РЕДАКТИРОВАТЬ: Спасибо, Брайан, Кажется, я забыл, как пользоваться компьютером! Вот публичная ссылка с zip-файлом: http://dl.dropbox.com/u/1734050/SO%20Polygon%20Project.zip

РЕДАКТИРОВАТЬ 2: Мартин, Большое спасибо, единственное, что мне нужно было сделать, это убедиться, что строка в файле CEquilDialog.cpp соответствует в файле ресурсов. Как только я это сделал, диалоговое окно работало как шарм.

ДЛЯ ЛЮБОГО новичка в MFC и проблем с диалоговым окном. Запомните следующее:

В любом из ваших файлов dialog.cpp при объявлении конструктора:

CYourDialog::CYourDialog() : CDialog("StringToMatchInResourceFile") { m_nSomeVariable = 0; }

"StringToMatchInResourceFile" должен также находиться в файле .rc:

#include <afxres.h>
#include "CEquilateralIds.h"

StringToMatchInResourceFile DIALOG 50,50,150,150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
...

То, что я сделал, - это «Равносторонний треугольник» в dialog.cpp, а затем «Равносторонний» в файле .rc. MFC Newbies, * обратите внимание! * a

1 Ответ

4 голосов
/ 21 мая 2011

Ваш ресурс диалога не найден. Когда вы вызываете конструктор базового класса: CDialog («Равносторонние треугольники»), вы сообщаете MFC и диспетчеру диалогов, что у вас есть ресурс шаблона диалога с идентификатором строки «Равносторонние треугольники». Но в вашем файле rc этого нет. У него есть диалоговый ресурс с идентификатором Equносторонний (который я нигде не определяю). Вместо этого добавьте IDD_EQUILATERAL как 101 в equatellids.h и обратитесь к нему в конструкторе CDialog.

Вероятно, это работает правильно для другого случая, потому что ваш идентификатор и его строка совпадают.

В качестве дополнительной точки, без специальной механики вы получаете только один файл .rc на проект. Так что, если случайно у вас есть два файла rc, объедините их в один файл. Это также может пойти не так, потому что второй RC-файл вообще никуда не денется.

Martyn

...