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

Основной модуль и динамическая библиотека Передача параметров



Рисунок 3.3.5. Основной модуль и динамическая библиотека. Передача параметров.

Трансляция программы на Рисунок 3.3.5.

MASM32.

ml /c /coff /DMASM dllex2.asm link /subsystem:windows dllex2.obj

TASM32.

tasm32 /ml dllex2.asm tlink32 -aa -Tpd dllex2.obj

Ниже мы рассмотрим весьма интересный пример (Рисунок 3.3.6). Основной процесс использует ресурсы загруженной им динамической библиотеки. Я уже говорил, что файлы шрифтов, по сути, являются динамическими библиотеками. Не правда ли удобно: ресурсы можно поместить отдельно от основной программы в динамическую библиотеку, загружая их по мере необходимости? Наша программа вначале загружает иконку из ресурсов динамической библиотеки и устанавливает ее на окно. Если Вы будете щелкать правой кнопкой мыши, направив курсор на окно, то будет вызываться процедура из динамической библиотеки, которая будет поочередно устанавливать то один, то другой значок на окно.

// файл dll3.rc // идентификаторы

#define IDI_ICON1 3 #define IDI_ICON2 10

// определили иконку IDI_ICON1 ICON "ico1.ico" IDI_ICON2 ICON "ico2.ico"

; динамическая библиотека DLL3.ASM .386P PUBLIC SETIC ; плоская модель IFDEF MASM .MODEL FLAT, stdcall ELSE .MODEL FLAT ENDIF

; константы WM_SETICON equ 80h

IFDEF MASM ; MASM ; прототипы внешних процедур EXTERN LoadIconA@8:NEAR EXTERN PostMessageA@16:NEAR ; директивы компоновщику для подключения библиотек includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE ; TASM ; прототипы внешних процедур EXTERN LoadIconA:NEAR EXTERN PostMessageA:NEAR ; директивы компоновщику для подключения библиотек includelib c:\tasm32\lib\import32.lib LoadIconA@8 = LoadIconA PostMessageA@16 = PostMessageA ENDIF ;-------------------------------------------------



; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' PRIZ DB 0 _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' DLLENTRY: MOV EAX,1 RET 12 ; [EBP+8] ; [EBP+0CH] SETIC PROC EXPORT PUSH EBP MOV EBP,ESP ; выбрать, какую иконку устанавливать CMP PRIZ,0 JZ IC_1 MOV PRIZ,0 PUSH 3 JMP CONT IC_1: MOV PRIZ,1 PUSH 10 CONT: ; загрузить иконку из ресурсов библиотеки PUSH DWORD PTR [EBP+0CH] ; идентификатор ; динамической ; библиотеки CALL LoadIconA@8 ; установить значок окна PUSH EAX PUSH 0 PUSH WM_SETICON PUSH DWORD PTR [EBP+08H] ; дескриптор окна CALL PostMessageA@16 POP EBP RET 8 SETIC ENDP _TEXT ENDS END DLLENTRY




// файл dllex3.rc // определение констант

#define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX 0x00010000L #define DS_3DLOOK 0x0004L

// определение диалогового окна

DIAL1 DIALOG 0, 0, 340, 120 STYLE WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK CAPTION "Диалоговое окно с иконкой из динамической библиотеки" FONT 8, "Arial" { }

; основной модуль DLLEX3.ASM, вызывающий ; процедуру из динамической библиотеки

.386P ; плоская модель IFDEF MASM .MODEL FLAT, stdcall ELSE .MODEL FLAT ENDIF

; константы ; сообщение приходит при закрытии окна WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_SETICON equ 80h WM_LBUTTONDOWN equ 201h

; прототипы внешних процедур IFDEF MASM ; MASM EXTERN PostMessageA@16:NEAR EXTERN GetProcAddress@8:NEAR EXTERN LoadLibraryA@4:NEAR EXTERN FreeLibrary@4:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN LoadIconA@8:NEAR ; директивы компоновщику для подключения библиотек includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE ; директивы компоновщику для подключения библиотек includelib c:\tasm32\lib\import32.lib EXTERN PostMessageA:NEAR EXTERN GetProcAddress:NEAR EXTERN LoadLibraryA:NEAR EXTERN FreeLibrary:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN LoadIconA:NEAR PostMessageA@16 = PostMessageA LoadIconA@8 = LoadIconA EndDialog@8 = EndDialog GetModuleHandleA@4 = GetModuleHandleA DialogBoxParamA@20 = DialogBoxParamA GetProcAddress@8 = GetProcAddress LoadLibraryA@4 = LoadLibraryA FreeLibrary@4 = FreeLibrary ExitProcess@4 = ExitProcess ENDIF ;------------------------------------------------

; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' LIBR DB 'DLL3.DLL',0 HLIB DD ? HINST DD ? PA DB "DIAL1",0 IFDEF MASM NAMEPROC DB "_SETIC@0",0 ELSE NAMEPROC DB "SETIC",0 ENDIF _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 ; создать диалог MOV [HINST], EAX PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 ; выход _EXIT: PUSH 0 CALL ExitProcess@4 ; процедура окна ; расположение параметров в стеке ; [EBP+014Н] ; LPARAM ; [EBP+10Н] ; 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_CLOSE JNE L1 ; закрыть библиотеку ; библиотека автоматически закрывается также ; при выходе из программы PUSH HLIB CALL FreeLibrary@4 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD PTR [EBP+0CH],WM_INITDIALOG JNE L2 ; загрузить библиотеку PUSH OFFSET LIBR CALL LoadLibraryA@4 MOV HLIB,EAX ; загрузить иконку PUSH 3 ; идентификатор иконки PUSH [HLIB] ; идентификатор процесса CALL LoadIconA@8 ; установить иконку PUSH EAX PUSH 0 ; тип иконки (маленькая) PUSH WM_SETICON PUSH DWORD PTR [EBP+08H] CALL PostMessageA@16 JMP FINISH L2: CMP DWORD PTR [EBP+0CH],WM_LBUTTONDOWN JNE FINISH ; получить адрес процедуры из динамической библиотеки PUSH OFFSET NAMEPROC PUSH HLIB CALL GetProcAddress@8 ; вызвать процедуру с двумя параметрами PUSH [HLIB] PUSH DWORD PTR [EBP+08H] CALL EAX FINISH: POP EDI POP ESI POP EBX POP EBP MOV EAX,0 RET 16 WNDPROC ENDP _TEXT ENDS END START


Содержание раздела