Да не просто создать а со своим функционалом.
Вопрос как оптимизировать код чтобы фон менял на отрисовке(картинке битмап) в замен этого?
For x=0 To *CustomCanvas\Canvas_Bufer\xy\x1-1
For y=0 To *CustomCanvas\Canvas_Bufer\xy\y1-1
; Debug Hex(GetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y),#PB_Long)
If GetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y)=cvetfona
SetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y,fon);перезаписываем пиксель на новый фон
EndIf
Next
Next
;
это условно прога
Macro CanvasSetPixel(HDC,nXPos,nYPos,COLORREF)
SetPixel_(HDC,nXPos,nYPos, COLORREF)
EndMacro
Macro CanvasGetPixel(HDC,nXPos,nYPos)
GetPixel_(HDC,nXPos,nYPos)
EndMacro
Macro CanvasDrawLine(HDC,x1,y1,x2,y2)
pt.POINT;
MoveToEx_(HDC, x1, y1,@pt);
LineTo_(HDC, x2, y2)
EndMacro
Macro CanvasDrawArc(HDC,x1,y1,x2,y2,x3,y3,x4,y4)
Arc_(HDC,x1,y1,x2,y2,x3,y3,x4,y4)
EndMacro
Structure xy
x1.l
y1.l
EndStructure
Structure Bufer_bitmap
hdc.i
xy.xy
fon_hdc.i
EndStructure
Structure CustomCanvas
Canvas_id.i
Canvas_Rect.rect
Canvas_Bufer.Bufer_bitmap
EndStructure
UseTIFFImageDecoder()
UseJPEGImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
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)
Protected canvashwnd.i
canvashwnd=CanvasGadget(canvas_id,x,y,x1,y1);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_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\xy\x1=x1
*CustomCanvas\Canvas_Bufer\xy\y1=y1
;
Protected hdc.i=GetDC_(canvashwnd);GetDCEx_(canvashwnd,0,#DCX_CACHE|#DCX_CLIPCHILDREN|#DCX_CLIPSIBLINGS)
*CustomCanvas\Canvas_Bufer\hdc = CreateCompatibleDC_(hdc);создает контекст устройства памяти (DC), совместимый с указанным устройством
*CustomCanvas\Canvas_Bufer\fon_hdc=CreateCompatibleDC_(hdc);создает контекст под bitmap фона
Protected hbmMem = CreateCompatibleBitmap_(hdc,x1,y1);создаём объект(шаблон) картинки bitmap
SelectObject_(*CustomCanvas\Canvas_Bufer\hdc,hbmMem) ;устанавливаем шаблон для буфера рисования
Protected hbmMem2 = CreateCompatibleBitmap_(hdc,x1,y1);оказывается первый шаблон хрен заселектишь :(
SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,hbmMem2);устанавливаем шаблон для буфера фона
DeleteObject_(hbmMem);больше шаблон bitmapa не нужен
DeleteObject_(hbmMem2);больше шаблон bitmapa не нужен
ReleaseDC_(canvashwnd,hdc)
Protected kistb.i=CreateSolidBrush_($57FFFF);создаём дискриптор кисти для создания битмапа фона
SelectObject_(*CustomCanvas\Canvas_Bufer\hdc,kistb)
SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,kistb)
FillRect_(*CustomCanvas\Canvas_Bufer\hdc,*CustomCanvas\Canvas_Rect,kistb);закрашиваем битмап под фон
FillRect_(*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect,kistb);закрашиваем битмап под фон
DeleteObject_(kistb);больше кисть не нужна
;копируем начальнай фон в канвас
Protected hdcccanvasa.i
hdcccanvasa= StartDrawing(CanvasOutput(canvas_id))
BitBlt_(hdcccanvasa,0,0,x1,y1,*CustomCanvas\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
StopDrawing()
;
SetWindowLongPtr_(canvashwnd,0,*CustomCanvas);заносим адрес памяти с структурой данных в дополнительную память окна cbWndExtra это не #gwl_userdata
ProcedureReturn canvashwnd
Else
ProcedureReturn 0;канвас не создан
EndIf
EndProcedure
Global *CustomCanvas2.CustomCanvas
Global hdcccanvasa2.i
Structure fon
byvhiy.l
stavhiy.l
CustomCanvas_hdc.i
EndStructure
;Global cvetfona.fon
;Threaded x
;Threaded y
Procedure Thread(*cvetfona.fon)
Debug 6666
Debug cvetfona\byvhiy
Debug *cvetfona\byvhiy
For x=0 To 249;*CustomCanvas\Canvas_Bufer\xy\x1-1/2;-1
For y=0 To 499;*CustomCanvas\Canvas_Bufer\xy\y1)
If GetPixel_(*cvetfona\CustomCanvas_hdc,x,y)=*cvetfona\byvhiy
SetPixel_(*cvetfona\CustomCanvas_hdc,x,y,*cvetfona\stavhiy);перезаписываем пиксель на новый фон
EndIf
Next
Next
EndProcedure
Procedure Thread2(*cvetfona.fon)
For x=250 To 499;*CustomCanvas\Canvas_Bufer\xy\x1-1
For y=0 To 499;*CustomCanvas\Canvas_Bufer\xy\y1-1
; Debug Hex(GetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y),#PB_Long)
If GetPixel_(*cvetfona\CustomCanvas_hdc,x,y)=*cvetfona\byvhiy
SetPixel_(*cvetfona\CustomCanvas_hdc,x,y,*cvetfona\stavhiy);перезаписываем пиксель на новый фон
EndIf
Next
Next
EndProcedure
Procedure.i SetCanvasFon(id,fon.l)
Protected canvashwnd.i=GadgetID(id)
Protected *CustomCanvas.CustomCanvas=GetWindowLongPtr_(canvashwnd,0);получаем адрес данных
Protected kistb.l=CreateSolidBrush_(fon)
;SetDCBrushColor(hdc,COLORREF);задает для цвета кисти текущего контекста
;Debug GetCurrentObject_(*CustomCanvas\Canvas_Bufer\hdc,#OBJ_BRUSH)
Protected cvetfona.l= GetPixel_(*CustomCanvas\Canvas_Bufer\fon_hdc,0,0)
Protected HBRUSH.l =SelectObject_(*CustomCanvas\Canvas_Bufer\fon_hdc,kistb)
;cvetfona\stavhiy=fon
; cvetfona\byvhiy= GetPixel_(*CustomCanvas\Canvas_Bufer\fon_hdc,0,0);GetDCBrushColor_(*CustomCanvas\Canvas_Bufer\fon_hdc)
;cvetfona\CustomCanvas_hdc=*CustomCanvas\Canvas_Bufer\hdc
;Debug cvetfona
;Debug "cvetfona "+Hex(cvetfona)
; Rectangle_(*CustomCanvas\Canvas_Bufer\hdc,0,0,*CustomCanvas\Canvas_Bufer\xy\x1,*CustomCanvas\Canvas_Bufer\xy\y1)
FillRect_(*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect,kistb)
;
; x1=GetDeviceCaps_(*CustomCanvas\Canvas_Bufer\hdc,#HORZRES)
;y1=GetDeviceCaps_(*CustomCanvas\Canvas_Bufer\hdc,#VERTRES)
; Debug *CustomCanvas\Canvas_Bufer\xy\x1
; Debug *CustomCanvas\Canvas_Bufer\xy\y1
;GetCurrentObject_(*CustomCanvas\Canvas_Bufer\hdc,#OBJ_BRUSH)
; BITMAP.BITMAP
; GetObject_(GetCurrentObject_(*CustomCanvas\Canvas_Bufer\hdc,#OBJ_BITMAP), SizeOf(BITMAP), @BITMAP)
; Debug BITMAP\bmWidth
; Debug BITMAP\bmHeight
; Debug BITMAP\bmBitsPixel
; Debug BITMAP\bmBits
; BITMAPINFO.BITMAPINFO
;BITMAPINFO\bmiHeader\biPlanes=1
;BITMAPINFO\bmiHeader\biBitCount=32
; BITMAPINFO\bmiHeader\biSize=SizeOf(BITMAPINFO)
; lpvBits.l=0
; GetDIBits_(*CustomCanvas\Canvas_Bufer\hdc,GetCurrentObject_(*CustomCanvas\Canvas_Bufer\hdc,#OBJ_BITMAP),0,0,@lpvBits,@BITMAPINFO,#DIB_RGB_COLORS)
;Debug BITMAPINFO\bmiColors\
; Debug BITMAPINFO\bmiHeader\biBitCount;Указывает количество бит на пиксель (bpp)
; Debug BITMAPINFO\bmiHeader\biSizeImage
; Debug BITMAPINFO\bmiHeader\biXPelsPerMeter
; Debug BITMAPINFO\bmiHeader\biYPelsPerMeter
; Debug BITMAPINFO\bmiHeader\biYPelsPerMeter
;lpvBits = AllocateMemory(1000000)
; If GetDIBits_(*CustomCanvas\Canvas_Bufer\hdc,GetCurrentObject_(*CustomCanvas\Canvas_Bufer\hdc,#OBJ_BITMAP),0,500,@lpvBits,@BITMAPINFO,#DIB_RGB_COLORS)<>0
; Debug lpvBits
; For i=118 To 500 Step 4
; Debug Hex(PeekL(lpvBits+i))
; Next
; EndIf
; FreeMemory(lpvBits)
For x=0 To *CustomCanvas\Canvas_Bufer\xy\x1-1
For y=0 To *CustomCanvas\Canvas_Bufer\xy\y1-1
; Debug Hex(GetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y),#PB_Long)
If GetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y)=cvetfona
SetPixel_(*CustomCanvas\Canvas_Bufer\hdc,x,y,fon);перезаписываем пиксель на новый фон
EndIf
Next
Next
;CreateThread(@Thread(),@cvetfona)
;CreateThread(@Thread2(),@cvetfona)
; GdiTransparentBlt_(*CustomCanvas\Canvas_Bufer\hdc,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,fon)
;Protected SelectObject_(*CustomCanvas\Canvas_Bufer\hdc,kistb)
; SetROP2_(*CustomCanvas\Canvas_Bufer\hdc,#R2_NOTMASKPEN|#R2_NOTXORPEN)
; Rectangle_(*CustomCanvas\Canvas_Bufer\hdc,0, 0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom)
;BitBlt_(*CustomCanvas\Canvas_Bufer\fon_hdc,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\hdc, 0, 0,#SRCINVERT)
;SelectObject_(*CustomCanvas\Canvas_Bufer\hdc,kistb)
;BitBlt_(*CustomCanvas\Canvas_Bufer\hdc,0,0,*CustomCanvas\Canvas_Rect\right,*CustomCanvas\Canvas_Rect\bottom,*CustomCanvas\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
; FillRect_(*CustomCanvas\Canvas_Bufer\fon_hdc,*CustomCanvas\Canvas_Rect,kistb)
;
;Debug *CustomCanvas\Canvas_id
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()
DeleteObject_(kistb);больше кисть не нужна
EndProcedure
Procedure CanvasCLS();clear
BitBlt_(hdcccanvasa2,0,0,*CustomCanvas2\Canvas_Rect\right,*CustomCanvas2\Canvas_Rect\bottom,*CustomCanvas2\Canvas_Bufer\fon_hdc, 0, 0,#SRCCOPY)
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
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
CanvasSetPixel(hdc,20,i,$00CFC1)
CanvasSetPixel(hdc,21,i,$00CFC1)
CanvasSetPixel(hdc,22,i,$00CFC1)
CanvasSetPixel(hdc,23,i,$00CFC1)
CanvasSetPixel(hdc,24,i,$00CFC1)
CanvasSetPixel(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()
;------------
;проверка на установку фона
SetCanvasFon(0,$F666FF)
;{;Обработчик сообщений
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow;{;
End
;};
Case #PB_Event_Gadget
Select EventGadget()
Case 0
EndSelect
EndSelect
ForEver;};
