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

 

В этой статье будут рассмотрены другие примитивы.

Рисование дуг:

Для рисования дуг можно использовать функцию Arc.

Arc(_
As HDC hdc,_ ' контекст
As Integer nLeftRect,_ ' X координата верхнего левого угла
As Integer nTopRect,_ ' Y координата верхнего левого угла
As Integer nRightRect,_ ' X координата правого нижнего угла
As Integer nBottomRect,_ ' Y координата правого нижнего угла
As Integer nXStartArc,_ ' X координата начала дуги
As Integer nYStartArc,_ ' Y координата начала дуги
As Integer nXEndArc,_ ' X координата конца дуги
As Integer nYEndArc) ' Y координата конца дуги


Последние 4 координаты могут не лежать на плоскости воображаемой дуги, GDI проведет воображаемые линии от точек к центру. Точки пересечения с эллипсом и будут началом и концом дуги.

Рисование сегмента эллипса:

Для рисования сегмента эллипса можно применить функцию Chord.

Chord(_
As HDC hdc,_ ' контекст
As Integer nLeftRect,_ ' X координата верхнего левого угла
As Integer nTopRect,_ ' Y координата верхнего левого угла
As Integer nRightRect,_ ' X координата правого нижнего угла
As Integer nBottomRect,_ ' Y координата правого нижнего угла
As Integer nXRadial1,_ ' X координата начала отсекаемой дуги(области)
As Integer nYRadial1,_ ' Y координата начала отсекаемой дуги(области)
As Integer nXRadial2,_ ' X координата конца отсекаемой дуги(области)
As Integer nYRadial2) ' Y координата конца отсекаемой дуги(области)


Рисуется по такому принципу.

1) рисуется эллипс
2) через точки проводятся 2 прямые к центру. Точки пересечения с эллипсом и будут началом и концом отсекаемой дуги
3) через точки начала и конца отсекаемой дуги проводится хорда
4) вся площадь , которая образована отсекаемой дугой до хорды, отсекается
5) то что осталось от эллипса , включая хорду, остается

Рисование сектора эллипса:

Для рисования сектора эллипса можно применить функцию Pie.

Pie(_
As HDC hdc,_ ' контекст
As Integer nLeftRect,_ ' X координата верхнего левого угла
As Integer nTopRect,_ ' Y координата верхнего левого угла
As Integer nRightRect,_ ' X координата правого нижнего угла
As Integer nBottomRect,_ ' Y координата правого нижнего угла
As Integer nXRadial1,_ ' X координата начала отсекаемой дуги(области)
As Integer nYRadial1,_ ' Y координата начала отсекаемой дуги(области)
As Integer nXRadial2,_ ' X координата конца отсекаемой дуги(области)
As Integer nYRadial2) ' Y координата конца отсекаемой дуги(области)

Рисуется по такому принципу.

1) рисуется эллипс
2) через точки проводятся 2 прямые к центру. Точки пересечения с эллипсом и будут началом и концом отсекаемой дуги
3) вся площадь , которая образована отсекаемой дугой до отрезков, отсекается
4) то что осталось от эллипса, включая отрезки от начала и конца отсекаемой дуги до центра, остается

Рисование многоугольников и ломанных линий:

Две функции PolyGon и PolyLine практически одинаковы. Их разница только в том, что первая при рисовании соединяет начальную и конечную вершины многоугольника. Поэтому первую используют для замкнутых фигур, вторую для ломанных линий. Их декларации одинаковы:

Polygon(_
As HDC hdc,_ ' контекст
As Point Ptr lpPoints,_ 'указатель на массив структур POINT для всех вершин
As Integer nCount) ' кол-во вершин


Рисование фокуса и рамки:

Фокус рисуется с помощью функции DrawFocusRect. По сути это таже рамка, но состоит из череды точек через пиксель.

DrawFocusRect(_
 As HDC hDC,    ' контекст
 As RECT Ptr lprc) ' указатель на структуру RECT с координатами прямоугольника для вывода фокуса

Для рисования рамки можно конечно использовать функцию Rectangle с нулевой кистю, но раз есть специальная функция для этого, не будет лишним ее описать. Функция FrameRect:

FrameRect(_
    As HDC hDC,_ ' контекст
    As RECT Ptr lprc,_ указатель на структуру RECT с координатами    
    As HBRUSH hbr) ' хендл кисти


И пример:

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

Sub DrawPrimitives(hdc As HDC)

   Dim As HBRUSH solid
   Dim As HPEN pen
   
   ' Создаем кисти и перо
   solid = CreateSolidBrush(&hFF0000)
   pen = CreatePen(PS_SOLID,1,&hFF0000)
   
   ' Загружаем перо в контекст
   SelectObject(hdc,pen)   
   ' Загружаем кисть в контекст
   SelectObject(hdc,solid)  
   
   ' рисуем сегмент эллипса
   Chord(hDC,10,10,110,110,50,20,60,60)
   
   ' рисуем сектор эллипса
   Pie(hDC,190,10,290,110,190,170,190,100)
      
   ' Рисуем дугу
   Arc(hDC,10,150,110,250,10,150,100,200)  
   
   ' рисуем многоугольник (треугольник)
   Dim pPoint(2) As Point = {(100,150),(130,180),(70,180)}
   PolyGon(hDC, @pPoint(0), 3)
   
   ' рисуем ломанную линию
   Dim pPoint2(3) As Point = {(260,200),(300,160),(300,250),(170,170)}
   PolyLine(hDC, @pPoint2(0), 4)   
   
   ' рисуем фокус
   Dim As RECT R = Type(8,8,112,112)
   DrawFocusRect(hDC,@R)
   
   ' рисуем рамку
   R = Type(188,8,292,112)
   FrameRect(hDC,@R,solid)   

   ' Удаляем перо и кисть
   DeleteObject(solid)
   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,320,hwnd,Cast(HMENU,1),0,0)
        Case WM_PAINT
            Dim ps As PAINTSTRUCT
            BeginPaint(canvas,@ps)
            DrawPrimitives(ps.hDC)
            EndPaint(canvas,@ps)
        Case WM_DESTROY
            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,340,0,0,Hinst,0)

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


06132013131143.png

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