API и FreeBasic. (Рисование примитивов с помощью GDI часть вторая)

 

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

Как я и писал, в контексте уже предустановлены объекты по умолчанию (перья , кисти, шрифт...). Кисти нужны для заполнения областей объектов рисования. Так перо по умолчанию с черным цветом и толщиной один пиксель , а кисть белого цвета. Если рисовать прямоугольники и эллипсы , не изменяя кисти и перья, то получится что-то вроде этого:

defaultdraw.png

Чтобы изменить кисть есть несколько функций:

  • GetStockObject (param) - задает кисть на основе встроенных системных кистей, при этом param может быть:
    • BLACK_BRUSH - черная кисть
    • DKGRAY_BRUSH - темно-серая кисть
    • DC_BRUSH - кисть сплошного тона, цвет белый, может меняться при помощи SetDCBrushColor
    • GRAY_BRUSH - серая кисть
    • LTGRAY_BRUSH - светло-серая кисть
    • NULL_BRUSH - нулевая(прозрачная) кисть
  • CreateSolidBrush (color) - задает кисть на основе цвета, при этом color (цвет) может быть от 0 до &hffffff
  • CreatePatternBrush (bmp) - задает кисть на основе рисунка , при этом bmp - хендл битмапа
  • GetSysColorBrush (index) - задает кисть на основе встроенных кистей, при этом индекс может быть одним из 21 элементов, используемых для окраски различных частей окон (подробнее структура wndclassex)
  • CreateHatchBrush (style , color) - задает штриховую кисть заданного цвета, при этом цвет может быть от 0 до &hffffff, а style может быть:
    • HS_BDIAGONAL - штрихует с наклоном влево под углом 45 градусов
    • HS_CROSS - перекрестный штрих (в клеточку)
    • HS_DIAGCROSS - перекрестный штрих под углом 45 градусов
    • HS_FDIAGONAL - штрихует с наклоном вправо под углом 45 градусов
    • HS_HORIZONTAL - штрихует по горизонтали
    • HS_VERTICAL - штрихует по вертикали
  • CreateDIBPatternBrush (hglbDIBPacked,fuColorSpec) - создает логическую кисть на основе аппаратно-независимого растра (DIB). При этом:
    • hglbDIBPacked - объект глобальной памяти, содержащий упакованный DIB
    • fuColorSpec - DIB_PAL_COLORS (на основе 16 цветной палитры) или DIB_RGB_COLORS (на основе цвета RGB)
  • CreateDIBPatternBrushPt (hglbDIBPacked,fuColorSpec) - то же что и CreateDIBPatternBrush, но на 32х битных системах рекомендуется использовать CreateDIBPatternBrushPt
  • CreateBrushIndirect (LOGBRUSH ptr) - создает логическую кисть с указанным стилем, цветом и узором. Сама структура LOGBRUSH описана здесь или здесь

После создания или получения кисти, ее необходимо выбрать в контекст с помощью SelectObject. Когда кисть более не требуется , ее нужно удалить с помощью DeleteObject.

По умолчанию начальные координаты вывода кистей соответствуют начальным координатам изображения в контексте (т.е. 0,0). Если требуется указать другие начальные координаты вывода кисти, то это можно сделать с помощью функции SetBrushOrgEx . Это особенно полезно при выводе кистей, созданных на основе bitmap. Так же для получения начальных координат кистей есть обратная функция GetBrushOrgEx. Их прототипы выглядят так:

SetBrushOrgEx(_
    HDC hdc,_    ' контекст
    Int nXOrg,_  ' новая x-координата вывода кисти 
    Int nYOrg,_  ' новая y-координата вывода кисти  
    LPPOINT lppt) ' указывает на предыдущее начало координат кисти, если не нужно , можно указать 0

GetBrushOrgEx(_
    HDC hdc,_    ' контекст  
    LPPOINT lppt) ' указывает на начало координат кисти


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

Эллипс:

Ellipse(_
    As HDC hdc,_ ' контекст 
    As Integer nLeftRect,_  'X-координата, ограничивающая верхний левый угол прямоугольника
    As Integer nTopRect,_   'Y-координата, ограничивающая верхний левый угол прямоугольника 
    As Integer nRightRect,_ 'X-координата, ограничивающая нижний правый угол прямоугольника 
    As Integer nBottomRect) 'Y-координата, ограничивающая нижний правый угол прямоугольника


Прямоугольник:

Rectangle(_
    As HDC hdc,_ ' контекст 
    As Integer nLeftRect,_  'X-координата, ограничивающая верхний левый угол прямоугольника
    As Integer nTopRect,_   'Y-координата, ограничивающая верхний левый угол прямоугольника 
    As Integer nRightRect,_ 'X-координата, ограничивающая нижний правый угол прямоугольника 
    As Integer nBottomRect) 'Y-координата, ограничивающая нижний правый угол прямоугольника

Закругленный прямоугольник:
RoundRect(_
    As HDC hdc,_ ' контекст 
    As Integer nLeftRect,_  'X-координата, ограничивающая верхний левый угол прямоугольника
    As Integer nTopRect,_   'Y-координата, ограничивающая верхний левый угол прямоугольника 
    As Integer nRightRect,_ 'X-координата, ограничивающая нижний правый угол прямоугольника 
    As Integer nBottomRect,_ 'Y-координата, ограничивающая нижний правый угол прямоугольника
    As Integer nWidth,_      'ширина эллипса, используемая для рисования закругленных углов
    As Integer nHeight)      'высота эллипса, используемая для рисования закругленных углов


И конечно пример рисования. Для примера я использовал изображение в формате bmp 128x128:

#INCLUDE "windows.bi"
Dim msg As MSG
Dim As WNDCLASSEX wc
Dim As String NameClass="MyClass"
Dim As HINSTANCE Hinst=GetModuleHandle(0)
Dim Shared As HBITMAP img

Sub DrawPrimitives(hdc As HDC)

   Dim As HBRUSH solid,hatch,pattern
   Dim As HPEN pen
   
   ' Создаем кисти и перо
   solid = CreateSolidBrush(&h6C1479)
   hatch = CreateHatchBrush(HS_DIAGCROSS,&h49C5F8)
   pattern = CreatePatternBrush(img)
   pen = CreatePen(PS_SOLID,2,&h7A26DE)
   
   ' Загружаем перо в контекст
   SelectObject(hdc,pen)
   
   'Для эллипса используем сплошную цветную кисть
   SelectObject(hdc,solid)  
   'Рисуем эллипс
   Ellipse(hdc,10,10,80,150)
   
   
   'Устанавливаем координаты кисти
   SetBrushOrgEx(hdc,100,10,0)
   'Для прямоугольника(квадрата) используем кисть на основе изображения
   SelectObject(hdc,pattern)  
   'Рисуем квадрат
   Rectangle(hdc,100,10,228,138) 
   
   'Для закругленного прямоугольника(квадрата) используем кисть для штриха
   SelectObject(hdc,hatch)  
   'Рисуем квадрат с закругленными углами
   RoundRect(hdc,255,10,335,150,10,10)      
   
   ' Удаляем перо и кисти
   DeleteObject(solid)
   DeleteObject(hatch)
   DeleteObject(pattern)
   DeleteObject(pen)

End Sub

Function wndproc(hwnd As HWND, msg As Uinteger,_
    wparam As WPARAM, lparam As LPARAM) As Integer

    Static canvas As HWND

    Select Case msg
        Case WM_CREATE
            canvas = CreateWindowEx(0,"Static","",WS_VISIBLE Or WS_CHILD,10,10,360,220,hwnd,Cast(HMENU,1),0,0)
           img = LoadImage(0,"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
        Case WM_PAINT
            Dim ps As PAINTSTRUCT
            BeginPaint(canvas,@ps)
            DrawPrimitives(ps.hDC)
            EndPaint(canvas,@ps)
        Case WM_DESTROY
            KillTimer(hwnd,1)
            DeleteObject(img)
            PostQuitMessage(0)
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function

With wc
    .cbSize=SizeOf(WNDCLASSEX)
    .style=CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc=@wndproc
    .hInstance=Hinst
    .hIcon=LoadIcon(0,IDI_QUESTION)
    .hCursor=LoadCursor(0,IDC_ARROW)
    .hbrBackground=Cast(HBRUSH,COLOR_WINDOW)
    .lpszClassName=StrPtr(NameClass)
    .hIconSm=.hIcon
End With

If RegisterClassEx(@wc)=0 Then
    Print "Register error, press any key"
    Sleep
    End
Endif

CreateWindowEx(0,NameClass,"Рисование примитивов",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,380,240,0,0,Hinst,0)

While GetMessage(@msg,0,0,0)
    TranslateMessage(@msg)
    DispatchMessage(@msg)
Wend

06072013111905.png

содержание | назад | вперед