Splitter и минимальный размер отображения
От: Alexander Dedusenko Украина  
Дата: 07.05.02 12:51
Оценка:
Как задать минимальный размер для CFormView во фрэйме разделенном сплитером? WM_GETMINMAXINFO не приходит.
Программист ошибается дважды: первый раз — при рождении, а второй раз — при выборе профессии. :crash:
Re: Splitter и минимальный размер отображения
От: Max_Akimov Россия  
Дата: 07.05.02 12:55
Оценка:
Здравствуйте 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 собственно и задают минимальные размеры.
Re[2]: Splitter и минимальный размер отображения
От: Alexander Dedusenko Украина  
Дата: 07.05.02 13:16
Оценка:
Здравствуйте Max_Akimov, Вы писали:


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:
Re[2]: Splitter и минимальный размер отображения
От: Alexander Dedusenko Украина  
Дата: 07.05.02 13:16
Оценка:
Здравствуйте Max_Akimov, Вы писали:


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:
Re[3]: Splitter и минимальный размер отображения
От: Max_Akimov Россия  
Дата: 07.05.02 14:26
Оценка:
Здравствуйте Alexander Dedusenko, Вы писали:


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 size
    if (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 pane
        if (GetStyle() & SPLS_DYNAMIC_SPLIT)
            DeleteRow(row + 1);
    }
}


Думаю для колонок решится аналогичным путем.
Правда придется еще подкрутить скролл бары. И можно минимальные размеры смотреть не в Row info,
а спросить их у окна с помощью WM_GETMINMAXINFO.
Re[4]: Splitter и минимальный размер отображения
От: Alexander Dedusenko Украина  
Дата: 08.05.02 06:25
Оценка:
Здравствуйте Max_Akimov, Вы писали:

MA>Здравствуйте Alexander Dedusenko, Вы писали:



AD>>Насколько я помню, если я уменшу отображение больше этого минимума, форма просто исчезнет.


MA>мда.. погорячился я немного...


MA>как вариант могу предложить перекрыть TrackRowSize(int y, int row) в которм все это безобразие творится.


Странно, но в MSDN-е я не нашел описания такой ф-ции. И в списке виртуальных ф-ций ее тоже не было. Пришлось руками прописывать.

MA>Думаю для колонок решится аналогичным путем.

MA>Правда придется еще подкрутить скролл бары. И можно минимальные размеры смотреть не в Row info,
MA>а спросить их у окна с помощью WM_GETMINMAXINFO.

Колонки мне не нужны. У меня один горизонтальный сплитер. Но есть 1 проблема. Сплитер получается тянуть до любого размера. Когда его отпускаешь, он возвращается в заданое минимальное положение. Хотелось бы запретить возможность тянуть сплиттер меньше заданого минимума.
Программист ошибается дважды: первый раз — при рождении, а второй раз — при выборе профессии. :crash:
Re[5]: Splitter и минимальный размер отображения
От: Max_Akimov Россия  
Дата: 08.05.02 15:07
Оценка:
Здравствуйте Alexander Dedusenko, Вы писали:


AD>Странно, но в MSDN-е я не нашел описания такой ф-ции. И в списке виртуальных ф-ций ее тоже не было. Пришлось руками прописывать.


Там много чего интересного не написанно, хорошо иногда исходники поотлаживать, проясняются многие вопросы.

AD>Колонки мне не нужны. У меня один горизонтальный сплитер. Но есть 1 проблема. Сплитер получается тянуть до любого размера. Когда его отпускаешь, он возвращается в заданое минимальное положение. Хотелось бы запретить возможность тянуть сплиттер меньше заданого минимума.


То что есть "тянуть сплиттер" рисуется в районе CSplitterWnd::OnMouseMove
точнее там зааются координаты для рисования, а сама прорисовка делается в CSplitterWnd::OnInvertTracker, к сожалению. по причине праздников, не могу точнее ответить на этот вопрос, может быть после....
Re[6]: Splitter и минимальный размер отображения
От: Марк Канада http://pages.infinit.net/philipok/gramota/Programmki.html
Дата: 30.05.02 13:38
Оценка:
Здравствуйте 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);
}
Re[7]: Splitter и минимальный размер отображения
От: Марк Канада http://pages.infinit.net/philipok/gramota/Programmki.html
Дата: 31.05.02 19:47
Оценка:
Вот мой нормально работающий пример — http://pages.infinit.net/philipok/gramota/ResizingFramePersist.zip
кстати в этом прототипе есть много другого интересного.

Смотри страницу http://pages.infinit.net/philipok/gramota/Programmki.html

Марк
Re[7]: Splitter и минимальный размер отображения
От: Hex65  
Дата: 20.11.08 09:41
Оценка:
Здравствуйте, Марк, Вы писали:

М>В принципе это помогает, хотя иногда с некоторой задержкой. Вот пример — держим минимальный размер левого вида = 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 захвачен. Как?
Re[8]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 20.11.08 12:06
Оценка:
H>У меня такая же проблема, которая обсуждается в этой ветке. Мне нужно задать фиксированный размер по Y одному из pane в CSplitterWnd и минимально возможный по X для нескольких.
H> Я мог бы воспользоваться этим примером, но как корректно поднять m_bBarLocked ?
H> Могу вычислить OnClick на splitBar-е, но лучше бы получить от CSplitterWnd, что splitBar захвачен. Как?
Вариант рас.
CSplitterWnd::OnLButtonDown
{
 return CWnd::OnLButtonDown(...);
}


Вариант два-с
CSplitterWnd::OnNcHitTest(...)
{
return 0;
}


Ну конечно же это блокирует только действия пользователя, кодом все двигается.
Aml Pages Home
Re[9]: Splitter и минимальный размер отображения
От: Hex65  
Дата: 20.11.08 13:14
Оценка:
Здравствуйте, Carc, Вы писали:

H>>У меня такая же проблема, которая обсуждается в этой ветке. Мне нужно задать фиксированный размер по Y одному из pane в CSplitterWnd и минимально возможный по X для нескольких.

H>> Я мог бы воспользоваться этим примером, но как корректно поднять m_bBarLocked ?
H>> Могу вычислить OnClick на splitBar-е, но лучше бы получить от CSplitterWnd, что splitBar захвачен. Как?
C>Вариант рас.
C>
C>CSplitterWnd::OnLButtonDown
C>{
C> return CWnd::OnLButtonDown(...);
C>}
C>


Здесь получаем только координаты нажатия мыши, дальше требуются вычисления, которые хотелось избежать.


C>Вариант два-с

C>
C>CSplitterWnd::OnNcHitTest(...)
C>{
C>return 0;
C>}
C>


Этот похож на то, что нужно. Спасибо.

C>Ну конечно же это блокирует только действия пользователя, кодом все двигается.
Re[10]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 20.11.08 13:31
Оценка:
C>>Вариант рас.
C>>
C>>CSplitterWnd::OnLButtonDown
C>>{
C>> return CWnd::OnLButtonDown(...);
C>>}
C>>

H>Здесь получаем только координаты нажатия мыши, дальше требуются вычисления, которые хотелось избежать.
Какие нафиг координаты? Я же специально выделил к примеру
CMySplitterWnd::OnLButtonDown(...)
{
 return CWnd::OnLButtonDown(...);//я не зову код базового CSplitterWnd
}

Вызывается не базовый стандартный CSplitterWnd, а CWnd — попробуйте — фиг чего мышом потаскаешь. А на WM_NCHITTEST вообще много может быть нагрузки — ну представьте у Вас там когда-нить потом будет тултип, к примеру, или еще что-то. Ну так это все тоже будет использовать WM_NCHITTEST в той или иной степени... Всплывет в проекте потом когда-нибудь — через пару лет. Когда от тоски до завала денег уже начнем рюшечки прикручивать. Вот в таких вот случаях искать подобный баг рехнуться можно — т.к. просто не работает в одном месте (тот же тултип не всплывет), а кривой код в другом месте. Да, код формально верный, и выйти на него потом будет несложно, но это еще надо сообразить туда залезть и то, если код под рукой, а не в DLL какой-нибудь. Нафига ж себе проблемы готовить? Имхо, WM_LBUTTONDOWN более узкий функционал — мышонку он работать как пить не даст, что вроде бы по условию задачи, как я понял, и нужно. Зачем же тогда применять более широкий функционал, который отвечает за кучу других вещей и вызывается по очень весьма разным причинам и может иметь далеко идущие и весьма не очевидные последствия для использующего этот код извне!?!
Aml Pages Home
Re[11]: Splitter и минимальный размер отображения
От: Hex65  
Дата: 20.11.08 13:41
Оценка:
Здравствуйте, Carc, Вы писали:

C>>>Вариант рас.

C>>>
C>>>CSplitterWnd::OnLButtonDown
C>>>{
C>>> return CWnd::OnLButtonDown(...);
C>>>}
C>>>

H>>Здесь получаем только координаты нажатия мыши, дальше требуются вычисления, которые хотелось избежать.
C>Какие нафиг координаты? Я же специально выделил к примеру
C>
C>CMySplitterWnd::OnLButtonDown(...)
C>{
C> return CWnd::OnLButtonDown(...);//я не зову код базового CSplitterWnd
C>}
C>

C>Вызывается не базовый стандартный CSplitterWnd, а CWnd — попробуйте — фиг чего мышом потаскаешь. А на WM_NCHITTEST вообще много может быть нагрузки — ну представьте у Вас там когда-нить потом будет тултип, к примеру, или еще что-то. Ну так это все тоже будет использовать WM_NCHITTEST в той или иной степени... Всплывет в проекте потом когда-нибудь — через пару лет. Когда от тоски до завала денег уже начнем рюшечки прикручивать. Вот в таких вот случаях искать подобный баг рехнуться можно — т.к. просто не работает в одном месте (тот же тултип не всплывет), а кривой код в другом месте. Да, код формально верный, и выйти на него потом будет несложно, но это еще надо сообразить туда залезть и то, если код под рукой, а не в DLL какой-нибудь. Нафига ж себе проблемы готовить? Имхо, WM_LBUTTONDOWN более узкий функционал — мышонку он работать как пить не даст, что вроде бы по условию задачи, как я понял, и нужно. Зачем же тогда применять более широкий функционал, который отвечает за кучу других вещей и вызывается по очень весьма разным причинам и может иметь далеко идущие и весьма не очевидные последствия для использующего этот код извне!?!

Вдвойне спасибо!!! Я понял сразу идею, и мне этого было достаточно. Остальное накопаю. Ответ был немного не в тему. Объяснение Ваше мне вполне понятно.
Спасибо.

Еще есть мысль из CMyFixedSizeView::OnSize() задать родительскому pane размер и вызвать CSplitterWnd::RecalLayout().
Re[12]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 20.11.08 13:51
Оценка:
H>Вдвойне спасибо!!! Я понял сразу идею, и мне этого было достаточно. Остальное накопаю. Ответ был немного не в тему. Объяснение Ваше мне вполне понятно.
H>Спасибо.
Сори за мой флуд выше — я Вас просто не понял.

H>Еще есть мысль из CMyFixedSizeView::OnSize() задать родительскому pane размер и вызвать CSplitterWnd::RecalLayout().

Если внимательно посмотреть на CSplitterWnd::RecalcLayout, то выясняется что о чудо она virtual — хотя в моем MSDN это не упоминается (правда у меня старый). Ну и соответственно ее можно перекрыть, и в ней обрабатывать логику. Я делал так.
Aml Pages Home
Re[13]: Splitter и минимальный размер отображения
От: Hex65  
Дата: 20.11.08 16:20
Оценка:
Здравствуйте, 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().

Спасибо за подсказки.
Re[14]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 20.11.08 16:46
Оценка:
H>Как и ожидалось, сплит-бар двигается, а окно остается на месте.
H>Позже может реализую второй вариант — через OnMouseMove().
H>Спасибо за подсказки.
Я уже немного запутался Что мы хотим?
1) Запретить вообще дергать сплиттер мышью?
2) Или запретить ему делать одну из панелей меньше чем положено?
если второе, то как запретить? Можно просто возвертать на место до минимального размера и пересчитать RecalcLayout
или "па-нармальному бум делать" — т.е. чтобы не могли утащить мышью дальше какого-то предела — со всеми рюшками, останавливать перетаскивание сплиттера, курсор менять там, то да сё!?!
3) если второе, может использоваться какое то управления сплиттером через клаву или нет (редко но бывает можно вроде Ctrl+Shift+стрелка или что-то в подобном роде)?
Aml Pages Home
Re[15]: Splitter и минимальный размер отображения
От: Hex65  
Дата: 21.11.08 10:26
Оценка:
Здравствуйте, Carc, Вы писали:

H>>Как и ожидалось, сплит-бар двигается, а окно остается на месте.

H>>Позже может реализую второй вариант — через OnMouseMove().
H>>Спасибо за подсказки.
C>Я уже немного запутался Что мы хотим?

Лично мне на данный момент нужно было: зафиксировать некий pane по одному размеру и ограничить по другому.
Сложность в моем случае в том, что у меня вложенные CSplitterWnd. Не сразу сообразил который отвечает за тот pane.

C>1) Запретить вообще дергать сплиттер мышью?


Это не важно, если окно остается на месте (перегрузка RecalcLayout дала желаемое).

C>2) Или запретить ему делать одну из панелей меньше чем положено?

C>если второе, то как запретить? Можно просто возвертать на место до минимального размера и пересчитать RecalcLayout

именно так и сделал. Код опубликовал в предыдущем посте.

C>или "па-нармальному бум делать" — т.е. чтобы не могли утащить мышью дальше какого-то предела — со всеми рюшками, останавливать перетаскивание сплиттера, курсор менять там, то да сё!?!

C>3) если второе, может использоваться какое то управления сплиттером через клаву или нет (редко но бывает можно вроде Ctrl+Shift+стрелка или что-то в подобном роде)?

"Рюшки рисовать" буду позже при наличии времени. За подсказку про управление с клавы — спасибо, учту, если буду имплементировать.

Спасибо за соучастие.
Re[16]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 21.11.08 12:05
Оценка:
H>"Рюшки рисовать" буду позже при наличии времени. За подсказку про управление с клавы — спасибо, учту, если буду имплементировать.
H>Спасибо за соучастие.
По умолчанию по моему нельзя, но если код обобщенный вроде какой-нить UI LibraryExt то рано или поздно начнут двигать, ну тем же кодом выполняющимся при нажатии клавы (однажды сам так делал) — тогда конечно будет посложнее...

К информацию к размышлению, из сорсов MFC

//Член НСДАП с 1998 года (VC6 SP6)
virtual void TrackRowSize(int y, int row);
virtual void TrackColumnSize(int x, int col);
virtual void StartTracking(int ht);
virtual void StopTracking(BOOL bAccept);

Названия функций в свете поставленной задачи не интригуют случаем!?!
Aml Pages Home
Re[17]: Splitter и минимальный размер отображения
От: Carc Россия http://www.amlpages.com/home.php
Дата: 21.11.08 12:07
Оценка:
PS: ну да забыл написать — вышеперечисленные функции из CSplitterWnd (afxext.h)
Aml Pages Home
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.