Здравствуйте Alexander Dedusenko, Вы писали:
AD>Как задать минимальный размер для CFormView во фрэйме разделенном сплитером? WM_GETMINMAXINFO не приходит.
У CSplitterWnd есть вполне подходящие методы
void SetRowInfo( int row, int cyIdeal, int cyMin );
void SetColumnInfo( int col, int cxIdeal, int cxMin );
где cyMin и cxMin собственно и задают минимальные размеры.
AD>>Как задать минимальный размер для CFormView во фрэйме разделенном сплитером? WM_GETMINMAXINFO не приходит.
MA>У CSplitterWnd есть вполне подходящие методы MA>void SetRowInfo( int row, int cyIdeal, int cyMin ); MA>void SetColumnInfo( int col, int cxIdeal, int cxMin ); MA>где cyMin и cxMin собственно и задают минимальные размеры.
Насколько я помню, если я уменшу отображение больше этого минимума, форма просто исчезнет.
Программист ошибается дважды: первый раз — при рождении, а второй раз — при выборе профессии. :crash:
AD>>Как задать минимальный размер для CFormView во фрэйме разделенном сплитером? WM_GETMINMAXINFO не приходит.
MA>У CSplitterWnd есть вполне подходящие методы MA>void SetRowInfo( int row, int cyIdeal, int cyMin ); MA>void SetColumnInfo( int col, int cxIdeal, int cxMin ); MA>где cyMin и cxMin собственно и задают минимальные размеры.
Насколько я помню, если я уменшу отображение больше этого минимума, форма просто исчезнет.
Программист ошибается дважды: первый раз — при рождении, а второй раз — при выборе профессии. :crash:
AD>Насколько я помню, если я уменшу отображение больше этого минимума, форма просто исчезнет.
мда.. погорячился я немного...
как вариант могу предложить перекрыть TrackRowSize(int y, int row) в которм все это безобразие творится.
void CExSplitterWnd ::TrackRowSize(int y, int row)
{
ASSERT_VALID(this);
ASSERT(m_nRows > 1);
CPoint pt(0, y);
ClientToScreen(&pt);
GetPane(row, 0)->ScreenToClient(&pt);
m_pRowInfo[row].nIdealSize = pt.y; // new sizeif (pt.y < m_pRowInfo[row].nMinSize)
{
// resized too small
// было так
// m_pRowInfo[row].nIdealSize = 0; // make it go away
m_pRowInfo[row].nIdealSize = m_pRowInfo[row].nMinSize; // вместо 0 пусть будет мин размерif (GetStyle() & SPLS_DYNAMIC_SPLIT)
DeleteRow(row);
}
else if (m_pRowInfo[row].nCurSize + m_pRowInfo[row+1].nCurSize
< pt.y + m_pRowInfo[row+1].nMinSize)
{
// not enough room for other paneif (GetStyle() & SPLS_DYNAMIC_SPLIT)
DeleteRow(row + 1);
}
}
Думаю для колонок решится аналогичным путем.
Правда придется еще подкрутить скролл бары. И можно минимальные размеры смотреть не в Row info,
а спросить их у окна с помощью WM_GETMINMAXINFO.
Здравствуйте Max_Akimov, Вы писали:
MA>Здравствуйте Alexander Dedusenko, Вы писали:
AD>>Насколько я помню, если я уменшу отображение больше этого минимума, форма просто исчезнет.
MA>мда.. погорячился я немного...
MA>как вариант могу предложить перекрыть TrackRowSize(int y, int row) в которм все это безобразие творится.
Странно, но в MSDN-е я не нашел описания такой ф-ции. И в списке виртуальных ф-ций ее тоже не было. Пришлось руками прописывать.
MA>Думаю для колонок решится аналогичным путем. MA>Правда придется еще подкрутить скролл бары. И можно минимальные размеры смотреть не в Row info, MA>а спросить их у окна с помощью WM_GETMINMAXINFO.
Колонки мне не нужны. У меня один горизонтальный сплитер. Но есть 1 проблема. Сплитер получается тянуть до любого размера. Когда его отпускаешь, он возвращается в заданое минимальное положение. Хотелось бы запретить возможность тянуть сплиттер меньше заданого минимума.
Программист ошибается дважды: первый раз — при рождении, а второй раз — при выборе профессии. :crash:
AD>Странно, но в MSDN-е я не нашел описания такой ф-ции. И в списке виртуальных ф-ций ее тоже не было. Пришлось руками прописывать.
Там много чего интересного не написанно, хорошо иногда исходники поотлаживать, проясняются многие вопросы.
AD>Колонки мне не нужны. У меня один горизонтальный сплитер. Но есть 1 проблема. Сплитер получается тянуть до любого размера. Когда его отпускаешь, он возвращается в заданое минимальное положение. Хотелось бы запретить возможность тянуть сплиттер меньше заданого минимума.
То что есть "тянуть сплиттер" рисуется в районе CSplitterWnd::OnMouseMove
точнее там зааются координаты для рисования, а сама прорисовка делается в CSplitterWnd::OnInvertTracker, к сожалению. по причине праздников, не могу точнее ответить на этот вопрос, может быть после....
Здравствуйте Max_Akimov, Вы писали:
MA>Здравствуйте Alexander Dedusenko, Вы писали:
AD>>Странно, но в MSDN-е я не нашел описания такой ф-ции. И в списке виртуальных ф-ций ее тоже не было. Пришлось руками прописывать.
MA>Там много чего интересного не написанно, хорошо иногда исходники поотлаживать, проясняются многие вопросы.
AD>>Колонки мне не нужны. У меня один горизонтальный сплитер. Но есть 1 проблема. Сплитер получается тянуть до любого размера. Когда его отпускаешь, он возвращается в заданое минимальное положение. Хотелось бы запретить возможность тянуть сплиттер меньше заданого минимума.
MA>То что есть "тянуть сплиттер" рисуется в районе CSplitterWnd::OnMouseMove MA>точнее там зааются координаты для рисования, а сама прорисовка делается в CSplitterWnd::OnInvertTracker, к сожалению. по причине праздников, не могу точнее ответить на этот вопрос, может быть после....
В принципе это помогает, хотя иногда с некоторой задержкой. Вот пример — держим минимальный размер левого вида = 50
void CMySplitterWnd::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (!m_bBarLocked)
{
int cxCur, cxMin;
GetColumnInfo(0, cxCur, cxMin);
if (point.x < 51)
return;
if (cxCur < 51)
{
SetColumnInfo(0, 50, cxMin);
RecalcLayout();
}
CSplitterWnd::OnMouseMove(nFlags, point);
}
else
CWnd::OnMouseMove(nFlags, point);
}
Здравствуйте, Марк, Вы писали:
М>В принципе это помогает, хотя иногда с некоторой задержкой. Вот пример — держим минимальный размер левого вида = 50
М>void CMySplitterWnd::OnMouseMove(UINT nFlags, CPoint point) М>{ М> // TODO: Add your message handler code here and/or call default М> if (!m_bBarLocked) М> { М> int cxCur, cxMin; М> GetColumnInfo(0, cxCur, cxMin); М> if (point.x < 51) М> return; М> if (cxCur < 51) М> { М> SetColumnInfo(0, 50, cxMin); М> RecalcLayout(); М> } М> CSplitterWnd::OnMouseMove(nFlags, point); М> } М> else М> CWnd::OnMouseMove(nFlags, point); М>}
У меня такая же проблема, которая обсуждается в этой ветке. Мне нужно задать фиксированный размер по Y одному из pane в CSplitterWnd и минимально возможный по X для нескольких.
Я мог бы воспользоваться этим примером, но как корректно поднять m_bBarLocked ?
Могу вычислить OnClick на splitBar-е, но лучше бы получить от CSplitterWnd, что splitBar захвачен. Как?
H>У меня такая же проблема, которая обсуждается в этой ветке. Мне нужно задать фиксированный размер по Y одному из pane в CSplitterWnd и минимально возможный по X для нескольких. H> Я мог бы воспользоваться этим примером, но как корректно поднять m_bBarLocked ? H> Могу вычислить OnClick на splitBar-е, но лучше бы получить от CSplitterWnd, что splitBar захвачен. Как?
Вариант рас.
Здравствуйте, Carc, Вы писали:
H>>У меня такая же проблема, которая обсуждается в этой ветке. Мне нужно задать фиксированный размер по Y одному из pane в CSplitterWnd и минимально возможный по X для нескольких. H>> Я мог бы воспользоваться этим примером, но как корректно поднять m_bBarLocked ? H>> Могу вычислить OnClick на splitBar-е, но лучше бы получить от CSplitterWnd, что splitBar захвачен. Как? C>Вариант рас. C>
H>Здесь получаем только координаты нажатия мыши, дальше требуются вычисления, которые хотелось избежать.
Какие нафиг координаты? Я же специально выделил к примеру
CMySplitterWnd::OnLButtonDown(...)
{
returnCWnd::OnLButtonDown(...);//я не зову код базового CSplitterWnd
}
Вызывается не базовый стандартный CSplitterWnd, а CWnd — попробуйте — фиг чего мышом потаскаешь. А на WM_NCHITTEST вообще много может быть нагрузки — ну представьте у Вас там когда-нить потом будет тултип, к примеру, или еще что-то. Ну так это все тоже будет использовать WM_NCHITTEST в той или иной степени... Всплывет в проекте потом когда-нибудь — через пару лет. Когда от тоски до завала денег уже начнем рюшечки прикручивать. Вот в таких вот случаях искать подобный баг рехнуться можно — т.к. просто не работает в одном месте (тот же тултип не всплывет), а кривой код в другом месте. Да, код формально верный, и выйти на него потом будет несложно, но это еще надо сообразить туда залезть и то, если код под рукой, а не в DLL какой-нибудь. Нафига ж себе проблемы готовить? Имхо, WM_LBUTTONDOWN более узкий функционал — мышонку он работать как пить не даст, что вроде бы по условию задачи, как я понял, и нужно. Зачем же тогда применять более широкий функционал, который отвечает за кучу других вещей и вызывается по очень весьма разным причинам и может иметь далеко идущие и весьма не очевидные последствия для использующего этот код извне!?!
H>>Здесь получаем только координаты нажатия мыши, дальше требуются вычисления, которые хотелось избежать. C>Какие нафиг координаты? Я же специально выделил к примеру C>
C>CMySplitterWnd::OnLButtonDown(...)
C>{
C> returnCWnd::OnLButtonDown(...);//я не зову код базового CSplitterWnd
C>}
C>
C>Вызывается не базовый стандартный CSplitterWnd, а CWnd — попробуйте — фиг чего мышом потаскаешь. А на WM_NCHITTEST вообще много может быть нагрузки — ну представьте у Вас там когда-нить потом будет тултип, к примеру, или еще что-то. Ну так это все тоже будет использовать WM_NCHITTEST в той или иной степени... Всплывет в проекте потом когда-нибудь — через пару лет. Когда от тоски до завала денег уже начнем рюшечки прикручивать. Вот в таких вот случаях искать подобный баг рехнуться можно — т.к. просто не работает в одном месте (тот же тултип не всплывет), а кривой код в другом месте. Да, код формально верный, и выйти на него потом будет несложно, но это еще надо сообразить туда залезть и то, если код под рукой, а не в DLL какой-нибудь. Нафига ж себе проблемы готовить? Имхо, WM_LBUTTONDOWN более узкий функционал — мышонку он работать как пить не даст, что вроде бы по условию задачи, как я понял, и нужно. Зачем же тогда применять более широкий функционал, который отвечает за кучу других вещей и вызывается по очень весьма разным причинам и может иметь далеко идущие и весьма не очевидные последствия для использующего этот код извне!?!
Вдвойне спасибо!!! Я понял сразу идею, и мне этого было достаточно. Остальное накопаю. Ответ был немного не в тему. Объяснение Ваше мне вполне понятно.
Спасибо.
Еще есть мысль из CMyFixedSizeView::OnSize() задать родительскому pane размер и вызвать CSplitterWnd::RecalLayout().
H>Вдвойне спасибо!!! Я понял сразу идею, и мне этого было достаточно. Остальное накопаю. Ответ был немного не в тему. Объяснение Ваше мне вполне понятно. H>Спасибо.
Сори за мой флуд выше — я Вас просто не понял.
H>Еще есть мысль из CMyFixedSizeView::OnSize() задать родительскому pane размер и вызвать CSplitterWnd::RecalLayout().
Если внимательно посмотреть на CSplitterWnd::RecalcLayout, то выясняется что о чудо она virtual — хотя в моем MSDN это не упоминается (правда у меня старый). Ну и соответственно ее можно перекрыть, и в ней обрабатывать логику. Я делал так.
Здравствуйте, Carc, Вы писали:
H>>Вдвойне спасибо!!! Я понял сразу идею, и мне этого было достаточно. Остальное накопаю. Ответ был немного не в тему. Объяснение Ваше мне вполне понятно. H>>Спасибо. C>Сори за мой флуд выше — я Вас просто не понял.
H>>Еще есть мысль из CMyFixedSizeView::OnSize() задать родительскому pane размер и вызвать CSplitterWnd::RecalLayout(). C>Если внимательно посмотреть на CSplitterWnd::RecalcLayout, то выясняется что о чудо она virtual — хотя в моем MSDN это не упоминается (правда у меня старый). Ну и соответственно ее можно перекрыть, и в ней обрабатывать логику. Я делал так.
Сделал так:
class CSizedSplittWnd : public CSplittWnd
{
public:
void RecalcLayout( )
{
...
SetRowInfo(0, sizedSize, fixedSize);
CSplittWnd::RecalcLayout();
}
}
Как и ожидалось, сплит-бар двигается, а окно остается на месте.
Позже может реализую второй вариант — через OnMouseMove().
H>Как и ожидалось, сплит-бар двигается, а окно остается на месте. H>Позже может реализую второй вариант — через OnMouseMove(). H>Спасибо за подсказки.
Я уже немного запутался Что мы хотим?
1) Запретить вообще дергать сплиттер мышью?
2) Или запретить ему делать одну из панелей меньше чем положено?
если второе, то как запретить? Можно просто возвертать на место до минимального размера и пересчитать RecalcLayout
или "па-нармальному бум делать" — т.е. чтобы не могли утащить мышью дальше какого-то предела — со всеми рюшками, останавливать перетаскивание сплиттера, курсор менять там, то да сё!?!
3) если второе, может использоваться какое то управления сплиттером через клаву или нет (редко но бывает можно вроде Ctrl+Shift+стрелка или что-то в подобном роде)?
Здравствуйте, Carc, Вы писали:
H>>Как и ожидалось, сплит-бар двигается, а окно остается на месте. H>>Позже может реализую второй вариант — через OnMouseMove(). H>>Спасибо за подсказки. C>Я уже немного запутался Что мы хотим?
Лично мне на данный момент нужно было: зафиксировать некий pane по одному размеру и ограничить по другому.
Сложность в моем случае в том, что у меня вложенные CSplitterWnd. Не сразу сообразил который отвечает за тот pane.
C>1) Запретить вообще дергать сплиттер мышью?
Это не важно, если окно остается на месте (перегрузка RecalcLayout дала желаемое).
C>2) Или запретить ему делать одну из панелей меньше чем положено? C>если второе, то как запретить? Можно просто возвертать на место до минимального размера и пересчитать RecalcLayout
именно так и сделал. Код опубликовал в предыдущем посте.
C>или "па-нармальному бум делать" — т.е. чтобы не могли утащить мышью дальше какого-то предела — со всеми рюшками, останавливать перетаскивание сплиттера, курсор менять там, то да сё!?! C>3) если второе, может использоваться какое то управления сплиттером через клаву или нет (редко но бывает можно вроде Ctrl+Shift+стрелка или что-то в подобном роде)?
"Рюшки рисовать" буду позже при наличии времени. За подсказку про управление с клавы — спасибо, учту, если буду имплементировать.
H>"Рюшки рисовать" буду позже при наличии времени. За подсказку про управление с клавы — спасибо, учту, если буду имплементировать. H>Спасибо за соучастие.
По умолчанию по моему нельзя, но если код обобщенный вроде какой-нить UI LibraryExt то рано или поздно начнут двигать, ну тем же кодом выполняющимся при нажатии клавы (однажды сам так делал) — тогда конечно будет посложнее...
К информацию к размышлению, из сорсов MFC
//Член НСДАП с 1998 года (VC6 SP6)virtualvoid TrackRowSize(int y, int row);
virtualvoid TrackColumnSize(int x, int col);
virtualvoid StartTracking(int ht);
virtualvoid StopTracking(BOOL bAccept);
Названия функций в свете поставленной задачи не интригуют случаем!?!