Assembler & Win32 - страница 2

стр.

>

>             mov    eax,IDOK

>@@cancel:    call   EndDialog,          @@hDlg, eax


>@@ret_false: xor    eax,eax

>             ret


>@@init:             call   GetDlgItem,         @@hDlg, IDR_NAME

>             call   SetFocus,           eax

>             jmp    @@ret_false

>endp   DlgProc

>end    Start


Файл ресурсов dlg.rc

>#include "resource.h"

>IDD_DIALOG DIALOGEX 0, 0, 187, 95

>STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU

>EXSTYLE WS_EX_CLIENTEDGE

>CAPTION "Dialog"

>FONT 8, "MS Sans Serif"

>BEGIN

>    DEFPUSHBUTTON   "OK",IDOK,134,76,50,14

>    PUSHBUTTON      "Cancel",IDCANCEL,73,76,50,14

>    LTEXT           "Type your name",IDC_STATIC,4,36,52,8

>    EDITTEXT        IDR_NAME,72,32,112,14,ES_AUTOHSCROLL

>END


Остальные файлы из данного примера, приведены в приложении 1.

Краткие комментарии к программе

Сразу после метки Start, программа обращается к функции API Win32 GetModuleHandle для получения handle данного модуля (данный параметр чаще именуют как handle of instance). Получив handle, мы вызываем диалог, созданный либо вручную, либо с помощью какой-либо программы построителя ресурсов. Далее программа проверяет результат работы диалогового окна. Если пользователь вышел из диалога посредством нажатия клавиши OK, то приложение запускает MessageBox с текстом приветствия.

Диалоговая процедура обрабатывает следующие сообщения. При инициализации диалога  (WM_INITDIALOG) она просит Windows установить фокус на поле ввода имени пользователя. Сообщение WM_COMMAND обрабатывается в таком порядке: делается проверка на код нажатия клавиши. Если была нажата клавиша OK, то пользовательский ввод копируется в переменную szValue, если же была нажата клавиша Cancel, то копирования не производится. Но и в том и другом случае вызывается функция окончания диалога: EndDialog. Остальные сообщения в группе WM_COMMAND просто игнорируются, предоставляя Windows действовать по умолчанию.

Вы можете сравнить приведённую программу с аналогичной программой, написанной на ЯВУ, разница в написании будет незначительна. Очевидно те, кто писал приложения на ассемблере под Windows 3.x, отметят тот факт, что исчезла необходимость в сложном и громоздком startup коде. Теперь приложение выглядит более просто и естественно.

Пример 2. Динамическая библиотека

Написание динамических библиотек под Win32 также значительно упростилось, по сравнению с тем, как это делалось под Windows 3.x. Исчезла необходимость вставлять startup код, а использование четырёх событий инициализации/деинициализации на уровне процессов и потоков, кажется логичным.

Рассмотрим простой пример динамической библиотеки, в которой всего одна функция, преобразования целого числа в строку в шестнадцатеричной системе счисления.

Файл mylib.asm

>Ideal

>P586

>Radix  16

>Model  flat

>DLL_PROCESS_ATTACH  = 1


>extrn  GetVersion:  proc


>DataSeg

>hInst        dd     0

>OSVer        dw     0


>CodeSeg

>proc   libEntry     stdcall

>arg    @@hInst      :dword,      @@rsn  :dword,      @@rsrv :dword

>             cmp    [@@rsn],DLL_PROCESS_ATTACH

>             jne    @@1

>             call   GetVersion

>             mov    [OSVer],ax

>             mov    eax,[@@hInst]

>             mov    [hInst],eax

>@@1:         mov    eax,1

>             ret

>endP   libEntry


>public stdcall      Hex2Str

>proc   Hex2Str      stdcall

>arg    @@num  :dword,      @@str  :dword

>uses   ebx

>             mov    eax,[@@num]

>             mov    ebx,[@@str]

>             mov    ecx,7

>@@1:         mov    edx,eax

>             shr    eax,4

>             and    edx,0F

>             cmp    edx,0A

>             jae    @@2

>             add    edx,'0'

>             jmp    @@3

>@@2:         add    edx,'A' - 0A

>@@3:         mov    [byte ebx + ecx],dl

>             dec    ecx

>             jns    @@1

>             mov    [byte ebx + 8],0

>             ret

>endp   Hex2Str


>end    libEntry


Остальные файлы, которые необходимы для данного примера, можно найти в приложении 2.

Краткие комментарии к динамической библиотеке

Процедура libEntry является точкой входа в динамическую библиотеку, её не надо объявлять как экспортируемую, загрузчик сам определяет её местонахождение. LibEntry может вызываться в четырёх случаях: