Заметки по WinAPI

  • перерисовка окон
    • сама система перерисовывает окно строится, меняется его размер, оно двигается, скроллируется, выделяется некоторая область или при любом другом внешенм изменении
    • основная функция перерисовки BOOL RedrawWindow(
        _In_  HWND hWnd,                // окно
        _In_  const RECT *lprcUpdate,    // какой прямоугольник надо преерисовать (игнорится. если задан регион)
        _In_  HRGN hrgnUpdate,            // какой регион надо перерисовать (если оба 0, то вся клиентская область)
        _In_  UINT flags                 // 
      
      ); флаги
        - RDW_ERASE ( эффективен только с RDW_INVALIDATE ), посылает окну WM_ERASEBKGND (один из параметров - HDC, второй не используется) при этом сообщении DefWindowProc удаляет задний фон
            - сообщение WM_ERSAEBKGND
                - wParam - хэндл к DC
                - lParam - не используется 
                - означает что надо удалить BackGround
        - RDW_FRAME - заставляет всю неклиенсткую часть, которая пересекается с перерисовываемым регионом, перерисовываться (притом WM_NCPAINT(один параметр - хэндл региона) шлется и DefWindowProc перерисовывает неклиентскую часть в области)
        - RDW_INTERNALPAINT - шлет окну WM_PAINT вне зависимости от региона и прямоугольника
        - RDW_INVALIDATE - делает невалидными область или прямоугольник или окно
        - RDW_NO{one of the messages above} - убирает все сообщения, которые были посланы теми флагами
        - RDW_ERASENOW, RDW_UPDATENOW - эта же функция и перерисовывает окно (а не просто помещает сообщения в очереди)
        - RDW_ALL(NO)CHILDREN - (не) применяет операции к дочерним окнам в зоне действия (по дефолту зависит от WS_CLIPCHILDREN)
      
  • сообщение WM_PAINT
    • это сообщение означает, что надо бы перерисовать клиентскую область
    • во время обработки этого сообщения можно перерисовывать содержимое экрана.
    • для этого сначала вызывается функция BeginPain( HWND, LPPAINTSTRUCT )
      • заполняет структура PANITSTRUCT и возвращает HDC (хэндл к display device context) typedef struct tagPAINTSTRUCT {
          HDC  hdc;        // dc экрана
          BOOL fErase;    // надо ли удалять background
          RECT rcPaint;    // прямоугольник, в котором можно рисовать
          BOOL fRestore;    // этот и далее - reserved
          BOOL fIncUpdate;
          BYTE rgbReserved[32];
        
        } PAINTSTRUCT, *PPAINTSTRUCT;
    • после BeginPaint рисуем/куралесим
    • в конце EndPaint( HWND, LPPAINTSTRUCT ) // кстати, он же и делает DeleteDc
  • что такое clipping?
    • Clipping - процесс ограничения вывода на регион или путь в пределах клиентской области окна предложения
    • фактически, мы рисуем один ирсунок, но ClippingPath DC это круг, двигаемый мышкой так мы можем двигать круг и просматривать только тот участок картины, который виден в кругу.
  • сообщение WM_PRINTCLIENT
    • параметры
      • обозначает, что окну надо отрисовать свою клиентскую область в определенном DC
      • wParam - Handle to DC
      • lParam - options
        • PRF_CHECKVISIBLE - отрисуй только если окно видимо
        • PRF_CHILDREN - отрисую видимых детей
        • PRF_CLIENT - отрисуй клиентскую область
        • PRF_ERASEBKGND - удали задний фон перед отрисовкой
        • PRF_NONCLIENT - отрисуй неклиентскую часть
        • PRF_OWNED - отрисуй все owned окна
  • Контексты устройств
    • смысл - выводить картинку на любое устройство, за счет того, что устройство предоставляет тебе DeviceContext, а мы. при помощи WinAPI функций, рисум в контексте устройства (например, драйвер к принтерам предоставляет нам возможность пользоваться его DeviceContext'ом.)
    • этот конекст содержит в себе набор выбранных инструментов
      • BitMap
      • Brush
      • Font
      • Pen
      • Region
    • при помощи ::SelectObject( HDC, HGDIOBJECT ) можно установить текущий объект для такого-то DC
      • возвращает предыдущий объект
  • Типы контекстов
    • Display
      • class
        • не использовать, существуют лишь для обратной совместимости с 16-битной версией
      • common
        • хранятся в специальном кеше системы, используются в приложениях с нечастой перерисовкой. Они заняты дефолтноыми данными, и приложение, после release все изменеия затираются. в связи со способом хранения, сильно огрнаничены в количестве
      • private
        • после release изменения сохраняются, и такой DC живет, пока существует хоть одно окно, которое ползуется этим DC. Создается при регистрации класса окна с флагом CS_OWNDC. Достается функциями GetDC, GetDCEx и BeginPaint
      • window
        • позволяют рисовать где угодно в окне (включая неклиентскую область), используются когад обрабатываются сообщения типа WM_NCPAINT WM_NCACTIVATE. Использовать не рекомендуется. Добывается функцией HDC ::GetWindowDC( HWND )
      • parent
        • используется системой для более быстрого определения, где перерирсовывать родителя, а где - ребенка
    • Printer
      • используется для печати на принтеры (ВАШ КЭП!), создается приомощи функции CreateDC HDC CreateDC(
          LPCTSTR lpszDriver,                // драйвер (в принтере обычно NULL)
          _In_  LPCTSTR lpszDevice,        // device (для принетра - как называется в панели управления принтерами)
          LPCTSTR lpszOutput,                // для обратной совместимости
          _In_  const DEVMODE *lpInitData    // дополнительная инициализация (если требуется)
        
        );
    • Memory
      • вместо того, чтобы все время отсылать команды устройству, можно все рисовать в памяти, на вирутальном девайсе. Для этого есть функция CreateCompatibleDC, потом задается BitMap'а (ерез SelectObject). Потом (после всех рисований), при помощи BitBlt можно скопировать ее на экран (вот и двойная буферизация)
    • Information
      • используются для вытаскивания дефолтных параметров девайса
      • CreateIC создает его, далее через GetCurrentOjbect и GetObject можно получить объекты
    • Decstop
      • спрсоить у препа
  • GDI объекты
    • regions
      • регион это прямоугольныя, полтгональная или круглая область (или объединения таковых), которая может быть заполнена,нарисована, отображена, и на ней отдельно можно обрабатывать всякие клики мышкой
      • создание
        • CreateRectRgn(Indirect) // создать прямоугольный регион из 4-х координат (или из RECT)
        • CreateRoundRectRgn - чеыре координаты прямоугольника и параметры эллипса для закругления
        • CreateEllipticRgn(Indirect) - четыре координаты (RECT)- прямоугольник, в который будет вписан эллипс эллипс
        • CreatePolygonRgn( POINT*, INT cPoints, INT fnPolyFillMode ) -массив точек, длина массива и тип заполнения
          • ALTERNATE - заполняет область между нечетно и четно нумерованными сторонами полигона каждой горизонтали (внутри)
          • WINDING - полностью заливает регион
      • сравнение BOOL EqualRgn( HRGN1, HRGN2 )
      • наполнение BOOL FillRgn( HDC, HRGN, HBRUSH )
      • объединение int CombineRgn( HRGN dest, HRGN1, HRGN2, RGN_AND|COPY|DIFF|OR|XOR )
        • возвращаемое значение NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR
      • отрисовка PaintRgn( HDC, HRGN )
      • инвертирование цветов InvertRgn( HDC, HRGN )
      • отрисовка границ региона FrameRgn( HDC, HRGN, HBRUSH, nWidth, nHeight )
      • также регионы можно сдвигать, получать содержащий их прямоугольник и проверять, лежит ли в не мтчока(GetRgnBox, OffsetRgn, PtInRegion )
  • трансформация координат
    • четыре типа координат
      • world
      • page
      • device
      • physical device