Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.04.2017, 15:31   #1
mikado3333
Пользователь
 
Регистрация: 25.09.2013
Сообщений: 58
По умолчанию Сабкласинг и WM_GETTEXTLENGTH

Приветствую! Помогите разобраться со следующим:
Создал функцию которая создает окно с EDIT CONTROL. Функция может создавать как модальное окно так и не модальное окно. Окно созданное этой функцией работало без нареканий до тех пор пока в программе я не сабкласил другой EDIT CONTROL( не созданный моей функцией) и не послал сообщение WM_GETTEXTLENGTH в сабкласнутый EDIT CONTROL.
После этого сообщения окно созданное моей функцией не закрывается (просто зависает окно) и шрифт не устанавливается.
Установил что если в сабкласнутой процедуре на вызов CallWindowProc возвращать 0, то все работает как часы. Но тогда посылать WM_GETTEXTLENGTH бесполезно всегда длина будет 0. Прошу подскажите где ошибка, 3 дня уже бьюсь с этим вопросом.

Процедура сабкласинга:
Код:
proc	NewDlgProcEditTb 		hwnd,wmsg,wparam,lparam												

				push	ebx esi edi	
				
				invoke	GetParent,		[hwnd]
				invoke	GetParent,		 eax
				mov		ebx, eax
													
				cmp 	[wmsg], WM_CHAR
				je 		.wmchar						
				cmp 	[wmsg], WM_KILLFOCUS 
				je 		.wmkillfocus
				
.def:			invoke  CallWindowProc,	[pOldProcEdit], [hwnd], [wmsg], [wparam], [lparam]
				jmp		.out
	
.wmchar:		cmp		[wparam], VK_TAB
				jnz		.def
				invoke	SendMessage,	ebx, WM_EDITTB, [hwnd], [wparam]
				jmp 	.finish	

.wmkillfocus:	invoke	SendMessage,	ebx, WM_EDITTB, [hwnd], -1
				jmp		.finish 

.finish:		xor		eax, eax
.out:			pop 	edi esi ebx
				
		
ret
endp
Функция создания окна с EDIT
Код:
proc	MyMessage					zagalovok, text, modal											; Окно для сообщений/ информации. Возращает text
; Аналог MessagBox, но без кнопок и возможностью копирования текста
; В случае успеха cf=0, eax - хэндл основного окна MyMessage, edx - хэндл окна edit для  возможности
; изменить текст в окне.
; В случае ошибки cf=1.

; ***ПАРАМЕТРЫ***
; zagalovok - Заголовок окна.
; text		- Адрес текста заносимого в окно.
; modal		- 1 - модальное окно, 0 - не модальное.

locals
hFont		dd 0
hWindow		dd ?
stMSG		MSG	
stRC		RECT
stWCM 		WNDCLASS 0,MyModalProc,0,0,0,0,0,COLOR_BTNHIGHLIGHT,0,.class
stWC 		WNDCLASS 0,MyNoModalProc,0,0,0,0,0,COLOR_BTNHIGHLIGHT,0,.class2
endl

styleEdit	equ  WS_CHILD+WS_VISIBLE+ES_AUTOVSCROLL+ES_READONLY+ES_MULTILINE+WS_VSCROLL

				push	esi edi ebx
			
				lea		edi, [stWC]																	; Определяем какой класс окна выбрать
				mov		esi, .class2
				cmp		[modal], 0
				jz		@f
				lea		edi, [stWCM]
				mov		esi, .class
				
@@:				invoke	FindWindow,			esi, 0													; Определяем нужно ли регистрировать класс окна
				cmp		eax,0
				jnz		@f
				
				INVOKE	GetModuleHandle,	[edi + WNDCLASS.hInstance], 0
				INVOKE	LoadIcon,			[edi + WNDCLASS.hIcon], 0, IDI_EXCLAMATION
				INVOKE  LoadCursor,			[edi + WNDCLASS.hCursor], 0, IDC_ARROW
				
			
				invoke	RegisterClass,		edi
				cmp		eax,0
				jz		.error	

@@:				mov		edx, .title																	; Создаем основное окно 
				cmp		[zagalovok], 0
				cmovne	edx, [zagalovok]
				INVOKE	CreateWindowEx,		[hWindow], 0, esi, edx, WS_VISIBLE+WS_OVERLAPPEDWINDOW,\
											128, 128, 500, 200, 0, 0, [edi + WNDCLASS.hInstance],0 
				cmp		eax,0
				jz		.error							
								
				lea		ebx, [stRC]																	; Создаем окно едит
				invoke  GetClientRect,	 	[hWindow], ebx
				
				INVOKE  CreateWindowEx,		edi, WS_EX_CLIENTEDGE, .edit, [text], styleEdit, 0,\
											0,[ebx + RECT.right],[ebx + RECT.bottom],[hWindow],0,\
											[edi + WNDCLASS.hInstance],0
				cmp		eax,0
				jz		.error							
			
				INVOKE	CreateFont, 		[hFont], 18, 0, 0, 0, 500, 0, 0, 0,DEFAULT_CHARSET,\	; Создать шрифт, который будет использоваться для отображения 
											OUT_DEFAULT_PRECIS ,CLIP_DEFAULT_PRECIS,\				; всех строк внутри элементы управления окна приложения.	
											PROOF_QUALITY, FIXED_PITCH + FF_DONTCARE, .FontName
				cmp		eax,0
				jz		.error
									
				invoke 	SendMessage,		edi, WM_SETFONT, [hFont], 1	
			
				cmp		[modal], 0
				jz		.exit
				
				lea		ebx,[stMSG]
.msg_loop: 																							;Цикл  сообщений
				invoke	GetMessage,ebx,0,0,0														;Выбираем сообщения из очереди сообщений  Приложения
				cmp 	eax,0																		;Проверяем не получила ли GetMessage сообщения WM_QUIT (eax =0)
				je 		.exit																		;Если 0  то завершаем программу
				invoke 	TranslateMessage,ebx														;Переводим нажатые  клавиши в сообщении (WM_CHAR) т.е. с учетом клавиатурной раскладки(рус/англ)
				invoke 	DispatchMessage,ebx															;Пересылаем сообщение процедуре соответствующего окна
				jmp 	.msg_loop 	

.exit:			mov		eax, [hWindow]
				mov		edx, edi
				pop		ebx edi esi
				clc
ret
.error:			invoke  DeleteObject, [hFont]
				pop		ebx edi esi
				stc
ret
				
.title 		db "Информация",0
.class 		db "E1",0
.class2 	db "E2",0
.edit		db 'EDIT',0	
.FontName	db "Courier New",0
			
endp
Процедура окна созданного моей функцией

Код:
proc	MyModalProc					hwnd,wmsg,wparam,lparam											; Процедура окна моего окна сообщения (Модальное)

locals
class	db "E1",0
edit	db 'EDIT',0
rc		RECT
endl

				push	ebx esi edi
				cmp     [wmsg],WM_CLOSE
				jz 		.close		
						cmp     [wmsg],WM_SIZE
						jz 		.size
								cmp     [wmsg],WM_DESTROY
								jz 		.destroy
				
				invoke	DefWindowProc,		[hwnd],[wmsg],[wparam],[lparam]
				jmp		.out

.close:			invoke	GetWindow, 			[hwnd], GW_CHILD
				invoke	SendMessage,		eax, WM_GETFONT, 0, 0
				invoke	DeleteObject,		eax	
				invoke 	DestroyWindow,		[hwnd] 
				lea		esi, [class]
				invoke	FindWindow,			esi, 0
				cmp		eax,0
				jnz		.exit
		
				invoke	GetModuleHandle,	0
				invoke	UnregisterClass,	esi, eax
				jmp		.exit
				
.destroy:		invoke  PostQuitMessage,	0
				jmp		.exit				
				
.size:			lea		ebx, [rc]
				invoke  GetClientRect,	 	[hwnd], ebx
				lea		eax, [edit]
				invoke	FindWindowEx,		[hwnd], 0, eax, 0
				invoke  MoveWindow,		 	eax, 0, 0, [ebx + RECT.right], [ebx + RECT.bottom], TRUE	

.exit:			mov 	eax, 0	
.out:			pop 	edi esi ebx	
ret	
endp
mikado3333 вне форума Ответить с цитированием
Старый 23.04.2017, 17:40   #2
mikado3333
Пользователь
 
Регистрация: 25.09.2013
Сообщений: 58
По умолчанию

Решено. Причина оказалась в дальнейшем коде программы - не правильно выделил стек (не кратно 4).
mikado3333 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск