Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скляров И. Изучаем Assembler за 7 дней (2010).pdf
Скачиваний:
1335
Добавлен:
23.02.2015
Размер:
2.11 Mб
Скачать

http://www.sklyaroff.ru

166

end start

7.5. Дочерние окна управления

Мы научились создавать простое оконное приложение. Теперь в окне можно размещать элементы управления – кнопки (buttons), флажки (check boxes), окна редактирования (edit boxes), списки (list boxes), комбинированные списки (combo boxes), строки текста (text strings), полосы прокрутки (scroll bars) и т. д.

Элементы управления на самом деле являются тоже окнами и поэтому их принято называть дочерними окнами управления (child window controls).

Дочернее окно, также как обычное окно, создается с помощью функции CreateWindow или CreateWindowEx. Но в случае стандартных элементов управления регистрировать класс окна функцией RegisterClassEx не нужно. Такой класс уже существует (зарегистрирован) в Windows и имеет одно из следующих имен: "button" (кнопка), "static" (статическое), "scrollbar" (полоса прокрутки), "edit" (окно редактирования), "listbox" (окно списка) или "combobox" (окно комбинированного списка). Вам необходимо только использовать одно из этих имен в качестве параметра класса окна в функции CreateWindow. Другие параметры, которые необходимо указать в этой функции - это дескриптор родительского окна и идентификатор (ID) элемента управления. ID элемента управления должен быть уникальным, он необходим для того, чтобы отличать элементы управления друг от друга.

Обычно дочерние окна создаются во время обработки сообщения WM_CREATE главного окна:

.ELSEIF uMsg==WM_CREATE

invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\ WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or\

ES_AUTOHSCROLL,\ 50,25,300,25,hWnd,EditID,hInstance,NULL

mov hwndEdit,eax

invoke SetFocus, hwndEdit

invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\ WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\ 50,60,100,25,hWnd,ButtonID,hInstance,NULL

mov hwndButton,eax

Вы видите, что в первом вызове CreateWindowEx создается окно редактирования

("edit"), а во втором вызове CreateWindowEx кнопка ("button"). Кроме обычных стилей окна каждый элемент управления имеет свои дополнительные стили. Например, стили кнопок имеют приставку "BS_", а стили окон редактирования - "ES_". Вам придется посмотреть информацию об этих стилях в MSDN или вашем справочнике по Win32 API, т. к. чтобы привести их все нужно отводить отдельную главу книги.

Функция SetFocus вызывается для того, чтобы установить фокус ввода на окно редактирования, для того чтобы пользователь мог сразу вводить в нем текст.

Обратите также внимание, что после создания каждого элемента управления, его дескриптор сохраняется в соответствующей переменной (hwndEdit и hwndButton) для будущего использования.

После того как элемент управления создан, он в случае изменения своего состояния (например, нажатия кнопки) посылает сообщение WM_COMMAND родительскому окну, при этом в младшем слове wParam передается ID элемента, в старшем слове wParam код события, а в lParam дескриптор элемента. В программе по значению этих параметров можно определить, с каким элементом и что произошло:

.ELSEIF uMsg==WM_COMMAND mov eax,wParam

http://www.sklyaroff.ru

167

.IF lParam==1

.IF ax==IDM_GETTEXT

invoke GetWindowText,hwndEdit,ADDR buffer,512

invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK

API-функция GetWindowText принимает текст из окна редактирования, который затем выводится на экран функцией MessageBox.

Участок кода, который обрабатывает нажатие на кнопку, показан ниже:

.IF ax==ButtonID shr eax,16

.IF ax==BN_CLICKED

invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,1

.ENDIF

.ENDIF

Сначала проверяется младшее слово параметра wParam, чтобы убедиться, что он содержит ID кнопки. Если это так, далее проверяется старшее слово wParam, чтобы убедиться, что был послан код уведомления BN_CLICKED, то есть кнопка была нажата.

Функция SendMessage посылает окну сообщение WM_COMMAND с параметрами lParam=1 и IDM_GETTEXT в старшем слове wParam.

Описание функции SendMessage:

LRESULT SendMessage(

HWND hWnd,

UINT Msg, WPARAM wParam, LPARAM lParam

);

Параметры:

hWnd — дескриптор окна, которому посылается сообщение. Если этот параметр равен HWND_BROADCAST, то сообщение посылается всем всплывающим окнам

всистеме, включая невидимые и окна без фокуса ввода и т. д., но кроме дочерних окон;

Msg — тип сообщения;

wParam — дополнительная инфоpмация о сообщении;

lParam — дополнительная инфоpмация о сообщении.

Компиляция программы:

ml /c /coff /Cp wincontrols.asm

link /SUBSYSTEM:WINDOWS /LIBPATH:d:\masm32\lib wincontrols.obj

На рис. 7.3 показан результат работы программы.

Рис. 7.3. Окно программы с элементами управления

http://www.sklyaroff.ru

168

Листинг 7.5. Пример окна с элементами управления (wincontrols.asm)

.386

.model flat,stdcall option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib

.data

 

 

 

ClassName

db

"SimpleWinClass",0

AppName

db

"Дочерние окна управления",0

ButtonClassName db

"button",0

ButtonText

db

"Вывести",0

EditClassName

db

"edit",0

.data?

 

 

 

hInstance

HINSTANCE

?

CommandLine

LPSTR

 

?

hwndButton

HWND

 

?

hwndEdit

HWND

 

?

buffer

db

 

512 dup(?)

.const

 

 

 

ButtonID

equ

1

 

EditID

equ

2

 

IDM_HELLO

equ

1

 

IDM_CLEAR

equ

2

 

IDM_GETTEXT

equ

3

 

IDM_EXIT

equ

4

 

.code

 

 

 

start:

 

 

 

invoke

GetModuleHandle,NULL

mov

hInstance,eax

 

invoke

GetCommandLine

 

mov

CommandLine,eax

invoke

WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT

invoke

ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

LOCAL

wc:WNDCLASSEX

LOCAL

msg:MSG

LOCAL

hwnd:HWND

mov

wc.cbSize,SIZEOF WNDCLASSEX

mov

wc.style, CS_HREDRAW or CS_VREDRAW

http://www.sklyaroff.ru

169

mov

wc.lpfnWndProc, OFFSET WndProc

mov

wc.cbClsExtra,NULL

mov

wc.cbWndExtra,NULL

push

hInst

pop

wc.hInstance

mov

wc.hbrBackground,COLOR_BTNFACE+1

mov

wc.lpszMenuName,NULL

mov

wc.lpszClassName,OFFSET ClassName

invoke

LoadIcon,NULL,IDI_APPLICATION

mov

wc.hIcon,eax

mov

wc.hIconSm,eax

invoke

LoadCursor,NULL,IDC_ARROW

mov

wc.hCursor,eax

invoke

RegisterClassEx, addr wc

INVOKE

CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\

WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\

CW_USEDEFAULT,400,150,NULL,NULL,\ hInst,NULL

mov hwnd,eax

INVOKE ShowWindow, hwnd,SW_SHOWNORMAL INVOKE UpdateWindow, hwnd

.WHILE TRUE

INVOKE GetMessage, ADDR msg,NULL,0,0

.BREAK .IF (!eax)

INVOKE TranslateMessage, ADDR msg INVOKE DispatchMessage, ADDR msg

.ENDW

mov eax,msg.wParam

ret WinMain endp

WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.IF uMsg==WM_DESTROY

invoke PostQuitMessage,NULL

.ELSEIF uMsg==WM_CREATE

invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,\

WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT

or\

 

ES_AUTOHSCROLL,\

 

50,25,300,25,hWnd,EditID,hInstance,NULL

mov

hwndEdit,eax

invoke

SetFocus, hwndEdit

invoke

CreateWindowEx,NULL, ADDR ButtonClassName,ADDR

ButtonText,\

WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\ 50,60,100,25,hWnd,ButtonID,hInstance,NULL

mov hwndButton,eax

.ELSEIF uMsg==WM_COMMAND mov eax,wParam

.IF lParam==1

.IF ax==IDM_GETTEXT