7.3.5. Полноценное приложение
Теперь, когда мы знаем, как строятся программы с меню и диалогами, попробуем написать настоящее полноценное приложение, включающее в себя все то, что требуется от программы, - меню, диалоги, комбинации клавиш для быстрого доступа к элементам меню и т. д. В качестве примера создадим простой текстовый редактор, аналогичный Notepad. В этом примере увидим, как получить параметры из командной строки, прочитать и записать файл, выделить и освободить память.
// winpad95. гс
// Файл ресурсов для программы winpad95.asm. //Идентификаторы сообщений от пунктов меню.
#define |
IDMJIEW |
OxIOOL |
#define |
IDM_0PEN |
Ox101L |
#define |
IDM_SAVE |
Oxl02L |
#define |
IDM_SAVEAS |
0x103L |
ffdefine |
I0M_EXIT |
Oxl04L |
#define |
IDM_AB0UT |
0x105L |
fldefine |
IDMJJNDO |
Ox106L |
ffdefine |
IDM_CUT |
Ox107L |
fldefine |
IDM_C0PY |
Oxl08L |
#define |
I0M_PASTE |
Ox109L |
#define |
IDM_CLEAR |
OxIOAL |
#define |
IDM_SETSEL |
OxIOBL |
// Идентификаторы основных ресурсов. #define ID_MENU 'Ox700L #define ID_ACCEL 0x701L
#define ID_ABOUT Ox702L
// Если есть иконка - можно раскомментировать эти две строки: // «define ID_ICON Ox703L // IDJC0N ICON "winpad95.ico"
// Основное меню.
ID_MENU MENU DISCARDABLE {
POPUP
POPUP
"&File" { MENUITEM
MENUITEM MENUITEM MENUITEM MENUITEM MENUITEM
{
MENUITEM MENUITEM "&New\tCtrl+N", IDM_NEW "&0pen...\tCtrl+0",IDM„0PEN "&Save\tCtrl+S", IDM_SAVE "Save &As. .. \tCtrl+Shift+S",
SEPARATOR
"E&xit\tCtrl+Q'\ IDM^EXIT
IDM_SAVEAS
"&Undo\tCtrl-
SEPARATOR
IDM_UNDO
MENUITEM. "Cu&tYtCtrl-X", IDM_CUT MENUITEM "&Copy\tCtrl-C", IDM_COPY
MENUITEM "&PaSte\tCtrl-V", IDM PASTE
MENUITEM "&Delete\tDel", I0M_CLEAR
MENUITEM SEPARATOR
MENUITEM "Select ШДгСггЬА", IOM_SETSEL
}
POPUP "&Help" <
MENUITEM "About", IDM_ABOUT
}
// Комбинации клавиш.
ID_ACCEL ACCELERATORS DISCARDABLE {
"N", IDM_NEW, CONTROL, VIRTKEY
"0", IDM_0PEN, CONTROL, VIRTKEY
"S", IDM_SAVE, CONTROL, VIRTKEY
"S", IDM_SAVEAS, CONTROL, SHIFT, VIRTKEY
"Q", IDM_EXIT, CONTROL, VIRTKEY
"2", IDM_UNDO, CONTROL, VIRTKEY "A", IDM_SETSEL, CONTROL, VIRTKEY
}
// Все эти определения можно заменить #include <winuser.h>.
Sdefine DS_M0DALFRAME Ox80L
#define DSJDLOOK 4
«define WS_POPUP 0x800000001
#define WS_CAPTI0N 0XC00000L
#define WS_SYSMENU Ox80000L
ttdefine ID0K 1
Sdefine IDC_STATIC -1
«define IDIJvPPLICATION 32512
fldefine WS_B0RDER Ox800000L
// Стандартный диалог "About".
IDJBOUT DIALOG DISCARDABLE 0, 0, 125, 75
STYLE DS_M0DALFRAME I DSJDLOOK I WS_FOFUF I WS_CAPTI0N | WS_SYSMENU
CAPTION "About Asmpad95"
{
ICON IDI_APPLICATI0N, IDC_STATIC, 12, 15, 21, 20
CTEXT "Asmpad95", IDC_STATIC, 0, 30, 40, 8
CTEXT "Prototype notepad-style editor for Windows 95 written
entirely in assembly language",IDC.STATIC, 45,10,70,45,WS_B0RDER DEFPUSHBUTTON "OK", ID0K,35, 60, 40, 10
}
Далее рассмотрим текст программы. ; winpad95.asm
; Графическое уап32-ПрилОЖение - текстовый редактор.
include def32.inc includeuser32.inc include kernel32.inc include comdlg32.inc
ID1 MENU |
equ |
IQQh |
ID_ACCEL |
equ |
701h |
ID_AB0UT |
equ |
702h |
MAXSIZE |
equ |
260 |
MEMSI2E |
equ |
65535 |
EditID |
equ |
|
|
.386 |
|
|
.model |
flat |
|
.const |
|
db |
|
|
edit_class |
db |
"edit |
changes_msg |
db |
"Save |
filter_string |
db |
"All 1 |
|
db |
"Text |
Максимальное имя файла. Максимальный размер временного буфера
в памяти.
; Это и имя класса, и имя основного окна. ,0 ; Предопределенное имя класса для редактора.
; Маски для Get*FileName.
changes?", 0 Files",0,'* .*' ,0 Files",0,' *.txt' ,0,0 .data
; Структура, исполвзующаяся Get*FileName.
ofn OPENFILENAME <SIZE ofn,?,?, offset filter_string,?,?,?,offset buffer,\
MAXSIZE,0, ?,?,?,?,?,?, 0,?,?,?> ; Структура, описывающая наш основной класс.
wc WN0CLA5SEX <SIZE WNDCLASSEX,CS_HREORAW or CS^VREDRAW,offset win_proc,0,\
0,?,?,?,C0L0R_WIND0W+1,ID_MENU,offset c_w_name,0>
flag_untitled |
db |
1; = 1, |
если имя файла не определейо (новый |
.data? |
|
|
|
h_editwindow |
dd |
і |
; Идентификатор окна редактора. |
h_accel |
dd |
і |
; Идентификатор массива акселераторої |
p memory |
dd |
? |
; Адрес буфера в памяти. |
SizeReadWrite |
dd |
? |
|
msg_ |
MSG |
О |
|
rec |
RECT |
<> |
|
buffer |
db |
MAXSIZE |
Оир(?) ; Имя файла. |
window_title |
db |
MAXSIZE |
гіир(?), 12 с1ир(?) |
start:
. code
call
mov mov
mov
repne
cmp
je
mov
mov
GetCommandLine edi,eax al ' '
ecx,MAXSIZE
scasb
byte ptr [edi],0 cmdline_empty esi,edi
buffer
• Получить нашу командную строку.
• Найти конец имени нашей программы.
rep mov
cmdline_empty:
; Подготовить movsb
flag_untitled,0
и зарегистрировать класс.
Создать
Цикл
message_loop:
push push
xor |
ebx,ebx |
call |
GetModuleHandle |
mov |
esi,eax |
fflOV |
wc.hlnstance, eax |
mov |
ofn._hInstance, eax |
push |
IDI APPLICATION |
push |
ebx |
call |
Loadlcon |
mov |
wc.hlcon,eax |
push |
IDC_ARROW |
push |
ebx |
call |
LoadCursor |
mov |
wc. hCursor.eax |
push |
offset |
call ■ |
RegisterClassEx |
ь основное окно. |
|
push |
ebx |
push |
esi |
push |
ebx |
push |
ebx |
push |
200 |
push |
300 |
push |
CW_USEDEFAULT |
push |
CW_USEDEFAULT |
push |
WS OVERLAPPEDWINDOW |
push |
offset |
■ push |
offset c_w_name |
push |
WS EX CLIENT£DGE |
call |
CreateWindowEx |
push |
eax |
push |
eax |
push |
SW.SHOWNORMAL |
push |
eax |
call |
ShowWindow |
call |
UpdateWindow |
ализировать акселераторы. |
|
push |
ID ACCEL |
push |
esi |
call |
LoadAccelerators |
mov |
h accel.eax |
ожидания |
сообщения. |
pop |
esi |
mov |
edi,offset msg_ |
Определить наш идентификатор
и сохранить его в wc.hInstance
или Ш_ЮТ, если иконка есть в ресурсах, или esi, если иконка есть в ресурсах.
Предопределенный курсор (стрелка).
Для pop esi перед
ESI - идентификатор основного окна. EDI - структура с сообщением от него.
ebx ebx
Программирование для Windows 95/NT
push |
ebx |
|
push |
edi |
|
call |
GetMessage |
; Получить сообщение. |
test |
eax,eax |
; Если это ЫМ_0ШТ, ' |
jz |
exit msg loop |
; выйти из цикла. |
push |
edi |
|
push |
h accel |
|
push |
esi |
; ^lWnd |
call |
TranslateAccelerator |
; Преобразовать акселераторы |
test |
eax,eax |
|
jnz |
message_loop |
|
push |
edi |
|
call |
TranslateMessage |
; Преобразовать сообщения от |
push |
edi |
|
call |
DispatchMessage |
; и отправить обратно. |
jmp |
short message_loop |
|
_loop: |
|
|
push |
msg_.wParam |
|
call |
ExitProcess |
; Конец программы. |
; Процедура win_proc.
; Процедура не должна win_proc proc near ; Параметры, (с учетом push ebp). wpJiWnd equ dword ptr [ebp+08h] wp_uMsg equ dword ptr [ebp+OCh] wp_wParam equ dword ptr [ebp+10h' wp_lParam equ dword ptr [ebp+14h] ; Инициализируем стековый кадр.
изменять регистры EBP,EDI,ESI и EBX!
push |
ebp |
mov |
ebp,esp |
pusha |
|
xor |
ebx,ebx |
mov |
esi,wp_hWnd |
mov |
eax,wp_uMsg |
тать пришедшее сообщение. |
|
стр |
eax,WM_CREATE |
je |
h_wm_create |
cmp |
eax,WM_SIZE |
je |
n_wm_size |
cmp |
eax,WM_DESTROY |
je |
h_wm_destroy |
cmp |
eax,WM_COMMAND |
je |
h_wm_command |
cmp |
eax,WM_ACTIVATE |
je |
h_wn_activate |
cmp |
eax,WM_CLOSE |
je |
h_wm_close |
; Создать стековый кадр. Сохранить все регистры. 0 для команд push 0. Для команд push hwnd.
def_proc:
рора
leave
imp
DefWindowProc
Если эта ненужное сообщение,
оставить его обработчику по умолчанию.
; Обработчик WM_CL0.SE.
; Если нужно, спрашивает, сохранить ли файл. h_wm_close:
call save_contents
jmp short def_proc
Обработчик
h_wm_create:
; Здесь также ; Создать
можно создать toolbar окно редактора.
statusbar.
push push push push push push push
push push
push push push
call mov ebx
wc.hlnstance
EditID
esi ; hWnd
ebx О
ebx ; О
ebx О
ebx ; 0 WS^VISIBLE or WS_CHILD or ES_LEFT
ES_AUT0HSCR0LL or ESJDTOVSCROLL
Идентификатор основной программы.
or ES_MULTILINE or\
ebx
offset edit_class
ebx
CreateWindowEx h editwindow,eax
Передать ему фокус.
push call cmp
je
call
continue_create;
call
jmp eax
SetFocus
flag_untitled,1
contlnue_create
skip_getopen
set.title end wm check
О
і О
Открыть файл, указанный в командной строке.
; Обработчик WM ..COMMAND.
h_wm_command:
mov cwde
sub
jb
eax,wp_wParam
Младшее слово содержит IDM_*.
eax,100h
def_proc
Обработать сообщения от пунктов меню.
call clworcl ptr menu_handlers[eax*4] jmp end_wm_check
Программирование для Windows 95/IMT
menu_handlers
dd ' offset h_idm_new,offset h_idm_open,offset h_idm_save
del offset h_idm_saveas, offset h_idm_exit, offset h_idm_about
dd offset h_idm_undo, offset h_idm_cut, offset h_idm_copy
dd offset h_idm_paste, offset h_idm_clear, offset h_idirrsetsel
; Сообщения от пунктов меню должны быть описаны в win95pad.rc именно в таком
; порядке - от IDMJEW lOOh до IDM_CLEAR lOAh.
h_idm_setsel:
push -1 ; -1
push ebx ; 0
push EM_SETSEL ; Выделитв весв текст.
push |
h_editwindow |
call |
SendMessage |
ret |
|
; Обработчики |
сообщений из меню EDIT: |
h idm clear: |
|
mov |
eax.WM CLEAR |
jmp |
short send_to_editor |
h_idm_paste: |
|
mov |
eax.WM PASTE |
jmp |
short send_to_editor |
h_idm_copy: |
|
mov |
eax.WM COPY |
jmp |
short send_to_editor |
n_idm_cut: |
|
mov |
eax,WM_CUT |
jmp |
short send_to_editor |
h_idm_undo: |
|
mov |
eax,EM_UND0 |
send„to_editor |
|
push |
ebx ; 0 |
push |
ebx ; 0 |
push |
eax |
push |
h editwindow |
call |
SendMessage |
ret |
|
; Обработчик IDM_NEW. h_idm_new:
call save_contents ; Записати файл, если нужно,
mov byte ptr flag_untitled, 1 ■
call set_title Отметить, что файл не назван.
push ebx
push ebx
push WM_SETTEXT
push h_editwindow
call SendMessage ; Послатв пустой WM_SETTEXT редактору,
ret
IBB
; Обработчик IDM_AB0UT. h_idm_about:
push ebx ; 0
push offset aboutjroc
■ push esi ; hWnd
push IDJBODT
push wc.hlnstance
call DialogBoxParam ret
; Обработчик IDM_SAVEAS и IDM_SAVE. h_idm_save:
cmp flag_untitled, 1 ; jne skip_getsave ;
h_idm_saveas:
; Узнать имя файла.
Если файл назван,
пропустить вызов
GetSaveFileName.
mov
push
call
test
jz
skip_getsave:
; Создать его.
push push push push push push push
call
mov or
ofn.Flags,0FN_EXPLORER
offset ofn
GetSaveFileName
eax.eax
file_save_failed
ebx
FILE_ATTRIBUTE_ARCHIVE
CREATE_ALWAYS
ebx
FILE_SHARE_READ or FILE_SHARE_WRITE GENERIC,READ or GENERIC_WRITE
offset buffer
CreateFlle edi,eax
Выделить память.
push push call push push call
mov
Забрать текст push push push push call
Записать в
push
call push
MEMSIZE GMEM_MOVEABLE
GlobalAlloc eax . eax
GlobalLock esi,eax
из редактора. esi
MEMSIZE-1
WM_GETTEXT h_editwindow
SendMessage файл. esi
lstrlen
ebx
or GMEM_ZEROINIT
hMemory
hMemory
для
для
GlobalFree. GlobalLock.
Адрес буфера в ESI.
pMemory
push push push push call push call call
push offset SizeReadWrite eax ; P
esi ; А
edi ; И
WriteFile
esi ;
GlobalUnlock
;
edi ;
уже в стеке. Идентификатор файла.
pMemory
Размер буфера.
Адрес
Идетафикатор файла.
call . CloseHandle ; Сбросить флаг модификации в редакторе.
push ebx
push ebx
push EM_SETMODIFY
push h„editwindow
call SendMessage
mov byte ptr flag_untitled,0
call set.title file_save_failed;
push h.editwindow
call SetFocus
ret
; Обработчик IDM_0PEN. h_idm_open:
call save_contents ; Вызвать стандартный диалог выбора имени файла.
mov Ofп. Flags, OFN^FILEMUSTEXIST or OFN^PATHMUSTEXIST or\ 0FN_EXPL0RER
push offset ofn
call GetOpenFileName
test eax,eax
jz file_open_failed skip_getopen: ; Открыть выбранный файл.
push ebx
push FILE_ATTRIBUTE_ARCHIVE
push OPEN_EXISTING push ebx
push FILE_SHARE_READ or FILE_SHARE_WRITE push GENERIC_READ or GENERIC-WRITE
push offset buffer call CreateFile
mov edi,eax ; Идентификатор для ReadFile.
; Выделить память.
push MEMSIZE
push GMEM_MOVEABLE or GMEM ZEROINIT 1
call GlobalAlloc
push eax ; hMemory для GlobalFree.
push . eax ; hMemory для GlobalLock.
call GlobalLock ; push eax ;
push eax ;
; Прочитать файл.
push push push push
Получить адрес выделенной памяти.
pMemory pMemory
для для
GlobalUnlock. SendMessage.
push call Послать окну
ebx
offset SizeReadWrite MEMSIZE-1
eax ; pMemory для ReadFlle.
edi
ReadFile
редактора сообщение wm_settext о том,
; что нужно забрать текст из
push ebx
push WM_SETTEXT push h_editwindow
call SendMessage ; А теперь можно закрыть файл
буфера. ; pMemory
уже в стеке.
и освободить память.
call
call
push
call
mov
call
file_open_failed:
push call
ret
GlobalUnlock ; pMemory уже GlobalFree ; hMemory уже
edi ; hFile.
CloseHandle
byte ptr flag_untitled,0
set_title
h_editwindow
SetFocus
стеке. стеке.
; Обработчик IDM_EXIT.
_idm_exit:
call
push
call
ret
save_contents
esi
DestroyWindow
hWnd
Уничтожить наше окно.
; Обработчик
n_wra_size:
; Здесь также надо послать WM_SIZE окнам toolbar и statusbar, изменить размер окна ; редактора так, чтобы оно по-прежнему было максимального размера.
push |
offset rec |
|
push |
esi |
hWnd |
call |
GetClientRect |
|
push |
1 |
true |
push |
rec.bottom ; |
height |
push |
rec.right ; |
width |
push |
ebx |
У |
push |
ebx ; |
X |
push |
h_editwindow |
|
call |
MoveWindow |
|
jmp |
short end_wm_check |
|
Обработчик WM_ACTIVATE.
Программирование для Windows 95/NT
h_wm_activate:
push call
jmp h_editwindow SetFocus
short end wm_check
; Обработчик WM_DESTROY.
h_wm_destroy:
push ebx
call PostQuitMessage
; Конец процедуры window_proc. end_wm_check:
popa
xor eax.eax ■
leave
ret 16
Послать WM_QUIT основной программе.
Вернуть 0.
; Процедура set. ; Устанавливает
set_title:
.title.
новый заголовок для основного окна.
. push |
esi |
|
push |
edi |
|
mov |
edi,offset window title |
|
cmp |
byte ptr flag untitled, 1 |
; Если у файла нет имени, |
je |
untitled |
; использовать Untitled. |
mov |
esi, ofn. IpstrFile |
; [ESI] - имя файла с путем. |
movzx |
eax.ofn.nFileOffset ; |
EAX - начало имени файла. |
add |
esi,eax |
|
copy_filename: |
|
|
lodsb |
і Скопировать файл побайтово в название |
|
test |
al.al |
|
jz |
add_progname ; |
; пока не встретится нолв. |
stosb |
|
|
jmp |
short copy_filename |
|
add_progname: |
|
|
mov |
dword ptr [edi],' - 1 ; |
Приписатв минус |
add |
edi,3 |
|
mov |
esi,offset c_w_name |
|
mov |
; |
и название программы. |
rep |
movsb |
|
pop |
edi |
|
pop |
esi |
|
push |
offset window title |
|
push |
esi ; |
Идентификатор окна. |
call |
SetWindowText |
|
ret |
|
|
untitled:
mov dword ptr і Дописатьтшт
mov dword ptr [edi+4],'delt' ; Дописать "tied".
add |
edi,8 |
|
jmp |
short add_progname |
|
Процедура |
save_contents. |
|
; EBX = 0, ESI = hWnd |
|
|
save_contents |
|
|
; Спросить редактор, изменялся ли текст. |
||
push |
ebx |
|
push |
ebx |
|
push |
EM_GETMODIFY |
|
push |
h editwindow |
|
call |
SendMessage |
|
test |
eax,eax |
|
jz |
not_modified |
|
; Спросить пользователя, сохранять ли его. |
||
push |
+ |
|
push |
offset c_w_name |
|
push |
offset |
|
push |
esi |
|
call |
MessageBox |
|
cmp |
eax,IDYES |
|
jne |
notjnodified |
|
; Сохранить |
его |
|
call |
h_idm_save |
|
notjnodified: |
|
|
ret |
|
|
win_proc |
endp |
|
about_proc |
proc near |
|
; Параметры |
(с учетом push ebp). |
|
ap_hDlg |
equ dword ptr |
[ebp+08h] |
ap_uMsg |
equ dword ptr |
[ebp+OCh] |
ap_wParam |
equ dword ptr |
[ebp+10h] |
ap lParam |
equ dword ptr |
[ebp+14h] |
push |
ebp |
|
mov ebp.esp ; Создать стековый кадр.
jne
push push
call
cmp
cmp
jne
ap_uMsg,WM_COMMAND
dont_proceed ap_wParam,IDOK
dont_proceed
ap_hDlg
EndDialog
dont_proceed:
xor
eax,eax
He обрабатывается.
leave
ret about_proc
16
endp
end
_start
Размер этой программы - 6,5 Кб (скомпилированной ml/link), и даже версия, в которую добавлено все, что есть в Notepad (вывод файла на печать и поиск по тексту), получилась меньше notepad.exe почти в четыре раза. Чем значительнее Windows-приложение создается, тем сильнее сказывается выигрыш в размерах при использовании ассемблера, даже несмотря На то, что мы лишь вызываем системные функции, практически не занимаясь программированием.
Прежде чем можно будет скомпилировать winpad95.asm, следует внести необходимые дополнения в наши включаемые файлы.
Добавления в файл def32.inc:" ; Hswinuser.h.
WM_CREATE |
equ |
1 |
WM_ACTIVATE |
equ |
6 |
WM_SETTEXT |
equ |
OCh |
WM_GETTEXT |
equ |
ODh |
WM_CUT |
equ |
" 300h |
WM_C0PY |
equ |
301h |
WM_PASTE |
equ- |
302h |
WM_CLEAR |
equ |
303h |
WM_UND0 |
equ |
304h |
WM_SIZE |
equ |
5 |
WS_VISIBLE |
equ |
10000000И |
WS_CHILD |
equ |
40000000h |
WS_EX_CLIENTEDGE |
equ • |
200h |
ESLEFT |
equ |
0 |
ES_MULTILINE |
equ |
4 |
ES_AUT0HSCR0LL |
equ |
SOh |
ES_AUT0VSCR0LL |
equ |
40h |
EM_GETHANDLE |
equ |
OBDh |
EMJETMODIFY |
equ |
0B8h |
EM_SETMODIFY |
equ |
0B9h |
EMJJNDO |
equ |
OC7h |
EM_SETSEL |
equ |
OB1h |
MB_YESNO |
equ |
4 |
MB_IC0NWARNING |
equ |
30h |
IDOK |
equ |
1 |
I DYES |
equ |
6 |
; fewinnt.h. |
|
|
GENERIC_READ |
equ |
80000000h |
GENERIC,WRITE |
equ |
40000000h |
FILE_SHARE_READ |
equ |
1 |
FILE_SHARE_WRITE |
equ |
2 |
FILE_ATTRIBUTE_ARCHIVE |
equ |
20h |
; Из commdlg.h. |
|
|
OFN_PATHMUSTEXIST |
equ |
800h |
0FN_FILEMUSTEXIST |
equ |
1000h |
0FN_EXPLORER |
equ |
80000h |
OFNJWERWRITEPROMPT OPENFILENAME
OPENFILENAME
; Из windef.h. RECT
RECT
; Из winbase.h.
GMEM.MOVEABLE
GMEM_ZEROINIT
OPEN_EXISTING CREATE.ALWAYS
equ 2 st rue StructSize hwndOwner _hlnstance IpstrFilter IpstrCustomFilter nMaxCustFilter nFilterlndex IpstrFile nMaxFile IpstrFileTitle nMaxFileTitle IpstrlnitialDir IpstrTitle Flags
nFileOffset
nFileExtension
IpstrDefExt
lCustData
lpfnHook
lpTemplateName
ends
struc
left
top
right
bottom
ends
equ equ equ equ
2
40h
3
2
dd dd dd dd dd dd dd
dd dd
dd
dd dd
dd
dd
dw dw
dd dd dd dd
dd dd dd dd
Добавления в файл kernel32.inc между ifdef _TASM_ и else:
GetCommandLine
CreateFile
extrn |
lstrlen:near |
extrn |
GetCommandLineA:near |
extrn |
CloseHandle:near |
extrn |
GlobalAlloc:near |
extrn |
GlobalLock:near |
extrn |
GlobalFreemear |
extrn |
CreateFileAmear |
extrn |
ReadFllesnear |
extrn |
WriteFile:near |
equ |
GetCommandLineA |
equ |
•Cr'eateFileA |
и между else и endif:
|
extrn |
imp lstrlen@4:dword ' |
|
extrn |
imp GetCommand LineA@0:dwo rd |
|
extrn |
_imp_CloseHandle(?4:dword |
|
extrn |
imp GlobalAlloc@8:dword |
|
extrn |
imp GlobalLock@4:dword |
|
extrn |
imp GlobalFree@4:dword |
|
extrn |
imp CreateFileA(gi28:dword |
|
extrn |
imp ReadFile@20:dword |
|
extrn |
imp WriteFile@20:dword |
lstrlen |
equ |
imp IstrlenW |
GetCommandLine |
equ |
imp GetCommandLineAW |
CloseHandle |
equ |
_imp_CloseHandle@4 |
GlobalAlloc |
equ |
__imp__GlobalAlloc@>8 |
GlobalLock |
equ |
imp GlobalLock@4 |
GlobalFree |
equ |
imp GlobalFree@4 |
CreateFile |
equ |
_imp_CreateFileA@28 |
ReadFile |
equ |
imp ReadFile@20 |
WriteFile |
equ |
_imp_WriteFile@20 |
Добавления в файл user32.inc: |
|
|
|
extrn |
LoadAcceleratorsAmear |
|
extrn |
TranslateAccelerator;near |
|
extrn |
SendMessageA:near |
|
extrn |
SetWindowTextA:near |
|
extrn |
MoveWindow:near |
|
extrn |
GetClientRect:near |
|
extrn |
GlobalUnlock:near |
LoadAccelerators |
equ |
LoadAcceleratorsA |
SendMessage |
equ |
SendMessageA |
SetWindowText |
equ |
SetWindowTextA |
и между else и endif: |
|
|
|
extrn |
__imp__LoadAcceleratorsA(5>8:dwo |
|
extrn |
imp TranslateAccelerator@l2 |
|
extrn |
_imp_SendMessageA@16:dwo rd |
|
extrn |
imp SetWindowTextA@8:dword |
|
extrn , |
_imp_MoveWindow@24: dword |
|
extrn |
imp GetClientRect@8:dword |
|
extrn |
imp GlobalUnlockH: dword |
LoadAccelerators |
equ |
imp LoadAcceleratorsA@8 |
TranslateAccelerator |
equ |
imp TranslateAccelerator@l2 |
SendMessage |
equ |
imp SendMessageA@16 |
SetWindowText |
equ |
imp SetWindowTextA(g>8 |
MoveWindow |
equ |
imp MoveWindow@24 |
GetClientRect |
equ |
imp GetClientRecWS |
GlobalUnlock |
equ |
imp GlobalUnlock^ |
rd
Динамические библиотеки
Кроме того, нам потребуется новый включаемый файл, сотсі^32.іпс, который описывает функции, связанные с вызовами стандартных диалогов (выбор имени файла, печать документа, выбор шрифта и т. д.):
■ comdlg32.inc
■ Включаемый файл
с функциями из
ifdef
GetOpenFileName
GetSaveFileName
includelib
extrn
extrn
equ equ
else
includelib
Истинные имена используемых функций.
extrn
GetOpenFileNameA:near GetSaveFileNameA:near GetOpenFileNameA GetSaveFileNameA
Jmp_Get0penFileNameA@4: dword _imp_GetSaveFileNameA@4:dword
imp_Get0penFileNameA@4 _imp_GetSaveFileNameA@4
extrn_
; Присваивания.для удобства использования.
GetOpenFileName equ_
GetSaveFileName equ_
endif
Конечно, эту программу можно еще очень долго совершенствовать — добавить toolbar и statusbar, написать документацию или сделать так, чтобы выделялось не фиксированное небольшое количество памяти для переноса файла в редактор, а равное его длине. Разрешается также применять функции отображения части файла в память (CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile), что позволит работать с файлами больших размеров. В Win32 API так много функций, что можно очень долго заниматься лишь их изучением.