На главную Наши проекты:
Журнал   ·   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
  
> правильное программирование окна свойств , отмена изменений без проверки значений
    Здрасте, тут такое дело я запуталси :D

    вообщем есть некое окно свойств для установки значений, там как полагается кнопки ОК, Отмена, Применить. все работатет но есть одна заминка. есть одна проверка на ввод диапозона чисел в CEdit, она реализована в обработчике OnEnKillfocus и все б норм ток если жать Отмену и при этом введеное число не попадает в правильный диапозон, то естествено окно не закрывается, а выходит мессаж об ошибке ввода пока не заполнить правильным значением. вот теперь не знаю как быть и что делать.

    если надо могу прилепить проект, а пока вот часть кода хотя она не очем не скажет :D

    ExpandedWrap disabled
      void CPage4::OnEnKillfocusFontsize()
      {
          TRACE("CPage4::OnEnKillfocusFontsize\n");
          int minVal = 8;
          int maxVal = 24;
          int value = GetDlgItemInt(IDC_FONTSIZE);    
          TRACE("mFontSize = %d\n", mFontSize);
          TRACE("value = %d\n", value);
       
          //if (mCancel) return;
       
          if (value < minVal || value > maxVal)
          {  
              AfxMessageBox(_T("Enter value between 8 and 24"), MB_ICONEXCLAMATION);              
              mPropSheet->SetActivePage(3);
          }
          else
              SetModified(TRUE);
      }
      Цитата Cfon @
      вообщем есть некое окно свойств для установки значений, там как полагается кнопки ОК, Отмена, Применить. все работатет но есть одна заминка. есть одна проверка на ввод диапозона чисел в CEdit, она реализована в обработчике OnEnKillfocus и все б норм ток если жать Отмену и при этом введеное число не попадает в правильный диапозон, то естествено окно не закрывается, а выходит мессаж об ошибке ввода пока не заполнить правильным значением. вот теперь не знаю как быть и что делать.


      А зачем ты так делаешь в killfocus. Это сообщение посылается всегда, когда ты выходишь из контрола, независимо куда. Там надо выводить не MesageBox, а какое-нибудь неблокирующее сообщение, например в Static.
      А MessageBoxы надо делать при нажатии на кнопку OK.
        Цитата Олег М @
        А зачем ты так делаешь в killfocus. Это сообщение посылается всегда, когда ты выходишь из контрола, независимо куда. Там надо выводить не MesageBox, а какое-нибудь неблокирующее сообщение, например в Static.
        А MessageBoxы надо делать при нажатии на кнопку OK.

        нет не помогло также не закрывает окно при отмене :no-sad:
        ExpandedWrap disabled
          void CPage4::OnEnKillfocusFontsize()
          {
              TRACE("CPage4::OnEnKillfocusFontsize\n");
              const int minVal = 8;
              const int maxVal = 24;
              //int value = GetDlgItemInt(IDC_FONTSIZE);  
              //TRACE("mFontSize = %d\n", mFontSize);
              TRACE("value = %d\n", value);
           
              //if (mCancel) return;
           
              if (value < minVal || value > maxVal)
              {  
                  //AfxMessageBox(_T("Enter value between 8 and 24"), MB_ICONEXCLAMATION);
                  SetDlgItemText(IDC_ERRORMESSAGE, _T("Enter value between 8 and 24"));
                  mPropSheet->SetActivePage(this);
              }
              else
                  SetModified(TRUE);
          }
        Сообщение отредактировано: Cfon -
          Цитата Cfon @
          вообщем есть некое окно свойств для установки значений, там как полагается кнопки ОК, Отмена, Применить.
          .. если жать Отмену и при этом введеное число не попадает в правильный диапозон, то естествено окно не закрывается,...

          Так если ты выбрал "отмена", значит должны быть возвращено старое значение, которое было.
          Значит, перед показом диалога где-то должна быть спасена старая версия предыдущих
          "вполне павильных" значений. Отмена означает их возврат в том числе в окна редактирования.
          Такая логика работы позволяет использовать "Отмена" даже после многочисленных "Применить".
          По-применял -> не понравилось -> Отменил, вернулся к старым значениям.
          ---
          Или делай в обработчике автомат состояний. Если последней операцией была "отмена" - значит проверка
          на диапазон правильных значенй не производится.
          Сообщение отредактировано: ЫукпШ -
            Когда знаешь диапазон верных значение, то можно не давать ввести неверное, т.е. обрабатывать WM_CHAR
              Цитата ЫукпШ @
              Так если ты выбрал "отмена", значит должны быть возвращено старое значение, которое было.
              Значит, перед показом диалога где-то должна быть спасена старая версия предыдущих
              "вполне павильных" значений. Отмена означает их возврат в том числе в окна редактирования.
              Такая логика работы позволяет использовать "Отмена" даже после многочисленных "Применить".
              По-применял -> не понравилось -> Отменил, вернулся к старым значениям.
              ---
              Или делай в обработчике автомат состояний. Если последней операцией была "отмена" - значит проверка
              на диапазон правильных значенй не производится.

              с логикой проблем нет, проблема в том что окно свойств не закрыть в моей случае даже если нажать отмену :no-sad:

              Цитата ter_nk_ @
              Когда знаешь диапазон верных значение, то можно не давать ввести неверное, т.е. обрабатывать WM_CHAR

              сам то пробовал обработку WM_CHAR на проверку ввода диапозона значений, например от 8 до 24? :D

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

              это не правильной программирование не качайте его, в самом низу есть другой полное демо как надо :D
              Сообщение отредактировано: Cfon -
                Цитата Cfon @
                с логикой проблем нет, проблема в том что окно свойств не закрыть в моей случае даже если нажать отмену :no-sad:

                К закрытию окна указанная логика работы отношения не имеет.. почти.
                Если окно не закрывается, то восстановление первоначальных данных
                по событию "Отмена" (в том числе и в окошках ввода) как раз весьма актуально !
                ---
                Что касается сообщения - MessageBox это не удобно.
                Если обработчиком обнаружена ошибка в числах, можно изменить неверный параметр
                на его граничное значение. Подробное описание назначения параметра, граничных значений
                и произошедшей ошибки можно представить в тул-типе.
                Сообщение отредактировано: ЫукпШ -
                  Цитата ЫукпШ @
                  К закрытию окна указанная логика работы отношения не имеет.. почти.
                  Если окно не закрывается, то восстановление первоначальных данных
                  по событию "Отмена" (в том числе и в окошках ввода) как раз весьма актуально !
                  ---
                  Что касается сообщения - MessageBox это не удобно.
                  Если обработчиком обнаружена ошибка в числах, можно изменить неверный параметр
                  на его граничное значение. Подробное описание назначения параметра, граничных значений
                  и произошедшей ошибки можно представить в тул-типе.

                  ясно спс, будем думать :D
                  кстати наш диалог будет более продуктивнее если ты запустишь мой примерчик и поймёшь о чем я толкую :D ж
                    Цитата Cfon @
                    сам то пробовал обработку WM_CHAR на проверку ввода диапозона значений, например от 8 до 24? :D


                    А в чем проблема? Когда символ уже есть то второй либо игнорируется, если число уже не будет соответствовать или ставится.
                      Цитата Cfon @
                      кстати наш диалог будет более продуктивнее если ты запустишь мой примерчик и поймёшь о чем я толкую :D ж

                      я и не против - но исполнимого файла в архиве нет,
                      а собирать из исходников не буду.
                        Цитата ter_nk_ @
                        А в чем проблема? Когда символ уже есть то второй либо игнорируется, если число уже не будет соответствовать или ставится.

                        нет проблем нет, только этот подход не правилен, т.к. каждый символ будет проверяться на соответствие диапазону ввода, а не все введённое число целиком, не? :whistle:

                        Цитата ЫукпШ @
                        я и не против - но исполнимого файла в архиве нет,
                        а собирать из исходников не буду.

                        ок позже запостю ехе файл :)
                        Сообщение отредактировано: Cfon -
                          много гуглил ничего толком не нашел, в основном лажу :D

                          решил по другому точнее по старому через DDX/DDV( валидация DDV мне подходит).
                          нужно было решить как быть чтобы изменения, которые сохранялись при переходе с вкладки на вкладку(речь идет о диалоге в несколькими вкладками), при отмене не сохранялись, решение простое хранить старое значение, а потом восстанавливать, если оно было отменено :D

                          поскольку в CPropertySheet нет обработчиков на OK, Cancel, Apply, то обработал OnCommand:
                          ExpandedWrap disabled
                            BOOL CPropSheet::OnCommand(WPARAM wParam, LPARAM lParam)
                            {
                                TRACE(_T("CPropSheet::OnCommand\n"));
                                UINT nID = LOWORD(wParam);
                                    
                                if (nID == IDCANCEL)
                                {
                                    TRACE(_T("IDCANCEL\n"));
                                    TRACE("mEditValue = %d\n", mPage2.EditValue());
                                    TRACE("mEditOldValue = %d\n", mPage2.EditOldValue());
                                    mPage2.EditValue(mPage2.EditOldValue());
                                }
                                
                                return CPropertySheet::OnCommand(wParam, lParam);
                            }



                          Вопрос решен, но если у вас есть что сказать вельком! :D
                          Сообщение отредактировано: Cfon -
                            возникла одна трабла мой вариант обрабатывал нажатие кнопки Отмена, но не нажатие кнопки Закрыть, та что в правом верхнем углу :D
                            короче запуталси я уж слишком много чего завязано тут надо снава разбирать :wacko:
                            Вопрос не решен однако :D
                              Цитата Cfon @
                              возникла одна трабла мой вариант обрабатывал нажатие кнопки Отмена, но не нажатие кнопки Закрыть, та что в правом верхнем углу :D
                              короче запуталси я ...

                              Всё же от тебя зависит.
                              Какую именно логику работы ты желаешь - такую и реализуй.
                              Что именно необходимо сделать по событию "закрыть окно" ?
                              В простейшем случае это эквивалент кнопки "Отмена".
                              Значит, напижем процедуру "OnCancel" и вызовем её из обоих
                              обработчиков.
                              При этом очевидно, что OnCancel это OnApply, но с изначальными
                              (спасёнными перед показом диалога) параметрами...
                              (Но не всегда, а только тогда, когда новые параметры не равны спасённым или
                              использовалась кнопка "Применить" с параметрами, не равными спасённым)
                              Если кнопка "Закрыть" вызывает у тебя сложности понимания, вообще
                              создай диалог без неё.
                              Сообщение отредактировано: ЫукпШ -
                                Цитата ЫукпШ @
                                Всё же от тебя зависит.
                                Какую именно логику работы ты желаешь - такую и реализуй.
                                Что именно необходимо сделать по событию "закрыть окно" ?
                                В простейшем случае это эквивалент кнопки "Отмена".
                                Значит, напижем процедуру "OnCancel" и вызовем её из обоих
                                обработчиков.
                                При этом очевидно, что OnCancel это OnApply, но с изначальными
                                (спасёнными перед показом диалога) параметрами...
                                (Но не всегда, а только тогда, когда новые параметры не равны спасённым или
                                использовалась кнопка "Применить" с параметрами, не равными спасённым)
                                Если кнопка "Закрыть" вызывает у тебя сложности понимания, вообще
                                создай диалог без неё.

                                все что ты говоришь правильно, но это всего лишь на бумаге а на практике мы имеем дело с MFC.
                                по тому что ты пишешь я сделал вывод, что ты никогда не писал на MFC верно? :)
                                  Цитата Cfon @
                                  все что ты говоришь правильно, но это всего лишь на бумаге а на практике мы имеем дело с MFC.
                                  по тому что ты пишешь я сделал вывод, что ты никогда не писал на MFC верно? :)

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

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


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


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

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

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

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

                                            пс. 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 -
                                                                Цитата KILLER @
                                                                Цитата Cfon @
                                                                и еще как теперь изменить Tab Order?

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

                                                                нет ты не понял, надо в ран-тайм. я создаю кнопку Reset вот ее надо вставить в tab order.

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

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

                                                                в том и дело, что я тоже предполагал это, но где кнопка которая ее вызывает? выяснил что ее вызывает кнопка Cancel. вот я и не пойму ее смысл.
                                                                думал что она (Reset) уже есть в CPropertySheet,точнее в ее ресурсах, но не нашел, поэтому создал свою кнопку в ран-тайм.

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

                                                                Не понял. Но вообще можно. В самом запущенном случае, я например вручную рисовал кнопку руками, пилил для нее обработчик события(свой класс, без использования MFC функций), расчитывал в ручную координаты клика(попали или нет по нарисованной кнопке,), делал анимацию нажатия вручную. Т.е. в твоем случае можно. Только я не понял что имелось ввиду под "созданой ручками, не ручками" ?

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

                                                                уже разобрался Class Wizard позволит сделать все за нас :D
                                                                Сообщение отредактировано: Cfon -
                                                                  Цитата Cfon @
                                                                  нет ты не понял, надо в ран-тайм. я создаю кнопку Reset вот ее надо вставить в tab order.

                                                                  В какой Tab Order? Я же тебе написал, открываешь свой диалог - меню Format -> Tab Order, там выставляешь порядок обхода контролов, либо в ресурсном файле - все элементы управления, располагаются в шаблоне диалога строго друг за дружкой, как выставленно в Tab Order, если там изменить порядок - тогда и Tab Order поменяется. Ну или можно программно, через SetWindowPos -> https://msdn.microsoft.com/en-us/library/ms...545(VS.85).aspx или вот тут пример есть -> http://www.devx.com/tips/Tip/27741
                                                                  Но я программно не заморачивался с этим, хотя судя по доке там проще простого, указываешь хендл ЭУ которому нужно поменять Tab Order, указываешь хендл ЭУ за кем он будет располагаться, ну и флаги с координатами.

                                                                  Цитата Cfon @
                                                                  в том и дело, что я тоже предполагал это, но где кнопка которая ее вызывает? выяснил что ее вызывает кнопка Cancel. вот я и не пойму ее смысл.

                                                                  Я хз, тогда надо читать доку.

                                                                  Цитата Cfon @
                                                                  я имел ввиду в студии есть помошники для автоматизации это процесса.

                                                                  Да есть, берешь открываешь диалог, и жмешь два раза мышкой по кнопке, среда для тебя сгенерирует обработчик события и перенесет курсов в код, в этот новый сгенерированный обработчик.
                                                                  Сообщение отредактировано: KILLER -
                                                                    Цитата KILLER @
                                                                    Ну или можно программно, через SetWindowPos -> https://msdn.microsoft.com/en-us/library/ms...545(VS.85).aspx или вот тут пример есть -> http://www.devx.com/tips/Tip/27741
                                                                    Но я программно не заморачивался с этим, хотя судя по доке там проще простого, указываешь хендл ЭУ которому нужно поменять Tab Order, указываешь хендл ЭУ за кем он будет располагаться, ну и флаги с координатами.

                                                                    если все контролы в ресурсе, то да нет нужды, но я создаю кнопку Reset программно вот и понадобилось выставить tab order :)

                                                                    спс разобрался SetWindowPos помог:
                                                                    ExpandedWrap disabled
                                                                      BOOL CDjVuPreferenceSheet::OnInitDialog()
                                                                      {
                                                                          BOOL bResult = CPropertySheet::OnInitDialog();
                                                                          CRect buttonRect, tabRect;
                                                                          
                                                                          // get size and positions OK button and tab control
                                                                          GetDlgItem(IDOK)->GetWindowRect(buttonRect);
                                                                          GetTabControl()->GetWindowRect(tabRect);
                                                                       
                                                                          // convert screen measure to client measure
                                                                          ScreenToClient(buttonRect);
                                                                          ScreenToClient(tabRect);
                                                                          
                                                                          /*TRACE(_T("buttonRect: left=%d, top=%d, right=%d, bottom=%d\n"),
                                                                              buttonRect.left, buttonRect.top, buttonRect.right, buttonRect.bottom);*/
                                                                       
                                                                          // calc new position Reset button
                                                                          int w = buttonRect.Width();
                                                                          buttonRect.left = tabRect.left;
                                                                          buttonRect.right = tabRect.left + w;
                                                                       
                                                                          mResetButton.Create(_T("Reset"), BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                                                                              buttonRect, this, IDC_RESET_BUTTON);
                                                                          mResetButton.SetFont(GetFont());    
                                                                       
                                                                          // set tab order Reset button
                                                                          const CWnd* pPrev = GetDlgItem(IDOK)->GetNextWindow(GW_HWNDPREV);    //<-- вот ана :)
                                                                          mResetButton.SetWindowPos(pPrev, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);  
                                                                       
                                                                          return bResult;
                                                                      }


                                                                    Цитата KILLER @
                                                                    Цитата Cfon @
                                                                    я имел ввиду в студии есть помошники для автоматизации это процесса.

                                                                    Да есть, берешь открываешь диалог, и жмешь два раза мышкой по кнопке, среда для тебя сгенерирует обработчик события и перенесет курсов в код, в этот новый сгенерированный обработчик.

                                                                    нет ты опять не понял меня :D
                                                                    то что студия умеет создавать обработчики контролов, которые присутвтвуют в ресурсе, я знаю, но вот то что он может создать обработчик и для не существующей кнопки не знал ( теперь знаю :D ), достаточно заранее определить ID в файле Resource.h
                                                                    вот это я создал с помощью мастера Class Wizard:
                                                                    ExpandedWrap disabled
                                                                      class CDjVuPreferenceSheet : public CPropertySheet
                                                                      {
                                                                       
                                                                       
                                                                          DECLARE_MESSAGE_MAP()      
                                                                          afx_msg void OnResetButton(); // 1
                                                                          
                                                                      };
                                                                       
                                                                       
                                                                      BEGIN_MESSAGE_MAP(CDjVuPreferenceSheet, CPropertySheet)
                                                                          ON_COMMAND(IDC_RESET_BUTTON, &CDjVuPreferenceSheet::OnResetButton)  //<-- 2
                                                                      END_MESSAGE_MAP()
                                                                       
                                                                      void CDjVuPreferenceSheet::OnResetButton() //<--- 3
                                                                      {
                                                                      }
                                                                    Сообщение отредактировано: Cfon -
                                                                      Цитата Cfon @
                                                                      то что студия умеет создавать обработчики контролов, которые присутвтвуют в ресурсе, я знаю, но вот то что он может создать обработчик и для не существующей кнопки не знал ( теперь знаю :D ), достаточно заранее определить ID в файле Resource.h

                                                                      Если у тебя элемент управления(не важно кнопка это или еще какая то дрянь) имеет HWND, тогда да, достаточно в Resource.h добавить идентификатор, который ты указал в CreateWindow, и добавить его в карту обработки сообщений. А если ты сам нарисовал, и у тебя элемент управления даже не имеет HWND, тогда надо самому писать класс-обработчик событий, расчитывать координаты - куда ткнул пользователь мышкой и вызывать его вручную. В твоем случае как я понял - этого не требуется.

                                                                      Цитата Cfon @
                                                                      вот это я создал с помощью мастера Class Wizard:

                                                                      Ну можно было и руками вообще это написать.
                                                                      Сообщение отредактировано: KILLER -
                                                                        Цитата KILLER @
                                                                        Если у тебя элемент управления(не важно кнопка это или еще какая то дрянь) имеет HWND, тогда да, достаточно в Resource.h добавить идентификатор, который ты указал в CreateWindow, и добавить его в карту обработки сообщений. А если ты сам нарисовал, и у тебя элемент управления даже не имеет HWND, тогда надо самому писать класс-обработчик событий, расчитывать координаты - куда ткнул пользователь мышкой и вызывать его вручную. В твоем случае как я понял - этого не требуется.

                                                                        не понял а как это конртол не имеет хендл?

                                                                        Цитата KILLER @
                                                                        Цитата Cfon @
                                                                        вот это я создал с помощью мастера Class Wizard:

                                                                        Ну можно было и руками вообще это написать.

                                                                        раньше я так и делал ;) но визард упрощает ИМХО
                                                                          Цитата Cfon @
                                                                          не понял а как это конртол не имеет хендл?

                                                                          Ну вот так, полностью нарисованный. Не через CreateWindow, а вручную все рисуется и эмулируется поведение.

                                                                          Цитата Cfon @
                                                                          раньше я так и делал ;) но визард упрощает ИМХО

                                                                          Это когда у тебя ресурсы в одном проекте с исходным кодом. А иногда бывает так, что ресурсы отдельный проект и храняться в DLL, а исходный код, где они используются вообще другой проект. Вот тогда уже через мастер не прокатит. Потому что ресурсы - это другой проект.
                                                                            Цитата KILLER @
                                                                            Цитата Cfon @
                                                                            не понял а как это конртол не имеет хендл?

                                                                            Ну вот так, полностью нарисованный. Не через CreateWindow, а вручную все рисуется и эмулируется поведение.

                                                                            не имел такой практики :)
                                                                            если надо что-то рисовать то рисовал в Picture control или Static control ну или во вьюшке по OnPaint.

                                                                            Цитата KILLER @
                                                                            Это когда у тебя ресурсы в одном проекте с исходным кодом. А иногда бывает так, что ресурсы отдельный проект и храняться в DLL, а исходный код, где они используются вообще другой проект. Вот тогда уже через мастер не прокатит. Потому что ресурсы - это другой проект.

                                                                            ну ты уже слишком строго подходишь к интрументам :D
                                                                            я например если что-то где-то можно применить то применяю, ну а если нельзя то нельзя :)
                                                                              Цитата Cfon @
                                                                              ну ты уже слишком строго подходишь к интрументам :D
                                                                              я например если что-то где-то можно применить то применяю, ну а если нельзя то нельзя

                                                                              Ну вот на прошлой работе, был проект. Логика отдельно в одном проекте, ресурсы отдельно в другом проекте. Потому как в одном только солюшине ресурсов больше пол сотни проектов было, в каждом проекте по 20-30 форм, причем все это еще на трех языках и т.д. Это дело очень сложно все поддерживать в одном солюшине, и очень много по памяти будет отгрызать, проще было разделить на отдельные проекты. Ресурсы в виде dll библиотек отдельно, логика, которая подключает все это отдельно. Плюс ко всему многие заморачиваются со всякими темами/скинами и т.п. для своих гуи свистоперделок. А в этом случае удобно ресурсы выносить отдельным проектом в виде DLL, чтоб можно было подкидывать другие DLL, без изменения исходного кода основной программы.

                                                                              Цитата Cfon @
                                                                              если надо что-то рисовать то рисовал в Picture control или Static control ну или во вьюшке по OnPaint.

                                                                              Ага, через DrawFrameControl все отрисовывал, в отдельном классе, и отдельно для него обработчик пилил.
                                                                              Сообщение отредактировано: KILLER -
                                                                                Цитата KILLER @
                                                                                Ну вот на прошлой работе, был проект. Логика отдельно в одном проекте, ресурсы отдельно в другом проекте. Потому как в одном только солюшине ресурсов больше пол сотни проектов было, в каждом проекте по 20-30 форм, причем все это еще на трех языках и т.д. Это дело очень сложно все поддерживать в одном солюшине, и очень много по памяти будет отгрызать, проще было разделить на отдельные проекты. Ресурсы в виде dll библиотек отдельно, логика, которая подключает все это отдельно. Плюс ко всему многие заморачиваются со всякими темами/скинами и т.п. для своих гуи свистоперделок. А в этом случае удобно ресурсы выносить отдельным проектом в виде DLL, чтоб можно было подкидывать другие DLL, без изменения исходного кода основной программы.

                                                                                да я понял :)
                                                                                я говорил о том, что если что-то можно автоматизировать зачем делать ручками?
                                                                                опять же я понимаю, что в некоторых случаях нельзя применить Class Wizard, тогда естественно ручками :D

                                                                                Цитата KILLER @
                                                                                Ага, через DrawFrameControl все отрисовывал, в отдельном классе, и отдельно для него обработчик пилил.

                                                                                не мне стандарных контролов хватает: кнопки, флажки и т.д. :)
                                                                                  обнаружил один баг (хотя тщательно не копал) короче не умею я складно писать, поэтому выкладываю код и комменты к нему :D
                                                                                  в таком варианте не пашет, при инициализации ползунок устанавливается в конец диапазона:
                                                                                  ExpandedWrap disabled
                                                                                    CDisplayPage::CDisplayPage()
                                                                                        : CPropertyPage(IDD_DISPLAY)
                                                                                        // устанавливаю начальное значение (раз)
                                                                                        , mMagnifyGlassSizeSliderValue(100)
                                                                                    {  
                                                                                     
                                                                                    }
                                                                                     
                                                                                    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, mMagnifyGlassSizeEditValue);  
                                                                                        DDV_MinMaxUInt(pDX, mMagnifyGlassSizeEditValue, cBeginRange, cEndRange);        
                                                                                        DDX_CBIndex(pDX, IDC_MAGNIFYGLASS_ZOOM_COMBO, mMagnifyGlassZoomIndex);
                                                                                        DDX_Check(pDX, IDC_DRAWBORDER_CHECK, mDrawBorderState);
                                                                                        DDX_CBIndex(pDX, IDC_KEY_COMBO, mKeyIndex);
                                                                                        DDX_Check(pDX, IDC_TOOLBAR_ENABLE_CHECK, mToolbarEnableState);
                                                                                        DDX_Check(pDX, IDC_TOOLBAR_AUTOHIDE_CHECK, mToolbarAutoHideState);  
                                                                                     
                                                                                    // связываю переменную с механизмом обмена данными (два)
                                                                                        DDX_Slider(pDX, IDC_MAGNIFYGLASS_SIZE_SLIDER, mMagnifyGlassSizeSliderValue);
                                                                                    }
                                                                                     
                                                                                    BOOL CDisplayPage::OnInitDialog()
                                                                                    {      
                                                                                        CPropertyPage::OnInitDialog();  
                                                                                        
                                                                                        const int cBeginRange = 50;
                                                                                        const int cEndRange = 300;
                                                                                        const int cStep = 10;
                                                                                     
                                                                                        mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                        mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);
                                                                                     
                                                                                    // инициализация контрола (три)
                                                                                        mMagnifyGlasSizeSlider.SetRange(cBeginRange, cEndRange);            
                                                                                        mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSliderValue);
                                                                                     
                                                                                        TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);
                                                                                     
                                                                                        for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                        {
                                                                                            mMagnifyGlasSizeSlider.SetTic(i);
                                                                                        }
                                                                                     
                                                                                    .......................
                                                                                     
                                                                                        return TRUE;  // return TRUE unless you set the focus to a control
                                                                                                      // EXCEPTION: OCX Property Pages should return FALSE
                                                                                    }


                                                                                  внес некоторые изменения работает:
                                                                                  ExpandedWrap disabled
                                                                                    CDisplayPage::CDisplayPage()
                                                                                        : CPropertyPage(IDD_DISPLAY)
                                                                                        
                                                                                        , mMagnifyGlassSizeSliderValue(100)
                                                                                    {
                                                                                    }
                                                                                     
                                                                                    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, mMagnifyGlassSizeEditValue);  
                                                                                        DDV_MinMaxUInt(pDX, mMagnifyGlassSizeEditValue, cBeginRange, cEndRange);        
                                                                                        DDX_CBIndex(pDX, IDC_MAGNIFYGLASS_ZOOM_COMBO, mMagnifyGlassZoomIndex);
                                                                                        DDX_Check(pDX, IDC_DRAWBORDER_CHECK, mDrawBorderState);
                                                                                        DDX_CBIndex(pDX, IDC_KEY_COMBO, mKeyIndex);
                                                                                        DDX_Check(pDX, IDC_TOOLBAR_ENABLE_CHECK, mToolbarEnableState);
                                                                                        DDX_Check(pDX, IDC_TOOLBAR_AUTOHIDE_CHECK, mToolbarAutoHideState);  
                                                                                     
                                                                                        // bug ???
                                                                                        //DDX_Slider(pDX, IDC_MAGNIFYGLASS_SIZE_SLIDER, mMagnifyGlassSizeSliderValue);
                                                                                     
                                                                                        // заменил вот этим
                                                                                        if (pDX->m_bSaveAndValidate)
                                                                                        {
                                                                                            //TRACE("Update slider data member\n");
                                                                                            ASSERT(mMagnifyGlasSizeSlider);
                                                                                            mMagnifyGlassSizeSliderValue = mMagnifyGlasSizeSlider.GetPos();
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            //TRACE("Update slider control\n");
                                                                                            ASSERT(mMagnifyGlasSizeSlider);
                                                                                            mMagnifyGlasSizeSlider.SetRange(cBeginRange, cEndRange);
                                                                                            mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSliderValue);
                                                                                        }  
                                                                                    }
                                                                                     
                                                                                    BOOL CDisplayPage::OnInitDialog()
                                                                                    {      
                                                                                        CPropertyPage::OnInitDialog();  
                                                                                        
                                                                                     
                                                                                     
                                                                                        mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                        mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);
                                                                                     
                                                                                        // перенес этот код в DoDataExchange
                                                                                        /*mMagnifyGlasSizeSlider.SetRange(cBeginRange, cEndRange);          
                                                                                        mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSliderValue);*/
                                                                                     
                                                                                        TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);
                                                                                     
                                                                                        for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                        {
                                                                                            mMagnifyGlasSizeSlider.SetTic(i);
                                                                                        }
                                                                                     
                                                                                    .......................
                                                                                     
                                                                                        return TRUE;  // return TRUE unless you set the focus to a control
                                                                                                      // EXCEPTION: OCX Property Pages should return FALSE
                                                                                    }
                                                                                  Сообщение отредактировано: Cfon -
                                                                                    Думаю, можно было в OnInitDialog просто поставить UpdateData(FALSE);, перед return
                                                                                      Цитата Олег М @
                                                                                      Думаю, можно было в OnInitDialog просто поставить UpdateData(FALSE);, перед return

                                                                                      пробовал не помогло :no-sad:

                                                                                      так?
                                                                                      ExpandedWrap disabled
                                                                                        BOOL CDisplayPage::OnInitDialog()
                                                                                        {      
                                                                                            CPropertyPage::OnInitDialog();  
                                                                                         
                                                                                            const int cBeginRange = 50;
                                                                                            const int cEndRange = 300;
                                                                                            const int cStep = 10;
                                                                                         
                                                                                            mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                            mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);
                                                                                         
                                                                                        // инициализация контрола (три)
                                                                                            mMagnifyGlasSizeSlider.SetRange(cBeginRange, cEndRange);            
                                                                                            mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSliderValue);
                                                                                         
                                                                                            TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);
                                                                                         
                                                                                            for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                            {
                                                                                                mMagnifyGlasSizeSlider.SetTic(i);
                                                                                            }
                                                                                         
                                                                                        .......................
                                                                                         
                                                                                            UpdateData(FALSE);
                                                                                               
                                                                                            return TRUE;  // return TRUE unless you set the focus to a control
                                                                                                          // EXCEPTION: OCX Property Pages should return FALSE
                                                                                        }
                                                                                        Цитата Cfon @
                                                                                        for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                        mMagnifyGlasSizeSlider.SetTic(i);

                                                                                        Наверное из-за этой штуки не работает. Когда ты делаешь SetRange после неё, то всё нормально.
                                                                                        После неё SetPos надо в тиках выставлять, наверное.
                                                                                        Сообщение отредактировано: Олег М -
                                                                                          Цитата Олег М @
                                                                                          Цитата Cfon @
                                                                                          for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                          mMagnifyGlasSizeSlider.SetTic(i);

                                                                                          Наверное из-за этой штуки не работает. Когда ты делаешь SetRange после неё, то всё нормально.
                                                                                          После неё SetPos надо в тиках выставлять, наверное.

                                                                                          так?
                                                                                          ExpandedWrap disabled
                                                                                            BOOL CDisplayPage::OnInitDialog()
                                                                                            {      
                                                                                                CPropertyPage::OnInitDialog();  
                                                                                                
                                                                                                
                                                                                                mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                                mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);          
                                                                                             
                                                                                                TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);
                                                                                             
                                                                                                for (int i = cBeginRange; i < cEndRange; i += cStep)
                                                                                                {
                                                                                                    mMagnifyGlasSizeSlider.SetTic(i);
                                                                                                }
                                                                                             
                                                                                                mMagnifyGlasSizeSlider.SetRange(cBeginRange, cEndRange);
                                                                                                mMagnifyGlasSizeSlider.SetPos(mMagnifyGlassSizeSliderValue);
                                                                                             
                                                                                                
                                                                                            ..........................
                                                                                                return TRUE;  // return TRUE unless you set the focus to a control
                                                                                                              // EXCEPTION: OCX Property Pages should return FALSE
                                                                                            }

                                                                                          не работает :no-sad:
                                                                                            DDX_Slider просто вызывает SetPos, больше ничего
                                                                                            Убери этот SetTic вообще, и попробуй
                                                                                              Цитата Олег М @
                                                                                              DDX_Slider просто вызывает SetPos, больше ничего
                                                                                              Убери этот SetTic вообще, и попробуй

                                                                                              также только без меток :(
                                                                                                А что ты вообще хочешь сделать? Я что то не пойму нифига. Ползунок не выставляется или что?

                                                                                                Добавлено
                                                                                                Цитата Cfon @
                                                                                                mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                                mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);

                                                                                                TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);

                                                                                                Ты точно в названиях своих переменных не запутался? Я бы так не называл переменные, потому как их легко перепутать.
                                                                                                  Цитата KILLER @
                                                                                                  А что ты вообще хочешь сделать? Я что то не пойму нифига. Ползунок не выставляется или что?

                                                                                                  Добавлено
                                                                                                  Цитата Cfon @
                                                                                                  mMagnifyGlassSizeSpin.SetRange(cBeginRange, cEndRange);
                                                                                                  mMagnifyGlassSizeSpin.SetPos(mMagnifyGlassSizeEditValue);

                                                                                                  TRACE("mMagnifyGlassSizeSliderValue = %d\n", mMagnifyGlassSizeSliderValue);

                                                                                                  Ты точно в названиях своих переменных не запутался? Я бы так не называл переменные, потому как их легко перепутать.

                                                                                                  да инициализация ползунка и последующая корректная его работа :)

                                                                                                  что тут путаться? нормальные названия по стандарту :D
                                                                                                  или ты об этом раз mMagnifyGlassSizeEditValue и два mMagnifyGlassSizeSliderValue?
                                                                                                  если о них то тут скорее исключение из правил :D
                                                                                                  Сообщение отредактировано: Cfon -
                                                                                                    Цитата Cfon @
                                                                                                    или ты об этом раз mMagnifyGlassSizeEditValue и два mMagnifyGlassSizeSliderValue?

                                                                                                    Именно об этом. Потому как в старом твоем проекте, который у меня - все работает замечательно.

                                                                                                    Добавлено
                                                                                                    Зачем тебе они нужны и почему 1 значения мало? Зачем их там две переменные? У тебя ведь данные в SpinEdit всегда должны быть равны данным ползунка.
                                                                                                      Цитата KILLER @
                                                                                                      Цитата Cfon @
                                                                                                      или ты об этом раз mMagnifyGlassSizeEditValue и два mMagnifyGlassSizeSliderValue?

                                                                                                      Именно об этом. Потому как в старом твоем проекте, который у меня - все работает замечательно.

                                                                                                      Добавлено
                                                                                                      Зачем тебе они нужны и почему 1 значения мало? Зачем их там две переменные? У тебя ведь данные в SpinEdit всегда должны быть равны данным ползунка.

                                                                                                      да хотел сделать все через DDX.
                                                                                                      как я уже писал создал кнопку Restore Defaults по которой восстановливаю исходные значения, так вот если бы не было этой переменой связанной с DDX, то прошлось вручную вызывать код обновления этого ползунка :)

                                                                                                      позже запостю то что я сделал :)

                                                                                                      да и вопрос решился,дело было в SetRange:

                                                                                                      ExpandedWrap disabled
                                                                                                        mMagnifyGlassSizeSlider.SetRange(cBeginRange, cEndRange, TRUE);


                                                                                                      т.е. TRUE добавить.

                                                                                                      Добавлено
                                                                                                      решение нашёл тут
                                                                                                      https://groups.google.com/forum/m/#!top...mfc/uCQWiWWebk4

                                                                                                      там правда не объясняют причину такого поведения, но и за решение им спс :D
                                                                                                      Сообщение отредактировано: Cfon -
                                                                                                        вот как надо программировать диалог свойств и никаких портянок :D
                                                                                                        Прикреплённый файлПрикреплённый файлtest4.zip (158,88 Кбайт, скачиваний: 88)

                                                                                                        еще не доделан, будет продолжение :D
                                                                                                        Сообщение отредактировано: Cfon -
                                                                                                          Решил "проблему" двух одинаковых переменных, я просто удалил вторую   :D
                                                                                                          Использую тока mMagnifyGlassSizeValue в обоих вызовах DDX_Text и DDX_Slider все пучком  :)

                                                                                                          Да и обработал OnKillfocus эдит для обновления ползунка, недоработку обнаружил случайно когда проверял выше изложеное решение :D
                                                                                                            Цитата Cfon @
                                                                                                            Решил "проблему" двух одинаковых переменных, я просто удалил вторую :D

                                                                                                            Ну вот, о чем я тебе выше и писал.
                                                                                                              Цитата KILLER @
                                                                                                              Цитата Cfon @
                                                                                                              Решил "проблему" двух одинаковых переменных, я просто удалил вторую :D

                                                                                                              Ну вот, о чем я тебе выше и писал.

                                                                                                              не знал, что можно юзать одну и туже переменную в DDX, теперь знаю :)
                                                                                                                Цитата Cfon @
                                                                                                                не знал, что можно юзать одну и туже переменную в DDX, теперь знаю

                                                                                                                Ты бы посмотрел реализацию этих DDX-функции, ещё больше бы узнал
                                                                                                                  Цитата Олег М @
                                                                                                                  Цитата Cfon @
                                                                                                                  не знал, что можно юзать одну и туже переменную в DDX, теперь знаю

                                                                                                                  Ты бы посмотрел реализацию этих DDX-функции, ещё больше бы узнал

                                                                                                                  да конечно надо больше смотреть изучать :)
                                                                                                                    ВСЕ ЗАКОНЧИЛ ФУЛ-ДЕМО "КАК НЕ НАДО ПРОГРАММИРОВАТЬ ДИАЛОГИ СВОЙСТВ" :D :lol: :lool:

                                                                                                                    качайте, но не делайте так никогда :D

                                                                                                                    Прикреплённый файлПрикреплённый файлtest4.zip (97,8 Кбайт, скачиваний: 74)
                                                                                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                    0 пользователей:


                                                                                                                    Рейтинг@Mail.ru
                                                                                                                    [ Script execution time: 0,1619 ]   [ 23 queries used ]   [ Generated: 27.04.24, 12:28 GMT ]