Работа с графикой при помощи Win32 API
Объявим функции, которые нам понадобятсяPrivate Declare Function RoundRect Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, _ByVal X3 As Long, ByVal Y3 As Long) As LongPrivate Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) _As LongPrivate Declare Function Ellipse Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) _As LongPrivate Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long) As LongPrivate Declare Function InvalidateRect Lib "user32" (ByVal hwnd As Long, _lpRect As RECT, ByVal bErase As Long) As LongPrivate Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long, ByVal crColor As Long, _ByVal wFillType As Long) As LongPrivate Declare Function SetPixel& Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long, ByVal crColor As Long)Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long) As LongPrivate Declare Function Polyline Lib "gdi32" (ByVal hdc As Long, _lpPoint As POINTAPI, ByVal nCount As Long) As LongPrivate Declare Function Polygon Lib "gdi32" (ByVal hdc As Long, _lpPoint As POINTAPI, ByVal nCount As Long) As LongPrivate Declare Function CreateBrushIndirect Lib "gdi32" _(lpLogBrush As LOGBRUSH) As LongPrivate Declare Function CreatePenIndirect Lib "gdi32" _(lpLogPen As LOGPEN) As LongPrivate Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) _As LongPrivate Declare Function ReleaseDC Lib "user32" (ByVal hwnd _As Long, ByVal hdc As Long) As LongPrivate Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) _As LongPrivate Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, _ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _ByVal dwRop As Long) As LongPrivate Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, _ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, _ByVal dwRop As Long) As LongPrivate Declare Function Arc Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, _ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As LongPrivate Declare Function Chord Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, _ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As LongPrivate Declare Function Pie Lib "gdi32" (ByVal hdc As Long, _ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, _ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As LongPrivate Declare Function GetDesktopWindow Lib "user32" () As LongPrivate Declare Function PaintDesktop Lib "user32" (ByVal hdc As Long) As LongPrivate Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, _ByVal hObject As Long) As LongPrivate Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, _ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As LongPrivate Type RECT Left As Long Top As Long Right As Long Bottom As LongEnd TypePrivate Type POINTAPI x As Long y As LongEnd TypePrivate Type LOGBRUSH lbStyle As Long lbColor As Long lbHatch As LongEnd TypePrivate Type LOGPEN lopnStyle As Long lopnWidth As POINTAPI lopnColor As LongEnd TypePrivate Const FLOODFILLBORDER = 0Private Const FLOODFILLSURFACE = 1Private Const BS_SOLID = 0Private Const BS_HATCHED = 2Private Const HS_HORIZONTAL = 0Private Const HS_VERTICAL = 1Private Const HS_FDIAGONAL = 2Private Const HS_BDIAGONAL = 3Private Const HS_CROSS = 4Private Const HS_DIAGCROSS = 5Private Const PS_SOLID = 0Private Const PS_DASH = 1Private Const PS_DOT = 2Private Const PS_DASHDOT = 3Private Const PS_DASHDOTDOT = 4Графические функции Win32 API работают с графикой гораздо быстрее, чем стандартные функции VB. К тому же они позволяют рисовать на других окнах (например на рабочем столе), и практически на любых контролах. API функции работают с масштабом vbPixels несмотря на свойство ScaleMode. Для работы с графикой при помощи Win32 API требуется контекст устройства (hdc). Если у контрола его нет, то его можно получить при помощи функции GetWindowDC по описателю hwnd. Например, чтобы нарисовать линию на кнопке можно ввести следующий код:
Dim dc As Long" Получаем hdc кнопкиdc = GetWindowDC(Command1.hwnd)" Рисуем линиюLineTo dc, 100, 10" Освобождаем ресурсыReleaseDC Command1.hwnd, dcЕсть еще одно отличие API от стандартных графических функций. При свойстве AutoRedraw = True после того как был нарисован рисунок, его надо обновить. Например
LineTo hdc, 100, 100RefreshНо метод Refresh работает довольно медленно. Лучше использовать API функцию InvalidateRect, которая обновляет не все окно, а только его часть. Например
Dim r As RECTAutoRedraw = TrueLineTo hdc, 100, 100" Устанавливаем координаты участка, который" нужно обновитьr.Left = 0r.Top = 0r.Right = 100r.Bottom = 100" Обновляем этот участокInvalidateRect hwnd, r, TrueТеперь рассмотрим что такое перо и кисть. Перо определяет тип линии т.е. ее толщину, цвет и стиль. Кисть определяет заливку, ее цвет и стиль. Следующий пример рисует в текстовом окошке квадрат с синей в черточку границей и красной штриховкой
Dim Pen As LongDim Brush As LongDim p As LOGPENDim b As LOGBRUSHDim dc As Long" Устанавливаем тип линииp.lopnColor = vbBluep.lopnStyle = PS_DASH" Устанавливаем тип заливкиb.lbStyle = BS_HATCHEDb.lbColor = vbRedb.lbHatch = HS_FDIAGONAL" Получаем hdc текстового окошкаdc = GetWindowDC(Text1.hwnd)" Создаем пероPen = CreatePenIndirect(p)" Создаем кистьBrush = CreateBrushIndirect(b)" Присваиваем контексту созданные перо и кистьSelectObject dc, PenSelectObject dc, Brush" Рисуем прямоугольникRectangle dc, 10, 10, 100, 100" Освобождаем ресурсыDeleteObject BrushDeleteObject PenReleaseDC Text1.hwnd, dcРассмотрев основные положения, можно приступить к рисованию
Функция RoundRect (hdc, X1, Y1, X2, Y2, X3, Y3) рисует прямоугольник с закругленными краями. Параметры x3 и y3 определяют закругленность углов по ширине и высоте. Например
RoundRect hdc, 10, 10, 100, 100, 10, 10Функция MoveToEx (hdc, x, y, lpPoint) устанавливает позицию графического пера. Последний параметр этой функции возвращает предыдущее положение пера. Например
" Рисуем линию из точки (10,10) в точку (100,100)Dim p As POINTAPIMoveToEx hdc, 10, 10, pLineTo hdc, 100, 100Функция Ellipse (hdc, X1, Y1, X2, Y2) рисует эллипс. Например
Ellipse hdc, 10, 10, 100, 50Функция SetPixel (x, y, crColor) рисует точку. Например
SetPixel hdc, 10, 10, vbRedФункция GetPixel (hdc, x, y) возвращает цвет точки. Например
Dim Color As LongColor = GetPixel(hdc, 10, 10)Функция Polyline (hdc, lpPoint, nCount) рисует ломаную линию, где lpPoint - начальный элемент массива, содержащего координаты вершин этой линии, nCount - число вершин. Например
Dim p(3) As POINTAPIp(0).x = 10p(0).y = 10p(1).x = 100p(1).y = 10p(2).x = 150p(2).y = 100p(3).x = 150p(3).y = 200Polyline hdc, p(0), 4Функция Polygon (hdc, lpPoint, nCount) рисует многоугольник, где lpPoint - начальный элемент массива, содержащего координаты вершин многоугольника, nCount - число вершин. Последняя точка многоугольника должна совпадать с начальной. Например
Dim p(4) As POINTAPIp(0).x = 10p(0).y = 10p(1).x = 100p(1).y = 10p(2).x = 150p(2).y = 100p(3).x = 150p(3).y = 200p(4).x = 10p(4).y = 10Polygon hdc, p(0), 5Функции Arc (hdc, X1, Y1, X2, Y2, X3, Y3, X4, Y4), Pie (hdc, X1, Y1, X2, Y2, X3, Y3, X4, Y4), Chord (hdc, X1, Y1, X2, Y2, X3, Y3, X4, Y4) рисуют фигуры в виде эллипса, усеченного двумя прямыми следующим образом:
Например
Arc hdc, 10, 10, 100, 100, 20, 20, 90, 20Pie hdc, 110, 10, 200, 100, 120, 20, 190, 20Chord hdc, 210, 10, 300, 100, 220, 20, 290, 20Функция PaintDesktop (hdc) заполняет окно рисунком рабочего стола (без иконок и других элементов, находящихся на нем).
Функция ExtFloodFill (hdc, x, y, crColor, wFillType) выполняет заливку фигуры. x, y - координаты любой точки, находящейся внутри этой фигуры. Если wFillType = FLOODFILLBORDER, то заливка выполняется до границ фигуры, где crColor должен быть равен цвету этой границы и не должен быть равен цвету точки с координатами x,y. Если wFillType = FLOODFILLSURFACE, то цвет crColor должен быть равен цвету точки (x,y). При этом заливается область, которая имеет этот цвет. Данный способ заливки нужен в том случае если цвет границ фигуры разный. Например
ScaleMode = vbPixels" Устанавливаем прозрачную заливкуFillStyle = 1" Рисуем красную окружностьCircle (50, 50), 40, vbRed" Рисуем синию окружность, пересеченную зеленой линиейCircle (150, 50), 40, vbBlueLine (190, 10)-(110, 90), vbGreen" Устанавливаем заливку в виде горизонтальных линийFillStyle = 2" Закрашиваем красную окружностьExtFloodFill hdc, 50, 50, vbRed, FLOODFILLBORDER" Закрашивает часть синей окружностиExtFloodFill hdc, 140, 40, GetPixel(hdc, 140, 40), FLOODFILLSURFACEФункция BitBlt (hdc, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop) копирует изображение из контекста hSrcDC в контекст hdc. x,y - координаты левой верхней точки картинки-приемника, nWidth, nHeight - размеры картинки-приемника, xSrc, ySrc - координаты левой верхней точки картинки-источника, DwRop - способ копирования. Используются константы как в стандартном методе PaintPicture (vbSrcCopy, vbSrcPaint и т.д.). Отличие этого метода от PaintPicture в том, что PaintPicture копирует лишь картинку, помещенную в PictureBox, а BitBlt копирует картинку вместе изобржением всех контролов, помещенных в PictureBox. Например скопируем на форму изображение рабочего стола
Dim deskhwnd As LongDim deskdc As Long" Получаем описатель рабочего столаdeskhwnd = GetDesktopWindow" Получаем контекст устройства рабочего столаdeskdc = GetWindowDC(deskhwnd)" Переносим изображение рабочего стола на формуBitBlt hdc, 0, 0, Screen.Width / 15, Screen.Height / 15, deskdc, 0, 0, vbSrcCopy" Освобождаем ресурсыReleaseDC deskhwnd, deskdcФункция StretchBlt (hdc, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop) масштабирует или отражает изображение. x,y - координаты левой верхней точки картинки-приемника, nWidth, nHeight - размеры картинки-приемника, xSrc, ySrc - координаты левой верхней точки картинки-источника, nSrcWidth, nSrcHeight - размеры картинки-источника, DwRop - способ копирования. Эта функция аналогична методу PaintPicture за исключением того, что копирует картинку с изображением всех контролов, находящихся поверх нее. Если nWidth и nSrcWidth или nHeight и nSrcHeight отличаются, то картинка масштабируется. Если nWidth<0 или nHeight<0, то картинка отображается. Например
" Копируем картинку, увеличив ее в 2 разаStretchBlt hdc, 0, 0, 48, 44, Picture2.hdc, 0, 0, 24, 22, vbSrcCopy" Копируем картинку, отобразив по горизонталиStretchBlt hdc, 24, 48, -24, 22, Picture2.hdc, 0, 0, 24, 22, vbSrcCopy