C ++ / MFC Ошибка доступа к переменной элемента управления - PullRequest
4 голосов
/ 18 января 2012

Я создал переменную элемента управления для CEdit:

class CGateDlg : public CDialog
{
    ...
    public:
        // here is my control's variable
        CEdit m_edit_a;
        // here I map variable to control
        virtual void DoDataExchange(CDataExchange* pDX);
}

И вот как я сопоставляю свою переменную с элементом управления:

void CGateDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_A, m_edit_a);
}

Вот как это работает: пользователь вводит текст в поле для редактирования. Затем он нажимает кнопку «Сброс», которая очищает окно редактирования. Это фрагмент кода, отвечающий за очистку поля редактирования после нажатия кнопки «Сброс»:

void CGateDlg::OnBnClickedReset()
{
    // clear edit box 
    m_edit_a.SetWindowTextW(L"");
}

Приложение запускается без ошибок. Я набираю текст в EditBox и нажимаю кнопку «Сброс». Затем я получаю сообщение об ошибке, которое приводит меня к winocc.cpp, строка 245 (УБЕДИТЕСЬ (это)):

void CWnd::SetWindowText(LPCTSTR lpszString)
{
    ENSURE(this);
    ENSURE(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

    if (m_pCtrlSite == NULL)
            ::SetWindowText(m_hWnd, lpszString);
    else
            m_pCtrlSite->SetWindowText(lpszString);
}

Я думаю, что проблема с hWnd:

this    0x0030fa54 {CEdit hWnd=0x00000000}  CWnd * const

а как это исправить?

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

CEdit *m_edit_a;
m_edit_a = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_A));
m_edit_a->SetWindowTextW(L"");

Что я делаю не так?

Ответы [ 4 ]

8 голосов
/ 18 января 2012

Я вижу две возможности:

  1. Элемент управления не существует при запуске диалога.Первое, что CDialog :: OnInitDialog сделает, это вызов DoDataExchange, поэтому, если вы создаете элемент управления позднее в процессе инициализации, это слишком поздно.

  2. Ваш собственный OnInitDialog не вызывает CDialog:: OnInitDialog, поэтому DoDataExchange не вызывается.

1 голос
/ 18 января 2012

Я думаю, что вы не должны использовать непосредственно свой контроль (в данном случае m_edit_a). Вместо этого вы должны использовать переменную memeber, скажем, CStrimg m_edit_data, и вы должны связать ее с элементом управления:

DDX_Text(pDX, IDC_EDIT_A, m_edit_data); // as you did it in DDC_Cotrol

Теперь вы можете напрямую использовать переменную, но для обновления элемента управления вы должны использовать следующий код перед его использованием:

UpdateData(true); // unlocks the control in a sense
m_edit_data = "this is my test";
UpdateData(false); // locks the control again (in a sense)

Это нормальная процедура в MFC :), надеюсь, я помог ...

ооо ... вы также должны добавить элемент управления в таблицу строк ... (дайте мне знать, если вы не знаете)

0 голосов
/ 28 августа 2015

Если ваш диалог начинается с вызова CDialog :: OnInitDialog (), а ваш DoDataExchange начинает с вызова CDialog :: DoDataExchange, но все же у вас есть нулевые указатели hWnd и выдается исключение CNotSupportedException, убедитесь, что шаблон диалога вашего файла ресурсов (rc) включает все элементы управления (IDC_) и такое у вас есть в DoDataExchange.

Проверьте наличие переопределенных определений при использовании библиотеки DLL, которая также предоставляет ресурсы.

0 голосов
/ 18 января 2012

Не могу найти что-то не так с тобой. Я создаю новый проект с использованием VC6.0 и связываю переменную с правкой, просто сделайте ссылку, которую вы делаете exe работает нормально.

class CEditTestDlg : public CDialog
{
// Construction
public:
CEditTestDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CEditTestDlg)
enum { IDD = IDD_EDITTEST_DIALOG };
CEdit   m_Edit;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditTestDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL

......

.cpp

void CEditTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CEditTestDlg)
    DDX_Control(pDX, IDC_EDIT1, m_Edit);
    //}}AFX_DATA_MAP
}
void CEditTestDlg::OnBnClickedReset() 
{
    // TODO: Add your control notification handler code here
    m_Edit.SetWindowText("tttt");
}

Итак, я думаю, что это не проблема кода. Вам лучше попробовать еще раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...