Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: стандартные полосы прокрутки CWnd  (Прочитано 16160 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 26-06-2012 18:09 » 

вопрос, наверное, к Джону Ага

Хочется получить следующее: на диалоге с изменяемым размером лежат контролы, а также включены стандартные встроенные в диалог полосы прокрутки. Когда контролы заезжают за край диалога, полоски должны появляться и позволять прокрутить содержимое диалога

это возможно встроенными методами CWnd ?

Для эксперимента сделал принудительную начальную установку позиции полосок (на скрине) , прокрутка не произошла, хотя ползунки сдвинуты


* 1.png (45.43 Кб - загружено 2601 раз.)
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-06-2012 21:03 » 

Видимо они не связаны со скролированием клиентской части окна. Т.е. скролбары есть, события генерятся - дальше сам перемещай.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 27-06-2012 04:23 » 

не не, это несерьёзно. Мне кажется, окно должно уметь отображать своих чайлдов со сдвигом, иначе зачем всё это навешивалось ? Недоделка от майкрософта ? )
Записан

zubr
Гость
« Ответ #3 : 27-06-2012 06:52 » 

Алексей1153++, может в NET есть что то похожее на дельфийский TScrollBar - там именно так реализовано как ты хочешь. Но если глянуть исходники этого TScrollBar, то все решается через стандартные скроллбары, от событий которых (SetWindowPos) перемещаются чилды окна, как и предложил RXL.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 27-06-2012 08:16 » 

Не, вручную перемещать не нужно. Просто клиентская область должна быть шире региона отображения. SetWindowPos как раз обеспечивают прокрутку в том смысле, что сдвигает регион отображения относительно клиентской области - содержимое двигается само собой при очередном refresh окна.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 27-06-2012 10:19 » 

Лёшик, а в OnSize ты чего делаешь?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 27-06-2012 16:54 » 

Джон, Джон, ну блин, как раз и хочется там ничего не делать ))  Ничего, собственно, не делаю

zubr, так у меня не дотнет )

Dimka, так ведь SetWindowPos занимается размещением всего окна в целом на экране (и Z-order) , а не сдвигом клиентской области. Как это сюда относится ?

Если без лишних движений в WinAPI/MFC это не реализуется, тогда придётся вручную все контролы двигать, похоже
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 27-06-2012 17:54 » 

Алексей1153++, это я перепутал. Я такую штуку делал на WinAPI 3 года назад, когда нужны были внешние ScrollBar'ы. Поэтому точно знаю, что двигается всё содержимое окна, а точка (0,0) уходит за границу видимости вверх и влево.

Во-первых, двигать можно, посылая вручную события WM_HSCROLL и WM_VSCROLL, работающие в любом случае. Во-вторых, есть системный вызов SetScrollInfo, но он, к сожалению, работает лишь при включенных ScrollBar'ах текущего окна (или что-то в этом духе).
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 28-06-2012 07:04 » 

Джон, Джон, ну блин, как раз и хочется там ничего не делать ))  Ничего, собственно, не делаю

В смысле "не хочется"? Ты там ваще ничего не делаешь? Те и удовольствие получить хочешь, и не забеременнеть? По WM_SIZE ты должен информировать твои скроллбары. Как ты себе это иначе представляешь? Откуда они знают, какого размера у тебя клиент?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 28-06-2012 16:11 » 

Джон, поставлю вопрос по-другому: как сказать окну, что ему нужно сдвинуть клиентскую область на dx,dy ?   Пофиг на полоски!
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 28-06-2012 17:53 » 

Лёшик, вот за что я тебя обычно люблю, так это за непвторимую манеру спрашивать одно, а ввиду иметь совершенно другое. Ага

Поэтому ты давай не увиливай, что сначала спросил, на то ответ и получишь. Ага Хотя...

ScrollWindow должна спасти гиганта мысли. Ага

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

Цитата: Алексей1153++
Когда контролы заезжают за край диалога, полоски должны появляться и позволять прокрутить содержимое диалога

наверняка означает, что "уезжают" они при ресайзе, или у тебя контролы самостоятельно ездят по форме? Ага

Итак, у тебя есть диалог, с кучей контролов. Ну я сильно не стал заморачиваться, где три там и тридцать. По запарке назвал его TesdScrollDlg имелось ввиду Test. Да и сделал его только для вертикального, ессно для горизонтального тоже самое, только в профиль.



Ты меняешь его размеры - уменьшаешь (увеличивать изначально ничего не принесёт), ессно часть контролов уходит из области видимости. Например так:



Теперь бы тебе хотелось увидеть эти контролы, не меняя размеров окна, двигая движки полосок типа так:



Надеюсь, я правильно уловил твою мысль? Если нет, забудь всё. В противном случае скажу, что ты абсолютно прав: двигать ручками каждый контрол не только неспортивно, но и даже накладно, ведь их у нас на форме как грязи, а если ещё добавить? Конечно, проще свалить всё на кривость МС и забыть. Но попробуем таки разобраться. А вдруг получится. Ага

"Остапа несло" (с)

Итак, диалог с полосками. Единственное, что им не хватает - информации о положении клиентской области. Для них она всегда постоянна и равна размерам окна минус какие-то рамки. Да ещё одно, в след раз внимательно читай мои вопросы. Я тебя попросил показать OnSize, и меня при этом совсем не волновало как ты там собирался, собираешься и тд контролы двигать. Я просто хотел увидеть, какую инфу ты там передаёшь полоскам, а точнее делаешь ли это ваще. Вот и всё.

Итак, для вертикального скрола тебе надо:

а) запомнить размеры клиента при инициализации диалога и запоминать текущую скролл-позицию для каждой полоски, те идея заключается в том, чтобы сравнивать текущие размеры окна, с некими постоянными размерами, я их из лени слямзил при старте:

Код: (C++)
        GetWindowRect(m_rect);
        m_nScrollPos = 0;

б) в OnSize информировать полоски об изменениях

Код: (C++)
void CTesdScrollDlgDlg::OnSize(UINT nType, int cx, int cy)
{
        CDialog::OnSize(nType, cx, cy);

        m_nCurHeight = cy;
        int nScrollMax;
        if (cy < m_rect.Height())
        {
                nScrollMax = m_rect.Height() - cy;
        }
        else
                nScrollMax = 0;

        SCROLLINFO si;
        si.cbSize = sizeof(SCROLLINFO);
        si.fMask = SIF_ALL; // SIF_ALL = SIF_PAGE | SIF_RANGE | SIF_POS;
        si.nMin = 0;
        si.nMax = nScrollMax;
        si.nPage = si.nMax/10;
        si.nPos = 0;
        SetScrollInfo(SB_VERT, &si, TRUE);
}

в) в OnScroll пересчитывать позицию в координаты и вызывать упомянутую ScroolWindow:

Код: (C++)
void CTesdScrollDlgDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
        int nDelta;
        int nMaxPos = m_rect.Height() - m_nCurHeight;

        switch (nSBCode)
        {
        case SB_LINEDOWN:
                if (m_nScrollPos >= nMaxPos)
                        return;
                nDelta = min(nMaxPos/100,nMaxPos-m_nScrollPos);
                break;

        case SB_LINEUP:
                if (m_nScrollPos <= 0)
                        return;
                nDelta = -min(nMaxPos/100,m_nScrollPos);
                break;

        case SB_PAGEDOWN:
                if (m_nScrollPos >= nMaxPos)
                        return;
                nDelta = min(nMaxPos/10,nMaxPos-m_nScrollPos);
                break;

        case SB_THUMBPOSITION:
                nDelta = (int)nPos - m_nScrollPos;
                break;

        case SB_PAGEUP:
                if (m_nScrollPos <= 0)
                        return;
                nDelta = -min(nMaxPos/10,m_nScrollPos);
                break;

        default:
                return;
        }
        m_nScrollPos += nDelta;
        SetScrollPos(SB_VERT,m_nScrollPos,TRUE);
        ScrollWindow(0,-nDelta);

        CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

Ну и фсё!

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

* ss1.gif (4.21 Кб - загружено 2396 раз.)
* ss2.gif (3.6 Кб - загружено 2429 раз.)
* ss3.gif (4.21 Кб - загружено 2477 раз.)
* TesdScrollDlg.zip (36.27 Кб - загружено 1048 раз.)
« Последнее редактирование: 28-06-2012 18:10 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 29-06-2012 04:09 » 

Джон, да всё понятно, не расстраивайся )

То, что мне нужно было, короче, это ScrollWindow Отлично

Проверил так:


Код:
BOOL CTesdScrollDlgDlg::OnInitDialog()
{
CDialog::OnInitDialog();

ScrollWindow(-50,-100);

return TRUE;
}

клиентская область сдвинулась, но кнопки продолжают нормально работать .



Спасибо!

ЗЫ нашёл баг в твоей программе Улыбаюсь Если при уменьшенном окне сдвинуть ползунок, а затем увеличть окно, контролы остануться "уехавшими". Но это уже не так важно, мелочи

* Безымянный.PNG (4.9 Кб - загружено 2514 раз.)
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 29-06-2012 07:30 » 

А ещё проще было бы добавить её в обработчик кнопки, например ОК. Тогда при каждом нажатии, клиенская часть будет "сползать". Ага

ps Лёш, баг в "программе" - слишком громко сказано. Ага Скорее в "иллюстрации" к тексту. Программой это назвать нельзя. Так что он там наверняка не единственный. switch в OnVScroll я тоже из какой-то своей проги выдрал, ибо не помню всех этих констант наизусть. Так что за него тоже 100% не ручаюсь. Дело было показать принцип.
Ну... рад что помог.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 29-06-2012 10:15 » new

А ещё проще было бы добавить её в обработчик кнопки, например ОК
нет, тут важно то, что функция прекрасно работает непосредственно после вызова родительского OnInitDialog и не "сбивается" далее. Это всегда радует ))
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines