On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru






 

Создание окна на Ассемблере в Windows

Основные шаги при создании окна:
1. Получить дискриптор Вашей программы(обязательно)
2. Получить указатель на командную строку(не обязательно)
3. Зарегистрировать класс окна(не требуется, если Вы используете встроенный тип окна, например MessageBox)
4. Создать окно(обязательно)
5. Показать окно(если хотите немедленно показать окно)
6. Обновить окно
7. Образовать бесконечный цикл, обрабатывающий сообщения окна
8. Если есть сообщения, то обработать специализированной функцией ответственной за окно
9. Выйти из программы, если пользователь закрыл окно

Разберем простую программу, которая выводит только окно. Я взял пример программы Wap32.asm из пакета TASM и несколько упостил ее.

       
         .386
         .model flat, stdcall
         include win32.inc
         ;Файл win32.inc содержит некоторые нужные константы и структуры
         
         extrn CreateWindowExA:PROC
         extrn DefWindowProcA:PROC
         extrn DispatchMessageA:PROC
         extrn ExitProcess:PROC
         extrn GetMessageA:PROC
         extrn GetModuleHandleA:PROC
         extrn LoadCursorA:PROC
         extrn LoadIconA:PROC
         extrn PostQuitMessage:PROC
         extrn RegisterClassA:PROC
         extrn ShowWindow:PROC
         extrn TranslateMessage:PROC
         extrn UpdateWindow:PROC
         
         
         .data
         
         newhwnd dd 0
         msg MSGSTRUCT <?>
         wc WNDCLASS <?>
         hInst dd 0
         szTitleName db 'Win32 Assembly Program',0
         szClassName db 'ASMCLASS32',0
         
         .code
         start:
         
         push 0
         call GetModuleHandleA
         mov [hInst], eax
         ;Получим дискриптор программы.
         ;Далее инициализируем структуру WndClass для регистрации окна
         
         mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
         ;clsStyle - определяет стиль класса
         
         mov [wc.clsLpfnWndProc], offset WndProc
         ;clsLpfnWndProc - указывает на процедуру окна
         
         mov [wc.clsCbClsExtra], 0
         mov [wc.clsCbWndExtra], 0
         
         mov eax, [hInst]
         mov [wc.clsHInstance], eax
         ;clsHInstance - содержит дискриптор программы
         
         push IDI_APPLICATION
         push 0
         call LoadIconA
         mov [wc.clsHIcon], eax
         
         push IDC_ARROW
         push 0
         call LoadCursorA
         mov [wc.clsHCursor], eax
         
         mov [wc.clsHbrBackground], COLOR_WINDOW + 1
         mov dword ptr [wc.clsLpszMenuName], 0
         mov dword ptr [wc.clsLpszClassName], offset szClassName
         ;clsLpszClassName - определяет имя класса окна
         
         push offset wc
         call RegisterClassA
         ;Создаем окно:
         
         push 0
         push [hInst] ; дискриптор окна
         push 0
         push 0
         push CW_USEDEFAULT ; высота
         push CW_USEDEFAULT ; ширина
         push CW_USEDEFAULT ; y
         push CW_USEDEFAULT ; x
         push WS_OVERLAPPEDWINDOW ; стиль
         push offset szTitleName ; заголовок окна
         push offset szClassName ; имя класса
         push 0 ; дополнительный стиль
         
         call CreateWindowExA
         
         mov [newhwnd], eax
         ;newhwnd - дискриптор окна
         ;Покажем окно:
         
         push SW_SHOWNORMAL
         push [newhwnd]
         call ShowWindow
         ;Обновим окно:
         
         push [newhwnd]
         call UpdateWindow
         ;Создаем цикл для обработки сообщений окна
         
         msg_loop:
         push 0
         push 0
         push 0
         push offset msg
         call GetMessageA
         
         cmp ax, 0
         je end_loop
         
         push offset msg
         call TranslateMessage
         
         push offset msg
         call DispatchMessageA
         
         jmp msg_loop
         
         end_loop:
         ;выход из программы:
         
         push [msg.msWPARAM]
         call ExitProcess
         ;Процедура окна:
         
         WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD,\
         wparam:DWORD, lparam:DWORD
         ;Win32 требует, чтобы EBX, EDI, и ESI были сохранены
         
         cmp [wmsg], WM_DESTROY
         je wmdestroy
         
         push [lparam]
         push [wparam]
         push [wmsg]
         push [hwnd]
         call DefWindowProcA
         jmp finish
         
         wmdestroy:
         push 0
         call PostQuitMessage
         mov eax, 0
         finish:
         ret
         WndProc endp
         ends
         end start 

На первый взгляд кажется, что слишком много написано для простой программы. На самом же деле писать все полностью не нужно, достаточно написать файл один раз, а потом использовать его как шаблон для своих новых программ. Можно создать объектный файл и использовать его как загрузочный код, а писать только процедуру окна(WinProc).



Литература по Assembler