Выбрать главу

— при первом вызове библиотеки из потока (DLL_THREAD_ATTACH), например, с помощью функции LoadLibrary;

— при выгрузке библиотеки потоком (DLL_THREAD_DETACH);

— при выгрузке библиотеки из адресного пространства процесса (DLL_PROCESS_DETACH).

В нашем примере обрабатывается только первое из событий DLL_PROCESS_ATTACH. При обработке данного события библиотека запрашивает версию OS сохраняет её, а также свой handle of instance.

Библиотека содержит только одну экспортируемую функцию, которая собственно не требует пояснений. Вы, пожалуй, можете обратить внимание на то, как производится запись преобразованных значений. Интересна система адресации посредством двух регистров общего назначения: ebx + ecx, она позволяет нам использовать регистр ecx одновременно и как счётчик и как составную часть адреса.

Пример 3. Оконное приложение

Файл dmenu.asm

Ideal

P586

Radix  16

Model  flat

struc  WndClassEx

       cbSize       dd     0

       style        dd     0

       lpfnWndProc  dd     0

       cbClsExtra   dd     0

       cbWndExtra   dd     0

       hInstance    dd     0

       hIcon        dd     0

       hCursor             dd     0

       hbrBackground dd     0

       lpszMenuName dd     0

       lpszClassName dd     0

       hIconSm             dd     0

ends   WndClassEx

struc  Point

       left         dd     0

       top          dd     0

       right        dd     0

       bottom       dd     0           

ends   Point

struc  msgStruc

       hwnd         dd     0

       message             dd     0

       wParam       dd     0

       lParam       dd     0

       time         dd     0

       pt           Point  <>

ends   msgStruc

MyMenu              = 0065

ID_OPEN                    = 9C41

ID_SAVE                    = 9C42

ID_EXIT                    = 9C43

CS_VREDRAW          = 0001

CS_HREDRAW          = 0002

IDI_APPLICATION            = 7F00

IDC_ARROW           = 7F00

COLOR_WINDOW        = 5

WS_EX_WINDOWEDGE    = 00000100

WS_EX_CLIENTEDGE    = 00000200

WS_EX_OVERLAPPEDWINDOW     = WS_EX_WINDOWEDGE OR WS_EX_CLIENTEDGE

WS_OVERLAPPED       = 00000000

WS_CAPTION          = 00C00000

WS_SYSMENU          = 00080000

WS_THICKFRAME       = 00040000

WS_MINIMIZEBOX             = 00020000

WS_MAXIMIZEBOX             = 00010000

WS_OVERLAPPEDWINDOW =      WS_OVERLAPPED     OR \

                           WS_CAPTION        OR \

                           WS_SYSMENU        OR \

                           WS_THICKFRAME     OR \

                           WS_MINIMIZEBOX    OR \

                           WS_MAXIMIZEBOX

CW_USEDEFAULT       = 80000000

SW_SHOW                    = 5

WM_COMMAND          = 0111

WM_DESTROY          = 0002

WM_CLOSE            = 0010

MB_OK               = 0

PROCTYPE     ptGetModuleHandle   stdcall      \

                    lpModuleName :dword

PROCTYPE     ptLoadIcon          stdcall      \

                    hInstance    :dword,      \

                    lpIconName   :dword

PROCTYPE     ptLoadCursor        stdcall      \

                    hInstance    :dword,      \

                    lpCursorName :dword

PROCTYPE     ptLoadMenu          stdcall      \

                    hInstance    :dword,      \

                    lpMenuName   :dword

PROCTYPE     ptRegisterClassEx   stdcall      \

                    lpwcx        :dword

PROCTYPE     ptCreateWindowEx    stdcall      \

                    dwExStyle    :dword,      \

                    lpClassName  :dword,      \

                    lpWindowName :dword,      \

                    dwStyle             :dword,      \

                    x            :dword, \

                    y            :dword,      \

                    nWidth       :dword,      \

                    nHeight             :dword,      \

                    hWndParent   :dword,      \

                    hMenu        :dword, \