Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.116.90.141] |
|
Страницы: (4) 1 2 [3] 4 все ( Перейти к последнему сообщению ) |
Сообщ.
#31
,
|
|
|
нет ты не понял, надо в ран-тайм. я создаю кнопку Reset вот ее надо вставить в tab order. Цитата KILLER @ Цитата Cfon @ а что за вирт функция CPropertyPage::OnReset зачем она нужна? что то не понял я ее отличия от OnCancel. Могу предположить, что эта херня просто сбрасывает данные в начальное состояние, без закрытия диалога настроек, а Cancel - отменяет все изменения и закрывает диалог. Но это я так предполагаю, как то не шибко часто встречался с этим обработчиком. в том и дело, что я тоже предполагал это, но где кнопка которая ее вызывает? выяснил что ее вызывает кнопка Cancel. вот я и не пойму ее смысл. думал что она (Reset) уже есть в CPropertySheet,точнее в ее ресурсах, но не нашел, поэтому создал свою кнопку в ран-тайм. Цитата KILLER @ Цитата Cfon @ Также попутно есть ли способ в VS2015 создать обработчик нажатия кнопки, созданой ручками, не ручками? Не понял. Но вообще можно. В самом запущенном случае, я например вручную рисовал кнопку руками, пилил для нее обработчик события(свой класс, без использования MFC функций), расчитывал в ручную координаты клика(попали или нет по нарисованной кнопке,), делал анимацию нажатия вручную. Т.е. в твоем случае можно. Только я не понял что имелось ввиду под "созданой ручками, не ручками" ? я имел ввиду в студии есть ли помошники для автоматизации это процесса (создание обработчика кнопки не из ресурса). уже разобрался Class Wizard позволит сделать все за нас |
Сообщ.
#32
,
|
|
|
Цитата 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 @ я имел ввиду в студии есть помошники для автоматизации это процесса. Да есть, берешь открываешь диалог, и жмешь два раза мышкой по кнопке, среда для тебя сгенерирует обработчик события и перенесет курсов в код, в этот новый сгенерированный обработчик. |
Сообщ.
#33
,
|
|
|
Цитата 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 помог: 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 @ я имел ввиду в студии есть помошники для автоматизации это процесса. Да есть, берешь открываешь диалог, и жмешь два раза мышкой по кнопке, среда для тебя сгенерирует обработчик события и перенесет курсов в код, в этот новый сгенерированный обработчик. нет ты опять не понял меня то что студия умеет создавать обработчики контролов, которые присутвтвуют в ресурсе, я знаю, но вот то что он может создать обработчик и для не существующей кнопки не знал ( теперь знаю ), достаточно заранее определить ID в файле Resource.h вот это я создал с помощью мастера Class Wizard: 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 { } |
Сообщ.
#34
,
|
|
|
Цитата Cfon @ то что студия умеет создавать обработчики контролов, которые присутвтвуют в ресурсе, я знаю, но вот то что он может создать обработчик и для не существующей кнопки не знал ( теперь знаю ), достаточно заранее определить ID в файле Resource.h Если у тебя элемент управления(не важно кнопка это или еще какая то дрянь) имеет HWND, тогда да, достаточно в Resource.h добавить идентификатор, который ты указал в CreateWindow, и добавить его в карту обработки сообщений. А если ты сам нарисовал, и у тебя элемент управления даже не имеет HWND, тогда надо самому писать класс-обработчик событий, расчитывать координаты - куда ткнул пользователь мышкой и вызывать его вручную. В твоем случае как я понял - этого не требуется. Цитата Cfon @ вот это я создал с помощью мастера Class Wizard: Ну можно было и руками вообще это написать. |
Сообщ.
#35
,
|
|
|
Цитата KILLER @ Если у тебя элемент управления(не важно кнопка это или еще какая то дрянь) имеет HWND, тогда да, достаточно в Resource.h добавить идентификатор, который ты указал в CreateWindow, и добавить его в карту обработки сообщений. А если ты сам нарисовал, и у тебя элемент управления даже не имеет HWND, тогда надо самому писать класс-обработчик событий, расчитывать координаты - куда ткнул пользователь мышкой и вызывать его вручную. В твоем случае как я понял - этого не требуется. не понял а как это конртол не имеет хендл? Цитата KILLER @ Цитата Cfon @ вот это я создал с помощью мастера Class Wizard: Ну можно было и руками вообще это написать. раньше я так и делал но визард упрощает ИМХО |
Сообщ.
#36
,
|
|
|
Цитата Cfon @ не понял а как это конртол не имеет хендл? Ну вот так, полностью нарисованный. Не через CreateWindow, а вручную все рисуется и эмулируется поведение. Цитата Cfon @ раньше я так и делал но визард упрощает ИМХО Это когда у тебя ресурсы в одном проекте с исходным кодом. А иногда бывает так, что ресурсы отдельный проект и храняться в DLL, а исходный код, где они используются вообще другой проект. Вот тогда уже через мастер не прокатит. Потому что ресурсы - это другой проект. |
Сообщ.
#37
,
|
|
|
Цитата KILLER @ Цитата Cfon @ не понял а как это конртол не имеет хендл? Ну вот так, полностью нарисованный. Не через CreateWindow, а вручную все рисуется и эмулируется поведение. не имел такой практики если надо что-то рисовать то рисовал в Picture control или Static control ну или во вьюшке по OnPaint. Цитата KILLER @ Это когда у тебя ресурсы в одном проекте с исходным кодом. А иногда бывает так, что ресурсы отдельный проект и храняться в DLL, а исходный код, где они используются вообще другой проект. Вот тогда уже через мастер не прокатит. Потому что ресурсы - это другой проект. ну ты уже слишком строго подходишь к интрументам я например если что-то где-то можно применить то применяю, ну а если нельзя то нельзя |
Сообщ.
#38
,
|
|
|
Цитата Cfon @ ну ты уже слишком строго подходишь к интрументам я например если что-то где-то можно применить то применяю, ну а если нельзя то нельзя Ну вот на прошлой работе, был проект. Логика отдельно в одном проекте, ресурсы отдельно в другом проекте. Потому как в одном только солюшине ресурсов больше пол сотни проектов было, в каждом проекте по 20-30 форм, причем все это еще на трех языках и т.д. Это дело очень сложно все поддерживать в одном солюшине, и очень много по памяти будет отгрызать, проще было разделить на отдельные проекты. Ресурсы в виде dll библиотек отдельно, логика, которая подключает все это отдельно. Плюс ко всему многие заморачиваются со всякими темами/скинами и т.п. для своих гуи свистоперделок. А в этом случае удобно ресурсы выносить отдельным проектом в виде DLL, чтоб можно было подкидывать другие DLL, без изменения исходного кода основной программы. Цитата Cfon @ если надо что-то рисовать то рисовал в Picture control или Static control ну или во вьюшке по OnPaint. Ага, через DrawFrameControl все отрисовывал, в отдельном классе, и отдельно для него обработчик пилил. |
Сообщ.
#39
,
|
|
|
Цитата KILLER @ Ну вот на прошлой работе, был проект. Логика отдельно в одном проекте, ресурсы отдельно в другом проекте. Потому как в одном только солюшине ресурсов больше пол сотни проектов было, в каждом проекте по 20-30 форм, причем все это еще на трех языках и т.д. Это дело очень сложно все поддерживать в одном солюшине, и очень много по памяти будет отгрызать, проще было разделить на отдельные проекты. Ресурсы в виде dll библиотек отдельно, логика, которая подключает все это отдельно. Плюс ко всему многие заморачиваются со всякими темами/скинами и т.п. для своих гуи свистоперделок. А в этом случае удобно ресурсы выносить отдельным проектом в виде DLL, чтоб можно было подкидывать другие DLL, без изменения исходного кода основной программы. да я понял я говорил о том, что если что-то можно автоматизировать зачем делать ручками? опять же я понимаю, что в некоторых случаях нельзя применить Class Wizard, тогда естественно ручками Цитата KILLER @ Ага, через DrawFrameControl все отрисовывал, в отдельном классе, и отдельно для него обработчик пилил. не мне стандарных контролов хватает: кнопки, флажки и т.д. |
Сообщ.
#40
,
|
|
|
обнаружил один баг (хотя тщательно не копал) короче не умею я складно писать, поэтому выкладываю код и комменты к нему
в таком варианте не пашет, при инициализации ползунок устанавливается в конец диапазона: 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 } внес некоторые изменения работает: 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 } |
Сообщ.
#41
,
|
|
|
Думаю, можно было в OnInitDialog просто поставить UpdateData(FALSE);, перед return
|
Сообщ.
#42
,
|
|
|
Цитата Олег М @ Думаю, можно было в OnInitDialog просто поставить UpdateData(FALSE);, перед return пробовал не помогло так? 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 } |
Сообщ.
#43
,
|
|
|
Цитата Cfon @ for (int i = cBeginRange; i < cEndRange; i += cStep) mMagnifyGlasSizeSlider.SetTic(i); Наверное из-за этой штуки не работает. Когда ты делаешь SetRange после неё, то всё нормально. После неё SetPos надо в тиках выставлять, наверное. |
Сообщ.
#44
,
|
|
|
Цитата Олег М @ Цитата Cfon @ for (int i = cBeginRange; i < cEndRange; i += cStep) mMagnifyGlasSizeSlider.SetTic(i); Наверное из-за этой штуки не работает. Когда ты делаешь SetRange после неё, то всё нормально. После неё SetPos надо в тиках выставлять, наверное. так? 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 } не работает |
Сообщ.
#45
,
|
|
|
DDX_Slider просто вызывает SetPos, больше ничего
Убери этот SetTic вообще, и попробуй |