Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Visual C++ / MFC / WTL > ассерт при попытке доступа к странице свойства


Автор: Cfon 28.02.17, 08:03
как исправить сабж? :wacko:

вот код:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class CMyDlg : public CDialogEx
    {
    // Construction
    public:
        CMyDlg(CWnd* pParent = NULL);   // standard constructor
        ~CMyDlg();
    // Dialog Data
        enum { IDD = IDD_TEST_PROPERTYPAGE };
     
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
     
     
    // Implementation
    protected:
        HICON m_hIcon;
     
        // Generated message map functions
        virtual BOOL OnInitDialog();
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP()
    public:
        CPropertySheet* mSheet;
        CMyPage1* mPage1;
        CMyPage2* mPage2;
        afx_msg void OnBnClickedOk();
    };
     
     
     
     
    CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CMyDlg::IDD, pParent)
        , mSheet(new CPropertySheet)
        , mPage1(new CMyPage1)
        , mPage2(new CMyPage2)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
     
    CMyDlg::~CMyDlg()
    {
        delete mSheet;
        delete mPage1;
        delete mPage2;
    }
     
     
    BOOL CMyDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
     
        // 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
     
        // добавление страниц
        mSheet->AddPage(mPage1);
        mSheet->AddPage(mPage2);
        // создание страницы свойств
        mSheet->Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);
        mSheet->SetWindowPos(NULL, 0,0,0,0, SWP_NOZORDER | SWP_NOSIZE);
        
        return TRUE;  // return TRUE  unless you set the focus to a control
    }
     
     
     
    void CMyDlg::OnBnClickedOk()
    {      
        // тут исключение
        //  V
        CButton *pBtn = static_cast<CButton*>(mPage2->GetDlgItem(IDC_CHECK1));
        
        if (pBtn->GetCheck())
            TRACE(_T("checked\n"));
        else
            TRACE(_T("no check\n"));
     
        CDialogEx::OnOK();
    }

но если сначало переключится на страницу, а затем нажать ОК, то все пучком.

на всякий вот сам проект :D
TestPropertyPage.zip (, : 79)

Автор: Олег М 28.02.17, 08:30
Потому что окно создаётся только при переключении на вкладку

AddPage adds the CPropertyPage object to the CPropertySheet object's list of pages but does not actually create the window for the page. The framework postpones creation of the window for the page until the user selects that page.

Добавлено
Проверяй m_hWnd у mPage2

Автор: Cfon 28.02.17, 10:13
Цитата Олег М @
Потому что окно создаётся только при переключении на вкладку

AddPage adds the CPropertyPage object to the CPropertySheet object's list of pages but does not actually create the window for the page. The framework postpones creation of the window for the page until the user selects that page.

Добавлено
Проверяй m_hWnd у mPage2

да это я понял :D
что делать то? как создать все вкладки?

Добавлено
должна быть функция которая создаёт все страницы, копал но не нашёл

Автор: Cfon 28.02.17, 12:11
Цитата Cfon @
что делать то? как создать все вкладки?

Добавлено
должна быть функция которая создаёт все страницы, копал но не нашёл

затупил конкретно :D :D

после закрытия окна свойства окна страниц уничтожаются, соотвествено будут уничтожены и их контролы :facepalm:

выход? все гениальное просто нужно сохранять состояние в переменных :lool:

Автор: Cfon 01.03.17, 07:18
чтобы не начинать новую тему в продолжение этой задам вопрос здесь:
если изменять значения чекбокса на одной странице (как в моем примере), а затем переключиться на другую страницу и закрыть окно свойств кнопкой отмена то изменения значения чекбокса всеравно сохраняются :wacko:. покопал несколько книжек, погуглил но тщетно. ответа не нашел. что-то я уже подзабыл в MFC. раньше таких проблем у меня не было. Что не так?

Автор: Олег М 01.03.17, 07:24
Ну, тут либо окно не удаляется, проверь. Либо чекбокс у тебя привязан к какой-то переменной, которая сохраняет значение между вызовами.

Автор: Cfon 01.03.17, 12:07
ответ нашел в книжке :wild::
Цитата Круглински "Visual C++ 6"
Обмен данными в окне свойств
Каркас приложений размещает в окне свойств три кнопки. Учтите: каркас вызывает DDX-код для страницы свойств всякий раз, когда пользователь переключается на нее или с нее на другую страницу. Кроме того, как и следовало ожидать, каркас приложений вызывает DDX-код для страницы, когда пользователь щелкает кнопку ОК, обновляя тем самым элементы данных страницы. Теперь понятно, что все элементы данных всех страниц свойств обновляются после щелчка кнопки ОК, и все это без программирования на C++!
Примечание. В обычном модальном диалоговом окне при щелчке кнопки Cancel все изменения теряются, и переменные-члены класса диалогового окна остаются неизменными. Однако в окне свойств переменные-члены обновляются, даже если пользователь модифицирует содержимое одной страницы, переходит к другой, а потом отменяет изменения в окне свойств щелчком кнопки Cancel.

в моем коде как раз была переменная mCheck1Value которая использовалась в DDX, я создал DDX связь по привычке как это делал для простого диалога.

выход? удалить DDX связь (естествено теряется возможность автоматического чтения и записи значения), теперь все пучком, а операции чтения и записи значения сделать вручную, переопределив вирт.функции OnOK и OnInitDialog для CMyPage2. ВСЕ! :D

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)