Рисуем линии Код (ASM): ; GUI # include win64a.inc ColorsGreen equ 0FF00FF00h;прозрачный - красный - зеленый - синий ColorsBlack equ 0FF000000h ColorsYellow equ 0FFFFFF00h ColorsRed equ 0FFFF0000h UnitWorld equ 0 PenAlignmentCenter equ 0 PenAlignmentInset equ 1 LineCapRoundAnchor equ 12h LineCapArrowAnchor equ 14h LineJoinBevel equ 1 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW ;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push 400 push 400 push rsi push rsi sub esp,20h invoke CreateWindowExA,WS_EX_TOOLWINDOW,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожить перья invoke GdipDeletePen,nativePen invoke GdipDeletePen,blackPen invoke GdipDeletePen,greenPen invoke GdipDeletePath,path ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmPAINT:invoke BeginPaint,hWnd,&ps ;зеленая линия invoke GdipDrawLineI,graphics,nativePen,40,40, 200, 100 ;x1,y1,x2,y2 ;"Странная" линия invoke GdipDrawLineI,graphics,greenPen,230,200,300,150 invoke GdipDrawLineI,graphics,blackPen,230,200,300,150 ;Прямоугольник с выравниванием линии по центру invoke GdipDrawRectangleI,graphics,greenPen,210,220,100,100 invoke GdipDrawRectangleI,graphics,blackPen,210,220,100,100 ;Прямоугольник с выравниванием линии по краю invoke GdipSetPenMode,greenPen,PenAlignmentInset invoke GdipDrawRectangleI,graphics,greenPen,250,250,100,100 invoke GdipDrawRectangleI,graphics,blackPen,250,250,100,100 ;Стрелка invoke GdipDrawLineI,graphics,hPen,12,92,60,80 ;Соединение линий invoke GdipAddPathLineI,path,10,200,100,200 invoke GdipAddPathLineI,path,100,200,100,300 invoke GdipAddPathLineI,path,100,300,150,300 invoke GdipSetPenLineJoin,hPen,LineJoinBevel invoke GdipDrawPath,graphics,hPen,path ;Прерывистая линия invoke GdipDrawLineI,graphics,hPen0,100,50,200,50 invoke GdipDrawLineI,graphics,hPen0,100,70,300,70 ;------------------------------------------------------------ invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics ;------------------------------------------------------------ movd xmm1,EpaisseurStylo invoke GdipCreatePen1,0FF00FF00h,,0,&nativePen movd xmm1,wi1 invoke GdipCreatePen1,ColorsBlack,,UnitWorld,&blackPen movd xmm1,wi2 invoke GdipCreatePen1,ColorsGreen,,UnitWorld,&greenPen invoke GdipSetPenMode,greenPen,PenAlignmentCenter movd xmm1,wi3 invoke GdipCreatePen1,ColorsYellow,,UnitWorld,&hPen invoke GdipSetPenStartCap,hPen,LineCapRoundAnchor invoke GdipSetPenEndCap,hPen,LineCapArrowAnchor invoke GdipCreatePath,0,&path invoke GdipStartPathFigure,path movd xmm1,wi3 invoke GdipCreatePen1,ColorsRed,,UnitWorld,&hPen0 invoke GdipSetPenStartCap,hPen0,LineCapRoundAnchor invoke GdipSetPenEndCap,hPen0,LineCapArrowAnchor invoke GdipSetPenDashArray,hPen0,&dash,2 wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'GDI+ рисование линий',0 gdiplusToken dd ? gsi GdiplusStartupInput <1,0,0,0,0> graphics dq ? nativePen dq ? blackPen dq ? greenPen dq ? hPen dq ? hPen0 dq ? path dq ? EpaisseurStylo REAL4 3.0;толщина пера в формате float wi1 real4 1.0 wi2 real4 10.0 wi3 real4 8.0 dash REAL4 1.0,0.5 end Во вложении asm/exe/cur-файлы
Рисуем круги, окружности и эллипсы Код (ASM): ; GUI # include win64a.inc ColorsGreen equ 0FF00FF00h .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push 500 push 500 push rsi push rsi sub esp,20h invoke CreateWindowExA,WS_EX_TOOLWINDOW,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожить путь invoke GdipDeletePath,path invoke GdipDeleteBrush,hBrush invoke GdipDeleteBrush,hBrush0 invoke GdipDeleteBrush,hBrush1 invoke GdipDeleteBrush,hBrush2 invoke GdipDeletePen,hPen ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmPAINT:invoke BeginPaint,hWnd,&ps ;Нелинейный градиент - эллипс invoke GdipAddPathEllipseI,path,-150,-150,600,600 invoke GdipCreatePathGradientFromPath,path,&hBrush invoke GdipSetPathGradientCenterColor,hBrush,900000FFh invoke GdipFillRectangleI,graphics,hBrush,0,0,700,700 ;нарисовать закрашенную окружность invoke GdipFillEllipseI,graphics,hBrush0,50,138,200,200 invoke GdipFillEllipseI,graphics,hBrush1,173,138,200,200 invoke GdipFillEllipseI,graphics,hBrush2,108,59,200,200 ;нарисовать незакрашенную окружность invoke GdipDrawEllipseI,graphics,hPen,250,100,200,200 ;------------------------------------------------------------ invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics ;------------------------------------------------------------ ;создать кисть invoke GdipCreateSolidFill,09000FFFFh,&hBrush0;голубой invoke GdipCreateSolidFill,090FFFF00h,&hBrush1;желтый invoke GdipCreateSolidFill,090FF00FFh,&hBrush2;малиновый ;создать перо movd xmm1,EpaisseurStylo;толщина пера в формате float invoke GdipCreatePen1,ColorsGreen,,0,&hPen; цвет пера invoke GdipCreatePath,0,&path wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'GDI+ рисование эллипсов',0 gdiplusToken dd ? gsi GdiplusStartupInput <1,0,0,0,0> graphics dq ? EpaisseurStylo REAL4 6.0 path dq ? hPen dq ? hBrush dq ? hBrush0 dq ? hBrush1 dq ? hBrush2 dq ? end Во вложении asm/exe/cur-файлы
Полупрозрачное окно круглой формы Окно перемещается по рабочему столу, если нажать на него левой клавишей мыши. Правый клик внутрь окна -- это окно закроет. Код (ASM): ; GUI # include win64a.inc PixelFormat32bppPARGB = 0E200Bh AC_SRC_OVER = 0 AC_SRC_ALPHA = 1 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW ;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push 600 push 600 push rbx push rbx sub esp,20h invoke CreateWindowExA,WS_EX_LAYERED,edi,edi,WS_POPUP or WS_VISIBLE ;WS_EX_LAYERED=80000h lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc <12> hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local hDC:HDC local memDC:HDC LOCAL hBmp:HBITMAP LOCAL OldBmp:HBITMAP LOCAL blend:BLENDFUNCTION LOCAL rect:RECT mov hWnd,rcx mov wParam,r8 mov lParam,r9 cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_RBUTTONDOWN je wmRBUTTONDOWN cmp edx,WM_LBUTTONDOWN je wmLBUTTONDOWN leave jmp NtdllDefWindowProc_ wmDESTROY:invoke ReleaseDC,hDC invoke GdipDisposeImage,bitmap0 ;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmLBUTTONDOWN:invoke SendMessageA,hWnd,WM_NCLBUTTONDOWN,HTCAPTION, lParam jmp wmLBUTTONUP wmRBUTTONDOWN:;invoke GetWindowLongPtrA,hWnd,GWL_EXSTYLE ; sub rax,WS_EX_LAYERED invoke SetWindowLongPtrA,hWnd,GWL_EXSTYLE,0 invoke SetLayeredWindowAttributes,hWnd,0,255,LWA_ALPHA invoke PostMessageA,hWnd,WM_CLOSE,0,0 jmp wmBYE wmCREATE:invoke GdipCreateBitmapFromFile,&pngfile,&bitmap0 invoke GetWindowRect,hWnd,&rect mov blend.BlendOp,AC_SRC_OVER mov blend.BlendFlags,0 mov blend.AlphaFormat,AC_SRC_ALPHA mov blend.SourceConstantAlpha, 255 invoke GetDC,0 mov hDC,rax wmLBUTTONUP:mov ecx,rect.right sub ecx,rect.left mov rect.right,ecx mov edx,rect.bottom sub edx,rect.top mov rect.bottom,edx lea eax,bitmap mov [rsp+28h],rax and qword ptr[rsp+20h],0 invoke GdipCreateBitmapFromScan0,,,0,PixelFormat32bppPARGB invoke GdipGetImageGraphicsContext,bitmap,&graphics invoke GdipDrawImage,graphics,bitmap0,0,0 mov ecx,rect.right mov edx,rect.bottom invoke GdipCreateBitmapFromGraphics,,,graphics,&bitmap10 invoke GdipCreateHBITMAPFromBitmap,bitmap,&hBmp,0 invoke CreateCompatibleDC,hDC mov memDC,rax invoke SelectObject,eax,hBmp mov OldBmp,rax mov qword ptr[rsp+40h],ULW_ALPHA lea eax,blend mov [rsp+38h],rax and qword ptr[rsp+30h],0 lea eax,ptZero mov [rsp+28h],rax mov rax,memDC mov [rsp+20h],rax invoke UpdateLayeredWindow,hWnd,0,&rect,&rect.right invoke DeleteObject,OldBmp invoke DeleteDC,memDC wmBYE: leave ret WndProc endp ;--------------------------------------- .data bitmap dq ? bitmap0 dq ? bitmap10 dq ? Hbitmap HBITMAP ? graphics dq ? ClassName db 'GDI+ полупрозрачный шар',0 gdiplusToken dd ? gsi GdiplusStartupInput <1,0,0,0,0> pngfile: du <crystal-ball.png> ptZero POINT <> end Во вложении asm/exe/png/cur-файлы
GIF-анимация Код (ASM): ; GUI # include win64a.inc PropertyTagFrameDelay equ 5100h cdIdTimer equ 1 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov edi,offset ClassName invoke LoadCursorFromFileA,&FileName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOWTEXT ;hbrBackground push rax ;hCursor push rax ;hIcon push IMAGE_BASE ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push IMAGE_BASE push rbx push rbx push rbx ; nHeight push rbx ; nWidth push 127; Y push 127; X sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 cmp msg.wParam,VK_ESCAPE;user press 'Esc'? je wmDESTROY invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:qword,umsg:qword,wParam:qword,lParam:qword local graphics:qword local ptDiff:POINT local rctWnd:RECT local rctClient:RECT local tmp:qword local pDimensionIDs:qword local count:qword local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_TIMER je wmTIMER leave jmp NtdllDefWindowProc_ wmDESTROY::invoke KillTimer,hWnd,cdIdTimer invoke GdipDisposeImage,hImage invoke GdipFree,pPropertyItem invoke GdiplusShutdown,gdiplusToken invoke RtlExitUserProcess,NULL ;DrawFrameGIF--------------------- wmPAINT:invoke BeginPaint,hWnd,&ps invoke GdipCreateFromHDC,eax,&graphics mov eax,dword ptr vdyClient mov [rsp+28h],rax mov eax,dword ptr vdxClient mov [rsp+20h],rax invoke GdipDrawImageRectI,graphics,hImage,0,0 invoke GdipImageSelectActiveFrame,hImage,&pageGuid,nFramePosition inc nFramePosition mov eax,nFrameCount sub rax,nFramePosition jnz @f mov nFramePosition,rax ;------------------------------- @@: invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd,&ps jmp wmBYE wmTIMER:invoke InvalidateRect,hWnd,0,0 jmp wmBYE wmCREATE:; Загрузить картинку из файла invoke GdipLoadImageFromFile,&szfilename,&hImage ; Проверить количество пространств invoke GdipImageGetFrameDimensionsCount,hImage,&count mov rcx,count test ecx,ecx jz @f shl ecx,4 invoke GdipAlloc mov pDimensionIDs,rax ; Получить идентификатор первого пространства invoke GdipImageGetFrameDimensionsList,hImage,eax,count ; Получить количество кадров в первом пространстве invoke GdipImageGetFrameCount,hImage,pDimensionIDs,&nFrameCount ; Получить значение задержек между кадрами invoke GdipGetPropertyItemSize,hImage,PropertyTagFrameDelay,&tmp mov rcx,tmp shl ecx,2 invoke GdipAlloc mov pPropertyItem,rax invoke GdipGetPropertyItem,hImage,PropertyTagFrameDelay,tmp,eax invoke GdipFree,pDimensionIDs @@:;------------------------------------ invoke GdipGetImageWidth,hImage,&nWidth invoke GdipGetImageHeight,hImage,&nHeight invoke GetClientRect,hWnd,&rctClient invoke GetWindowRect,hWnd,&rctWnd mov eax,rctWnd.right sub eax,rctWnd.left sub eax,rctClient.right mov ptDiff.x,eax mov eax,rctWnd.bottom sub eax,rctWnd.top sub eax,rctClient.bottom mov ptDiff.y,eax mov qword ptr [rsp+28h],TRUE ; bRepaint mov ecx,nHeight add ecx,ptDiff.y mov [rsp+20h],rcx ;nHeight mov r9d,nWidth add r9d,ptDiff.x invoke MoveWindow,hWnd,127,127 invoke SetTimer,hWnd,cdIdTimer,tmp,0 jmp wmBYE wmSIZE: mov rax,r9;lParam mov vdxClient,ax shr eax,10h mov vdyClient,ax wmBYE: leave retn WndProc endp ;----------------------------------- .data ClassName db "GDI+ gif animation",0 FileName db "br_Rabbit3.cur",0 gsi GdiplusStartupInput <1,0,0,0,0> pageGuid GUID <6AEDBD6Dh,3FB5h,418Ah,<83h,0A6h,7Fh,45h,22h,9Dh,0C8h,72h>> szfilename: du <movie.gif> vdxClient dw 0,0 vdyClient dw 0,0 nFramePosition dq 0 .data? gdiplusToken dq ? nWidth dd ? nHeight dd ? nFrameCount dd ? pPropertyItem dq ? hImage dq ? end Во вложении asm/exe/gif/cur-файлы
Интересная на мой взгляд идея: нарисовать график функций для данных --- Сообщение объединено, 7 янв 2025 --- Для красоты весь график можно разделить на прямоугольники сплошными прерывистыми линиями --- Сообщение объединено, 7 янв 2025 --- Для каждого числа делается линия как на сортировках, длина линии = значение, потом линии стираются последние точки соединяются.
Вот вариант на fasm 1.73.32 первого туториала Код (ASM): format PE64 GUI 6.0 include "WIN64W.INC" ; include "EXTIMPORT.INC" ; ----------------------------------------------------------------- irpv library, v { purge v } irpv import, v { purge v } macro .import { purge .import macro .import \{\} section '.idata' import data readable writeable define __SECTION import } macro library [name] { common .import label import_data forward label name#.ref if defined name#.use dd RVA name#.adr, 0, 0, RVA name#.txt, RVA name#.aim end if common if $ > import_data dd 0, 0, 0, 0, 0 end if } macro import name, [deff] { common match lbl==txt, name \{ if definite lbl\#.ref label lbl\#.aim \} forward match lbl==txt, name \{ match aim==val, deff \\{ macro lbl\\#.\\#aim arg& \\\{ invoke lbl\\\#.\\\#aim\\\#.point, arg\\\} macro aim arg& \\\{ lbl\\\#.\\\#aim arg \\\} if used __imp__\\#aim label __imp__\\#aim qword at lbl\\\#.\\\#aim\\\#.point end if if used lbl\\#.\\#aim\\#.point label lbl\\#.\\#aim\\#.point qword if val eqtype '' dq RVA lbl\\#.\\#aim\\#.text else dq 0x8000000000000000 + val end if end if \\} \} common match lbl==txt, name \{ if $ > lbl\#.aim lbl\#.use dq 0 end if label lbl\#.adr \} forward match lbl==txt, name \{ match aim==val, deff \\{ if used lbl\\#.\\#aim\\#.point if val eqtype '' dq RVA lbl\\#.\\#aim\\#.text else dq 0x8000000000000000 + val end if end if \\} \} common match lbl==txt, name \{ if $ > lbl\#.adr dq 0 end if lbl\#.txt db txt, 0 \} forward match lbl==txt, name \{ match aim==val, deff \\{ if used lbl\\#.\\#aim\\#.point & val eqtype '' rb RVA $ and 1 lbl\\#.\\#aim\\#.text db 0, 0, val, 0 end if \\} \} common end if } ; ----------------------------------------------------------------- ; include "GDIPLUS.INC" ; ----------------------------------------------------------------- UnitWorld equ 0 PenAlignmentCenter equ 0 PenAlignmentInset equ 1 LineCapRoundAnchor equ 12h LineCapArrowAnchor equ 14h LineJoinBevel equ 1 struc GdiplusStartupInput ver=1,cbk=0,bkg=?,ext=?,inp=? { label . .GdiplusVersion dd ver,0 .DebugEventCallback dq cbk .SuppressBackgroundThread dd bkg .SuppressExternalCodecs dd ext .GdiplusStartupInput dq inp label .Length at $ - . } ; ----------------------------------------------------------------- library KERNEL32.DLL,USER32.DLL,GDIPLUS.DLL import KERNEL32.DLL = "KERNEL32.DLL",\ ExitProcess = "ExitProcess",\ GetLastError = "GetLastError",\ SetLastError = "SetLastError" import USER32.DLL = "USER32.DLL",\ BeginPaint = "BeginPaint",\ CreateWindowExW = "CreateWindowExW",\ DefWindowProcW = "DefWindowProcW",\ DispatchMessageW = "DispatchMessageW",\ EndPaint = "EndPaint",\ GetMessageW = "GetMessageW",\ LoadImage = "LoadImageW",\ PostQuitMessage = "PostQuitMessage",\ RegisterClassExW = "RegisterClassExW",\ TranslateMessage = "TranslateMessage" import GDIPLUS.DLL = "GDIPLUS.DLL",\ GdipAddPathLineI = "GdipAddPathLineI",\ GdipCreateFromHWND = "GdipCreateFromHWND",\ GdipCreatePath = "GdipCreatePath",\ GdipDeleteGraphics = "GdipDeleteGraphics",\ GdipCreatePen1 = "GdipCreatePen1",\ GdipDeletePath = "GdipDeletePath",\ GdipDeletePen = "GdipDeletePen",\ GdipDrawLineI = "GdipDrawLineI",\ GdipDrawPath = "GdipDrawPath",\ GdipDrawRectangleI = "GdipDrawRectangleI",\ GdipSetPenDashArray = "GdipSetPenDashArray",\ GdipSetPenLineJoin = "GdipSetPenLineJoin",\ GdipSetPenMode = "GdipSetPenMode",\ GdipSetPenEndCap = "GdipSetPenEndCap",\ GdipSetPenStartCap = "GdipSetPenStartCap",\ GdipStartPathFigure = "GdipStartPathFigure",\ GdiplusShutdown = "GdiplusShutdown",\ GdiplusStartup = "GdiplusStartup" section '.data' data readable writeable gsi GdiplusStartupInput 1,0,0,0,0 gdipDash dd 1.0,\ 0.5 nativePenWidth dd 3.0 blackPenWidth dd 1.0 greenPenWidth dd 10.0 hPenWidth dd 8.0 hPen0Width dd 10.0 szClassName du "GDI+ рисование линий",0 szFileName du "br_Rabbit3.cur",0 align 8 gdipGraphics rq 1 gdipPath rq 1 hPen0 rq 1 hPen rq 1 nativePen rq 1 blackPen rq 1 greenPen rq 1 gdiplusToken rd 1 virtual at 0 wce WNDCLASSEX label WNDCLASSEXW.Length end virtual section '.text' code readable executable label ImageBase at $ - $$ entry WinMain proc WinMain RegisterClassExW_SizeAndStyle = WNDCLASSEXW.Length or ((CS_HREDRAW or CS_VREDRAW or CS_GLOBALCLASS or CS_DBLCLKS) shl 32) local msg:MSG frame GdiplusStartup gdiplusToken, gsi, 0 LoadImage NULL, addr szFileName, IMAGE_CURSOR, LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_LOADFROMFILE or LR_SHARED RegisterClassExW addr rsp + 32, rdx, r8, r9, RegisterClassExW_SizeAndStyle,\ addr WndProc, NULL, addr ImageBase, rax, rax, COLOR_WINDOWFRAME+1,\ NULL, addr szClassName, rax CreateWindowExW WS_EX_TOOLWINDOW, addr szClassName, addr szClassName,\ WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400,\ NULL, NULL, addr ImageBase, NULL SetLastError NULL jmp .start @@: TranslateMessage addr msg DispatchMessageW addr msg .start: GetMessageW addr msg, NULL, NULL, NULL inc eax jz @f dec eax jnz @b mov eax, dword [msg.wParam] jmp .exit @@: GetLastError .exit: GdiplusShutdown [gdiplusToken] ExitProcess eax endf endp proc WndProc, hWnd:QWORD,uMsg:DWORD,wPar:QWORD,lPar:QWORD frame local ps:PAINTSTRUCT cmp edx, WM_PAINT jz .wm_paint cmp edx, WM_DESTROY jz .wm_destroy cmp edx, WM_CREATE jz .wm_create DefWindowProcW rcx, edx, r8, r9 jmp .quit .wm_create: GdipCreateFromHWND rcx, gdipGraphics GdipCreatePen1 0FF00FF00h, float [nativePenWidth], UnitWorld, addr nativePen GdipCreatePen1 0FF000000h, float [blackPenWidth], UnitWorld, addr blackPen GdipCreatePen1 0FF00FF00h, float [greenPenWidth], UnitWorld, addr greenPen GdipSetPenMode [greenPen], PenAlignmentCenter GdipCreatePen1 0FFFFFF00h, float [hPenWidth], UnitWorld, addr hPen GdipSetPenStartCap [hPen], LineCapRoundAnchor GdipSetPenEndCap [hPen], LineCapArrowAnchor GdipCreatePath 0, addr gdipPath GdipStartPathFigure [gdipPath] GdipCreatePen1 0FFFF0000h, float [hPen0Width], UnitWorld, addr hPen0 GdipSetPenStartCap [hPen0], LineCapRoundAnchor GdipSetPenEndCap [hPen0], LineCapArrowAnchor GdipSetPenDashArray [hPen0], addr gdipDash, 2 xor eax, eax jmp .quit .wm_destroy: GdipDeletePen [hPen0] GdipDeletePen [hPen] GdipDeletePen [greenPen] GdipDeletePen [blackPen] GdipDeletePen [nativePen] GdipDeletePath [gdipPath] GdipDeleteGraphics [gdipGraphics] PostQuitMessage NULL jmp .quit .wm_paint: mov [hWnd], rcx BeginPaint, [hWnd], addr ps ;зеленая линия GdipDrawLineI [gdipGraphics], [nativePen], 40, 40, 200, 100 ;x1,y1,x2,y2 ;"Странная" линия GdipDrawLineI [gdipGraphics], [greenPen], 230, 200, 300, 150 GdipDrawLineI [gdipGraphics], [blackPen], 230, 200, 300, 150 ;Прямоугольник с выравниванием линии по центру GdipDrawRectangleI [gdipGraphics], [greenPen], 210, 220, 100, 100 GdipDrawRectangleI [gdipGraphics], [blackPen], 210, 220, 100, 100 ;Прямоугольник с выравниванием линии по краю GdipSetPenMode [greenPen], PenAlignmentInset GdipDrawRectangleI [gdipGraphics], [greenPen], 250, 250, 100, 100 GdipDrawRectangleI [gdipGraphics], [blackPen], 250, 250, 100, 100 ;Стрелка GdipDrawLineI [gdipGraphics], [hPen], 12, 92, 60, 80 ;Соединение линий GdipAddPathLineI [gdipPath], 10, 200, 100, 200 GdipAddPathLineI [gdipPath], 100, 200, 100, 300 GdipAddPathLineI [gdipPath], 100, 300, 150, 300 GdipSetPenLineJoin [hPen], LineJoinBevel GdipDrawPath [gdipGraphics], [hPen], [gdipPath] ;Прерывистая линия GdipDrawLineI [gdipGraphics], [hPen0], 100, 50, 200, 50 GdipDrawLineI [gdipGraphics], [hPen0], 100, 70, 300, 70 ;------------------------------------------------------------ EndPaint, [hWnd], addr ps jmp .quit .quit: endf ret endp
Градиент Код (C): ; GUI # include win64a.inc WINDOWWIDTH equ 640 WINDOWHEIGHT equ 480 WINDOWWIDTHF equ 640.0 WINDOWHEIGHTF equ 480.0 RectF STRUCT Left REAL4 ? Top REAL4 ? Right REAL4 ? Bottom REAL4 ? RectF ENDS ;Various wrap modes for brushes WrapModeTile equ 0 WrapModeTileFlipX equ 1 WrapModeTileFlipY equ 2 WrapModeTileFlipXY equ 3 WrapModeClamp equ 4 ; LinearGradient Modes LinearGradientModeHorizontal equ 0 LinearGradientModeVertical equ 1 LinearGradientModeForwardDiagonal equ 2 LinearGradientModeBackwardDiagonal equ 3 equRed equ 0FFFF0000h equBlue equ 0FF0080FFh .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,&FileName mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push WINDOWHEIGHT push WINDOWWIDTH push rsi push rsi sub esp,20h invoke CreateWindowExA,WS_EX_TOOLWINDOW,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_SIZE je wmSIZE cmp edx,WM_MOUSEWHEEL je wmMOUSEWHEEL cmp edx,WM_LBUTTONDOWN je wmLBUTTONDOWN leave jmp NtdllDefWindowProc_ wmDESTROY: ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmSIZE: invoke GetClientRect,hWnd,&rect cvtsi2ss xmm0,rect.Left movd rect.Left,xmm0 cvtsi2ss xmm0,rect.Top movd rect.Top,xmm0 cvtsi2ss xmm0,rect.Right movd rect.Right,xmm0 cvtsi2ss xmm0,rect.Bottom movd rect.Bottom,xmm0 invoke InvalidateRgn,hWnd,NULL,FALSE jmp wmBYE wmMOUSEWHEEL:mov eax,r8d shr eax,16 cmp ax,1000h;.if signed r8d > 0 jle @f add ChangeColor,0A050Fh or ChangeColor,0FF000000h jmp @1 @@: sub ChangeColor, 90305h or ChangeColor, 0FF000000h @1: invoke InvalidateRgn, rcx, NULL, FALSE jmp wmBYE wmLBUTTONDOWN:inc GradientMode and GradientMode,11y wmPAINT:invoke DrawGradient jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics ;------------------------------------------------------------ wmBYE: leave ret WndProc endp DrawGradient proc LOCAL hBrush:QWORD lea eax,hBrush mov [rsp+28h],rax mov qword ptr[rsp+20h],WrapModeTile invoke GdipCreateLineBrushFromRect,&rect,equRed,ChangeColor,GradientMode mov eax,rect.Bottom mov [rsp+28h],rax mov eax,rect.Right mov [rsp+20h],rax movd xmm3,rect.Top movd xmm2,rect.Left invoke GdipFillRectangle,graphics,hBrush invoke GdipDeleteBrush, hBrush leave ret DrawGradient endp ;--------------------------------------- .data ClassName db 'GDI+ градиент: [щелкаем левой клавишей мыши и вращаем колесико]',0 FileName db "br_Rabbit3.cur",0 gdiplusToken dd ? gsi GdiplusStartupInput <1,0,0,0,0> graphics dq ? GradientMode dq 0 ;how the gradient will look in the window ChangeColor dq equBlue rect RectF <0.0, 0.0, WINDOWWIDTHF, WINDOWHEIGHTF> hDC dq ? end Во вложении asm/exe/cur-файлы
Вывод на экран JPEG Код (ASM): ; GUI # include win64a.inc .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push 600 push 800 push rsi push rsi sub esp,20h invoke CreateWindowExA,WS_EX_TOOLWINDOW,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT local hDC:HDC mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmDESTROY:invoke GdipDisposeImage,hJPG ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmPAINT:invoke BeginPaint,hWnd,&ps ;------------------------------------------------------------ invoke GdipDrawImageI,graphics,hJPG,0,0 invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics ;------------------------------------------------------------ ;загрузить изображение из файла invoke GdipLoadImageFromFile,&jpegfile,&hJPG wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'GDI+ Image Resize',0 gsi GdiplusStartupInput <1,0,0,0,0> jpegfile: du <Arenalv0.jpg> .data? gdiplusToken dd ? hJPG dq ? graphics dq ? end Во вложении asm/exe/jpg/cur-файлы
Рисуем мышью Код (ASM): ; GUI # include win64a.inc .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName mov hCursor1,rax push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW+1;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push rsi push rsi push rsi push rsi sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT local hdc:HDC local X:dword local Y:dword mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp dx,WM_LBUTTONDOWN je wmLBUTTONDOWN cmp dx,WM_LBUTTONUP je wmLBUTTONUP cmp dx,WM_MOUSEMOVE je wmMOUSEMOVE leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmLBUTTONDOWN:;младшая часть lParam = x старшая часть lParam = y or doDraw,TRUE jmp wmBYE wmLBUTTONUP:and doDraw,FALSE invoke SetCursor,hCursor1 jmp wmBYE wmMOUSEMOVE:cmp doDraw,FALSE je wmBYE mov X,r9d and X,0FFFFh shr r9,16 mov Y,r9d invoke SetCursor,hCursor2 mov qword ptr[rsp+28h],10 mov qword ptr[rsp+20h],10 mov r9d,Y mov r8d,X invoke GdipFillEllipseI,graphics,hBrush jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics invoke GdipCreateSolidFill,0FFFF0000h,&hBrush;красный invoke LoadCursorA,0,32631;IDC_HAND mov hCursor2,rax wmBYE: leave retn WndProc endp ;--------------------------------------- .data ClassName db 'GDI+: Рисуем мышью',0 gsi GdiplusStartupInput <1,0,0,0,0> doDraw db FALSE .data? gdiplusToken dd ? graphics dq ? hBrush dq ? hCursor1 dq ? hCursor2 dq ? end Во вложении asm/exe/cur-файлы
Надписи, прямоугольники, эллипсы, линии' Код (ASM): ; GUI # include win64a.inc RectF STRUCT Left REAL4 ? Top REAL4 ? Right REAL4 ? Bottom REAL4 ? RectF ENDS .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_WINDOW+1;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h shl esi,9 ;rsi=CW_USEDEFAULT push rbx push rbx push 400;rsi push 560;rsi push rsi push rsi sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@:invoke GetMessageA,edi,0,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT local hDC:HDC mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmDESTROY:;уничтожить перо invoke GdipDeletePen,hPen ;уничтожить перо invoke GdipDeleteBrush,hBrush ;уничтожить шрифт invoke GdipDeleteFont,gpfont ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL wmPAINT:invoke BeginPaint,hWnd,&ps mov hDC,rax invoke GdipCreateFontFromLogfont,eax,&logfont,&gpfont invoke GdipDrawString,graphics,&wphrase,-1,gpfont,&RectText,nativeFormat,hBrush invoke GdipDrawRectangleI,graphics,hPen, 10, 40, 200, 100 invoke GdipDrawEllipseI,graphics,hPen, 150, 120, 100, 130 xor edi,edi @@:mov r9d,edi add r9d,10 mov qword ptr [rsp+28h],r9 mov qword ptr [rsp+20h],500 invoke GdipDrawLineI,graphics,hPen,300 add edi,6 cmp edi,50*6 jb @b ;------------------------------------------------------------ invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd,&graphics movd xmm1,const3_0 invoke GdipCreatePen1,0FF00FF00h,,0,&hPen invoke GdipCreateSolidFill,0FF00C832h,&hBrush invoke CreateFontIndirect,&logfont mov hFont,rax invoke SendMessageA,hWnd,WM_SETFONT,rax,0 ;---------- prepare all can be possible for drawing here (WM_PAINT is faster as this) invoke GdipCreateStringFormat,0,LANG_NEUTRAL,&nativeFormat wmBYE: leave retn WndProc endp ;--------------------------------------- .data ClassName db 'GDI+: Надписи, прямоугольники, эллипсы, линии',0 gsi GdiplusStartupInput <1,0,0,0,0> const3_0 REAL4 3.0;толщина пера в формате float logfont LOGFONT <36,12,0,0,400,0,0,0,0,0,0,0,DEFAULT_PITCH or FF_SCRIPT,"Helvetica"> RectText RectF <0.0,0.0,270.0,90.0> wphrase: du <hello, World> .data? gdiplusToken dd ? graphics dq ? gpfont dq ? hBrush dq ? hPen dq ? hFont dq ? nativeFormat dq ? end Во вложении asm/exe/cur-файлы
Рисование с помощью GDI+(по мотивам Alfonso Víctor Caballero Hurtado PintarWC01.c) В дополнение к объекту graphics нам понадобилось создать hPen для рисования линий и hBrush для рисования закрашенных прямоугольников. Программа выводит несколько типов линий и прямоугольников: закрашенный прямоугольник, линия, прямоугольник со скругленными углами, пунктирный прямоугольник, линия в виде стрелки. Прямоугольник со скругленными углами имеет обладает прозрачностью по отношению к объектам, расположенным под ним. Это связано с тем, уровень альфа-смешивания установлен =99h вместо 0FFh, что делало бы его полностью непрозрачным. Объекты нарисованы со сглаживанием, поскольку применено к объекту graphics с помощью: invoke GdipSetSmoothingMode,graphics, SmoothingModeAntiAlias Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 400 cdYSize = 200 PenAlignmentCenter = 0 SmoothingModeAntiAlias = 5 UnitPixel = 2 LineJoinRound = 2 LineCapRoundAnchor = 12h LineCapArrowAnchor = 14h .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local hGraphics:qword local hBrush:qword local hPen:dword local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_PAINT je wmPAINT cmp edx,WM_SIZE je wmSIZE cmp edx,WM_KEYDOWN je wmKEYDOWN leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmSIZE: mov vdxClient,r9d and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) shr r9d,16 mov vdyClient,r9d;vdyClient = HIWORD (lParam) ; invoke InvalidateRect,hWnd, NULL,TRUE jmp wmBYE wmPAINT:invoke BeginPaint,hWnd, &ps invoke GdipCreateFromHDC,eax,&graphics invoke GdipSetSmoothingMode,graphics, SmoothingModeAntiAlias; Рисование со сглаживанием ; Заполненный прямоугольник invoke GdipCreateSolidFill,0FF0064FFh,&hBrush mov eax,vdyClient shr eax,1 mov [rsp+28h],rax;vdyClient/2 mov eax,vdxClient shr eax,1 mov [rsp+20h],rax;vdxClient/2 invoke GdipFillRectangleI,graphics,hBrush, 0, 0 ; Заполненный прямоугольник invoke GdipDeleteBrush,hBrush ; Толстая линия movd xmm1, const10;41200000h invoke GdipCreatePen1,0FFFF0091h, , UnitPixel, &hPen mov eax,vdyClient mov [rsp+28h],rax mov eax,vdxClient mov [rsp+20h],rax invoke GdipDrawLineI,graphics, hPen, 0, 0 invoke GdipDeletePen,hPen ; Прямоугольник с закругленными углами movd xmm1, const10 invoke GdipCreatePen1,9964FF00h,, UnitPixel, &hPen invoke GdipSetPenMode,hPen, PenAlignmentCenter invoke GdipSetPenLineJoin,hPen, LineJoinRound mov r9d,vdyClient shr r9d,2;vdyClient/4 mov r8d,vdxClient shr r8d,2;vdxClient/4 mov eax,r9d add eax,eax mov [rsp+28h],rax;2*vdyClient/4 mov eax,r8d add eax,eax mov [rsp+20h],rax;2*vdxClient/4 invoke GdipDrawRectangleI,graphics, hPen invoke GdipDeletePen,hPen ; пунктиром прямоугольник movd xmm1,const3;40400000h invoke GdipCreatePen1,0FF00FF91h,, UnitPixel, &hPen invoke GdipSetPenMode,hPen, PenAlignmentCenter; dashed pen invoke GdipSetPenDashArray,hPen, &f, 4 mov eax,vdyClient shr eax,1 mov [rsp+28h],rax;vdyClient/2 mov eax,vdxClient sub eax,3 mov [rsp+20h],rax;vdxClient-3 mov r8d,vdxClient shr r8d,1 inc r8d;vdxClient/2+1 invoke GdipDrawRectangleI,graphics, hPen, , 0 invoke GdipDeletePen,hPen ; Различные завершение линий movd xmm1, const7;40E00000h invoke GdipCreatePen1,0FF25FF73h, , UnitPixel, &hPen invoke GdipSetPenStartCap,hPen, LineCapRoundAnchor invoke GdipSetPenEndCap,hPen, LineCapArrowAnchor mov eax,const10 mov qword ptr[rsp+28h],10 mov eax,vdxClient sub eax,10 mov [rsp+20h],rax;vdxClient-10 mov r9d,vdyClient sub r9d,10;vdyClient-10 invoke GdipDrawLineI,graphics, hPen,10 invoke GdipDeletePen,hPen invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Рисование с помощью GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> f dd 1.0,1.0,2.0,2.0 const3 dd 3.0 const7 dd 7.0 const10 dd 10.0 .data? gdiplusToken dd ? graphics dq ? vdxClient dd ? vdyClient dd ? end Во вложении asm/exe/cur-файлы
Штриховые кисти в GDI+ Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 240 cdYSize = 240 HatchStyleTotal = 53 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT local graphics:qword local hBrush:qword local style:qword mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd, &ps invoke GdipCreateFromHDC,eax, &graphics and style,0 xor edi,edi @0: xor esi,esi @1: invoke GdipCreateHatchBrush,style,0FF000000h,0FFA0A0A0h, &hBrush mov qword ptr[rsp+28h],20 mov qword ptr[rsp+20h],20 invoke GdipFillRectangleI,graphics, hBrush, esi, edi invoke GdipDeleteBrush,hBrush inc style cmp style,HatchStyleTotal jb @f and style,0 @@: add esi,20 cmp esi,vdxClient jb @1 add edi,20 cmp edi,vdyClient jb @0 invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps jmp wmBYE wmSIZE: mov vdxClient,r9d and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) ; shr r9d,16 mov vdyClient,r9d; vdyClient = HIWORD (lParam) ; invoke InvalidateRect,hWnd, NULL,TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Штриховые кисти в GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> .data? gdiplusToken dd ? ; vdxClient dd ? ; vdyClient dd ? ; end Во вложении asm/exe/cur-файлы
Градиентные кисти и кисти с текстурным наполнениемКисти с градиентными цветами и текстура с изображениями в эллипсах и многоугольниках. Кисть с мелкими фигурками Pacman использована для заполнения эллипса. Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 240 cdYSize = 240 cdSizeSmPcman = 30 GpRect STRUCT X dd ? Y dd ? Width_ dd ? Height dd ? GpRect ENDS WrapModeTile = 0 LinearGradientModeHorizontal = 0 FillModeAlternate = 0 WrapModeClamp = 4 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_CREATE je wmCREATE cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke GdipDeleteBrush,myTextureBrush invoke GdipDeleteBrush,myLinearGradientBrush invoke GdipDeleteBrush,myPathBrush invoke GdipDeletePath,myPath invoke GdipDeletePath,tuPath invoke GdipDeleteBrush,tuPathBrush ;уничтожить объект GDI+ invoke GdipDeleteGraphics,graphics mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd, &ps invoke GdipCreateFromHDC,eax, &graphics mov rax,vdyClient shr eax,1 mov [rsp+28h],rax;vdyClient/2 mov rax,vdxClient shr eax,1 mov [rsp+20h],rax;vdxClient/2 invoke GdipFillEllipseI,graphics,myTextureBrush, 0, 0 mov rax,vdyClient shr eax,1 mov [rsp+28h],rax;vdyClient/2 mov r8,vdxClient shr r8,1;vdxClient/2 mov [rsp+20h],r8;vdxClient/2 invoke GdipFillEllipseI,graphics,myLinearGradientBrush,,0 mov rax,vdxClient shr eax,1 mov [rsp+28h],rax;vdxClient/2 mov r9,vdyClient shr r9,1;vdyClient/2 mov [rsp+28h],r9;vdyClient/2 invoke GdipFillEllipseI,graphics, myPathBrush, 0, invoke GdipFillPath,graphics, tuPathBrush, tuPath; Заполнение с помощью градиентной кисти invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps jmp wmBYE wmSIZE: mov vdxClient,r9 and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) ; shr r9d,16 mov vdyClient,r9; vdyClient = HIWORD (lParam) ; mov rax,vdxClient shr eax,1 mov myRect.X,eax;myRect.X = vdxClient/2; and myRect.Y,0;myRect.Y = 0; mov myRect.Width_,eax;myRect.Width = vdxClient/2; mov rax,vdyClient shr eax,1 mov myRect.Height,eax;myRect.Height = vdyClient/2; mov eax,cdYSize mov myPoints[0*8].y,eax;myPoints[0].Y = cdYSize mov myPoints[1*8].y,eax;myPoints[1].Y = cdYSize mov eax,cdYSize mov myPoints[1*8].x,eax;myPoints[1].X = cdXSize shr eax,1 mov myPoints[0*8].x,eax;myPoints[0].X = cdXSize/2; mov eax,cdXSize shr eax,2 lea eax,[eax+eax*2] mov myPoints[2*8].x,eax;myPoints[2].X = 3*cdXSize/4; and myPoints[2*8].y,0;myPoints[2].Y = 0; mov rax,vdxClient shr eax,2 lea eax,[eax+eax*2] mov pt[0*8].x,eax;pt[0].X = 3*vdxClient/4; mov pt[5*8].x,eax;pt[5].X = 3*vdxClient/4; mov rax,vdyClient shr eax,1 mov pt[0*8].y,eax;pt[0].Y = vdyClient/2 mov rax,vdxClient shr eax,4 imul eax,eax,13 mov pt[1*8].x,eax;pt[1].X = 13*vdxClient/16; mov rax,vdyClient mov pt[4*8].y,eax;pt[4].Y = vdyClient; mov pt[6*8].y,eax;pt[6].Y = vdyClient; shr eax,3 lea eax,[eax+eax*4] mov pt[1*8].y,eax;pt[1].Y = 5*vdyClient/8; mov pt[2*8].y,eax;pt[2].Y = 5*vdyClient/8; mov pt[8*8].y,eax;pt[8].Y = 5*vdyClient/8; mov pt[9*8].y,eax;pt[9].Y = 5*vdyClient/8; mov rax,vdxClient mov pt[2*8].x,eax;pt[2].X = vdxClient; mov rax,vdxClient mov pt[4*8].x,eax;pt[4].X = vdxClient; shr eax,3 imul eax,eax,7 mov pt[3*8].x,eax;pt[3].X = 7*vdxClient/8; mov rax,vdyClient shr eax,2 lea eax,[eax+eax*2] mov pt[3*8].y,eax;pt[3].Y = 3*vdyClient/4; mov pt[7*8].y,eax;pt[7].Y = 3*vdyClient/4; mov rax,vdyClient shr eax,3 imul eax,eax,7 mov pt[5*8].y,eax;pt[5].Y = 7*vdyClient/8; mov rax,vdxClient shr eax,1 mov pt[6*8].x,eax;pt[6].X = vdxClient/2; mov pt[8*8].x,eax;pt[8].X = vdxClient/2; mov rax,vdxClient shr eax,3 lea eax,[eax+eax*4] mov pt[7*8].x,eax; pt[7].X = 5*vdxClient/8; mov rax,vdxClient shr eax,4 imul eax,eax,11 mov pt[9*8].x,eax;pt[9].X = 11*vdxClient/16 lea eax,myLinearGradientBrush mov [rsp+28h],rax mov qword ptr[rsp+20h],WrapModeTile invoke GdipCreateLineBrushFromRectI,&myRect,0FF0000FFh,0FFFF0000h, LinearGradientModeHorizontal invoke GdipCreatePath,FillModeAlternate, &myPath mov r8,vdyClient shr r8d,1;vdyClient/2 mov [rsp+20h],r8;vdyClient/2 mov r9,vdxClient shr r9d,1;vdxClient/2 invoke GdipAddPathEllipseI,myPath, 0 invoke GdipCreatePathGradientFromPath,myPath, &myPathBrush invoke GdipSetPathGradientCenterColor,myPathBrush, 0FFFF00FFh mov rax,vdxClient cmp rax,vdyClient cmova rax,vdyClient shr eax,1 mov count,eax;count = min(vdxClient/2, vdyClient/2) invoke GdipSetPathGradientSurroundColorsWithCount,myPathBrush, &BorderColor, &count invoke GdipCreatePathGradientI,&myPoints[0], 3, WrapModeClamp, &PathGradient invoke GdipSetLinePresetBlend,PathGradient, &PresetColors[0], &InterpPositions[0], 3 invoke GdipCreatePath,FillModeAlternate, &tuPath; Создать объект GraphicsPath invoke GdipAddPathLine2I,tuPath, &pt, (sizeof pt/(sizeof POINT)); Использовать массив точек для построения пути invoke GdipCreatePathGradientFromPath,tuPath, &tuPathBrush; Использовать путь для создания градиентной кисти invoke GdipSetPathGradientCenterColor,tuPathBrush,0FFFF0000h; Установить красный цвет в центре пути. invoke GdipSetPathGradientSurroundColorsWithCount,tuPathBrush, &Colors[0], &numCols invoke InvalidateRect,hWnd, NULL, TRUE jmp wmBYE wmCREATE:invoke GdipLoadImageFromFile,&FileName, &myImage invoke GetDC,hWnd invoke GdipCreateFromHDC,eax, &graphics invoke GdipCreateBitmapFromGraphics,cdSizeSmPcman, cdSizeSmPcman, graphics, &smBitmap invoke GdipGetImageGraphicsContext,smBitmap, &memGraphics invoke GdipDrawImageRectI,memGraphics, myImage, 0, 0,cdSizeSmPcman, cdSizeSmPcman; x, y координаты верхней точки, где поместим изображение invoke GdipCreateTexture,smBitmap, WrapModeTile, &myTextureBrush invoke GdipDeleteGraphics,smBitmap invoke GdipDisposeImage,myImage wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Рисование с помощью GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> PresetColors dd 0FFFFFF00h,0FFFF0000h,0FF00FF00h Colors dd 0FFFF0000h,0FFFFFF00h,0FF00FF00h,0FFFFFF00h,0FF00FFFFh,\ 0FFFFFF00h,0FF00FF00h,0FFFFFF00h,0FF00FFFFh,0FFFFFF00h InterpPositions dd 0, 0.5, 1.0 numCols dd 10 BorderColor dd 0FF80FFFFh FileName: du <Comecocos.bmp> .data? myImage dq ? myTextureBrush dq ? smBitmap dq ? myLinearGradientBrush dq ? myPath dq ? tuPath dq ? myPathBrush dq ? PathGradient dq ? tuPathBrush dq ? myRect GpRect <> memGraphics dq ? myPoints POINT 3 dup(<>) pt POINT 10 dup(<>) count dd ? gdiplusToken dd ? vdxClient dq ? vdyClient dq ? graphics dq ? end Во вложении asm/exe/cur/bmp-файлы
Изменить размер изображения с помощью GDI+Исходное изображение — это большая картинка слева, размер которой изменен в memGraphics с помощью GdipDrawImageRectI, которая использована для создания кисти с маленькими Пакманами, которая использована для заполнения эллипса. Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 400 cdYSize = 300 WrapModeTile = 0 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN cmp edx,WM_CREATE je wmCREATE leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke GdipDisposeImage,hBitmap invoke GdipDeleteGraphics,memGraphics ;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd, &ps invoke GdipCreateFromHDC,eax, &graphics invoke GdipDrawImage,graphics, hBitmap, 0, 0 mov r8,nWidth add r8d,20;nWidth+20 invoke GdipDrawImageI,graphics, smBitmap,, 0 mov r8,nWidth mov [rsp+20h],r8 mov r9,nHeight mov [rsp+28h],r9 shr r9d,2;nHeight/4 invoke GdipFillEllipseI,graphics, myTextureBrush invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd, &graphics invoke GdipLoadImageFromFile,&FileName, &hBitmap invoke GdipCreateBitmapFromGraphics,40, 40, graphics, &smBitmap invoke GdipGetImageWidth,hBitmap, &nWidth invoke GdipGetImageHeight,hBitmap, &nHeight invoke GdipGetImageGraphicsContext,smBitmap, &memGraphics mov qword ptr[rsp+28h],40 ; x-size mov qword ptr[rsp+20h],40 ; y-size invoke GdipDrawImageRectI,memGraphics, hBitmap, 0, 0; x, y координаты верхней точки, куда поместим изображение invoke GdipCreateTexture,smBitmap, WrapModeTile, &myTextureBrush invoke GdipDeleteGraphics,graphics jmp wmBYE wmSIZE: mov vdxClient,r9d and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) ; shr r9d,16 mov vdyClient,r9d; vdyClient = HIWORD (lParam) ; invoke InvalidateRect,hWnd, NULL,TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Изменить размер изображения с помощью GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> FileName: du <Comecocos.bmp> .data? gdiplusToken dd ? ; myTextureBrush dq ? memGraphics dq ? hBitmap dq ? vdxClient dd ? ; vdyClient dd ? ; nWidth dq ? nHeight dq ? smBitmap dq ? graphics dq ? end Во вложении asm/exe/cur/bmp-файлы
Загрузить bmp из ресурсов с помощью GDI+Используется функция GdipCreateBitmapFromResource. Окно создается с учетом размеров растрового изображения. Размер растрового изображения изменяется в соответствии с размерами окна. asm-файл Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 400 cdYSize = 300 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN cmp edx,WM_CREATE je wmCREATE leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke GdipDisposeImage,hBitmap invoke GdipDeleteGraphics,graphics ;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke GdipDrawImageRectI,graphics, hBitmap, 0, 0, nWidth, nHeight jmp wmBYE wmCREATE:invoke GdipCreateFromHWND,hWnd, &graphics invoke GdipCreateBitmapFromResource,IMAGE_BASE,&szRsName,&hBitmap invoke GdipGetImageWidth,hBitmap, &nWidth invoke GdipGetImageHeight,hBitmap, &nHeight jmp wmBYE wmSIZE: invoke InvalidateRect,hWnd, NULL,TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Загрузить bmp из ресурсов с помощью GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> szRsName: du <MAIN_BMP> .data? gdiplusToken dd ? ; hBitmap dq ? nWidth dq ? nHeight dq ? graphics dq ? end rc-файл Код (C): MAIN_BMP BITMAP Comecocos.bmp Во вложении asm/exe/cur/rc/bmp-файлы
Вывод текста с помощью GDI+Текст всегда будет центрирован, так как установлено выравнивание StringAlignmentCenter Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 300 cdYSize = 200 UnitPixel = 2 SmoothingModeAntiAlias = 4 StringAlignmentCenter = 1 FontStyleBold = 1 RectF struct X dd ? Y dd ? Width_ dd ? Height dd ? RectF ends .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@:invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN cmp edx,WM_CREATE je wmCREATE leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke GdipDeleteBrush,hBrush invoke GdipDisposeImage,hBitmap ;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd,&ps invoke GdipCreateFromHDC,eax,&graphics invoke GdipSetPageUnit,graphics,UnitPixel mov eax,nHeight mov [rsp+28h],rax mov eax,nWidth mov [rsp+20h],rax invoke GdipDrawImageRectI,graphics,hBitmap,0,0 ; Загружаем фоновое изображение и растягиваем его на все окно invoke GdipSetSmoothingMode,graphics, SmoothingModeAntiAlias; Рисование со сглаживанием invoke GdipDrawString,graphics,szMensaje,-1,hFont,&rect,hStringFormat, hBrush invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipLoadImageFromFile,&FileName, &hBitmap invoke GdipCreateStringFormat,0, 0, &hStringFormat invoke GdipSetStringFormatAlign,hStringFormat, StringAlignmentCenter invoke GdipSetStringFormatLineAlign,hStringFormat, StringAlignmentCenter invoke GdipCreateFontFamilyFromName,&FontName, 0, &hFontFamily movd xmm1,cdemSize invoke GdipCreateFont,hFontFamily, , FontStyleBold, 3, &hFont invoke GdipDeleteFontFamily,hFontFamily invoke GdipCreateSolidFill,0FF0000FFh, &hBrush jmp wmBYE wmSIZE: mov eax,r9d and eax,0FFFFh mov nWidth,eax cvtsi2ss xmm0,eax movd rect.Width_,xmm0;rect.Width = (float) LOWORD (lParam) ; shr r9d,10h mov nHeight,r9d cvtsi2ss xmm0,r9d movd rect.Height,xmm0;rect.Height = (float) HIWORD (lParam) invoke InvalidateRect,hWnd, NULL,TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Вывод текста в GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> szMensaje: du <Привет из GDI+> rect RectF <0,0,0,0> FontName: du <Tahoma> FileName: du <Backgrnd.gif> cdemSize dd 36.0 .data? gdiplusToken dd ? hBitmap dq ? hStringFormat dq ? hFont dq ? hFontFamily dq ? hBrush dq ? graphics dq ? nWidth dd ? nHeight dd ? end Во вложении asm/exe/cur/gif-файлы
Рисование сплайнов в GDI+ Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 340 cdYSize = 400 SmoothingModeAntiAlias = 4 PointF struct X dd ? Y dd ? PointF ends .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT local hPen:qword mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd,&ps invoke GdipCreateFromHDC,eax,&graphics invoke GdipSetSmoothingMode,graphics, SmoothingModeAntiAlias; Рисование со сглаживанием movd xmm1,cdPenWith invoke GdipCreatePen1,0FFFF0000h, ,2,&hPen invoke GdipSetPenLineJoin,hPen, 0 invoke GdipDrawCurve,graphics, hPen, &mtPuntos[0*8], (sizeof mtPuntos)/(sizeof PointF); invoke GdipDeletePen,hPen invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd,&ps wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Рисование сплайнов в GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> mtPuntos PointF <300.0, 40.0>, <100.0, 80.0>, <200.0, 120.0>, <50.0, 160.0>, <90.0, 195.726405817773>, <100.0, 113.562336350022>,<110.0, 180.236093561674>, <120.0, 183.205669204542>, <130.0, 147.408057803263>, <140.0, 179.066485842909>,<150.0, 296.488263212844>, <160.0, 295.763813340541>, <170.0, 330.941617453638>, <180.0, 112.155812175893>,<190.0, 306.762179445474>, <200.0, 55.8951339964604>, <210.0, 230.641779238024>, <220.0, 17.4446966322051> cdPenWith dd 4.0 .data? gdiplusToken dd ? ; graphics dq ? vdxClient dq ? vdyClient dq ? end Во вложении asm/exe/cur-файлы
Вращение фигуры в GDI+ Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 250 cdYSize = 200 width_ = 155 height = 5 cdIdTimer = 1 MatrixOrderAppend = 1 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local memGraphics:qword local hbmpBuf:qword local graphics:qword local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_TIMER je wmTIMER cmp edx,WM_SIZE je wmSIZE cmp edx,WM_CREATE je wmCREATE cmp edx,WM_KEYDOWN je wmKEYDOWN cmp edx,WM_PAINT je wmPAINT leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke KillTimer,hWnd, cdIdTimer invoke GdipDeleteBrush,hBrush mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd, &ps invoke GdipCreateFromHDC,eax,&graphics ;---------------------------------------- ; Создаем двойной буфер в medGraphics, связанный с hbmpBuf mov ecx,vdxClient mov edx,vdyClient invoke GdipCreateBitmapFromGraphics,,,graphics, &hbmpBuf invoke GdipGetImageGraphicsContext,hbmpBuf, &memGraphics ;------------------------------------------ invoke GdipGraphicsClear,memGraphics,0FFFFFFFFh; Очистить буфер mov eax,centrex neg eax cvtsi2ss xmm1,eax;(float)-centrex mov eax,centrey neg eax cvtsi2ss xmm2,eax;(float)-centrey invoke GdipTranslateWorldTransform,memGraphics,,,MatrixOrderAppend cvtsi2ss xmm1,iAng;(float)iAng invoke GdipRotateWorldTransform,memGraphics,,MatrixOrderAppend cvtsi2ss xmm1,centrex;(float)centrex cvtsi2ss xmm2,centrey;(float)centrey invoke GdipTranslateWorldTransform,memGraphics,,,MatrixOrderAppend mov qword ptr[rsp+28h],height mov qword ptr[rsp+20h],width_ mov r9d,topy mov r8d,topx invoke GdipFillRectangleI,memGraphics, hBrush; Заполненный прямоугольник ; Выводим содержимое буфера на экран (hGraphics) mov qword ptr[rsp+40h],2 mov eax,vdyClient mov qword ptr[rsp+38h],rax;cdYSize mov eax,vdxClient mov qword ptr[rsp+30h],rax xor r8,r8 mov [rsp+28h],r8 mov [rsp+20h],r8 invoke GdipDrawImagePointRectI,graphics, hbmpBuf,,0 invoke GdipDisposeImage,hbmpBuf invoke GdipDeleteGraphics,memGraphics invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps jmp wmBYE wmCREATE:invoke SetTimer,hWnd, cdIdTimer, 200, NULL invoke GdipCreateSolidFill,0FF0000FFh,&hBrush jmp wmBYE wmSIZE: mov vdxClient,r9d and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) shr r9d,16 mov vdyClient,r9d;vdyClient = HIWORD (lParam) ; shr r9d,1 mov centrey,r9d;centrey=vdyClient/2 mov eax,vdxClient mov ecx,eax shr ecx,1 mov centrex,ecx;centrex=vdxClient/2 sub eax,width_ jns @f neg eax @@: shr eax,1 mov topx,eax;topx = (vdxClient-width)/2, mov eax,vdyClient sub eax,height shr eax,1 mov topy,eax;topy = (vdyClient-height)/2; jmp wmBYE wmTIMER:mov eax,iAng add eax,20 cmp eax,360;101101000 jb @f xor eax,eax @@: mov iAng,eax invoke InvalidateRect,hWnd, NULL, TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Вращение фигуры в GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> const2 dd 2.0 iAng dd 0 .data? gdiplusToken dd ? vdxClient dd ? vdyClient dd ? hBrush dq ? topx dd ? topy dd ? centrex dd ? centrey dd ? end Во вложении asm/exe/cur-файлы
Вращение фигуры в GDI+ Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 320 cdYSize = 220 SmoothingModeInvalid = 0 SmoothingModeDefault = 1 SmoothingModeHighSpeed = 2 SmoothingModeHighQuality = 3 SmoothingModeNone = 4 SmoothingModeAntiAlias = 5 SmoothingModeAntiAlias8x4 = 6 SmoothingModeAntiAlias8x8 = 7 .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local hdc:HDC ; local ps:PAINTSTRUCT local hGraphics:qword local hBrush:qword mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_PAINT je wmPAINT cmp edx,WM_SIZE je wmSIZE cmp edx,WM_KEYDOWN je wmKEYDOWN leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmSIZE: mov vdxClient,r9d and vdxClient,0FFFFh;vdxClient = LOWORD (lParam) shr r9d,16 mov vdyClient,r9d;vdyClient = HIWORD (lParam) ; invoke InvalidateRect,hWnd, NULL, TRUE jmp wmBYE wmPAINT:invoke BeginPaint,hWnd, &ps mov hdc,rax invoke GdipCreateFromHDC,eax,&graphics invoke GdipSetSmoothingMode,graphics, SmoothingModeAntiAlias; Рисование со сглаживанием ; Заполненный прямоугольник invoke GdipCreateSolidFill,0FF0000FFh,&hBrush xor edi,edi @@: cvtsi2ss xmm1,edi invoke GdipRotateWorldTransform,graphics,, 1 cvtsi2ss xmm1,vdxClient divss xmm1,const2; (float)vdxClient/2.0 cvtsi2ss xmm2,vdyClient divss xmm2,const2;(float)vdyClient/2.0 invoke GdipTranslateWorldTransform,graphics,,,1 mov r8d,10 mov [rsp+28h],r8 mov qword ptr[rsp+20h], 70 invoke GdipFillRectangleI,graphics, hBrush,,10; Заполненный прямоугольник invoke GdipResetWorldTransform,graphics add edi,40 cmp edi,360 jb @b invoke GdipDeleteBrush,hBrush invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd, &ps wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Вращение фигуры GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> const2 dd 2.0 .data? gdiplusToken dd ? graphics dq ? vdxClient dd ? vdyClient dd ? end Во вложении asm/exe/cur-файлы
Вращение текста в GDI+Вращение выполняется функцией GdipRotateWorldTransform, перемещение — с помощью GdipRotateWorldTransform, что необходимо, если мы не хотим, чтобы объект вращался на экране вокруг точки (0,0) . Поскольку вращение является инкрементным, необходимо сбросить его в начало координат с помощью GdipResetWorldTransform. Выравнивание шрифта установлено с помощью StringAlignmentNear. При изменении размера экрана созданная фигура будет располагаться по центру. Код (ASM): ; GUI # include win64a.inc cdXPos = 128 cdYPos = 128 cdXSize = 450 cdYSize = 400 MatrixOrderAppend = 1 UnitPixel = 2 SmoothingModeAntiAlias = 4 StringAlignmentCenter = 1 FontStyleBold = 1 RectF struct X dd ? Y dd ? Width_ dd ? Height dd ? RectF ends .code WinMain proc local msg:MSG ;инициализация библиотеки GDIPLUS invoke GdiplusStartup,&gdiplusToken,&gsi,0 xor ebx,ebx mov esi,IMAGE_BASE invoke LoadCursorFromFileA,"br_Rabbit3.cur" mov edi,offset ClassName push rax ;hIconSm push rdi ;lpszClassName push rbx ;lpszMenuName push COLOR_BTNFACE;hbrBackground push rax ;hCursor push rax ;hIcon push rsi ;hInstance push rbx ;cbClsExtra & cbWndExtra pushaddr WndProc ;lpfnWndProc push sizeof WNDCLASSEX;cbSize & style invoke RegisterClassExA,esp ;addr WNDCLASSEX push rbx push rsi ;rsi=400000h push rbx push rbx push cdYSize push cdXSize push cdYPos push cdXPos sub esp,20h invoke CreateWindowExA,0,edi,edi,WS_OVERLAPPEDWINDOW or WS_VISIBLE lea edi,msg @@: invoke GetMessageA,edi,NULL,0,0 invoke DispatchMessageA,edi jmp @b WinMain endp WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD local ps:PAINTSTRUCT mov hWnd,rcx cmp edx,WM_DESTROY je wmDESTROY cmp edx,WM_SIZE je wmSIZE cmp edx,WM_PAINT je wmPAINT cmp edx,WM_KEYDOWN je wmKEYDOWN cmp edx,WM_CREATE je wmCREATE leave jmp NtdllDefWindowProc_ wmKEYDOWN:mov al,r8b;wParam cmp al,VK_ESCAPE;user press 'Esc'? jne wmBYE wmDESTROY:invoke GdipDeleteBrush,hBrush ;уничтожить объект GDI+ mov ecx,gdiplusToken invoke GdiplusShutdown invoke RtlExitUserProcess,NULL ;------------------------------------------------------------ wmPAINT:invoke BeginPaint,hWnd,&ps invoke GdipCreateFromHDC,eax,&graphics xor edi,edi @@: cvtsi2ss xmm1,edi ;Вращение достигается с помощью GdipRotateWorldTransform ;перемещение — с помощью GdipTranslateWorldTransform invoke GdipRotateWorldTransform,graphics,, 1 cvtsi2ss xmm1,nWidth divss xmm1,const2; (float)vdxClient/2.0 cvtsi2ss xmm2,nHeight divss xmm2,const2;(float)vdyClient/2.0 invoke GdipTranslateWorldTransform,graphics,,,MatrixOrderAppend invoke GdipDrawString,graphics,szMensaje,-1,hFont,&rect,hStringFormat, hBrush invoke GdipResetWorldTransform,graphics add edi,30 cmp edi,360 jb @b invoke GdipDeleteGraphics,graphics invoke EndPaint,hWnd,&ps jmp wmBYE wmCREATE:invoke GdipCreateStringFormat,0, 0, &hStringFormat invoke GdipSetStringFormatAlign,hStringFormat, StringAlignmentCenter invoke GdipSetStringFormatLineAlign,hStringFormat, StringAlignmentCenter invoke GdipCreateFontFamilyFromName,&FontName, 0, &hFontFamily movd xmm1,cdemSize invoke GdipCreateFont,hFontFamily, , FontStyleBold, 3, &hFont invoke GdipDeleteFontFamily,hFontFamily invoke GdipCreateSolidFill,0FF0000FFh, &hBrush jmp wmBYE wmSIZE: mov eax,r9d and eax,0FFFFh mov nWidth,eax cvtsi2ss xmm0,eax movd rect.Width_,xmm0;rect.Width = (float) LOWORD (lParam) ; divss xmm0,const_4 movd rect.X,xmm0 shr r9d,10h mov nHeight,r9d cvtsi2ss xmm0,r9d movd rect.Height,xmm0;rect.Height = (float) HIWORD (lParam) divss xmm0,const_4 movd rect.Y,xmm0 invoke InvalidateRect,hWnd, NULL,TRUE wmBYE: leave ret WndProc endp ;--------------------------------------- .data ClassName db 'Вращение текста в GDI+',0 gsi GdiplusStartupInput <1,0,0,0,0> szMensaje: du <Привет из GDI+> FontName: du <Tahoma> cdemSize dd 18.0 const2 dd 2.0 const_4 dd -4.0 .data? gdiplusToken dd ? hStringFormat dq ? hFont dq ? hFontFamily dq ? hBrush dq ? graphics dq ? nWidth dd ? nHeight dd ? rect RectF <> end Во вложении asm/exe/cur-файлы