Разное
Последние книги
Самое популярное
Все бесплатно
Все ссылки на файлы, расположенные на страницах сайта, добавлены пользователями и доступны для бесплатного скачивания. За содержание этих файлов администрация сайта ответственности не несет.
Навигация
Вопросы
Упаковка таблиц в BDE
Категория: Базы данных
Категория: Базы данных
Создание ярлыка на Рабочем столе
Категория: Приложение
Категория: Приложение
Сохраняем Bitmap в поле dbase
Категория: Базы данных
Категория: Базы данных
Добавление текстовой информации в .ехе-файл и чтение ее
Категория: Файловая система
Категория: Файловая система
Дата изменения файла
Категория: Файловая система
Категория: Файловая система
Как получить список устройств, подключённых к компьютеру
Категория: Файловая система
Категория: Файловая система
Получение выделенного текста из компонента TWebBrowser
Категория: Интернет и Сети
Категория: Интернет и Сети
Как нарисовать фрактал
Категория: Математика
Категория: Математика
Вычисление интеграла с заданной точностью алгоритмом Симпсона.
Категория: Математика
Категория: Математика
Число четное или нечетное
Категория: Математика
Категория: Математика
Чемодан реплика луи виттон купить. Чемоданы луи виттон купить в спб.
Assembler and Win32
Assembler&Win32. Курс молодого бойца. Урок 14.
Оконное приложение
На этом уроке мы напишем
оконное приложение на ассемблере. Я буду писать его на MASM. Это
приложение я постарался сделать наиболее минимальным и понятным.
.386p
.model flat, stdcall
option casemap:none
includelib .\masm32\lib\kernel32.lib
includelib .\masm32\lib\user32.lib
include .\masm32\include\windows.inc
include .\masm32\include\kernel32.inc
include .\masm32\include\user32.inc
.data
newhwnd dd 0
hInst dd 00000000h
szTitleName db 'Window Application',0
szClassName db 'ASMCLASS32',0
msg MONMSGSTRUCT >; структура сообщения
wc WNDCLASS >; структура класса
.code
start:
Invoke GetModuleHandle,0 ; получаем hInstanse
Mov [hInst], eax
Mov [wc.style], CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
; устанавливаем стиль окна
Mov [wc.lpfnWndProc], offset WndProc ;
Mov [wc.cbClsExtra], 0
Mov [wc.cbWndExtra], 0
Mov eax, [hInst]
Mov [wc.hInstance], eax
Invoke LoadIcon,0,IDI_APPLICATION ; получаем значок приложения по
; умолчанию
Mov [wc.hIcon], eax
Invoke LoadCursorA,0,IDC_ARROW ; получаем курсор по умолчанию
Mov [wc.hCursor], eax
Mov [wc.hbrBackground], COLOR_BACKGROUND+1
Mov dword ptr [wc.lpszMenuName], 0
Mov dword ptr [wc.lpszClassName], offset szClassName ; задаём имя класса
;окна
Invoke RegisterClassA,offset wc ; регистрируем класс окна
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 CreateWindowEx ; создаём окно
mov [newhwnd], eax ; сохраняем его дескриптор
invoke ShowWindow,[newhwnd],SW_SHOWNORMAL; показываем окно
invoke UpdateWindow, [newhwnd]; обновляем его
msg_loop: ; запускаем цикл обработки сообщений
invoke GetMessage,offset msg, 0,0,0
cmp ax, 0
je end_loop
invoke TranslateMessage, offset msg
invoke DispatchMessage, offset msg
jmp msg_loop
end_loop:
invoke ExitProcess, 0
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
Cmp [wmsg], WM_DESTROY
Je wmdestroy
Cmp [wmsg], WM_KEYDOWN
Je wmkeydown
Invoke DefWindowProcA,[hwnd],[wmsg],[wparam],[lparam]
; вызываем стандартный обработчик сообщений Jmp finish
wmkeydown:
cmp [wparam], VK_ESCAPE
je wmdestroy; если нажата клавиша Escape то выход
jmp finish
wmdestroy:
invoke PostQuitMessage, 0
invoke ExitProcess, 0 ; выход
finish:
ret
WndProc endp
end start
В самой первой строке мы получаем hInstanse т.е хендл приложения, фактически это база образа приложения, т.е. то место в памяти в которого начинается наша программа. Не пойму, зачем именно это нужно, но это зачем-то нужно. Функция GetModuleHandle нужна для получения хендла библиотеки (фактически хендл библиотеки это и есть её база образа), параметром этой функции надо передавать имя библиотеки, но если мы укажем 0, то получим хендл нашего приложения. Потом мы заполняем структуру класса окна, т.е. задаём атрибуты класса окна.
Mov [wc.lpfnWndProc], offset WndProc
Этой строкой мы указываем, какая функция будет обрабатывать сообщения окна. Функция, которая обрабатывает сообщения окна, называется оконной функцией. Оконная функция вызывается всякий раз, когда окну было прислано какое-либо сообщение.
Потом мы получаем иконку окна с помощью функции LoadIcon, в качестве первого параметра этой функции надо передавать хендл приложения, но мы указали 0 поэтому мы получим стандартный значок окна. Во втором параметре мы указываем указатель строку, которая содержит имя иконки, которую мы хотим получить, но если мы укажем определённую константу, то сможем получить предопределённую иконку. Точно также мы получаем курсор, т.е. его хендл.
Потом мы вызываем RegisterClass, единственным параметром которой является указатель на структуру, которая описывает новый класс окна.
Потом мы создаём окно с помощью функции CreateWindowEx.
HWND CreateWindowEx(
DWORD dwExStyle, // расширенный стиль окна
LPCTSTR lpClassName, // имя класса
LPCTSTR lpWindowName, // заголовок окна
DWORD dwStyle, // стиль окна
int x, // позиция х
int y, // позиция у
int nWidth, // ширина
int nHeight, // высота
HWND hWndParent, // хендл окна родителя
HMENU hMenu, // хендл меню
HINSTANCE hInstance, // хендл приложения
LPVOID lpParam //указатель на данные (обычно они не нужны)
);
После создания окна мы показываем его и обновляем. Потом запускаем бесконечный цикл обработки системных сообщений.
В оконной функции мы получаем сообщение и обрабатываем его. Если тип сообщения WM_DESTROY, то мы прыгаем на соответствующую метку, после которой вы выходим из нашей программы. Если была нажата клавиша, то мы продолжаем обработку и смотрим, нажата ли клавиша escape, если да, то выходим. Если сообщение, какое либо другое, то вызываем стандартный обработчик сообщений окна. Этот обработчик превращает наше окно в настоящее "живое" окно, которое может двигаться, расширятся и свёртываться. Можно и не вызывать эту функцию, но для того чтобы окно стало живым нам придётся вручную обрабатывать все сообщения окна, а это просто нецелесообразно.
Вот и написали мы оконное приложение. Мне кажется для первого раза это не слишком трудно. Надеюсь, этот урок был не слишком скучным.
.386p
.model flat, stdcall
option casemap:none
includelib .\masm32\lib\kernel32.lib
includelib .\masm32\lib\user32.lib
include .\masm32\include\windows.inc
include .\masm32\include\kernel32.inc
include .\masm32\include\user32.inc
.data
newhwnd dd 0
hInst dd 00000000h
szTitleName db 'Window Application',0
szClassName db 'ASMCLASS32',0
msg MONMSGSTRUCT >; структура сообщения
wc WNDCLASS >; структура класса
.code
start:
Invoke GetModuleHandle,0 ; получаем hInstanse
Mov [hInst], eax
Mov [wc.style], CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
; устанавливаем стиль окна
Mov [wc.lpfnWndProc], offset WndProc ;
Mov [wc.cbClsExtra], 0
Mov [wc.cbWndExtra], 0
Mov eax, [hInst]
Mov [wc.hInstance], eax
Invoke LoadIcon,0,IDI_APPLICATION ; получаем значок приложения по
; умолчанию
Mov [wc.hIcon], eax
Invoke LoadCursorA,0,IDC_ARROW ; получаем курсор по умолчанию
Mov [wc.hCursor], eax
Mov [wc.hbrBackground], COLOR_BACKGROUND+1
Mov dword ptr [wc.lpszMenuName], 0
Mov dword ptr [wc.lpszClassName], offset szClassName ; задаём имя класса
;окна
Invoke RegisterClassA,offset wc ; регистрируем класс окна
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 CreateWindowEx ; создаём окно
mov [newhwnd], eax ; сохраняем его дескриптор
invoke ShowWindow,[newhwnd],SW_SHOWNORMAL; показываем окно
invoke UpdateWindow, [newhwnd]; обновляем его
msg_loop: ; запускаем цикл обработки сообщений
invoke GetMessage,offset msg, 0,0,0
cmp ax, 0
je end_loop
invoke TranslateMessage, offset msg
invoke DispatchMessage, offset msg
jmp msg_loop
end_loop:
invoke ExitProcess, 0
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
Cmp [wmsg], WM_DESTROY
Je wmdestroy
Cmp [wmsg], WM_KEYDOWN
Je wmkeydown
Invoke DefWindowProcA,[hwnd],[wmsg],[wparam],[lparam]
; вызываем стандартный обработчик сообщений Jmp finish
wmkeydown:
cmp [wparam], VK_ESCAPE
je wmdestroy; если нажата клавиша Escape то выход
jmp finish
wmdestroy:
invoke PostQuitMessage, 0
invoke ExitProcess, 0 ; выход
finish:
ret
WndProc endp
end start
В самой первой строке мы получаем hInstanse т.е хендл приложения, фактически это база образа приложения, т.е. то место в памяти в которого начинается наша программа. Не пойму, зачем именно это нужно, но это зачем-то нужно. Функция GetModuleHandle нужна для получения хендла библиотеки (фактически хендл библиотеки это и есть её база образа), параметром этой функции надо передавать имя библиотеки, но если мы укажем 0, то получим хендл нашего приложения. Потом мы заполняем структуру класса окна, т.е. задаём атрибуты класса окна.
Mov [wc.lpfnWndProc], offset WndProc
Этой строкой мы указываем, какая функция будет обрабатывать сообщения окна. Функция, которая обрабатывает сообщения окна, называется оконной функцией. Оконная функция вызывается всякий раз, когда окну было прислано какое-либо сообщение.
Потом мы получаем иконку окна с помощью функции LoadIcon, в качестве первого параметра этой функции надо передавать хендл приложения, но мы указали 0 поэтому мы получим стандартный значок окна. Во втором параметре мы указываем указатель строку, которая содержит имя иконки, которую мы хотим получить, но если мы укажем определённую константу, то сможем получить предопределённую иконку. Точно также мы получаем курсор, т.е. его хендл.
Потом мы вызываем RegisterClass, единственным параметром которой является указатель на структуру, которая описывает новый класс окна.
Потом мы создаём окно с помощью функции CreateWindowEx.
HWND CreateWindowEx(
DWORD dwExStyle, // расширенный стиль окна
LPCTSTR lpClassName, // имя класса
LPCTSTR lpWindowName, // заголовок окна
DWORD dwStyle, // стиль окна
int x, // позиция х
int y, // позиция у
int nWidth, // ширина
int nHeight, // высота
HWND hWndParent, // хендл окна родителя
HMENU hMenu, // хендл меню
HINSTANCE hInstance, // хендл приложения
LPVOID lpParam //указатель на данные (обычно они не нужны)
);
После создания окна мы показываем его и обновляем. Потом запускаем бесконечный цикл обработки системных сообщений.
В оконной функции мы получаем сообщение и обрабатываем его. Если тип сообщения WM_DESTROY, то мы прыгаем на соответствующую метку, после которой вы выходим из нашей программы. Если была нажата клавиша, то мы продолжаем обработку и смотрим, нажата ли клавиша escape, если да, то выходим. Если сообщение, какое либо другое, то вызываем стандартный обработчик сообщений окна. Этот обработчик превращает наше окно в настоящее "живое" окно, которое может двигаться, расширятся и свёртываться. Можно и не вызывать эту функцию, но для того чтобы окно стало живым нам придётся вручную обрабатывать все сообщения окна, а это просто нецелесообразно.
Вот и написали мы оконное приложение. Мне кажется для первого раза это не слишком трудно. Надеюсь, этот урок был не слишком скучным.