Member 11380615 Ответов: 1

Mfc onvscroll не вызывается в классе основного кадра MDI


У меня есть проект на основе c++ MFC MDI, использующий сообщество visual studio 2013. Класс мэйнфрейма является производным от класса CMainFrame : public CMDIFrameWndEx

В класса мэйнфрейм предварительного создания полосы прокрутки устанавливается, как показано ниже.
cs.style |= WS_VSCROLL | WS_HSCROLL;
Функция обратного вызова OnVScroll была добавлена для приема обратного вызова всякий раз, когда перемещается полоса прокрутки основного кадра. ON_WM_VSCROLL() был добавлен в карту сообщений в мэйнфрейме. Мы обнаруживаем, что OnVScroll никогда не вызывается. Как мы включаем обратные вызовы OnVScroll всякий раз, когда пользователь перемещает полосу прокрутки? Любая помощь будет очень признательна. Спасибо и с уважением, Ракеш

Что я уже пробовал:

Я не знаю, что делать. Я хотел вызвать SetScrollSizes в любом месте в классе мэйнфреймов.

Richard MacCutchan

Вы вызывали SetScrollSizes, и появляется ли полоса прокрутки в вашем окне?

Member 11380615

Спасибо, Ричард, да, полоса прокрутки появляется в главном окне фрейма. Всякий раз, когда количество дочерних окон и их сквозной экстент выходят за пределы клиентской области MDI, автоматически появляется вертикальная и горизонтальная полоса прокрутки.
Я не смог вызвать SetScrollSizes, так как эта функция недоступна в основном классе фреймов.

Richard MacCutchan

Это происходит потому, что полосы прокрутки связаны с окнами просмотра, а не с Мэйнфреймом. Вам нужно установить размеры прокрутки для каждого отдельного вида.

Member 11380615

Для каждого отдельного вида были установлены размеры прокрутки.

1 Ответов

Рейтинг:
1

Jochen Arndt

Это потому что CFrameWnd основанные классы направляют эти сообщения в активное представление и CMDIFrameWnd ловушки эти WS_VSCROLL и WS_HSCROLL и стили:

Класс CFrameWnd обеспечивает управление активным представлением. Следующие сообщения направляются через активное представление:
  • Все командные сообщения (активное представление получает к ним первый доступ).
  • Сообщения WM_HSCROLL и WM_VSCROLL от родственных полос прокрутки (см. ниже).
  • WM_ACTIVATE (и WM_MDIACTIVATE для MDI) превращаются в вызовы виртуальной функции CView::OnActivateView.

...
Кроме того, существует два производных класса CWnd, в которых стили полосы прокрутки, указанные во время создания, захватываются и не передаются в Windows.
...
Для CMDIFrameWnd стили полосы прокрутки, которые вы передаете для создания или LoadFrame, используются для создания MDICLIENT.

Таким образом, вы не можете использовать полосы прокрутки с CFrameWnd базовый класс. Это было бы возможно только путем реализации ваших собственных (CWnd классы), которая должна обеспечить всем необходимым функционалом МДИ. Из - за взаимосвязи между классами MFC document и view вам может потребоваться создать полностью новую реализацию document и view.

Обратите также внимание, что фреймовые окна предназначены для размещения и организации представлений и обычно не требуют полос прокрутки.


Member 11380615

Спасибо, Йохен. Я действительно нахожу, что окно фрейма MDI автоматически создает вертикальную и горизонтальную полосу прокрутки, когда дочерние окна выходят за пределы экстента клиентской области mdi. Полоса прокрутки окна кадра MDI прекрасно работает, когда она там есть. Прокрутка работает нормально.
Моя цель состоит в том, чтобы перехватить событие прокрутки, когда пользователь пытается прокрутить его. Можно ли перехватить прокрутку окна кадра MDI в классе active view с помощью WM_HSCROLL, WM_VSCROLL. Если да, то как бы мы различали прокрутку окна просмотра и главного фреймового окна MDI?

Jochen Arndt

Я не знаю. Просто попробуй.

Смотрите документацию MS для прокрутки WM_[H|V]:
параметр lparam
Если сообщение отправляется с помощью элемента управления полосой прокрутки, этот параметр является дескриптором элемента управления полосой прокрутки. Если сообщение отправляется с помощью стандартной полосы прокрутки, этот параметр равен нулю.

Вам нужно будет создать по крайней мере один набор полос прокрутки в качестве элемента управления, чтобы узнать, из которого было отправлено сообщение (на самом деле я не знаю, использует ли CScrollView стандартную полосу или элемент управления). Затем вы можете дифференцироваться в представлении и отправлять определяемое пользователем сообщение в представление или предоставлять функцию в вашем основном классе фреймов.

Member 11380615

Я попытался добавить OnVScroll в класс ScrollView. SetScrollSizes также вызывались в классе view. Там была только одна полоса прокрутки, и это было в главном окне фрейма. Несмотря на то, что я мог прокручивать вверх и вниз клиентскую область mdi, функция обратного вызова OnVScroll так и не была вызвана.