Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 августа!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Возможности языков семейства Си по истине безграничны, однако, в этой свободе кроются и недостатки: всегда нужно программисту держать ухо востро и контроллировать "переполнение буфера", чтобы потом программа не вылетала в "синий экран" на массе разнообразных версий Windows и железа у пользователей. Те же крэкеры и реверсеры специально ищут в коде программ на Си уязвимости, куда можно подсадить любой вирусный код, об этом более подробно автор рассказывал в своём видеокурсе здесь. Я там многое узнал и теперь мой код стал значительно более безопасный.

Меняем цвет Scroll Bar в приложении MFC

Автор: Paul DiLascia

Windows имеет два типа скролбаров. Это "встроенные" скролбары, которые мы получаем при использовании оконных стилей WS_HSCROLL и/или WS_VSCROLL, и скролбар контролы, которые фактически являются дочерними окнами и которые можно создавать в пределах окна. Сообщение WM_CTLCOLOR могут посылать только последние.

    Естевственно, возникает вопрос, а почему существует два вида скролбаров ? Ответ кроется в истории. Давным давно, когда Windows была ещё очень маленькой, существовала необходимость экономить каждый бит памяти, а окна занимали значительное пространство. Так как почти в каждом окне присутствовали скролбары, то разработчики решили сделать их неотемлемой частью окон. С другой стороны, программистам не понравилось такое решение, так как им больше хотелось работать со скролбарами, как с отдельными окнами. С одной стороны, конечно же встроенные скролбары удобнее в использовании и требуют меньше кода, но с другой имеют меньше настроек, позволяющих менять их внешний вид.
   А как насчёт MFC? Поумолчанию, MFC-шный CScrollView использует встроенные скролбары, у которых нельзя менять цвет. Однако, ничего страшного не случится, если мы заставим CScrollView использовать Ваш собственный контрол скролбара. Но перед тем, как мы решим данную задачу, я хочу заметить, что WM_CTLCOLOR позволяет устанавливать только цвет фона, но не цвет стрелки и бегунок. Поэтому, если Вы хотите менять все цвета, то скорее всего WM_CTLCOLOR окажется бесполезным. Позже я постараюсь подкинуть несколько идей по этому поводу, ну а теперь давайте посмотрим, как заставить CScrollView использовать Ваш скролбар вместо встроенного.
   Итак, для начала, объявим экземпляры CScroll баров в основном фрейме:

class CMainFrame : public CFrameWnd {
 protected:
   CScrollbar m_wndHScroll;
   CScrollBar m_wndVScroll;
   •••
 };
 

Затем, при создании фрейма, создаём их окна:

int CMainFrame::OnCreate(...)
 {
   •••
   CRect rc(0,0,0,0);
   VERIFY(m_wndSBHorz.Create(WS_VISIBLE|WS_CHILD|SBS_HORZ,
     rc, this, AFX_IDW_HSCROLL_FIRST));
   VERIFY(m_wndSBVert.Create(WS_VISIBLE|WS_CHILD|SBS_VERT,
     rc, this, AFX_IDW_HSCROLL_FIRST+1));
   VERIFY(m_wndSBBox.Create(WS_VISIBLE|WS_CHILD|SBS_SIZEBOX,
     rc, this,-1));
   return 0;
 }
 

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

CScrollBar* CPictureView::GetScrollBarCtrl(int nBar) const
 {
   CWnd* pParent = GetParent();
   UINT nID = AFX_IDW_HSCROLL_FIRST;
   if (nBar==SB_VERT)
     nID++;
   return (CScrollBar*)pParent->GetDlgItem(nID);
 }
 

Она получает управление от родителя используя удобные идентификаторы (ID) AFX_IDW_HSCROLL_FIRST и AFX_IDW_HSCROLL_FIRST+1.
   А как же уведомления? Когда пользователь перемещает полосу прокрутки, скролбар посылает WM_HSCROLL или WM_VSCROLL своему родителю, чтобы Вы могли что-нибудь сделать. Это есть очень хорошо, так как если Вы поместите свои скролбары во фрейм, то CFrameWnd уже имеет обработчики OnHScroll и OnVScroll, которые направляют WM_HSCROLL и WM_VSCROLL в вид (view):

// Из winfrm.cpp
 void CFrameWnd::OnHScroll(...)
 {
   CWnd* pActiveView = GetActiveView();
   if (pActiveView != NULL) {
     pActiveView->SendMessage(WM_HSCROLL, ...);
   }
 }
 

   Если Ваш вид наследован от CScrollView, то для того, чтобы обработать сообщения прокрутки, ничего делать не надо, так как MFC делает это автоматически!
   Теперь о размерах. Это то место, где прийдётся проделать определённую работу. Для того, чтобы всё летало, необходимо управлять позицией скролбаров каждый раз, когда размер фрейма изменяется. Помните, что скролбары, это потомки фрейма а не вида. Обычно, обработка изменения размеров производится в OnSize, однако для фреймовых окон это делается в CFrameWnd::RecalcLayout. Применительно к программе (исходник которой можно скачать ниже) эта функция выглядит так:

 //////////////////
 // изменение размеров фрейма: перемещение вида и скролбаров
 //
 void CMainFrame::RecalcLayout(BOOL bNotify)
 {
     CFrameWnd::RecalcLayout();
 
     CView* pView = GetActiveView();
     if (pView) {
         CRect rc;
         pView->GetWindowRect(&rc);
         ScreenToClient(&rc);
 
         // shrink view by scrollbars
         int cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
         int cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
         rc.right  -= cxVScroll;
         rc.bottom -= cyHScroll;
         pView->MoveWindow(rc);
 
         // next, move the scroll bars: horz, vert and box
         rc.left   = rc.right;
         rc.right += cxVScroll;
         m_wndSBVert.MoveWindow(rc);
 
         rc.left   = 0;
         rc.right -= cxVScroll;
         rc.top    = rc.bottom;
         rc.bottom+= cyHScroll;
         m_wndSBHorz.MoveWindow(rc);
 
         rc.left = rc.right;
         rc.right+=cxVScroll;
         m_wndSBBox.MoveWindow(rc);
     }
 }  }
 }
 


Скачать исходник (201K)

 



<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS