Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.239.57.87] |
|
Страницы: (4) 1 [2] 3 4 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Цитата Cfon @ все что ты говоришь правильно, но это всего лишь на бумаге а на практике мы имеем дело с MFC. по тому что ты пишешь я сделал вывод, что ты никогда не писал на MFC верно? Т.е. тебе мало обсуждения вопроса по-существу, тебе ещё хочется, чтобы я перед тобой оправдывался в чём-то ? Да иди ты нафик. --- Не получится из тебя инженера. |
Сообщ.
#17
,
|
|
|
Цитата ЫукпШ @ Т.е. тебе мало обсуждения вопроса по-существу, тебе ещё хочется, чтобы я перед тобой оправдывался в чём-то ? По существу это пространые расуждения? Где конкретика? |
Сообщ.
#18
,
|
|
|
Цитата Cfon @ нет проблем нет, только этот подход не правилен, т.к. каждый символ будет проверяться на соответствие диапазону ввода, а не все введённое число целиком, не? Ты получив WM_CHAR формируешь число в памяти какое оно бы было в случае отработки сообщения, проверяешь и дальше либо делаешь обработку, либо нет, либо делаешь обработку но к примеру выделяешь все значение или цвет меняешь. |
Сообщ.
#19
,
|
|
|
Цитата Cfon @ По существу это пространые расуждения? Где конкретика? Вообще, он тебе дело советует. Основная идея такая (для диалога с OK, Apply, Cancel): У тебя есть набор данных При инициализации диалога, та делаешь копию этих данных Загружаешь скопированные данные и редактируешь их При нажатии OK проверяешь их и сохраняешь в оригинальных данных и закрываешь диалог При нажатии Cancel просто закрываешь диалог При Apply - тут спорный вопрос, но я бы сделал то же, что и по OK, только без закрытия диалога Для окна свойств - тут вот можно тупо проверять/сохранять по killfocus или типа того. По кнопке закрытия только закрывать окно и всё. |
Сообщ.
#20
,
|
|
|
Я бы логически решение сделал так: вводить числа позволял ограничивая по длине, но неправильный ввод бы выделял просто (EM_SETSEL что ли), а если человек после этого ОК или apply то мессвджбокс с пояснением и кнопкой ОК, а потом фокус в это окно.
|
Сообщ.
#21
,
|
|
|
короче устал я объяснять
вот еще один чистый пример (заготовка) с реальным диалоговым окном, запрограммируйте так чтобы при отмене не сохранялись значения. это не проверка ваших знаний, просто я туплю и не знаю что делать и не обижусь если кому лень, но тока больше не пишите рассуждений, ибо мне не помогает я по прежнему на месте Прикреплённый файлtest4.zip (83,15 Кбайт, скачиваний: 91) пс. VS2015 + MFC. да там надо сохранять тока значения 2ой вкладки (для простоты) да еще чуть главное не забыл в пример данные уже не сохраняются при отмене, но тока если не переключаться на другие вкладки, а если переключиться то сохраняться даже если нажать отмену. Я юзал механизм DDX/DDV. |
Сообщ.
#22
,
|
|
|
Цитата Cfon @ вот еще один чистый пример (заготовка) с реальным диалоговым окном, запрограммируйте так чтобы при отмене не сохранялись значения. Что то вообще не понимаю что ты хочешь. Скачал твой проект, запустил. Ткнул в белое пространство, вылез диалог, выставил там какую то муть - нажал Отмена, диалог закрылся, я его заного открыл тем же способом, моих настроек нет. Это неправильно или правильно? |
Сообщ.
#23
,
|
|
|
Цитата KILLER @ Что то вообще не понимаю что ты хочешь. Скачал твой проект, запустил. Ткнул в белое пространство, вылез диалог, выставил там какую то муть - нажал Отмена, диалог закрылся, я его заного открыл тем же способом, моих настроек нет. Это неправильно или правильно? да в том дело ты не переключался с вкладки на вкладку еще раз объясню: значения при нажатии ОК сохраняются тут все пучком, но если задать значения и переключиться на другую вкладку а потом нажать отмену, то тоже сохраняются а не должно по логике |
Сообщ.
#24
,
|
|
|
Самое простое, в лоб:
DisplayPage.h #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 // 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, как я добавил): virtual BOOL OnApply(); virtual void OnOK(); virtual void OnCancel(); virtual BOOL OnSetActive(); virtual BOOL OnKillActive(); И в них реализовать валидацию значений(кроме OnCancel и OnSetActive), написать функцию валидации всех контролов, и вызывать ее в этих обработчиках, и если что то не то - то выводить MessageBox и не вызывать у родителя обработчик, тогда не придется все это в onKillFocus'e пилить, и например на другую вкладку ты не перейдешь, пока не введешь корректные данные в текущую.ю |
Сообщ.
#25
,
|
|
|
Цитата KILLER @ Самое простое, в лоб: спс большое пока не проверял, но чуйка говорит что ты правильно сделал позже проверю отпишусь |
Сообщ.
#26
,
|
|
|
есть на ж*** шерсть получилось все работает!
еще раз Киллер СПАСИБО! 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(); } вот что значит свежая голова, а то моя забилась, вскипела |
Сообщ.
#27
,
|
|
|
Ну и валидацию запили в отдельный метод и вызывай ее внутри вот этих методов:
virtual BOOL OnApply(); virtual void OnOK(); virtual BOOL OnKillActive() Если все ок - тогда для OnApply и OnKillFocus пишешь return __super::OnKillActive, иначе return FALSE, тогда ты можешь в пределах одной страницы редактировать как хочешь и вписывать даже неверные значения, но как только нажмешь OK/Apply или захочешь переключиться на другую страницу - тебе выскочит окно с ошибкой и не даст этого сделать, пока не введешь корректные значения. И тогда не нужно будет заморачиваться с OnKillFocus'ом. |
Сообщ.
#28
,
|
|
|
Цитата KILLER @ Ну и валидацию запили в отдельный метод и вызывай ее внутри вот этих методов: 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). |
Сообщ.
#29
,
|
|
|
а что за вирт функция CPropertyPage::OnReset зачем она нужна? что то не понял я ее отличия от OnCancel.
думал что она обрабатывает кнопку Reset, но не нашел ее, пришлось вручную добавить весь код. и еще как теперь изменить Tab Order? кнопка Reset создается, располагается как надо, но порядок обхода естественно не правлиьный. Также попутно есть ли способ в VS2015 создать обработчик нажатия кнопки, созданой ручками, не ручками? |
Сообщ.
#30
,
|
|
|
Цитата Cfon @ и еще как теперь изменить Tab Order? Ctrl+D, или меню Format->Tab Order. Цитата Cfon @ а что за вирт функция CPropertyPage::OnReset зачем она нужна? что то не понял я ее отличия от OnCancel. Могу предположить, что эта херня просто сбрасывает данные в начальное состояние, без закрытия диалога настроек, а Cancel - отменяет все изменения и закрывает диалог. Но это я так предполагаю, как то не шибко часто встречался с этим обработчиком. Цитата Cfon @ Также попутно есть ли способ в VS2015 создать обработчик нажатия кнопки, созданой ручками, не ручками? Не понял. Но вообще можно. В самом запущенном случае, я например вручную рисовал кнопку руками, пилил для нее обработчик события(свой класс, без использования MFC функций), расчитывал в ручную координаты клика(попали или нет по нарисованной кнопке,), делал анимацию нажатия вручную. Т.е. в твоем случае можно. Только я не понял что имелось ввиду под "созданой ручками, не ручками" ? |