Пользователь
Регистрация: 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
|