UseTIFFImageDecoder()
UseJPEGImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
Structure xy
x1.w
y1.w
EndStructure
Structure Bufer_bitmap
hdc.i
start_hdc_bits.i
end_hdc_bits.i
hdcxy.xy
fon_hdc.i
start_fon_bits.i
end_fon_bits.i
EndStructure
Structure CustomCanvas
Canvas_id.i
Canvas_hwnd.i
Canvas_Rect.rect
Canvas_Bufer.Bufer_bitmap
EndStructure
;================================
Global *CustomCanvas2.CustomCanvas
Global hdcccanvasa2.i
;================================
;================================
Structure _PATRECT
x.i; // x-coord of upper-left rectangle corner
y.i; // y-coord of upper-left rectangle corner
cx.i; // width of rectangle
cy.i; // height of rectangle
HBRUSH.i ; // brush handle
EndStructure
Structure r
r.a
g.a
b.a
a.a
EndStructure
Structure rgba
StructureUnion
x.r
rgba.l
EndStructureUnion
EndStructure
Macro CanvasApiSetPixel(HDC,nXPos,nYPos,COLORREF)
SetPixel_(HDC,nXPos,nYPos, COLORREF)
EndMacro
Macro CanvasApiGetPixel(HDC,nXPos,nYPos)
GetPixel_(HDC,nXPos,nYPos)
EndMacro
Macro CanvasApiSetPixelV(HDC,x,y,COLORREF)
SetPixelV_(HDC,x,y COLORREF)
EndMacro
;------
Macro CanvasMoveToEx(hdc,x,y,lpout_POINT)
;обновляет текущую позицию до указанной точки и при необходимости возвращает предыдущую позицию
MoveToEx_(hdc,x,y,lpout_POINT)
EndMacro
Macro CanvasLineDDA(xStart,yStart,xEnd,yEnd,lpProc_LINEDDAPROC,lp_Data)
;определяет, какие пиксели должны быть выделены для линии, определенной указанными начальной и конечной точками.
LineDDA_(xStart,yStart,xEnd,yEnd,lpProc_LINEDDAPROC,lp_Data)
EndMacro
Macro CanvasLineTo(HDC,x,y)
;рисует линию от текущей позиции до указанной точки, но не включает ее
LineTo_(HDC,x,y)
EndMacro
Macro CanvasDrawLine(HDC,x1,y1,x2,y2)
pt.POINT;
MoveToEx_(HDC, x1, y1,@pt);
LineTo_(HDC, x2, y2)
EndMacro
;------
Macro CanvasPie(hdc,left,top,right,bottom,xr1,yr1,xr2,yr2)
;рисует круговую клиновую форму, ограниченную пересечением эллипса и двух радиалей.
;Круговая диаграмма создается с помощью текущего пера и заполняется с помощью текущей кисти
Pie_(hdc,left,top,right,bottom,xr1,yr1,xr2,yr2)
EndMacro
Macro CanvasDrawArc(HDC,x1,y1,x2,y2,x3,y3,x4,y4)
Arc_(HDC,x1,y1,x2,y2,x3,y3,x4,y4)
EndMacro
Macro CanvasDrawArcTo(HDC,left,top,right,bottom,xr1,yr1,xr2,yr2)
ArcTo_(HDC,left,top,right,bottom,xr1,yr1,xr2,yr2)
EndMacro
Macro CanvasDrawAngleArc(HDC,x1,y1,x2,r,StartAngle,SweepAngle)
;рисует сегмент линии и дугу. Сегмент линии отрисовывается от текущей позиции до начала дуги.
;Дуга рисуется по периметру окружности с заданным радиусом и центром. Длина дуги определяется заданными углами начала и развертки
AngleArc_(HDC,x1,y1,x2,r,StartAngle,SweepAngle)
EndMacro
Macro CanvasChord(hdc,x1,y1,x2,y2,x3,y3,x4,y4)
;рисует аккорд (область, ограниченную пересечением эллипса и сегмента линии, называемого секантом).
;Аккорд задается с помощью текущего пера и заполняется с помощью текущей кисти.
Chord_(hdc,x1,y1,x2,y2,x3,y3,x4,y4)
EndMacro
Macro CanvasSetArcDirection(hdc,dir)
;задает направление рисования, которое будет использоваться для дуговых и прямоугольных функций.
;#AD_COUNTERCLOCKWISE Рисунки, нарисованные против часовой стрелки.
;#AD_CLOCKWISE Рисунки, нарисованные по часовой стрелке.
SetArcDirection_(hdc, dir)
EndMacro
Macro CanvasEllipse(hdc,left,top,right,bottom)
;рисует эллипс. Центр эллипса — это центр указанного ограничивающего прямоугольника.
;Эллипс выделен с помощью текущего пера и заполняется с помощью текущей кисти
Ellipse_(hdc,left,top,right,bottom)
EndMacro
;------
;===========
ProcedureDLL.l RGBrearrange(l.l)
!ror word [p.v_l],8;кольцевой сдвиг
!ror dword [p.v_l],16;кольцевой сдвиг
!ror word [p.v_l],8;кольцевой сдвиг
!ror dword [p.v_l],8;кольцевой сдви
ProcedureReturn l
EndProcedure
;=============================
;для операций загрузки выгрузки
;получить структуру канваса
ProcedureDLL.i GetDataCanvasid(id)
EndProcedure
;загрузить данные в структуру канваса
ProcedureDLL.i SetDataCanvasid(id)
EndProcedure
;=============================
ProcedureDLL.i DialogSetCanvasFon(id)
Protected window_hwnd.i = OpenWindow(#PB_Any, 0, 0,300, 300, "Выбор фона",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If window_hwnd<>0
Protected Button_hwnd.i=ButtonGadget(#PB_Any,215,265,75,25,"Применить")
;{;гаджеты для цвета фона окна
TextGadget(#PB_Any, 50, 100, 100, 20,"Цвет фона")
Protected vyvod_fona_okna=TextGadget(#PB_Any, 180, 100, 100, 20,"")
;
TextGadget(#PB_Any, 5, 120, 10, 20,"R")
Protected tr=TextGadget(#PB_Any, 18, 120, 20, 20,"")
Protected r=TrackBarGadget(#PB_Any, 40,120, 250, 20, 0, 255)
;
TextGadget(#PB_Any, 5, 145, 10, 20,"G")
Protected tg=TextGadget(#PB_Any, 18,145, 20, 20,"")
Protected g=TrackBarGadget(#PB_Any, 40,145, 250, 20, 0, 255)
;
TextGadget(#PB_Any, 5, 170, 10, 20,"B")
Protected tb=TextGadget(#PB_Any, 18,170, 20, 20,"")
Protected b=TrackBarGadget(#PB_Any, 40,170, 250, 20, 0, 255)
;};
;{;получаем из контекста цвет фона окна
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(GadgetID(id),0);получаем адрес структуры наших контекстов памяти и их параметров
Protected *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits
Protected cvetfona.l=*i\l;получаем предыдущий цвет фона
Protected fon_okna.rgba
fon_okna\rgba=*i\l
SetGadgetText(vyvod_fona_okna,"$"+Hex(cvetfona))
;Debug GetDCBrushColor_(hdc)
;color_fon_okna\rgba=GetStockObject_(#DC_BRUSH)
;Debug color_fon_okna\rgba
SetGadgetText(tr,"$"+Hex(fon_okna\x\r))
SetGadgetState(r,fon_okna\x\r)
;*a+1
SetGadgetText(tg,"$"+Hex(fon_okna\x\g))
SetGadgetState(g,fon_okna\x\g)
;*a+1
SetGadgetText(tb,"$"+Hex(fon_okna\x\b))
SetGadgetState(b,fon_okna\x\b)
;};
Else
ProcedureReturn 0
EndIf
Protected predydushii_cvetfona.l=cvetfona
Protected hdcccanvasa.i
Protected cvet.l
;обработчик
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
;{;установка цвета Фона окна
Case r
predydushii_cvetfona=fon_okna\rgba;*i\l;получаем предыдущий цвет фона
fon_okna\x\r=GetGadgetState(r)
SetGadgetText(tr,"$"+Hex(fon_okna\x\r))
SetGadgetText(vyvod_fona_okna,"$"+Hex(fon_okna\rgba))
;==========
;если предыдущий цвет пикселя у фона контекста совпадает то меняем на новый пиксель фона
podprograma:
cvet=fon_okna\rgba
For *i.long=*CustomCanvas\Canvas_Bufer\start_hdc_bits To *CustomCanvas\Canvas_Bufer\end_hdc_bits Step 4
If *i\l=predydushii_cvetfona
*i\l=cvet;fon_okna\rgba
EndIf
Next
hdcccanvasa = StartDrawing(CanvasOutput(id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
;==========
Case g
predydushii_cvetfona=fon_okna\rgba;*i\l;получаем предыдущий цвет фона
fon_okna\x\g=GetGadgetState(g)
SetGadgetText(tg,"$"+Hex(fon_okna\x\g))
SetGadgetText(vyvod_fona_okna,"$"+Hex(fon_okna\rgba))
Goto podprograma
Case b
predydushii_cvetfona=fon_okna\rgba;*i\l;получаем предыдущий цвет фона
fon_okna\x\b=GetGadgetState(b)
SetGadgetText(tb,"$"+Hex(fon_okna\x\b))
SetGadgetText(vyvod_fona_okna,"$"+Hex(fon_okna\rgba))
Goto podprograma
Case Button_hwnd
For *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits To *CustomCanvas\Canvas_Bufer\end_fon_bits Step 4
*i\l=fon_okna\rgba
Next
CloseWindow(window_hwnd)
ProcedureReturn 1
;};
EndSelect
Case #PB_Event_CloseWindow;{;
CloseWindow(window_hwnd)
;DestroyWindow_(window_hwnd)
For *i.long=*CustomCanvas\Canvas_Bufer\start_hdc_bits To *CustomCanvas\Canvas_Bufer\end_hdc_bits Step 4
If *i\l=predydushii_cvetfona
*i\l=cvetfona
EndIf
Next
hdcccanvasa = StartDrawing(CanvasOutput(id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
ProcedureReturn 0
;};
EndSelect
ForEver
EndProcedure
;
ProcedureDLL.i DialogCanvasScale(id)
Protected window_hwnd.i = OpenWindow(#PB_Any, 0, 0,300, 300, "Palette",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If window_hwnd<>0
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(GadgetID(id),0);получаем адрес структуры наших контекстов памяти и их параметров
;Protected *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits
EndIf
;извлекает текущий графический режим для указанного контекста устройства
If GetGraphicsMode_(*CustomCanvas\Canvas_Bufer\hdc)=#GM_COMPATIBLE
SetGraphicsMode_(*CustomCanvas\Canvas_Bufer\hdc,#GM_ADVANCED);установить расширенный режим
EndIf
Protected PFLOAT.f
;извлекает ограничение miter для указанного контекста устройства
;Ограничение митеров используется при рисовании геометрических линий с митерными соединениями
;извлекает предел скоса для указанного контекста устройства
;Предел скоса используется при рисовании геометрических линий, имеющих соединения под углом
Debug GetMiterLimit_(*CustomCanvas\Canvas_Bufer\hdc,@PFLOAT)
Debug StrF(PFLOAT)
;обработчик
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
;{;
;};
EndSelect
Case #PB_Event_CloseWindow;{;
CloseWindow(window_hwnd)
ProcedureReturn 0
;};
EndSelect
ForEver
EndProcedure
ProcedureDLL.i DialogCanvasTestDrawing(id)
EndProcedure
;
ProcedureDLL.l CanvasIdMemSetPixel(id,nXPos,nYPos,COLORREF)
Protected canvashwnd.i=GadgetID(id);контекст окна канваса для копирование в него контекста памяти куда рисуем
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
;
If nXPos<0 Or nXPos>*CustomCanvas\Canvas_Bufer\hdcxy\x1 Or nYPos<0 Or nYPos>*CustomCanvas\Canvas_Bufer\hdcxy\y1
;вне окна контекста
ProcedureReturn 0
Else
COLORREF= RGBrearrange(COLORREF)
Protected *cvet.long
If y>-1
nYPos=(*CustomCanvas\Canvas_Bufer\hdcxy\x1*4)*(nYPos-1)
*cvet=*CustomCanvas\Canvas_Bufer\end_hdc_bits-nYPos-(nXPos*4)
*cvet\l=COLORREF
ProcedureReturn 1
Else
*cvet=*CustomCanvas\Canvas_Bufer\end_hdc_bits-(nXPos*4)
*cvet\l=COLORREF
ProcedureReturn 1
EndIf
EndIf
EndProcedure
ProcedureDLL.l CanvasIdMemGetPixel(id,nXPos,nYPos)
Protected canvashwnd.i=GadgetID(id);контекст окна канваса для копирование в него контекста памяти куда рисуем
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
;
If nXPos<0 Or nXPos>*CustomCanvas\Canvas_Bufer\hdcxy\x1 Or nYPos<0 Or nYPos>*CustomCanvas\Canvas_Bufer\hdcxy\y1
;вне окна контекста
ProcedureReturn 0
Else
Protected *cvet.long
If y=0
*cvet=*CustomCanvas\Canvas_Bufer\end_hdc_bits-(nXPos*4)
ProcedureReturn RGBrearrange(*cvet\l)
Else
nYPos=(*CustomCanvas\Canvas_Bufer\hdcxy\x1*4)*(nYPos-1)
*cvet=*CustomCanvas\Canvas_Bufer\end_hdc_bits-nYPos-(nXPos*4)
ProcedureReturn RGBrearrange(*cvet\l)
EndIf
EndIf
EndProcedure
;
ProcedureDLL.l CanvasMemSetPixel(nXPos,nYPos,COLORREF)
;
If nXPos<0 Or nXPos>*CustomCanvas2\Canvas_Bufer\hdcxy\x1 Or nYPos<0 Or nYPos>*CustomCanvas2\Canvas_Bufer\hdcxy\y1
;вне окна контекста
ProcedureReturn 0
Else
COLORREF= RGBrearrange(COLORREF)
Protected *cvet.long
If y>-1
nYPos=(*CustomCanvas2\Canvas_Bufer\hdcxy\x1*4)*(nYPos-1)
*cvet=*CustomCanvas2\Canvas_Bufer\end_hdc_bits-nYPos-(nXPos*4)
*cvet\l=COLORREF
ProcedureReturn 1
Else
*cvet=*CustomCanvas2\Canvas_Bufer\end_hdc_bits-(nXPos*4)
*cvet\l=COLORREF
ProcedureReturn 1
EndIf
EndIf
EndProcedure
ProcedureDLL.l CanvasMemGetPixel(nXPos,nYPos)
;
If nXPos<0 Or nXPos>*CustomCanvas2\Canvas_Bufer\hdcxy\x1 Or nYPos<0 Or nYPos>*CustomCanvas2\Canvas_Bufer\hdcxy\y1
;вне окна контекста
ProcedureReturn 0
Else
Protected *cvet.long
If y=0
*cvet=*CustomCanvas2\Canvas_Bufer\end_hdc_bits-(nXPos*4)
ProcedureReturn RGBrearrange(*cvet\l)
Else
nYPos=(*CustomCanvas2\Canvas_Bufer\hdcxy\x1*4)*(nYPos-1)
*cvet=*CustomCanvas2\Canvas_Bufer\end_hdc_bits-nYPos-(nXPos*4)
ProcedureReturn RGBrearrange(*cvet\l)
EndIf
EndIf
EndProcedure
;====установка фона которым также можно функциями CanvasCLS() очистить контекст памяти
ProcedureDLL.l SetCanvasFon(newfon);
If newfon>16777215 Or newfon<0;только три байта цвета иначе происходит сбой
ProcedureReturn -1
EndIf
;===========
Protected *i.long=*CustomCanvas2\Canvas_Bufer\start_fon_bits
Protected predydushii_cvetfona.l=*i\l;получаем предыдущий цвет фона
cikl:;установки нового фона
*i\l=newfon
If *i<*CustomCanvas2\Canvas_Bufer\end_fon_bits
*i+4
Goto cikl
EndIf
;===============
For *i.long=*CustomCanvas2\Canvas_Bufer\start_hdc_bits To *CustomCanvas2\Canvas_Bufer\end_hdc_bits Step 4;если предыдущий цвет пикселя у фона контекста совпадает то меняем на новый пиксель фона
If *i\l=predydushii_cvetfona
*i\l=newfon
EndIf
Next
Protected hdcccanvasa.i
hdcccanvasa = StartDrawing(CanvasOutput(*CustomCanvas2\Canvas_id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas2\Canvas_Rect\right,*CustomCanvas2\Canvas_Rect\bottom,*CustomCanvas2\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
ProcedureReturn predydushii_cvetfona
EndProcedure
ProcedureDLL.l SetCanvasIdFon(id,newfon.l)
If newfon>16777215 Or newfon<0;только три байта цвета иначе происходит сбой
ProcedureReturn -1
EndIf
;===========
Protected canvashwnd.i=GadgetID(id);контекст окна канваса для копирование в него контекста памяти куда рисуем
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
Protected *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits
Protected predydushii_cvetfona.l=*i\l;получаем предыдущий цвет фона
;newfon=RGBrearrange(newfon);новый фон для установки в буфер напрямую в таблицу цветов пикселей
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],16;кольцевой сдвиг
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],8;кольцевой сдви
;
;Debug "GetPixel_ "+Str(RGBrearrange(GetPixel_(*CustomCanvas\Canvas_Bufer\fon_hdc,0,0)))
;Debug "CanvasIdMemGetPixel "+Str(RGBrearrange(CanvasIdMemGetPixel(id,0,0)))
;================
; Protected HBRUSH.l =SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,kistb);установка нового фона в контекст фона
; FillRect_(*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect,kistb);закраска контекста для фона новым фоном
cikl:;установки нового фона
*i\l=newfon
If *i<*CustomCanvas\Canvas_Bufer\end_fon_bits
*i+4
Goto cikl
EndIf
;===============
For *i.long=*CustomCanvas\Canvas_Bufer\start_hdc_bits To *CustomCanvas\Canvas_Bufer\end_hdc_bits Step 4;если предыдущий цвет пикселя у фона контекста совпадает то меняем на новый пиксель фона
If *i\l=predydushii_cvetfona
*i\l=newfon
EndIf
Next
Protected hdcccanvasa.i
hdcccanvasa = StartDrawing(CanvasOutput(id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
ProcedureReturn predydushii_cvetfona
EndProcedure
ProcedureDLL.l SetCanvasHwndFon(canvashwnd,newfon.l)
If newfon>16777215 Or newfon<0;только три байта цвета иначе происходит сбой
ProcedureReturn -1
EndIf
;===========
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
Protected *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits
Protected predydushii_cvetfona.l=*i\l;получаем предыдущий цвет фона
;newfon=RGBrearrange(newfon);новый фон для установки в буфер напрямую в таблицу цветов пикселей
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],16;кольцевой сдвиг
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],8;кольцевой сдви
;
cikl:;установки нового фона
*i\l=newfon
If *i<*CustomCanvas\Canvas_Bufer\end_fon_bits
*i+4
Goto cikl
EndIf
;===============
For *i.long=*CustomCanvas\Canvas_Bufer\start_hdc_bits To *CustomCanvas\Canvas_Bufer\end_hdc_bits Step 4;если предыдущий цвет пикселя у фона контекста совпадает то меняем на новый пиксель фона
If *i\l=predydushii_cvetfona
*i\l=newfon
EndIf
Next
Protected hdcccanvasa.i
hdcccanvasa = StartDrawing(CanvasOutput(id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
ProcedureReturn predydushii_cvetfona
EndProcedure
ProcedureDLL.l SetCanvasDataFon(*CustomCanvas.CustomCanvas,newfon.l)
If newfon>16777215 Or newfon<0;только три байта цвета иначе происходит сбой
ProcedureReturn -1
EndIf
;===========
Protected *i.long=*CustomCanvas\Canvas_Bufer\start_fon_bits
Protected predydushii_cvetfona.l=*i\l;получаем предыдущий цвет фона
;newfon=RGBrearrange(newfon);новый фон для установки в буфер напрямую в таблицу цветов пикселей
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],16;кольцевой сдвиг
!ror word [p.v_newfon],8;кольцевой сдвиг
!ror dword [p.v_newfon],8;кольцевой сдви
;
;Debug "GetPixel_ "+Str(RGBrearrange(GetPixel_(*CustomCanvas\Canvas_Bufer\fon_hdc,0,0)))
;Debug "CanvasIdMemGetPixel "+Str(RGBrearrange(CanvasIdMemGetPixel(id,0,0)))
;================
; Protected HBRUSH.l =SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,kistb);установка нового фона в контекст фона
; FillRect_(*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect,kistb);закраска контекста для фона новым фоном
cikl:;установки нового фона
*i\l=newfon
If *i<*CustomCanvas\Canvas_Bufer\end_fon_bits
*i+4
Goto cikl
EndIf
;===============
For *i.long=*CustomCanvas\Canvas_Bufer\start_hdc_bits To *CustomCanvas\Canvas_Bufer\end_hdc_bits Step 4;если предыдущий цвет пикселя у фона контекста совпадает то меняем на новый пиксель фона
If *i\l=predydushii_cvetfona
*i\l=newfon
EndIf
Next
Protected hdcccanvasa.i
hdcccanvasa = StartDrawing(CanvasOutput(*CustomCanvas\Canvas_id))
;копируем в контекст вывода канваса окна (хотя у него тоже буфер в памяти :))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
ProcedureReturn predydushii_cvetfona
EndProcedure
;=============Очистка контекста
ProcedureDLL CanvasCLS();clear для рисования по startdrawing-stop очистка контекста памяти
BitBlt_(hdcccanvasa2,0,0,*CustomCanvas2\Canvas_Rect\right,*CustomCanvas2\Canvas_Rect\bottom,*CustomCanvas2\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
EndProcedure
ProcedureDLL CanvasIdCLS(id);clear по id
Protected canvashwnd.i=GadgetID(id);контекст окна канваса для копирование в него контекста памяти куда рисуем
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
Protected hdcccanvasa.i=StartDrawing(CanvasOutput(id))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
StopDrawing()
EndProcedure
ProcedureDLL CanvasHwndCLS(canvashwnd);clear по hwnd
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес структуры наших контекстов памяти и их параметров
Protected hdcccanvasa.i=StartDrawing(CanvasOutput(id))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
StopDrawing()
EndProcedure
ProcedureDLL CanvasDataCLS(*CustomCanvas.CustomCanvas);clear по hwnd
Protected hdcccanvasa.i=StartDrawing(CanvasOutput(*CustomCanvas\Canvas_id))
BitBlt_(hdcccanvasa,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
StopDrawing()
EndProcedure
;============
;Вывод контекста памяти в контекст окна
ProcedureDLL.i StartCanvasDrawing(canvashwnd)
*CustomCanvas2.CustomCanvas = GetWindowLongPtr_(canvashwnd,0)
hdcccanvasa2 = StartDrawing(CanvasOutput(*CustomCanvas2\Canvas_id))
ProcedureReturn *CustomCanvas2\Canvas_Bufer\hdc
EndProcedure
ProcedureDLL StopCanvasDrawing()
BitBlt_(hdcccanvasa2,0,0,*CustomCanvas2\Canvas_Rect\right,*CustomCanvas2\Canvas_Rect\bottom,*CustomCanvas2\Canvas_Bufer\hdc, 0, 0,#SRCCOPY)
StopDrawing()
EndProcedure
Global rodnoi_obrabothik_canvasov.i=0
Procedure Canvascalbakk(hwnd,msg,wparam,lparam)
Protected *CustomCanvas.CustomCanvas
;result=CallWindowProc_(rodnoi_obrabothik_canvasov, hWnd, Msg, wParam, lParam);перерисовка с родного обработчика
Select msg
; Case #WM_PAINT
;ProcedureReturn CallWindowProc_(rodnoi_obrabothik_canvasov, hWnd, Msg, wParam, lParam);перерисовка с родного обработчика
; *CustomCanvas=GetWindowLongPtr_(hwnd,0)
;Protected hdc= StartDrawing(CanvasOutput(GetWindowLongPtr_(hwnd,#GWL_ID)))
; Protected kistb.i=CreateSolidBrush_($294EEC)
;SelectObject_(hdc,kistb)
;Rectangle_(hdc,0,0,*CustomCanvas\Canvas_Bufer\xy\x1,*CustomCanvas\Canvas_Bufer\xy\y1)
;BitBlt_(hdc,*CustomCanvas\Canvas_Rect\left,*CustomCanvas\Canvas_Rect\top,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCCOPY);копирование картинки из контекста окна в память ввиде поля bitmap
;StopDrawing()
;ProcedureReturn 0
Case #WM_DESTROY
Debug "#WM_NCDESTROY"
Debug hwnd
*CustomCanvas=GetWindowLongPtr_(hwnd,0);получаем адрес данных
If *CustomCanvas\Canvas_Bufer\fon_hdc<>0;если контекст получен был
;DeleteObject_(*CustomCanvas\Canvas_Bufer\fon_hdc);удаляем контекст
DeleteDC_(*CustomCanvas\Canvas_Bufer\fon_hdc)
EndIf
If *CustomCanvas\Canvas_Bufer\hdc<>0;если контекст получен был
;DeleteObject_(*CustomCanvas\Canvas_Bufer\hdc);удаляем контекст
DeleteDC_(*CustomCanvas\Canvas_Bufer\hdc)
EndIf
; ReleaseDC_(hwnd,*CustomCanvas\Canvas_hdc);удаляем контекст канваса
FreeMemory(*CustomCanvas);удаляем память данных для окна канваса
;SetWindowLongPtr_(hwnd,0,0);память очищена и в доп.память окна под адрес данных ставим 0
;
SetWindowLongPtr_(hwnd,#GWL_WNDPROC,rodnoi_obrabothik_canvasov)
EndSelect
; ProcedureReturn result;
ProcedureReturn CallWindowProc_(rodnoi_obrabothik_canvasov, hWnd, Msg, wParam, lParam);перерисовка с родного обработчика
; ProcedureReturn DefWindowProc_(hwnd,msg,wParam,lParam)
EndProcedure
;Создание контекста памяти для рисования и фона
ProcedureDLL.i CreateCustomCanvas(windowhwnd,canvas_id,x,y,x1,y1,flag.l=0)
Protected canvashwnd.i
canvashwnd=CanvasGadget(canvas_id,x,y,x1,y1,flag);Createcanvas(windowhwnd,0,30,0,450,500,@Canvaskalbak())
If GetClassLongPtr_(canvashwnd,-18)=0;дополнтительная память в классе под окно не выделенна
SetClassLongPtr_(canvashwnd,-18,8) ;теперь окна канваса создаются с дополнительной памятью
;SetClassLongPtr_(canvashwnd,-26,#CS_OWNDC);теперь контекст рисования частный(постоянный)
;пересоздаём окно канваваса уже с нашимии изменениями
DestroyWindow_(canvashwnd)
canvashwnd=CanvasGadget(canvas_id,x,y,x1,y1)
EndIf
;
If canvashwnd<>0
If rodnoi_obrabothik_canvasov=0;он изначально один для всех что бы не повторяться с этой операцией
rodnoi_obrabothik_canvasov=SetWindowLongPtr_(canvashwnd,#GWLP_WNDPROC,@Canvascalbakk())
SetWindowLongPtr_(canvashwnd,#GWL_ID,canvas_id)
Else
SetWindowLongPtr_(canvashwnd,#GWLP_WNDPROC,@Canvascalbakk())
SetWindowLongPtr_(canvashwnd,#GWL_ID,canvas_id)
EndIf
;структура данных для хранения
Protected *CustomCanvas.CustomCanvas
*CustomCanvas=AllocateMemory(SizeOf(CustomCanvas))
*CustomCanvas\Canvas_id=canvas_id
*CustomCanvas\Canvas_hwnd=canvashwnd
*CustomCanvas\Canvas_Rect\left=0
*CustomCanvas\Canvas_Rect\top=0
*CustomCanvas\Canvas_Rect\right=x1
*CustomCanvas\Canvas_Rect\bottom=y1
;Protected rect.RECT
;GetClientRect_(canvashwnd,*CustomCanvas\Canvas_Rect)
;Debug "rect"
;Debug *CustomCanvas\Canvas_Rect\left;*CustomCanvas\Canvas_Rect\left
;Debug *CustomCanvas\Canvas_Rect\top
;Debug *CustomCanvas\Canvas_Rect\right
;Debug *CustomCanvas\Canvas_Rect\bottom
;
*CustomCanvas\Canvas_Bufer\hdcxy\x1=x1
*CustomCanvas\Canvas_Bufer\hdcxy\y1=y1
;
Protected hdc.i=GetDC_(canvashwnd);GetDCEx_(canvashwnd,0,#DCX_CACHE|#DCX_CLIPCHILDREN|#DCX_CLIPSIBLINGS)
*CustomCanvas\Canvas_Bufer\hdc = CreateCompatibleDC_(hdc);создаем контекст устройства памяти для рисованя, совместимый с указанным устройством
*CustomCanvas\Canvas_Bufer\fon_hdc=CreateCompatibleDC_(hdc);создаем контекст памяти под фон
;
Protected bi.BITMAPINFO
ZeroMemory_(@bi, SizeOf(bi));
bi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER);
bi\bmiHeader\biCompression = #BI_RGB;
bi\bmiHeader\biBitCount = 32;
bi\bmiHeader\biPlanes = 1;
bi\bmiHeader\biWidth = x1;
bi\bmiHeader\biHeight = y1;
bi\bmiHeader\biSizeImage = x1 * y1 * 4;
bi\bmiHeader\biXPelsPerMeter=1000;1;
bi\bmiHeader\biYPelsPerMeter=1000;1;
bi\bmiHeader\biClrUsed=0;
bi\bmiHeader\biClrImportant=0;
Protected hbmMem = CreateDIBSection_(*CustomCanvas\Canvas_Bufer\hdc, @bi, #DIB_RGB_COLORS, @*CustomCanvas\Canvas_Bufer\start_hdc_bits, #Null, #Null)
*CustomCanvas\Canvas_Bufer\end_hdc_bits=*CustomCanvas\Canvas_Bufer\start_hdc_bits+bi\bmiHeader\biSizeImage-4
SelectObject_(*CustomCanvas\Canvas_Bufer\hdc,hbmMem) ;устанавливаем шаблон для буфера рисования
;
;Protected hbmMem2 = CreateCompatibleBitmap_(hdc,x1,y1);оказывается первый шаблон хрен заселектишь :(
Protected hbmMem2 = CreateDIBSection_(*CustomCanvas\Canvas_Bufer\fon_hdc, @bi, #DIB_RGB_COLORS, @*CustomCanvas\Canvas_Bufer\start_fon_bits, #Null, #Null);
*CustomCanvas\Canvas_Bufer\end_fon_bits=*CustomCanvas\Canvas_Bufer\start_fon_bits+bi\bmiHeader\biSizeImage-4
SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,hbmMem2);устанавливаем шаблон для буфера фона
DeleteObject_(hbmMem);больше шаблон bitmapa не нужен
DeleteObject_(hbmMem2);больше шаблон bitmapa не нужен
ReleaseDC_(canvashwnd,hdc)
;================================
SetCanvasDataFon(*CustomCanvas,$57FFFF);установка фона по данным структуры
;=================================
;
SetWindowLongPtr_(canvashwnd,0,*CustomCanvas);заносим адрес памяти с структурой данных в дополнительную память окна cbWndExtra это не #gwl_userdata
;SetCanvasHwndFon(canvashwnd,$57456F)
;SetCanvasIdFon(canvas_id,$57FFFF)
ProcedureReturn canvashwnd
Else
ProcedureReturn 0;канвас не создан
EndIf
EndProcedure
;Настройка контекста памяти для рисования
Procedure.i CanvasOpenFileImage(Canvas_id);открытие файла и загрузка в канвас
file$ = OpenFileRequester("Open File","","*.PNG|*.PNG*|*.GIF|*.GIF*|*.JPG|*.JPG*|*.BMP|*.BMP*|All files|*.*",1)
Debug file$
LoadImage(0, file$)
SetGadgetAttribute(Canvas_id, #PB_Canvas_Image, ImageID(0))
hdc=StartDrawing(CanvasOutput(Canvas_id))
BitBlt_(hdc, 0, 0, imgW, imgH, hDC, 0, 0, #SRCCOPY)
StopDrawing()
EndProcedure
If OpenWindow(0, 0, 0,1200, 600, "CustomCanvas", #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
CreateCustomCanvas(WindowID(0),0,10,10,500,500)
; SetCanvasFon(0,$29D4EC)
CreateCustomCanvas(WindowID(0),1,600,10,450,400)
; SetCanvasFon(1,$29D4EC)
;OpenFileImage(0)
Else
End
EndIf
;--------предварительные данные(рисунок) для теста
hdc=StartCanvasDrawing(GadgetID(0))
For i=0 To 100
CanvasApiSetPixel(hdc,20,i,$00CFC1)
CanvasApiSetPixel(hdc,21,i,$00CFC1)
CanvasApiSetPixel(hdc,22,i,$00CFC1)
CanvasApiSetPixel(hdc,23,i,$00CFC1)
CanvasApiSetPixel(hdc,24,i,$00CFC1)
CanvasApiSetPixel(hdc,25,i,$00CFC1)
CanvasDrawLine(hdc,100,i+50,300,i)
CanvasDrawArc(hdc,200,200,400+i,400+i,300,300,200,200)
Next
StopCanvasDrawing()
;------------
;проверка на установку фона
SetCanvasIdFon(0,$F666FF)
;SetCanvasFon(1,$2266FF)
hdc=StartCanvasDrawing(GadgetID(1))
For i=0 To 100
CanvasApiSetPixel(hdc,20,i,$00CFC1)
CanvasApiSetPixel(hdc,21,i,$00CFC1)
CanvasApiSetPixel(hdc,22,i,$00CFC1)
CanvasApiSetPixel(hdc,23,i,$00CFC1)
CanvasApiSetPixel(hdc,24,i,$00CFC1)
CanvasApiSetPixel(hdc,25,i,$00CFC1)
CanvasDrawLine(hdc,100,i+50,300,i)
CanvasDrawArc(hdc,200,200,400+i,400+i,300,300,200,200)
Next
StopCanvasDrawing()
;тест
;For i=0 To 100
;SetCanvasIdFon(0,i*i+$F666FF)
;Next
;For i=0 To 100
;SetCanvasIdFon(1,i*i+$5677)
;Next
;проверка что цвет меняется
;SetCanvasIdFon(1,$57FFFF)
;Debug GetPixelFormat_(GetDC_(GadgetID(0)))
;hdc=StartDrawing(CanvasOutput(0))
;Debug GetPixelFormat_(hdc)
;StopDrawing()
DialogSetCanvasFon(0)
DialogCanvasScale(0)
;{;Обработчик сообщений
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow;{;
End
;};
Case #PB_Event_Gadget
Select EventGadget()
Case 0
EndSelect
EndSelect
ForEver;};