Ассемблер для Windows



         

Этот раздел главы посвящается графике - часть 3


WNDCLASS STRUC CLSSTYLE DD ? ; стиль окна CLSLPFNWNDPROC DD ? ; указатель на процедуру окна CLSCBCLSEXTRA DD ? ; информация о доп. байтах для ; данной структуры

CLSCBWNDEXTRA DD ? ; информация о доп. байтах для окна CLSHINSTANCE DD ? ; дескриптор приложения CLSHICON DD ? ; идентификатор иконы окна CLSHCURSOR DD ? ; идентификатор курсора окна CLSHBRBACKGROUND DD ? ; идентификатор кисти окна MENNAME DD ? ; имя-идентификатор меню CLSNAME DD ? ; специфицирует имя класса окон WNDCLASS ENDS

PAINTSTR STRUC hdc DD 0 fErase DD 0 left DD 0 top DD 0 right DD 0 bottom DD 0 fRes DD 0 fIncUp DD 0 Reserv DB 32 dup(0) PAINTSTR ENDS

RECT STRUC L DD ? ; Х-левого верхнего угла T DD ? ; Y-левого верхнего угла R DD ? ; Х- правого нижнего угла B DD ? ; Y- правого нижнего угла RECT ENDS

; файл graph.asm .386P ; плоская модель .MODEL FLAT, stdcall ;------------------------------------------------------------------ include graph1.inc ; подключения библиотек includelib c:\masm32\iib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\gdi32.lib ;------------------------------------------------------------------ ; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' NEWHWND DWORD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> PNT PAINTSTR <?> HINST DWORD 0 TITLENAME BYTE 'Графика в окне',0 NAM BYTE 'CLASS32',0 XT DWORD 30 YT DWORD 30 XM DWORD ? YM DWORD ? HDC DWORD ? MEMDC DWORD ? HPEN DWORD ? HBRUSH DWORD ? P DWORD 0 ; признак вывода XP DWORD ? YP DWORD ? _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX REG_CLASS: ; заполнить структуру окна ; стиль MOV [WC.CLSSTYLE],stylcl ; процедура обработки сообщений MOV [WC.CLSLPFNWNDPROC], OFFSET WNDPROC MOV [WC.CLSCBCLSEXTRA],0 MOV [WC.CLSCBWNDEXTRA], 0 MOV EAX, [HINST] MOV [WC.CLSHINSTANCE], EAX ; ----------иконка окна PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA@8 MOV [WC.CLSHICON], EAX ; ----------курсор окна PUSH IDC_CROSS PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHCURSOR], EAX ;----------- PUSH RGBW ; цвет кисти CALL CreateSolidBrush@4 ; создать кисть MOV [WC.CLSHBRBACKGROUND], EAX MOV DWORD PTR [WC.MENNAME],0 MOV DWORD PTR [WC.CLSNAME], OFFSET NAM PUSH OFFSET WC CALL RegisterClassA@4 ; создать окно зарегистрированного класса PUSH 0 PUSH [HINST] PUSH 0 PUSH 0 PUSH DY0 ; DYO - высота окна PUSH DX0 ; DXO - ширина окна PUSH 100 ; координата Y PUSH 100 ; координата X PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; имя окна PUSH OFFSET NAM ; имя класса PUSH 0 CALL CreateWindowExA@48 ; проверка на ошибку CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX ; дескриптор окна ;------------------------------------------------------------ PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow@8 ; показать созданное окно ;------------------------------------------------------------ PUSH [NEWHWND] CALL UpdateWindow@4 ; перерисовать видимую часть окна ; петля обработки сообщений MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA@16 CMP AX, 0 JE END_LOOP PUSH OFFSET MSG CALL TranslateMessage@4 PUSH OFFSET MSG CALL DispatchMessageA@4 JMP MSG_LOOP END_LOOP: ; выход из программы (закрыть процесс) PUSH [MSG.MSWPARAM] CALL ExitProcess@4 _ERR: JMP END_LOOP ;------------------------------------------------------------ ; процедура окна ; расположение параметров в стеке ; [EBP+014Н] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ; MES ; [EBP+8] ; HWND WNDPROC PROC PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI PUSH EDI CMP DWORD PTR [EBP+0CH],WM_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH],WM_CREATE JE WMCREATE CMP DWORD PTR [EBP+0CH],WM_PAINT JE WMPAINT CMP DWORD PTR [EBP+0CH],WM_LBUTTONDOWN JE LBUTTON JMP DEFWNDPROC LBUTTON: CMP P,0 JNE F1 ; линия точками (горизонтальная) MOV YP,50 ; Y MOV XP,10 ; X MOV ECX,200 LL: PUSH ECX PUSH RGBP PUSH YP PUSH XP PUSH MEMDC CALL SetPixel@16 INC XP POP ECX LOOP LL INC P JMP F3 F1: CMP P,1 JNE F2 ; вначале установим текущие координаты на конец ; предыдущей линии PUSH 0 PUSH YP PUSH XP PUSH MEMDC CALL MoveToEx@16 ; линия пером PUSH 300 PUSH 550 PUSH MEMDC CALL LineTo@12 INC P JMP F3 F2: CMP P,2 JNE FIN ; замкнутая фигура - прямоугольник ; вначале выбрать кисть для заполнения области PUSH HBRUSH PUSH MEMDC CALL SelectObject@8 ; теперь рисуем заполненный прямоугольник если не выбирать ; кисть, то будет нарисован незаполненный прямоугольник PUSH 350 PUSH 400 PUSH 200 PUSH 200 PUSH MEMDC CALL Rectangle@20 INC P F3: ; дать команду перерисовать окно PUSH 0 PUSH OFFSET RECT PUSH DWORD PTR [EBP+08H] CALL InvalidateRect@12 FIN: MOV EAX, 0 JMP FINISH WMPAINT: PUSH OFFSET PNT PUSH DWORD PTR [EBP+08H] CALL BeginPaint@8 MOV HDC,EAX ; сохранить контекст (дескриптор) ; скопировать виртуальное окно на реальное PUSH 0CC0020h ; SRCCOPY=изображение как есть PUSH 0 ; у-источника PUSH 0 ; х-источника PUSH MEMDC ; контекст источника PUSH YM ; высота - куда PUSH XM ; ширина - куда PUSH 0 ; у - куда PUSH 0 ; х-куда PUSH HDC ; контекст - куда CALL BitBlt@36 ;---------------- закрыть контекст окна PUSH OFFSET PNT PUSH DWORD PTR [EBP+08H] CALL EndPaint@8 MOV EAX, 0 JMP FINISH WMCREATE: ; размеры экрана PUSH 0 ; X CALL GetSystemMetrics@4 MOV XM, EAX PUSH 1 ; Y CALL GetSystemMetrics@4 MOV YM, EAX ; открыть контекст окна PUSH DWORD PTR [EBP+08H] CALL GetDC@4 MOV HDC,EAX ; создать совместимый с данным окном контекст PUSH EAX CALL CreateCompatibleDC@4 MOV MEMDC, EAX ; создать в памяти растровое изображение, совместимое с hdc PUSH YM PUSH XM PUSH HDC CALL CreateCompatibleBitmap@12 ; выбрать растровое изображение в данном контексте PUSH EAX PUSH MEMDC CALL SelectObject@8 ; цвет кисти PUSH RGBW CALL CreateSolidBrush@4 ; создать кисть ; выбрать кисть в данном контексте PUSH EAX PUSH MEMDC CALL SelectObject@8 ; заполнить данную прямоугольную область PUSH 0F00021h ; РАТСОРУ=заполнить данным цветом PUSH YM PUSH XM PUSH 0 PUSH 0 PUSH MEMDC CALL PatBlt@24 ; создать кисть и перо для рисования ; цвет кисти PUSH RGBR CALL CreateSolidBrush@4 ; создать кисть MOV HBRUSH,EAX ; задать перо PUSH RGBR ; цвет PUSH 0 ; толщина=1 PUSH 0 ; сплошная линия CALL CreatePen@12 MOV HPEN, EAX ; удалить контекст PUSH HDC PUSH DWORD PTR [EBP+08H] CALL ReleaseDC@8 MOV EAX, 0 JMP FINISH DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA@16 JMP FINISH WMDESTROY: ; удалить перо PUSH HPEN CALL DeleteDC@4 ; удалить кисть PUSH HBRUSH CALL DeleteDC@4 ; удалить виртуальное окно PUSH MEMDC CALL DeleteDC@4 ; выход PUSH 0 CALL PostQuitMessage@4 ; WM_QUIT MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START




Содержание  Назад  Вперед