На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
Страницы: (4) 1 [2] 3 4  все  ( Перейти к последнему сообщению )  
> правильное программирование окна свойств , отмена изменений без проверки значений
    Цитата Cfon @
    все что ты говоришь правильно, но это всего лишь на бумаге а на практике мы имеем дело с MFC.
    по тому что ты пишешь я сделал вывод, что ты никогда не писал на MFC верно? :)

    Т.е. тебе мало обсуждения вопроса по-существу, тебе ещё хочется,
    чтобы я перед тобой оправдывался в чём-то ?
    Да иди ты нафик.
    ---
    Не получится из тебя инженера.
      Цитата ЫукпШ @
      Т.е. тебе мало обсуждения вопроса по-существу, тебе ещё хочется,
      чтобы я перед тобой оправдывался в чём-то ?

      По существу это пространые расуждения? Где конкретика? :)
        Цитата Cfon @
        нет проблем нет, только этот подход не правилен, т.к. каждый символ будет проверяться на соответствие диапазону ввода, а не все введённое число целиком, не?


        Ты получив WM_CHAR формируешь число в памяти какое оно бы было в случае отработки сообщения, проверяешь и дальше либо делаешь обработку, либо нет, либо делаешь обработку но к примеру выделяешь все значение или цвет меняешь.
          Цитата Cfon @
          По существу это пространые расуждения? Где конкретика?


          Вообще, он тебе дело советует.

          Основная идея такая (для диалога с OK, Apply, Cancel):
          У тебя есть набор данных
          При инициализации диалога, та делаешь копию этих данных
          Загружаешь скопированные данные и редактируешь их
          При нажатии OK проверяешь их и сохраняешь в оригинальных данных и закрываешь диалог
          При нажатии Cancel просто закрываешь диалог
          При Apply - тут спорный вопрос, но я бы сделал то же, что и по OK, только без закрытия диалога

          Для окна свойств - тут вот можно тупо проверять/сохранять по killfocus или типа того. По кнопке закрытия только закрывать окно и всё.
            Я бы логически решение сделал так: вводить числа позволял ограничивая по длине, но неправильный ввод бы выделял просто (EM_SETSEL что ли), а если человек после этого ОК или apply то мессвджбокс с пояснением и кнопкой ОК, а потом фокус в это окно.
              короче устал я объяснять :D
              вот еще один чистый пример (заготовка) с реальным диалоговым окном, запрограммируйте так чтобы при отмене не сохранялись значения.
              это не проверка ваших знаний, просто я туплю и не знаю что делать и не обижусь если кому лень, но тока больше не пишите рассуждений, ибо мне не помогает я по прежнему на месте :)

              Прикреплённый файлПрикреплённый файлtest4.zip (83,15 Кбайт, скачиваний: 91)

              пс. VS2015 + MFC. да там надо сохранять тока значения 2ой вкладки (для простоты)

              да еще чуть главное не забыл в пример данные уже не сохраняются при отмене, но тока если не переключаться на другие вкладки, а если переключиться то сохраняться даже если нажать отмену. Я юзал механизм DDX/DDV.
              Сообщение отредактировано: Cfon -
                Цитата Cfon @
                вот еще один чистый пример (заготовка) с реальным диалоговым окном, запрограммируйте так чтобы при отмене не сохранялись значения.

                Что то вообще не понимаю что ты хочешь. Скачал твой проект, запустил. Ткнул в белое пространство, вылез диалог, выставил там какую то муть - нажал Отмена, диалог закрылся, я его заного открыл тем же способом, моих настроек нет. Это неправильно или правильно?
                  Цитата KILLER @
                  Что то вообще не понимаю что ты хочешь. Скачал твой проект, запустил. Ткнул в белое пространство, вылез диалог, выставил там какую то муть - нажал Отмена, диалог закрылся, я его заного открыл тем же способом, моих настроек нет. Это неправильно или правильно?

                  да в том дело ты не переключался с вкладки на вкладку :)
                  еще раз объясню: значения при нажатии ОК сохраняются тут все пучком, но если задать значения и переключиться на другую вкладку а потом нажать отмену, то тоже сохраняются а не должно по логике :)
                  Сообщение отредактировано: Cfon -
                    Самое простое, в лоб:
                    DisplayPage.h
                    ExpandedWrap disabled
                      #pragma once
                      #include "afxcmn.h"
                      #include "afxwin.h"
                       
                       
                      // CDisplayPage dialog
                       
                      class CDisplayPage : public CPropertyPage
                      {
                          DECLARE_DYNAMIC(CDisplayPage)
                       
                      public:
                          CDisplayPage();
                          virtual ~CDisplayPage();
                       
                      // Dialog Data
                      #ifdef AFX_DESIGN_TIME
                          enum { IDD = IDD_DISPLAY };
                      #endif
                       
                      protected:
                          virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
                       
                          DECLARE_MESSAGE_MAP()
                      public:
                          CSpinButtonCtrl mMagnifyGlassSizeSpin;
                          CSliderCtrl mMagnifyGlasSizeSlider;
                          CComboBox mMagnifyGlassZoomCombo;
                          CButton mDrawBorderCheck;
                          CComboBox mKeyCombo;
                          CButton mToolbarEnableCheck;
                          CButton mToolbarAutoHideCheck;
                          virtual BOOL OnInitDialog();
                          afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
                          afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
                       
                      public:
                          virtual void OnCancel();
                       
                      private:
                          UINT mMagnifyGlassSizeValueDefault;
                          int mMagnifyGlassZoomIndexDefault;
                          BOOL mDrawBorderValueDefault;
                          int mKeyIndexDefault;
                          BOOL mToobarEnableValueDefault;
                          BOOL mToobarAutoHideValueDefault;
                       
                          UINT mMagnifyGlassSizeValue;
                          int mMagnifyGlassZoomIndex;
                          BOOL mDrawBorderValue;
                          int mKeyIndex;
                          BOOL mToobarEnableValue;
                          BOOL mToobarAutoHideValue;
                       
                      };

                    DisplayPage.cpp
                    ExpandedWrap disabled
                      // DisplayPage.cpp : implementation file
                      //
                       
                      #include "stdafx.h"
                      #include "test4.h"
                      #include "DisplayPage.h"
                      #include "afxdialogex.h"
                       
                       
                      // CDisplayPage dialog
                       
                      IMPLEMENT_DYNAMIC(CDisplayPage, CPropertyPage)
                       
                      CDisplayPage::CDisplayPage()
                          : CPropertyPage(IDD_DISPLAY)
                          , mMagnifyGlassSizeValue(100)
                          , mMagnifyGlassZoomIndex(1)
                          , mDrawBorderValue(FALSE)
                          , mKeyIndex(0)
                          , mToobarEnableValue(FALSE)
                          , mToobarAutoHideValue(FALSE)
                      {
                       
                      }
                       
                      CDisplayPage::~CDisplayPage()
                      {
                      }
                       
                      void CDisplayPage::DoDataExchange(CDataExchange* pDX)
                      {
                          CPropertyPage::DoDataExchange(pDX);
                          DDX_Control(pDX, IDC_MAGNIFYGLASS_SIZE_SPIN, mMagnifyGlassSizeSpin);
                          DDX_Control(pDX, IDC_MAGNIFYGLASS_SIZE_SLIDER, mMagnifyGlasSizeSlider);
                          DDX_Control(pDX, IDC_MAGNIFYGLASS_ZOOM_COMBO, mMagnifyGlassZoomCombo);
                          DDX_Control(pDX, IDC_DRAWBORDER_CHECK, mDrawBorderCheck);
                          DDX_Control(pDX, IDC_KEY_COMBO, mKeyCombo);
                          DDX_Control(pDX, IDC_TOOLBAR_ENABLE_CHECK, mToolbarEnableCheck);
                          DDX_Control(pDX, IDC_TOOLBAR_AUTOHIDE_CHECK, mToolbarAutoHideCheck);
                       
                          DDX_Text(pDX, IDC_MAGNIFYGLASS_SIZE_EDIT, mMagnifyGlassSizeValueDefault);
                          DDV_MinMaxUInt(pDX, mMagnifyGlassSizeValueDefault, 50, 300);
                          DDX_CBIndex(pDX, IDC_MAGNIFYGLASS_ZOOM_COMBO, mMagnifyGlassZoomIndexDefault);
                          DDX_Check(pDX, IDC_DRAWBORDER_CHECK, mDrawBorderValueDefault);
                          DDX_CBIndex(pDX, IDC_KEY_COMBO, mKeyIndexDefault);
                          DDX_Check(pDX, IDC_TOOLBAR_ENABLE_CHECK, mToobarEnableValueDefault);
                          DDX_Check(pDX, IDC_TOOLBAR_AUTOHIDE_CHECK, mToobarAutoHideValueDefault);
                       
                      }
                       
                       
                      BEGIN_MESSAGE_MAP(CDisplayPage, CPropertyPage)
                          ON_WM_VSCROLL()
                          ON_WM_HSCROLL()
                      END_MESSAGE_MAP()
                       
                       
                      // CDisplayPage message handlers
                       
                       
                      BOOL CDisplayPage::OnInitDialog()
                      {
                          CPropertyPage::OnInitDialog();
                       
                          const int cBegin = 50;
                          const int cEnd = 300;
                          const int cStep = 10;
                       
                          mMagnifyGlassSizeSpin.SetRange(cBegin, cEnd);
                          mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeValueDefault);
                       
                          mMagnifyGlasSizeSlider.SetRange(cBegin, cEnd);
                          
                          for (int i = cBegin; i < cEnd; i += cStep)
                          {
                              mMagnifyGlasSizeSlider.SetTic(i);
                          }
                          mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSpin.GetPos());
                       
                          SetDlgItemInt(IDC_BEGINRANGE_TXT, cBegin);
                          SetDlgItemInt(IDC_ENDRANGE_TXT, cEnd);
                          
                          mMagnifyGlassZoomCombo.AddString(_T("2x"));
                          mMagnifyGlassZoomCombo.AddString(_T("3x"));
                          mMagnifyGlassZoomCombo.AddString(_T("4x"));
                          mMagnifyGlassZoomCombo.AddString(_T("5x"));
                          mMagnifyGlassZoomCombo.SetCurSel(mMagnifyGlassZoomIndexDefault);
                          
                          //mDrawBorderCheck.SetCheck(mDrawBorderValue);
                          
                          mKeyCombo.AddString(_T("SHIFT"));
                          mKeyCombo.AddString(_T("CTRL"));
                          mKeyCombo.SetCurSel(mKeyIndexDefault);
                       
                          mMagnifyGlassSizeValue = mMagnifyGlassSizeSpin.GetPos();
                          mMagnifyGlassZoomIndex = mMagnifyGlassZoomCombo.GetCurSel();
                          mDrawBorderValue = mDrawBorderCheck.GetCheck();
                          mKeyIndex = mKeyCombo.GetCurSel();
                          mToobarEnableValue = mToolbarEnableCheck.GetCheck();
                          mToobarAutoHideValue = mToolbarAutoHideCheck.GetCheck();
                       
                          
                          
                          //mToolbarEnableCheck.SetCheck(mToobarEnableValue);
                          //mToolbarAutoHideCheck.SetCheck(mToobarAutoHideValue);
                       
                          return TRUE;  // return TRUE unless you set the focus to a control
                                        // EXCEPTION: OCX Property Pages should return FALSE
                      }
                       
                       
                      void CDisplayPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
                      {
                          if (pScrollBar->GetDlgCtrlID() == IDC_MAGNIFYGLASS_SIZE_SPIN)
                          {
                              mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSpin.GetPos());
                          }
                          
                          CPropertyPage::OnVScroll(nSBCode, nPos, pScrollBar);
                      }
                       
                       
                      void CDisplayPage::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
                      {
                          if (pScrollBar->GetDlgCtrlID() == IDC_MAGNIFYGLASS_SIZE_SLIDER)
                          {
                              mMagnifyGlassSizeSpin.SetPos(mMagnifyGlasSizeSlider.GetPos());      
                          }
                       
                          CPropertyPage::OnHScroll(nSBCode, nPos, pScrollBar);
                      }
                       
                      void CDisplayPage::OnCancel()
                      {
                          mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeValue);
                          mMagnifyGlassZoomCombo.SetCurSel(mMagnifyGlassZoomIndex);
                          mDrawBorderCheck.SetCheck(mDrawBorderValue);
                          mKeyCombo.SetCurSel(mKeyIndex);
                          mToolbarEnableCheck.SetCheck(mToobarEnableValue);
                          mToolbarAutoHideCheck.SetCheck(mToobarAutoHideValue);
                       
                          UpdateData(true);
                       
                          __super::OnCancel();
                      }


                    Добавлено
                    Ну и похорошему, там в конструктор надо добавить инициализацию новых членов, я видимо забыл. Но вообще там можно просто запилить какой нибудь класс, который будет сохранять начальное состояние всех контролов диалога в OnInitDialog, и в случае нажатия Cancel в обработчике - OnCancel - просто скидывать состояние всех котролов в начальные, сохраненные значения.

                    Добавлено
                    Ну и вообще, в своем классе CDisplayPage ты можешь переопределить еще такие методы(по принципу OnCancel, как я добавил):
                    ExpandedWrap disabled
                          virtual BOOL OnApply();
                          virtual void OnOK();
                          virtual void OnCancel();
                          virtual BOOL OnSetActive();
                          virtual BOOL OnKillActive();

                    И в них реализовать валидацию значений(кроме OnCancel и OnSetActive), написать функцию валидации всех контролов, и вызывать ее в этих обработчиках, и если что то не то - то выводить MessageBox и не вызывать у родителя обработчик, тогда не придется все это в onKillFocus'e пилить, и например на другую вкладку ты не перейдешь, пока не введешь корректные данные в текущую.ю
                    Сообщение отредактировано: KILLER -
                      Цитата KILLER @
                      Самое простое, в лоб:

                      спс большое ;)
                      пока не проверял, но чуйка говорит что ты правильно сделал
                      позже проверю отпишусь :D
                        есть на ж*** шерсть :D получилось все работает! :dance:
                        еще раз Киллер СПАСИБО! :victory:
                        ExpandedWrap disabled
                          class CDisplayPage : public CPropertyPage
                          {
                              DECLARE_DYNAMIC(CDisplayPage)
                           
                          public:
                              CDisplayPage();
                              virtual ~CDisplayPage();
                           
                          // Dialog Data
                          #ifdef AFX_DESIGN_TIME
                              enum { IDD = IDD_DISPLAY };
                          #endif
                           
                          protected:
                              virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
                              virtual BOOL OnInitDialog();
                              virtual void OnCancel();
                           
                              DECLARE_MESSAGE_MAP()
                              afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
                              afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
                          public:
                              CSpinButtonCtrl mMagnifyGlassSizeSpin;
                              CSliderCtrl mMagnifyGlasSizeSlider;
                              CComboBox mMagnifyGlassZoomCombo;
                              CButton mDrawBorderCheck;
                              CComboBox mKeyCombo;
                              CButton mToolbarEnableCheck;
                              CButton mToolbarAutoHideCheck;
                           
                           
                              struct DisplayData
                              {
                                  UINT magnifyGlassSizeValue;
                                  int magnifyGlassZoomIndex;
                                  BOOL drawBorderState;
                                  int keyIndex;
                                  BOOL toolbarEnableState;
                                  BOOL toolbarAutoHideState;
                              } mDisplayData;
                           
                           
                              UINT mMagnifyGlassSizeValue;
                              int mMagnifyGlassZoomIndex;
                              BOOL mDrawBorderState;
                              int mKeyIndex;
                              BOOL mToolbarEnableState;
                              BOOL mToolbarAutoHideState;
                          };
                           
                           
                          BOOL CDisplayPage::OnInitDialog()
                          {
                              CPropertyPage::OnInitDialog();
                           
                              TRACE(_T("mMagnifyGlassSizeValue = %d\n"), mMagnifyGlassSizeValue);
                           
                              mDisplayData.drawBorderState = mDrawBorderState;
                              mDisplayData.keyIndex           = mKeyIndex;
                              mDisplayData.magnifyGlassSizeValue = mMagnifyGlassSizeValue;
                              mDisplayData.magnifyGlassZoomIndex = mMagnifyGlassZoomIndex;
                              mDisplayData.toolbarAutoHideState = mToolbarAutoHideState;
                              mDisplayData.toolbarEnableState = mToolbarEnableState;
                          ................
                           
                           
                          void CDisplayPage::OnCancel()
                          {  
                              TRACE(_T("CDisplayPage::OnCancel\n"));
                              
                              mMagnifyGlassSizeValue = mDisplayData.magnifyGlassSizeValue;
                              mMagnifyGlassZoomIndex = mDisplayData.magnifyGlassZoomIndex;
                              mDrawBorderState = mDisplayData.drawBorderState;
                              mKeyIndex = mDisplayData.keyIndex;
                              mToolbarEnableState = mDisplayData.toolbarEnableState;
                              mToolbarAutoHideState = mDisplayData.toolbarAutoHideState;
                           
                              TRACE(_T("mMagnifyGlassSizeValue = %d\n"), mMagnifyGlassSizeValue);
                           
                              CPropertyPage::OnCancel();  
                          }

                        вот что значит свежая голова, а то моя забилась, вскипела :D
                        Сообщение отредактировано: Cfon -
                          Ну и валидацию запили в отдельный метод и вызывай ее внутри вот этих методов:
                          ExpandedWrap disabled
                               virtual BOOL OnApply();
                                virtual void OnOK();
                                virtual BOOL OnKillActive()

                          Если все ок - тогда для OnApply и OnKillFocus пишешь return __super::OnKillActive, иначе return FALSE, тогда ты можешь в пределах одной страницы редактировать как хочешь и вписывать даже неверные значения, но как только нажмешь OK/Apply или захочешь переключиться на другую страницу - тебе выскочит окно с ошибкой и не даст этого сделать, пока не введешь корректные значения. И тогда не нужно будет заморачиваться с OnKillFocus'ом.
                            Цитата KILLER @
                            Ну и валидацию запили в отдельный метод и вызывай ее внутри вот этих методов:
                            ExpandedWrap disabled
                                 virtual BOOL OnApply();
                                  virtual void OnOK();
                                  virtual BOOL OnKillActive()

                            Если все ок - тогда для OnApply и OnKillFocus пишешь return __super::OnKillActive, иначе return FALSE, тогда ты можешь в пределах одной страницы редактировать как хочешь и вписывать даже неверные значения, но как только нажмешь OK/Apply или захочешь переключиться на другую страницу - тебе выскочит окно с ошибкой и не даст этого сделать, пока не введешь корректные значения. И тогда не нужно будет заморачиваться с OnKillFocus'ом.

                            спс нужное направление задано разберемся :)
                            да и OnKillFocus я уже здесь не юзаю, через DDV делаю валидацию DDV_MinMaxUInt(pDX, mMagnifyGlassSizeValue, 50, 300).
                            Сообщение отредактировано: Cfon -
                              а что за вирт функция CPropertyPage::OnReset зачем она нужна? что то не понял я ее отличия от OnCancel.
                              думал что она обрабатывает кнопку Reset, но не нашел ее, пришлось вручную добавить весь код.
                              и еще как теперь изменить Tab Order? кнопка Reset создается, располагается как надо, но порядок обхода естественно не правлиьный.
                              Также попутно есть ли способ в VS2015 создать обработчик нажатия кнопки, созданой ручками, не ручками? :D
                              Сообщение отредактировано: Cfon -
                                Цитата Cfon @
                                и еще как теперь изменить Tab Order?

                                Ctrl+D, или меню Format->Tab Order.

                                Цитата Cfon @
                                а что за вирт функция CPropertyPage::OnReset зачем она нужна? что то не понял я ее отличия от OnCancel.

                                Могу предположить, что эта херня просто сбрасывает данные в начальное состояние, без закрытия диалога настроек, а Cancel - отменяет все изменения и закрывает диалог. Но это я так предполагаю, как то не шибко часто встречался с этим обработчиком.

                                Цитата Cfon @
                                Также попутно есть ли способ в VS2015 создать обработчик нажатия кнопки, созданой ручками, не ручками? :D

                                Не понял. Но вообще можно. В самом запущенном случае, я например вручную рисовал кнопку руками, пилил для нее обработчик события(свой класс, без использования MFC функций), расчитывал в ручную координаты клика(попали или нет по нарисованной кнопке,), делал анимацию нажатия вручную. Т.е. в твоем случае можно. Только я не понял что имелось ввиду под "созданой ручками, не ручками" ?
                                Сообщение отредактировано: KILLER -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (4) 1 [2] 3 4  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0671 ]   [ 19 queries used ]   [ Generated: 28.03.24, 08:48 GMT ]