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

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


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

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



Программисты долго мучаются с кодом прогаммы, изучают С++, WinAPI функции, MSDN. Потом пишут банальную систему защиты или навешивают банальный протектор, а крэкеры и реверсеры справляются с такой защитой за 5 минут. В итоге, продажи программы почти нулевые. Чтобы такого не допустить, тут самому надо немного поднабрать опыта отладки, реверсинга, тот же отладчик Ollydbg изучить или дизассемблер IDA Pro. Но где искать по крохам эти знания? Нет, конечно можно годами "методом тыка" разбираться, но куда быстрее видеокурс специальный посмотреть. Вот тут он есть: ссылка. Автор курса с большим опытом и объясняет понятно, я из этого курса много узнал про то как работает компьютер, процессор, про инструменты специальные и как с ними работать. Мои коллеги программисты на работе ничего такого и не знают, теперь я им нос утру.

Создание MFC Property Sheet изменяемого размера

Иногда для приложения требуется большей гибкости в использовании property sheet, чем может предоставить Microsoft Foundation Classes (MFC). В данной статье, демонстрируются шаги, по созданию класса property sheet, который так же содержит полоску меню.

Приведённые ниже инструкции, показывают, как добавить новый класс property sheet в существующий проект MFC и настроить окошко, обработав запросы на изменение размера, а так же добавив меню. В галвной роли будет выступать класс, CMyPropertySheet, который можно использовать для воплощения нашего замысла. Этот класс мог бы стать достойной заменой  для MFC-шного CPropertySheet так как обеспечивает дополнительную функциональность, описанную выше.

  1. В проекте, основанном на MFC, добавление нового property sheet осуществляется при помощи галереи компонентов. Для этого в меню Project кликните на Add to project, а затем на Component and Controls. В появившемся диалоговом окошке сделайте двойной щелчёк на папку "Components", а затем выберите Property Sheet.

  2. Для того, чтобы сделать рамку изменяемого размера, необходимо переопределить DoModal() и создать callback функцию, которая установит соответствующие стили для окошка свойств (property sheet). Поэтому, необходимо добавить следующие две функции (как в заголовочном файле, так и в файле исходника для класса CMyPropertySheet.):

    • Статическая callback функция окошка свойств, XmnPropSheetCallback():

      // Эта функция должна быть STATIC.
       //Callback позволяет нам установить стили окна поумолчанию
       //    для property sheet
       int CALLBACK CMyPropertySheet::XmnPropSheetCallback(HWND hWnd,
                                               UINT message, LPARAM lParam)
       {
          extern int CALLBACK AfxPropSheetCallback(HWND, UINT message, LPARAM lParam);
          // XMN: Вызывает MFC-шный callback
          int nRes = AfxPropSheetCallback(hWnd, message, lParam);
       
          switch (message)
          {
          case PSCB_PRECREATE:
             // Устанавливаем наши собственные стили окна
             ((LPDLGTEMPLATE)lParam)->style |= (DS_3DLOOK | DS_SETFONT
                | WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION);
             break;
          }
          return nRes;
       }
         
    • Переопределение DoModal():

      // Переопределение DoModal() позволяет нам перехватить наш callback
       //    при создании окошка свойств
       int CMyPropertySheet::DoModal()
       {
          // Ловушка в коде создания property sheet
          AFX_OLDPROPSHEETHEADER* psh = GetPropSheetHeader();
          psh->dwFlags |= PSH_USECALLBACK;
          psh->pfnCallback = XmnPropSheetCallback;
          return CPropertySheet::DoModal();
       } 
  3. Теперь мы имеем property sheet, размеры которого можно изменять при помощи мышки. Чтобы добавить меню, Вам необходимо переопределить OnInitDialog(). В меню View выберите Class Wizard, затем в диалоговом окне Class Wizard выберите проект и класс для property sheet. Далее в выпадающем списке Messages выберите пункт OnInitDialog. Приведённый ниже код, показывает, как должно выглядеть переопределение OnInitDialog():

    BOOL CMyPropertySheet::OnInitDialog()
     {
        BOOL bResult = CPropertySheet::OnInitDialog();
     
        // Добавляем новое меню
        CMenu *pMenu = new CMenu; pMenu->LoadMenu(IDR_PS_MENU);
        SetMenu(pMenu);
     
        // Корректируем размер propsheet под новое меню
        CRect r;  GetWindowRect(&r);
        r.bottom += GetSystemMetrics(SM_CYMENU);
        MoveWindow(r);
     
        return bResult;
     } 
  4. Теперь нам необходимо обеспечить политику изменения размеров. Наиболее правильный способ сделать это, заключается в том, чтобы изменить размеры внедрённого контрола tab в соответствии с запросом на изменение размеров и перемещая кнопки, присутствующие на окне. Для этого проделаем следующее:

    1. В класс CMyPropertySheet добавьте следующие переменные:
      protected:
          BOOL   m_bNeedInit;
          CRect  m_rCrt;
          int    m_nMinCX;
          int    m_nMinCY; 
    2. Инициализируйте эти переменные и установите m_bNeedInit в TRUE в конструкторе CMyPropertySheet:

      CMyPropertySheet::CMyPropertySheet(CWnd* pWndParent)
       	 : CPropertySheet(IDS_PROPSHT_CAPTION, pWndParent)
       	 , m_bNeedInit(TRUE)
       	 , m_nMinCX(0)
       	 , m_nMinCY(0)
       
       {
          AddPage(&m_Page1);
          AddPage(&m_Page2);
       
       } 
    3. Добавьте следующие строки в конец OnInitDialog():

      BOOL CMyPropertySheet::OnInitDialog()
       {
          // ...
          // Инициализируем m_nMinCX/Y
          m_nMinCX = r.Width();
          m_nMinCY = r.Height();
          // After this point we allow resize code to kick in
          m_bNeedInit = FALSE;
          GetClientRect(&m_rCrt);
       
          return bResult;
       } 
    4. Делаем обработчики для события WM_SIZE. Для этого в меню View кликаем Class Wizard, а затем в диалоговом окошке Class Wizard выбираем проект и класс окна свойств (property sheet). Далее, в выпадающем списке Messages выбираем пункт WM_SIZE. Ниже показана реализаци обработчика сообщения:

      // Обрабатываем событие WM_SIZE путём изменения размера контрола tab
       //    и перемещая все кнопки на property sheet.
       void CMyPropertySheet::OnSize(UINT nType, int cx, int cy)
       {
          CRect r1;
          CPropertySheet::OnSize(nType, cx, cy);
       
          if (m_bNeedInit)
             return;
       
          CTabCtrl *pTab = GetTabControl();
          ASSERT(NULL != pTab && IsWindow(pTab->m_hWnd));
       
          int dx = cx - m_rCrt.Width();
          int dy = cy - m_rCrt.Height();
          GetClientRect(&m_rCrt);
       
          HDWP hDWP = ::BeginDeferWindowPos(5);
       
          pTab->GetClientRect(&r1);
          r1.right += dx; r1.bottom += dy;
          ::DeferWindowPos(hDWP, pTab->m_hWnd, NULL,
                           0, 0, r1.Width(), r1.Height(),
                           SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
       
          // Перемещаем все кнопки с нижних правых сторон
          for (CWnd *pChild = GetWindow(GW_CHILD);
               pChild != NULL;
               pChild = pChild->GetWindow(GW_HWNDNEXT))
          {
             if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
             {
                pChild->GetWindowRect(&r1); ScreenToClient(&r1);
                r1.top += dy; r1.bottom += dy; r1.left+= dx; r1.right += dx;
                ::DeferWindowPos(hDWP, pChild->m_hWnd, NULL,
                                 r1.left, r1.top, 0, 0,
                                 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
             }
             // Ресайзим всё остальное...
             else
             {
                pChild->GetClientRect(&r1);
       	 r1.right += dx; r1.bottom += dy;
       	 ::DeferWindowPos(hDWP, pChild->m_hWnd, NULL, 0, 0,
                             r1.Width(), r1.Height(),
                             SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
             }
       
          }
       
          ::EndDeferWindowPos(hDWP);
       } 
    5. В заключении, Вам необходимо создать обработчик сообщения WM_GETMINMAXINFO. Для этого в меню View кликаем Class Wizard, а затем в диалоговом окошке Class Wizard выбираем проект и класс окна свойств (property sheet). Далее, в выпадающем списке Messages выбираем пункт WM_GETMINMAXINFO. Ниже приведена реализация обработчика WM_GETMINMAXINFO:

      void CMyPropertySheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
       {
          CPropertySheet::OnGetMinMaxInfo(lpMMI);
          lpMMI->ptMinTrackSize.x = m_nMinCX;
          lpMMI->ptMinTrackSize.y = m_nMinCY;
       } 



ССЫЛКИ

Для получения дополнительной информации, можно посмотреть следующие статьи из Microsoft Knowledge Base:

Q143291 Как изменить размер CPropertyPages во время выполнения

Q146916 Как создать немодальный CPropertySheet со стандартными кнопками

 



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

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




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



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


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