16.07.2018, 21:15 [+3 UTC]
в нашей команде: 2 882 чел. | участники онлайн: 3 (рекорд: 21)

:: РЕГИСТРАЦИЯ

:: задать вопрос

:: все разделы

:: правила

:: новости

:: участники

:: доска почёта

:: форум

:: блоги

:: поиск

:: статистика

:: наш журнал

:: наши встречи

:: наша галерея

:: отзывы о нас

:: поддержка

:: руководство

Версия системы:
7.47 (16.04.2018)

Общие новости:
13.04.2018, 10:33

Форум:
16.07.2018, 10:05

Последний вопрос:
16.07.2018, 07:17

Последний ответ:
13.07.2018, 17:32

Последняя рассылка:
15.07.2018, 19:45

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
07.11.2009, 10:14 »
Sergeva
Спасибо большое вам, все работает отлично! [вопрос № 174039, ответ № 256245]
09.03.2011, 00:49 »
Евгений
Огромное спасибо! Столь исчерпывающий ответ просто впечатляет! [вопрос № 182418, ответ № 266144]

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Зенченко Константин Николаевич
Статус: Модератор
Рейтинг: 311
cain52
Статус: 1-й класс
Рейтинг: 3
Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 0

Перейти к консультации №:
 

Консультация онлайн # 193065
Раздел: • Assembler
Автор вопроса: cupoma58 (Посетитель)
Отправлена: 10.04.2018, 14:37
Поступило ответов: 1

Здравствуйте! У меня возникли сложности с таким вопросом:
Возвращаясь к взаимоотношениям С/С++ и ассемблера:

...
    call    CreateWindowExA@48       ;создали кнопку 
    mov	    HWNDBTN,EAX
...  
  wmcomnd:
;блок обработки событий кнопки 
    mov     EAX,HWNDBTN
    cmp     DWORD ptr [EBP+14h],EAX  ;если такой нет - exit
    jne	    exit
;-----------------
;GetDlgItemText(hWnd:HWND, IDC_KEY:HWNDBTN12, str:?, 15); -->получаем символ кнопки
;SetDlgItemText(hWnd:HWND, IDC_EDIT:HWNDEDT, str:?);      -->добавляем на дисплей
;-------------------------
;получаем символ с кнопки:                                          
    push  15
    push  0                  ;?
    push  HWNDBTN
    push  HWND               ;окно-родитель
    call  GetDlgItemTextA@4  ;unresolved external symbol _GetDlgItemTextA@4
;добавляем на дисплей:  
    push  0                  ;?
    push  HWNDEDT
    push  HWND 
    call  SetDlgItemTextA@4  ;неразрешённое внешнее имя (id) _SetDlgItemTextA@4
;--------------------------  
  noexit:
	mov	    EAX,0
	jmp	    finish
...

Этот код не работает. Почему - unresolved? Специально создал def-файлы с используемых dll-библиотек,
всё на месте.
В Win 32 API аргумент "str" трактуется:
-- в первом случае, как буфер для приёма текста
-- во втором случае, как строка (заканчивающаяся пустым символом)
В любом случае - это обращение к адресу. Только - к какому(-ким)?

Наиболее оптимальным видится такой вариант:
...
wndproc:
...
  wmcreate:
    ...
    call  CreateWindowExA@48      ;создали кнопку 
    mov	  HWNDBTN,EAX
    .if EAX==WM_COMMAND & ?==HWNDBTN               
      invoke GetDlgItemText,HWND,HWNDBTN,NULL,15 
      invoke SetDlgItemText,HWND,HWNDEDT,NULL      
    .endif
...

Kак мне связать событие конкретной кнопки с WM_COMMAND?

Состояние: Консультация закрыта

Ответ # 276432 от Лысков Игорь Витальевич (Старший модератор)

Здравствуйте, cupoma58!
Подправленный код из мини-форума. Под masm32.
Пришлось добавить стандартные include и lib от masm32, константы да переменные
Соответственно, пришлось переименовать поля структур.
Изменены функции для получения/записи текста контролов.

Код (Assembler) :: выделить код
;fenix.asm, арифмометр с обработкой 2-х кнопок

	.386			;32-битный код
	.model flat, stdcall	;модель памяти и соглашение о вызове параметров
	option casemap :none	;различаем большие-малые буковки

; include files
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm

; libraries
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

STYLE	equ	CS_HREDRAW or CS_VREDRAW
STYLBTN	equ	WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON or WS_TABSTOP
STYLEDT	equ	WS_CHILD or WS_VISIBLE or WS_BORDER

	.data
TITLENAME	db	"fenix",0
CLASSNAME	db	"fenixClass",0
CPBUT12		db	"7",0
CPBUT14		db	"9",0
CPEDT		db	0
CLSBUTN		db	"button",0
CLSEDIT		db	"edit",0

	.data?
WC		WNDCLASSEX	<>
msg		MSG		<>
HINST		dd		?
HWNDBUT12	dd		?
HWNDBUT14	dd		?
HWNDEDT		dd		?
HWNDMAIN	dd		?
BUF		db		16 dup(?)

	.code 
go:
	push 0
	call GetModuleHandle ;получить дескриптор приложения
	mov [HINST],EAX
wndproc: ;заполняем структуру окна 
	mov [WC.cbSize],sizeof WNDCLASSEX
	mov [WC.style],STYLE ;стиль(здесь и далее-смотри fenix.inc)
	mov [WC.lpfnWndProc],offset winproc ;обрабатываем сообщения
	mov [WC.cbClsExtra],0
	mov [WC.cbWndExtra],0
	mov EAX, [HINST]
	mov [WC.hInstance],EAX
	push IDI_APPLICATION ;иконка окна (по желанию)
	push 0
	call LoadIconA
	mov [WC.hIcon],EAX
	mov [WC.hIconSm],EAX
	push IDC_ARROW ;курсор окна
	push 0
	call LoadCursor
	mov [WC.hCursor],EAX
	mov [WC.hbrBackground],18 ;цвет окна
	mov [WC.lpszMenuName],0
	mov [WC.lpszClassName],offset CLASSNAME
	push offset WC ;загоняем созданный класс в стэк и... 
	call RegisterClassEx ;...регистрируем его

	;окно создадим в развёрнутом виде:
	push 0
	push [HINST]
	push 0
	push 0
	push 300	;dy - высота окна
	push 380	;dx - ширина окна
	push 200	;y - координата левого верхнего угла
	push 200	;x - координата левого верхнего угла
	push WS_OVERLAPPEDWINDOW ;перекрывающий стиль
	push offset TITLENAME ;имя окна
	push offset CLASSNAME ;имя класса
	push 0
	call CreateWindowEx
	cmp EAX,0
	jz _err 
	mov [HWNDMAIN],EAX ;если всё получилось - добавляем адрес,
	
	push SW_SHOWNORMAL ;стиль и
	push [HWNDMAIN]
	call ShowWindow ;показываем созданное окно
	push [HWNDMAIN]
	call UpdateWindow ;перерисовываем видимую часть окна 

msg_loop: ;цикл обработки сообщений
	push 0
	push 0
	push 0
	push offset msg
	call GetMessageA
	cmp EAX,0 ;если MSG нет...
	je end_loop ;...окончание цикла

	push offset msg
	call TranslateMessage
	push offset msg
	call DispatchMessageA
	jmp msg_loop ;закольцовываем

end_loop:
	push [msg.wParam]
	call ExitProcess ;выход из программы (закрыть процесс)
	
_err: ;символ "_" перед именем - общедоступность
	jmp end_loop
	
winproc: ;процедура окна - чем занимаемся
	push EBP 
	mov EBP,ESP 
	push EBX
	push ESI
	push EDI 
	cmp dword ptr [EBP+0Ch],WM_CREATE 
	je wmcreate 
	cmp dword ptr [EBP+0Ch],WM_COMMAND ;что сработало?..
	je wmcmd ;...смотрим тут
	cmp dword ptr [EBP+0Ch],WM_DESTROY 
	je wmdestroy 
	jmp defwndproc

wmcreate: 
;создали кнопку '7': 
	push 0
	push [HINST]
	push 0Eh 
	push [EBP+8h]
	push 45	
	push 65	
	push 55	
	push 5	
	push STYLBTN
	push offset CPBUT12 ;имя окна (символ на кнопке)
	push offset CLSBUTN ;имя класса
	push 0
	call CreateWindowEx ;функция создания окна
	mov HWNDBUT12,EAX ;сохраняем адрес кнопки
	
;создали кнопку '9': 
	push 0
	push [HINST]
	push 10h 
	push [EBP+8h]
	push 45	
	push 65	
	push 55 
	push 80	
	push STYLBTN
	push offset CPBUT14 
	push offset CLSBUTN 
	push 0
	call CreateWindowEx
	mov HWNDBUT14,EAX 
	
;создали окно редактирования:
	push 0
	push [HINST]
	push 1 
	push [EBP+8h]
	push 30	
	push 350	
	push 10	
	push 10	
	push STYLEDT
	push offset CPEDT ;символы в окне: " "
	push offset CLSEDIT ;имя класса
	push 0
	call CreateWindowEx
	mov HWNDEDT,EAX ;сохраняем адрес окна редактирования
	push HWNDEDT 
	call SetFocus
	mov EAX, 0
	jmp finish
	
wmcmd: 
	movzx EAX,word ptr[EBP+10h] ;wParam
	cmp EAX,0Eh
	je handl1_2
	cmp EAX,10h
	je handl1_2
	jmp defwndproc

handl1_2:
	push 16
	push offset BUF 
	push [EBP+14h] ;lParam = button handle
	call GetWindowText
	push offset BUF 
	push [HWNDEDT] 
	call SetWindowText
	
_exit:
	mov EAX,0
	jmp finish
	
wmdestroy:
	push 0
	call PostQuitMessage
	
defwndproc: ;обработка сообщений
	push [EBP+14h] 
	push [EBP+10h] ;WPARAM
	push [EBP+0Ch] 
	push [EBP+ 8h] 
	call DefWindowProc
	
finish:
	pop EDI
	pop ESI
	pop EBX
	pop EBP
	ret 16

	end go


Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 19.04.2018, 16:00

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 193065

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 1

 +1 
 
= общий = | 10.04.2018, 16:02 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

1)

© Цитата:
unresolved
Это значит неразрешенная внешняя ссылка. Т.е. Имя как бы есть, сказано, что оно внешнее, но реально оно нигде не найдено.
Данные функции имеют четыре параметра, поэтому необходимо писать в конце @16 (раз уж Вы решили писать в стиле С++)
2)
© Цитата:
В Win 32 API аргумент "str" трактуется:
-- в первом случае, как буфер для приёма текста
-- во втором случае, как строка (заканчивающаяся пустым символом)
В любом случае - это обращение к адресу. Только - к какому(-ким)?
Так и надо указывать адрес буфера, а не NULL!
Куда, по-Вашему, писать принятый текст, и что отправлять в edit?

Честно говоря, в голове у Вас каша. Например, не видите отличия между ID контрола от его HANDLE.
В целом, нет четкого понимания строения программы под Windows.

Но смею Вас обрадовать: это дело поправимое smile
Приведите весь свой код. И мы общими усилиями сформируем правильный код smile

Да, для какого компилятора пишете? MASM32, FASM, ... ?

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 2

= общий = | 11.04.2018, 10:52 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Делаю простой калькулятор, на Java и Android - получилось. На assembler получилась , пока, только графическая часть. Пишу для masm32. Вот, упёрся в обработку кнопок. Трудно найти литературу по обработке событий с элементами окна.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 3

 +1 
 
= общий = | 11.04.2018, 11:12 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

© Цитата:
Делаю простой калькулятор
Ну тогда надо делать по-другому smile
Зная ID кнопки, Вы легко можете получить некий код (символ) (цифру, операцию, неважно), соответствующий данной кнопке.
Далее работаете уже с полученным кодом (символом).
Иначе, следующая кнопка тут же затрет старое содержимое редактора. Что же это за калькулятор? smile

В принципе нет ничего сложного. smile Когда создается орган управления, ему присваивается ID, назначенное программистом число.
При нажатии на кнопку приходит событие WM_COMMAND с LOWORD(wParam) = ID нажатой кнопки. Собственно все!
Строите switch (в ассемблере просто последовательное сравнение со всеми нужными ID) по отработке каждой кнопки и вуаля!

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

• Отредактировал: Лысков Игорь Витальевич (Старший модератор)
• Дата редактирования: 11.04.2018, 11:36

cupoma58
Посетитель

ID: 401688

# 4

= общий = | 11.04.2018, 11:50 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Благодарю за совет, попробую smile

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 5

= общий = | 11.04.2018, 16:38 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Дарю Вам небольшой проектик hexcalc.rar (8.8 кб), переделанный из С++, автор Петзольд.
Кстати, найдите книжки и почитайте. Весьма неплохое руководство для старта в WinApi.

Данный проект будет весьма интересен и полезен. Применены несколько неплохих решений...

Ничего не буду рассказывать, разберитесь самостоятельно... smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 6

= общий = | 17.04.2018, 10:48 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Это был о-о-очень "сырой" код. Не стоило его выкладывать.

• Отредактировал: cupoma58 (Посетитель)
• Дата редактирования: 24.04.2018, 10:10

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 7

= общий = | 17.04.2018, 10:57 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Хорошо, посмотрю, когда будет время

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 8

= общий = | 17.04.2018, 11:05 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Благодарю, для пенсионера - время относительно.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 9

= общий = | 17.04.2018, 12:59 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Немного подправил smile
Пришлось добавить стандартные include и lib от masm32, константы да переменные :)
Раз не дали свои.
Соответственно, пришлось переименовать поля структур.
Поменял функции для получения/записи текста контролов.
Развлекайтесь дальше smile

Код (Assembler) :: выделить код
;fenix.asm, арифмометр с обработкой 2-х кнопок

	.386			;32-битный код
	.model flat, stdcall	;модель памяти и соглашение о вызове параметров
	option casemap :none	;различаем большие-малые буковки

; include files
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm

; libraries
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

STYLE	equ	CS_HREDRAW or CS_VREDRAW
STYLBTN	equ	WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON or WS_TABSTOP
STYLEDT	equ	WS_CHILD or WS_VISIBLE or WS_BORDER

	.data
TITLENAME	db	"fenix",0
CLASSNAME	db	"fenixClass",0
CPBUT12		db	"7",0
CPBUT14		db	"9",0
CPEDT		db	0
CLSBUTN		db	"button",0
CLSEDIT		db	"edit",0

	.data?
WC		WNDCLASSEX	<>
msg		MSG		<>
HINST		dd		?
HWNDBUT12	dd		?
HWNDBUT14	dd		?
HWNDEDT		dd		?
HWNDMAIN	dd		?
BUF		db		16 dup(?)

	.code 
go:
	push 0
	call GetModuleHandle ;получить дескриптор приложения
	mov [HINST],EAX
wndproc: ;заполняем структуру окна 
	mov [WC.cbSize],sizeof WNDCLASSEX
	mov [WC.style],STYLE ;стиль(здесь и далее-смотри fenix.inc)
	mov [WC.lpfnWndProc],offset winproc ;обрабатываем сообщения
	mov [WC.cbClsExtra],0
	mov [WC.cbWndExtra],0
	mov EAX, [HINST]
	mov [WC.hInstance],EAX
	push IDI_APPLICATION ;иконка окна (по желанию)
	push 0
	call LoadIconA
	mov [WC.hIcon],EAX
	mov [WC.hIconSm],EAX
	push IDC_ARROW ;курсор окна
	push 0
	call LoadCursor
	mov [WC.hCursor],EAX
	mov [WC.hbrBackground],18 ;цвет окна
	mov [WC.lpszMenuName],0
	mov [WC.lpszClassName],offset CLASSNAME
	push offset WC ;загоняем созданный класс в стэк и... 
	call RegisterClassEx ;...регистрируем его

	;окно создадим в развёрнутом виде:
	push 0
	push [HINST]
	push 0
	push 0
	push 300	;dy - высота окна
	push 380	;dx - ширина окна
	push 200	;y - координата левого верхнего угла
	push 200	;x - координата левого верхнего угла
	push WS_OVERLAPPEDWINDOW ;перекрывающий стиль
	push offset TITLENAME ;имя окна
	push offset CLASSNAME ;имя класса
	push 0
	call CreateWindowEx
	cmp EAX,0
	jz _err 
	mov [HWNDMAIN],EAX ;если всё получилось - добавляем адрес,
	
	push SW_SHOWNORMAL ;стиль и
	push [HWNDMAIN]
	call ShowWindow ;показываем созданное окно
	push [HWNDMAIN]
	call UpdateWindow ;перерисовываем видимую часть окна 

msg_loop: ;цикл обработки сообщений
	push 0
	push 0
	push 0
	push offset msg
	call GetMessageA
	cmp EAX,0 ;если MSG нет...
	je end_loop ;...окончание цикла

	push offset msg
	call TranslateMessage
	push offset msg
	call DispatchMessageA
	jmp msg_loop ;закольцовываем

end_loop:
	push [msg.wParam]
	call ExitProcess ;выход из программы (закрыть процесс)
	
_err: ;символ "_" перед именем - общедоступность
	jmp end_loop
	
winproc: ;процедура окна - чем занимаемся
	push EBP 
	mov EBP,ESP 
	push EBX
	push ESI
	push EDI 
	cmp dword ptr [EBP+0Ch],WM_CREATE 
	je wmcreate 
	cmp dword ptr [EBP+0Ch],WM_COMMAND ;что сработало?..
	je wmcmd ;...смотрим тут
	cmp dword ptr [EBP+0Ch],WM_DESTROY 
	je wmdestroy 
	jmp defwndproc

wmcreate: 
;создали кнопку '7': 
	push 0
	push [HINST]
	push 0Eh 
	push [EBP+8h]
	push 45	
	push 65	
	push 55	
	push 5	
	push STYLBTN
	push offset CPBUT12 ;имя окна (символ на кнопке)
	push offset CLSBUTN ;имя класса
	push 0
	call CreateWindowEx ;функция создания окна
	mov HWNDBUT12,EAX ;сохраняем адрес кнопки
	
;создали кнопку '9': 
	push 0
	push [HINST]
	push 10h 
	push [EBP+8h]
	push 45	
	push 65	
	push 55 
	push 80	
	push STYLBTN
	push offset CPBUT14 
	push offset CLSBUTN 
	push 0
	call CreateWindowEx
	mov HWNDBUT14,EAX 
	
;создали окно редактирования:
	push 0
	push [HINST]
	push 1 
	push [EBP+8h]
	push 30	
	push 350	
	push 10	
	push 10	
	push STYLEDT
	push offset CPEDT ;символы в окне: " "
	push offset CLSEDIT ;имя класса
	push 0
	call CreateWindowEx
	mov HWNDEDT,EAX ;сохраняем адрес окна редактирования
	push HWNDEDT 
	call SetFocus
	mov EAX, 0
	jmp finish
	
wmcmd: 
	movzx EAX,word ptr[EBP+10h] ;wParam
	cmp EAX,0Eh
	je handl1_2
	cmp EAX,10h
	je handl1_2
	jmp defwndproc

handl1_2:
	push 16
	push offset BUF 
	push [EBP+14h] ;lParam = button handle
	call GetWindowText
	push offset BUF 
	push [HWNDEDT] 
	call SetWindowText
	
_exit:
	mov EAX,0
	jmp finish
	
wmdestroy:
	push 0
	call PostQuitMessage
	
defwndproc: ;обработка сообщений
	push [EBP+14h] 
	push [EBP+10h] ;WPARAM
	push [EBP+0Ch] 
	push [EBP+ 8h] 
	call DefWindowProc
	
finish:
	pop EDI
	pop ESI
	pop EBX
	pop EBP
	ret 16

	end go

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

cupoma58
Посетитель

ID: 401688

# 10

= общий = | 24.04.2018, 10:48 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Хочу извинится за выложенный код, поспешил я. С графикой и добавлением символов в редактор я разобрался, но столкнулся с другой
проблемой. Код "через стек" получается очень объёмным. На момент обработки цифровых кнопок - более 500 строк. Код "через invoke+API" более чем в три раза меньше. Возможно в API есть аналоги нижеприведённых функций:

setText() <---> SetDlgItemTextA(hwnd,id_edt,str)
setText(getText() + "str") <---> ?
setText(" " + result) <---> ?
Double.parseDouble(text) <---> ?  ;или придётся преобразовывать "str <---> hex" перед арифметическими действиями ?

Посоветуйте литературу. Есть ощущение - без углубления в теорию не обойтись.
А по добавлению символов у меня сработал код:
...
wmcmd:
  mov  eax,[ebp+8h]     ;wParam
  cmp  id_but7
  je     hcond1
  cmp  id_but9
  je     hcond2
  jmp  exit
  hcond1:
    push  offset but7
    push  id_edt
    push  hwnd
    call   SetDlgItemTextA@12
    jmp  exit
  hcond2:
    push  offset but9
    push  id_edt
    push  hwnd
    call   SetDlgItemTextA@12
    jmp  exit
    ...
    exit  eax,0
    finish:
      ;восстанавливаем регистры

Только с накоплением символов не получается, один заменяет другой.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 11

= общий = | 24.04.2018, 13:28 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
cupoma58:

Код (Assembler) :: выделить код
;fenix.asm, арифмометр с обработкой 2-х кнопок

	.386			;32-битный код
	.model flat, stdcall	;модель памяти и соглашение о вызове параметров
	option casemap :none	;различаем большие-малые буковки

; include files
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm

; libraries
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

STYLE	equ	CS_HREDRAW or CS_VREDRAW
STYLBTN	equ	WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON or WS_TABSTOP
STYLEDT	equ	WS_CHILD or WS_VISIBLE or WS_BORDER

	.data
TITLENAME	db	"fenix",0
CLASSNAME	db	"fenixClass",0
CPBUT12		db	"7",0
CPBUT14		db	"9",0
CPEDT		db	0
CLSBUTN		db	"button",0
CLSEDIT		db	"edit",0

	.data?
WC		WNDCLASSEX	<>
msg		MSG		<>
HINST		dd		?
HWNDBUT12	dd		?
HWNDBUT14	dd		?
HWNDEDT		dd		?
HWNDMAIN	dd		?
BUF		db		16 dup(?)

	.code 
go:
	invoke GetModuleHandle,0 ;получить дескриптор приложения
	mov [HINST],EAX
wndproc: ;заполняем структуру окна 
	mov [WC.cbSize],sizeof WNDCLASSEX
	mov [WC.style],STYLE ;стиль(здесь и далее-смотри fenix.inc)
	mov [WC.lpfnWndProc],offset winproc ;обрабатываем сообщения
	mov [WC.cbClsExtra],0
	mov [WC.cbWndExtra],0
	mov EAX, [HINST]
	mov [WC.hInstance],EAX
	invoke LoadIconA,0,IDI_APPLICATION ;иконка окна (по желанию)
	mov [WC.hIcon],EAX
	mov [WC.hIconSm],EAX
	invoke LoadCursor,0,IDC_ARROW ;курсор окна
	mov [WC.hCursor],EAX
	mov [WC.hbrBackground],18 ;цвет окна
	mov [WC.lpszMenuName],0
	mov [WC.lpszClassName],offset CLASSNAME
	invoke RegisterClassEx,ADDR WC ;...регистрируем его

	;окно создадим в развёрнутом виде:
	invoke CreateWindowEx,0,ADDR CLASSNAME,ADDR TITLENAME,WS_OVERLAPPEDWINDOW,200,200,380,300,0,0,[HINST],0
	cmp EAX,0
	jz _err 
	mov [HWNDMAIN],EAX ;если всё получилось - добавляем адрес,
	
	invoke ShowWindow,[HWNDMAIN],SW_SHOWNORMAL ;показываем созданное окно
	invoke UpdateWindow,[HWNDMAIN] ;перерисовываем видимую часть окна 

msg_loop: ;цикл обработки сообщений
	invoke GetMessageA,ADDR msg,0,0,0
	cmp EAX,0 ;если MSG нет...
	je end_loop ;...окончание цикла

	invoke TranslateMessage,ADDR msg
	invoke DispatchMessageA,ADDR msg
	jmp msg_loop ;закольцовываем

end_loop:
	invoke ExitProcess,[msg.wParam] ;выход из программы (закрыть процесс)
	
_err: ;символ "_" перед именем - общедоступность
	jmp end_loop
	
winproc: ;процедура окна - чем занимаемся
	push EBP 
	mov EBP,ESP 
	push EBX
	push ESI
	push EDI 
	cmp dword ptr [EBP+0Ch],WM_CREATE 
	je wmcreate 
	cmp dword ptr [EBP+0Ch],WM_COMMAND ;что сработало?..
	je wmcmd ;...смотрим тут
	cmp dword ptr [EBP+0Ch],WM_DESTROY 
	je wmdestroy 
	jmp defwndproc

wmcreate: 
;создали кнопку '7': 
	invoke CreateWindowEx,0,ADDR CLSBUTN,ADDR CPBUT12,STYLBTN,5,55,65,45,[EBP+8h],0eh,[HINST],0
	mov HWNDBUT12,EAX ;сохраняем адрес кнопки
	
;создали кнопку '9': 
	invoke CreateWindowEx,0,ADDR CLSBUTN,ADDR CPBUT14,STYLBTN,80,55,65,45,[EBP+8h],10h,[HINST],0
	mov HWNDBUT14,EAX 
	
;создали окно редактирования:
	invoke CreateWindowEx,0,ADDR CLSEDIT,ADDR CPEDT,STYLEDT,10,10,350,30,[EBP+8h],1,[HINST],0
	mov HWNDEDT,EAX ;сохраняем адрес окна редактирования
	invoke SetFocus, eax	;HWNDEDT
	mov EAX, 0
	jmp finish
	
wmcmd: 
	movzx EAX,word ptr[EBP+10h] 
	cmp EAX,0Eh
	je handl1_2
	cmp EAX,10h
	je handl1_2
	jmp defwndproc

handl1_2:
	invoke GetWindowText, [HWNDEDT], ADDR BUF, 16
	add  eax, offset BUF	;eax = lenght of text
	invoke GetWindowText, [EBP+14h], eax, 16 ;lParam = button handle
	invoke SetWindowText, [HWNDEDT], ADDR BUF
	
_exit:
	mov EAX,0
	jmp finish
	
wmdestroy:
	invoke PostQuitMessage, 0
	
defwndproc: ;обработка сообщений
	invoke DefWindowProc, [EBP+8h],[EBP+0Ch],[EBP+10h],[EBP+14h]
	
finish:
	pop EDI
	pop ESI
	pop EBX
	pop EBP
	ret 16

	end go

© Цитата:
setText() <---> SetDlgItemTextA(hwnd,id_edt,str)
Я предпочел SetWindowText()
© Цитата:
setText(getText() + "str") <---> ?
См. отработку handl1_2
© Цитата:
setText(" " + result) <---> ?
Аналогично
© Цитата:
Double.parseDouble(text) <---> ? ;или придётся преобразовывать "str <---> hex" перед арифметическими действиями ?
А это, как сделаете.
Можно хранить в целом, преобразовывать при выводе. А можно хранить в строке, преобразовывать при использовании...
А еще есть функции SetDlgItemInt и GetDlgItemInt, которые делают преобразования автоматически. Храним в целом, оперируем, отдаем edit-у целое , показывается числовая строка (десятичное число).

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.22174 сек.

© 2001-2018, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.47 от 16.04.2018