Главная » Win32 API » Пример 2.

0

Пусть даны три числа. Напишем функции для расчета среднего арифметического, произведения, суммы квадратов чисел, а также для проверки, являются ли 2 и 3 числа делителями первого. Все действия с числами оформим в виде меню, которое опишем в файле ресурсов:

500 ICON MOVEABLE PUKE LOADONCALL DISCARDABLE

"MAINICON.ICO" 600 MENUEX MOVEABLE IMPURE LOADONCALL DISCARDABLE BEGIN

POPUP "(Функции",,,0 BEGIN

MENUITEM "&Делители",2000 MENUITEM "&Среднее арифм",2100 MENUIТЕМ "(Умножение",2200 MENUITEM "&Сумма квадратов",2300 MENUIТЕМ "&Очистить",2400 MENUITEM "&Выход", 1000 END END

Исходные числа и результаты расчетов будем помещать в строки редактирования элементов Edifflox, поэтому в качестве параметров функции DLL будут получать дескрипторы этих элементов. Назовем нашу библиотеку tstdll. Ее описание в файле tstdll.def имеет вид:

LIBRARY  tstdll

EXPORTS  Deliteli

EXPORTS  SrArifm

EXPORTS  FindMult

EXPORTS  FindMultSqr

Текст, содержащий описание функций библиотеки, приведен ниже.

.model flat, stdcall

option casemap :none

include d:\masm32\include\windows.inc

include d:\masm32\include\user32.inc

include d:\masm32\include\kernel32.inc

include d:\masm32\include\masm32.inc

includelib d:\masm32\lib\masm32.lib

includelib d:\masm32\lib\user32.lib

includelib d:\masm32\lib\kernel32.lib

szText MACRO Name, Text:VARARG

LOCAL 1Ы jmp 1Ы

Name db Text,0 1Ы: ENDM m2m MACRO Ml, M2

push M2

pop Ml ENDM return MACRO arg

mov eax, arg

ret ENDM .data

buff db 50 dup(0) ; буфер для преобразования числа в строку . code LibMain proc hlnstDLL:DWORD, reason:DWORD,

unused:DWORD szText LmTitle,"tstdll’s LibMain Function"

.if reason == DLL_PROCESS_ATTACH return TRUE

.endif ret LibMain Endp

; функция, получающая три числа из строк ; редактирования элементов EditBox с дескрипторами ; hEl, hE2, hE3, проверяющая являются ли второе и ; третье числа делителями первого и выдающая сообщение ; о результатах проверки Deliteli proc hE1:DWORD,hE2:DWORD,hE3:DWORD

LOCA1 chislol:DWORD ; число 1

LOCA1 chislo2: DWORD ; число 2

LOCA1 chislo3:DWORD ; число 3

LOCA1 flagl:DWORD LOCA1 flag2:DWORD ; вспомогательные флаги для запоминания результатов ; проверки на делимость

invoke SendMessage, hEl,WM_GETTEXT,50,addr buff ; забрать строку из EditBox для первого числа ; и поместить в buff

invoke atodw,addr buff ; преобразовать строку из buff в число, записываемое в ; регистр еах

mov chislol,еах ; запомнить первое число в chislol

; аналогичные действия со вторым и третьим числом invoke SendMessage, hE2,WM_GETTEXT,50,addr buff invoke atodw,addr buff mov chislo2,eax

invoke SendMessage, hE3,WM_GETTEXT,50,addr buff invoke atodw,addr buff mov chislo3,eax .if chislol = 0 szText Msg,

"Число равно 0!У него нет ненулевых делителей!" szText Ttil,"Решение"

invoke MessageBox,NULL,addr Msg,addr Ttll,MB_OK .else

.if chislo2 = 0

szText Msg2,"Второе число равно О!" s z Text Ttl2,"Решение"

invoke MessageBox,NULL,addr Msg2,addr Ttl2, MB_OK .else

mov flagl,0

mov eax,ch±slol

mov ebx,ch±slo2

cdq

div ebx

.if edx == 0

mov flagl,1 .endif mov flag2,0 .if chislo3 == 0

szText Msg3,"Второе число равно О!" szText Ttl3,"Решение" invoke MessageBox,NULL,addr Msg3, addr Ttl3,MB_OK .else

mov eax,chislol

mov ebx,chislo3

cdq

div ebx

.if edx = 0

mov flag2,1 .endif .endif

.if flagl == 1 .if flag2 == 1

szText Msg4,"06a числа явл делителями!" szText Ttl4,"Решение" invoke MessageBox,NULL,addr Msg4, addr Ttl4,MB_OK .else

szText Msg5,"Только второе число делитель!" s z Text Ttl5,"Решение" invoke MessageBox,NULL,addr Msg5, addr Ttl5,MB_OK .endif .else

.if flag2 == 1

szText Msg6,"Только третье число делитель!" s z Text Ttl6,"Решение" invoke MessageBox,NULL,addr Msg6, addr Ttl6,MB_OK .else

szText Msg7,"Числа не явл делителями!" szText Ttl7/’Решение" invoke MessageBox,NULL,addr Msg7, addr Ttl7,MB_OK .endif .endif

.endif

.endif

ret Deliteli endp

; функция, находящая среднее арифметическое трех чисел ; из строк редактирования трех элементов EditBox и ; выводящая результат в четвертый EditBox SrArifm proc hEl:DWORD,hE2:DWORD,hE3:DWORD,hE4:DWORD

LOCA1 chislol:DWORD

LOCA1 chislo2: DWORD

LOCA1 chislo3:DWORD

LOCA1 rezult:DWORD

invoke SendMessage, hEl,WM_GETTEXT,50,addr buff

invoke atodw,addr buff

mov chislol,eax

invoke SendMessage, hE2,WM_GETTEXT,50,addr buff

invoke atodw,addr buff

mov chislo2,eax

invoke SendMessage, hE3,WM_GETTEXT,50,addr buff

invoke atodw,addr buff

mov chislo3,eax

mov eax,chislol

mov edx,chislo2

add eax,edx

mov edx,chislo3

add eax,edx

mov ebx,3

cdq

idiv ebx

mov rezult,eax

invoke dwtoa,rezult,addr buff

invoke  SendMessage,hE4,WM_SETTEXT,0,addr buff ; запись строки из buff в строку редактирования ; однострочного редактора с дескриптором hE4

ret SrArifm endp

; функция для поиска произведения трех чисел ; из строк редактирования трех элементов EditBox и ; выводящая результат в четвертый EditBox FindMult proc hEl:DWORD,hE2:DWORD,hE3:DWORD,hE4:DWORD

LOCA1 chislol:DWORD

LOCA1 chislo2: DWORD

LOCA1 chislo3:DWORD

LOCA1 rezult:DWORD

invoke SendMessage, hEl,WM_GETTEXT,50,addr buff

invoke atodw,addr buff

mov chislol,eax

invoke SendMessage, hE2,WM_GETTEXT,50,addx buff

invoke atodw,addr buff

mov chislo2,eax

invoke SendMessage, hE3,WM_GETTEXT,50,addx buff

invoke atodw,addr buff

mov chislo3,eax

mov eax,chislol

mov ebx,chislo2

mov ecx,chislo3

imul ebx

imul ecx

mov rezult,eax

invoke dwtoa,rezult,addx buff

invoke  SendMessage,hE4,WM_SETTEXT,0,addr buff

ret FindMult endp

; функция для нахождения суммы квадратов трех чисел ; из строк редактирования трех элементов EditBox и ; выводящая результат в четвертый EditBox FindMultSqr proc hEl:DWORD,hE2:DWORD,hE3:DWORD, hE4:DWORD

LOCA1 chislol:DWORD

LOCA1 chislo2:DWORD

LOCA1 chislo3:DWORD

LOCA1 rezult:DWORD

LOCA1 kvl:DWORD

LOCA1 kv2:DWORD

LOCA1 kv3:DWORD

invoke SendMessage, hEl,WM_GETTEXT,50,addx buff

invoke atodw,addr buff

mov chislol,eax

invoke SendMessage, hE2,WM_GETTEXT,50,addx buff

invoke atodw,addr buff

mov chislo2,eax

invoke SendMessage, hE3,WM_GETTEXT,50,addx buff

invoke atodw,addr buff

mov chislo3,eax

mov eax,chislol

imul eax

mov kvl,eax

mov eax,chislo2

imul eax

mov kv2,eax

mov eax,chislo3

imul eax

mov kv3,eax

mov eax,kvl

mov ebx,kv2

add eax,ebx

mov ebx,kv3

add eax,ebx

mov rezult,eax

invoke dwtoa,rezult,addr buff

invoke  SendMessage,hE4,WM_SETTEXT,0,addr buff

ret FindMultSqr endp End LibMain

Текст, содержащий вызов функций библиотеки, приведен ниже.

.model flat, stdcall

option casemap :none

include d:\masm32\include\windows.inc

include d:\masm32\include\user32.inc

include d:\masm32\include\masm32.inc

include d:\masm32\include\kernel32.inc

includelib d:\masm32\lib\masm32.lib

includelib d:\masm32\lib\user32.lib

includelib d:\masm32\lib\kernel32.lib

includelib tstdll.lib

szText MACRO Name, Text:VARARG

LOCAL 1Ы jmp 1Ы

Name db Text,0 1Ы: ENDM m2m MACRO Ml, M2

push M2

pop Ml ENDM return MACRO arg

mov eax, arg

ret ENDM

DWORD,:DWORD, DWORD,:DWORD, DWORD,:DWORD, DWORD,:DWORD :DWORD,:DWORD, DWORD,:DWORD,: :DWORD,:DWORD,:DWORD,:DWORD FindMultSqr PROTO :DWORD,:DWORD,:DWORD,:DWORD .data

DWORD,

:DWORD

DWORD,

:DWORD

DWORD,

:DWORD,

:DWORD,

:DWORD

DWORD,

:DWORD

Deliteli PROTO SrArifm PROTO FindMult PROTO

WinMain PROTO WndProc PROTO EditSl PROTO

szDisplayName db "DLL-функции",0 CommandLine  dd 0 hWnd dd 0 hlnstance dd 0 nulbyte db 0 hEditl  DWORD 0 hEdit2  DWORD 0 hEdit3  DWORD 0 hEdit4  DWORD 0 hEdit5  DWORD 0 hEdit6  DWORD 0 buff db 50 dup(0) . code start:

invoke GetModuleHandle, NULL

mov hlnstance, eax

invoke GetCommandLine

mov CommandLine, eax

invoke WinMain,hlnstance,NULL,CommandLine,

SW_SHOWDEFAULT invoke ExitProcess,eax WinMain proc hlnst     :DWORD,

hPrevInst :DWORD,

CmdLine   :DWORD,

CmdShow   :DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL Wwd:DWORD LOCAL Wht:DWORD LOCAL Wtx:DWORD LOCAL Wty:DWORD

mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW \

or CS_BYTEALIGNWINDOW mov wc.lpfnWndProc, offset WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL m2m wc.hlnstance, hlnst mov wc.hbrBackground, COLOR_BTNFACE+l mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset szClassName invoke LoadIcon,hlnst,500 mov wc.hlcon, eax

invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor, eax mov wc.hlconSm, 0 invoke RegisterClassEx, ADDR wc

szText szClassName,"MyClass"

invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW, ADDR szClassName, ADDR szDisplayName, WS_OVERLAPPEDWINDOW, 0,0,480,480, NULL,NULL, hInst,NULL mov hWnd,eax

invoke LoadMenu,hInst,600 invoke SetMenu,hWnd,eax invoke ShowWindow,hWnd,SW_SHOWNORMAL invoke UpdateWindow,hWnd StartLoop: invoke GetMessage,ADDR msg,NULL,0,0 cnp eax, 0 je ExitLoop

invoke TranslateMessage, ADDR msg invoke DispatchMessage,  ADDR msg jmp StartLoop ExitLoop: return msg.wParam WinMain endp

WndProc proc hWin   :DWORD, uMsg   :DWORD, wParam :DWORD, lParam :DWORD LOCAL hLib  :DWORD LOCAL nol:DWORD .if uMsg == WM_COMMAND .if wParam == 1000

invoke SendMessage,hWin,WM_SYSCOMMAND, SC_CLOSE, NULL .elseif wParam == 2000

invoke Deliteli,hEditl,hEdit2,hEdit3 .elseif wParam == 2100

invoke SrArifm,hEditl ,hEdit2 ,hEdit3 ,hEdit4 ; результат вычисления среднего арифметического в ; четвертый EditBox

.elseif wParam == 2200

invoke FindMult,hEditl,hEdit2,hEdit3,hEdit5 ; результат вычисления произведения трех чисел -; в пятый EditBox

.elseif wParam == 2300

invoke FindMultSqr ,hEditl ,hEdit2 ,hEdit3 ,hEdit6 ; результат вычисления суммы квадратов трех чисел -; в шестой EditBox

.elseif wParam == 2400 ; очистка всех элементов EditBox mov nol,0

invoke dwtoa,nol,addr buff

invoke SendMessage, hEditl,WM_SETTEXT,0,

addr buff invoke SendMessage, hEdit2,WM_SETTEXT,0,

addr buff invoke SendMessage, hEdit3,WM_SETTEXT,0,

addr buff invoke SendMessage, hEdit4,WM_SETTEXT,0,

addr buff invoke SendMessage, hEdit5,WM_SETTEXT,0,

addr buff invoke SendMessage, hEdit6,WM_SETTEXT,0, addr buff .endif .elseif uMsg == WM_CREATE

invoke EditSl,ADDR nulbyte,100,10,50,23,hWin,200 mov hEditl, eax

invoke EditSl,ADDR nulbyte,100,50,50,23,hWin,200 mov hEdit2, eax

invoke EditSl,ADDR nulbyte,100,90,50,23,hWin,200 mov hEdit3, eax

invoke EditSl,ADDR nulbyte,160,10,50,23,hWin,200 mov hEdit4, eax

invoke EditSl,ADDR nulbyte,160,50,50,23,hWin,200 mov hEdit5, eax

invoke EditSl,ADDR nulbyte,160,90,50,23,hWin,200 mov hEdit6, eax .elseif uMsg == WM_DESTROY

invoke PostQuitMessage,NULL return 0 .endif

invoke DefWindowProc,hWin,uMsg,wParam,lParam ret WndProc endp ; Создание EditBox EditSl proc szMsg:DWORD,a:DWORD,b:DWORD,

wd:DWORD,ht:DWORD,hParent:DWORD,ID:DWORD szText slEdit,"EDIT"

invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR slEdit,szMsg,

WS_VISIBLE or WS_CHILDWINDOW or \ ES_AUTOHSCROLL or ES_NOHIDESEL, a,b,wd,ht,hParent,ID,hlnstance,NULL ret EditSl endp end start

 

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии