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



         

Глава Экскурс в битное программирование - часть 3


ML /c prog.asm LINK prog,prog,,libw (вопрос о файле .def можно проигнорировать)

.286 .DOSSEG ; порядок сегментов согласно соглашению Microsoft DGROUP GROUP DATA, STA ASSUME CS: CODE, DS: DGROUP

;прототипы внешних процедур EXTRN INITTASK:FAR EXTRN INITAPP:FAR EXTRN WAITEVENT:FAR EXTRN DOS3CALL:FAR EXTRN REGISTERCLASS:FAR EXTRN LOADCURSOR:FAR EXTRN GETSTOCKOBJECT:FAR EXTRN GETMESSAGE:FAR EXTRN TRANSLATEMESSAGE:FAR EXTRN DISPATCHMESSAGE:FAR EXTRN CREATEWINDOW:FAR EXTRN CREATEWINDOWEX:FAR EXTRN UPDATEWINDOW:FAR EXTRN SHOWWINDOW:FAR EXTRN POSTQUITMESSAGE:FAR EXTRN DEFWINDOWPROC:FAR

; шаблоны

WNDCL STRUCT STYLE DW 0 ; стиль класса окна LPFNWNDPROC DD 0 ; указатель на процедуру обработки CBCLSEXTRA DW 0 CBWNDEXTRA DW 0 HINSTANCE DW 0 HICON DW 0 HCURSOR DW 0 HBRBACKGROUND DW 0 LPSZMENUNAME DD 0 ; указатель на строку LPSZCLASSNAME DD 0 ; указатель на строку WNDCL ENDS ; MESSA STRUCT HWND DW ? MESSAGE DW ? WPARAM DW ? LPARAM DD ? TIME DW ? X DW ? Y DW ? MESSA ENDS

; сегмент стека STA SEGMENT STACK 'STACK' DW 2000 DUP(?) STA ENDS

; сегмент данных DATA SEGMENT WORD 'DATA' ; в начале 16 байт — резерв, необходимый 16-ти битному ; приложению для правильной работы в среде Windows DWORD 0 WORD 5 WORD 5 DUP (0) HPREV DW ? HINST DW ? LPSZCMD DD ? CMDSHOW DW ? ; структура для создания класса WNDCLASS WNDCL <> ; структура сообщения MSG MESSA <> ;имя класса окна CLAS_NAME DB 'PRIVET',0 ; заголовок окна APP_NAME DB '16-битная программа',0 ; тип курсора CURSOR EQU 00007F00H ; стиль окна STYLE EQU 000CF0000H ; параметры окна XSTART DW 100 YSTART DW 100 DXCLIENT DW 300 DYCLIENT DW 200 DATA ENDS

; сегмент кода CODE SEGMENT WORD 'CODE' _BEGIN: ; I. Начальный код CALL INITTASK ; инициализировать задачу OR AX, AX ; CX - границы стека (!!! CX или AX ????) JZ _ERR MOV HPREV, SI ; номер предыдущего прил. MOV HINST, DI ; номер для новой задачи MOV WORD PTR LPSZCMD, BX ; ES:BX - адрес MOV WORD PTR LPSZCMD+2,ES ; командной строки MOV CMDSHOW, DX ; экранный параметр PUSH 0 ; текущая задача CALL WAITEVENT ; очистить очередь событий PUSH HINST CALL INITAPP ; инициализировать приложения OR AX, AX JZ _ERR CALL MAIN ; запуск основной части _TO_OS: MOV AH,4CH INT 21H ; выйти из программы _ERR: ; здесь можно поставить сообщение об ошибке JMP SHORT _TO_OS ; основная процедура ;************************************************************ MAIN PROC ; II. Регистрация класса окна ; стиль окна NULL — стандартное окно MOV WNDCLASS.STYLE, 0 ; процедура обработки LEA BX,WNDPROC MOV WORD PTR WNDCLASS.LPFNWNDPROC, BX MOV BX,CS MOV WORD PTR WNDCLASS.LPFNWNDPROC+2, BX ;------------------------------------------------------------ ; резервные байты в конце резервируемой структуры MOV WNDCLASS.CBCLSEXTRA, 0 ; резервные байты в конце структуры для каждого окна MOV WNDCLASS.CBWNDEXTRA, 0 ; иконка окна отсутствует MOV WNDCLASS.HICON, 0 ; номер запускаемой задачи MOV AX, HINST MOV WNDCLASS.HINSTANCE,AX ; определить номер стандартного курсора PUSH 0 PUSH DS PUSH CURSOR CALL LOADCURSOR MOV WNDCLASS.HCURSOR, AX ; определить номер стандартного объекта PUSH 0 ; WHITE_BRUSH CALL GETSTOCKOBJECT ; цвет фона MOV WNDCLASS.HBRBACKGROUND, AX ; имя меню из файла ресурсов (отсутствует = NULL) MOV WORD PTR WNDCLASS.LPSZMENUNAME, 0 MOV WORD PTR WNDCLASS.LPSZMENUNAME+2,0 ; указатель на строку, содержащую имя класса LEA BX,CLAS_NAME MOV WORD PTR WNDCLASS.LPSZCLASSNAME,BX MOV WORD PTR WNDCLASS.LPSZCLASSNAME+2,DS ; вызов процедуры регистрации PUSH DS ; указатель на LEA DI,WNDCLASS PUSH DI ; структуры WNDCLASS CALL REGISTERCLASS CMP AX,0 JNZ _OK1 ; ошибка регистрации RET ; ошибка при регистрации _OK1: ; III. Создание окна ; адрес строки-имени класса окна PUSH DS LEA BX,CLAS_NAME PUSH BX ; адрес строки-заголовка окна PUSH DS LEA BX,APP_NAME PUSH BX ; стиль окна MOV BX,HIGHWORD STYLE PUSH BX MOV BX,LOWWORD STYLE PUSH BX ; координата X левого верхнего угла PUSH XSTART ; координата Y левого верхнего угла PUSH YSTART ; ширина окна PUSH DXCLIENT ; высота окна PUSH DYCLIENT ; номер окна-родителя PUSH 0 ; номер (идентификатор) меню окна PUSH 0 ; NULL ; номер задачи PUSH HINST ; адрес блока параметров окна (нет) PUSH 0 PUSH 0 CALL CREATEWINDOW CMP AX,0 JNZ NO_NULL ; ошибка создания окна RET ; ошибка при создании окна ; установка для окна состояния видимости ; (окно или пиктограмма) ; согласно параметру CMDSHOW ; и его отображение NO_NULL: MOV SI,AX PUSH SI PUSH CMDSHOW CALL SHOWWINDOW ; посылка команды обновления области окна (команда WM_PAINT) ; сообщение посылается непосредственно окну PUSH SI CALL UPDATEWINDOW ; IV. Цикл ожидания LOOP1: ; извлечение сообщения из очереди PUSH DS LEA BX,MSG ; указатель на структуру PUSH BX ; сообщения PUSH 0 PUSH 0 PUSH 0 CALL GETMESSAGE ; проверка — не получено сообщение "выход" CMP AX,0 JZ NO_LOOP1 ; перевод всех пришедших сообщений к стандарту ANSI PUSH DS LEA BX,MSG PUSH BX CALL TRANSLATEMESSAGE ; указать WINDOWS ; передать данное сообщение соответствующему окну PUSH DS LEA BX,MSG PUSH BX CALL DISPATCHMESSAGE ; замкнуть цикл (петлю) JMP SHORT LOOP1 NO_LOOP1: RET MAIN ENDP




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