Уроки Iczelion'а



         

Урок 20. Сабклассинг окна - часть 4


;----------------------------------------- invoke SetWindowLong,hwndEdit,GWL_WNDpROC,addr EditWndproc mov OldWndproc,eax .elseif uMsg==WM_DESTROY

invoke postQuitMessage,NULL .else invoke DefWindowproc,hWnd,uMsg,wparam,lparam ret

.endif xor eax,eax ret Wndproc endp

EditWndproc pROC hEdit:DWORD,uMsg:DWORD,wparam:DWORD,lparam:DWORD .if uMsg==WM_CHAR

mov eax,wparam .if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") || al==VK_BACK .if al>="a" && al<="f"

sub al,20h .endif invoke CallWindowproc,OldWndproc,hEdit,uMsg,eax,lparam ret

.endif .elseif uMsg==WM_KEYDOWN mov eax,wparam .if al==VK_RETURN

invoke MessageBox,hEdit,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION invoke SetFocus,hEdit .else

invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam ret .endif .else

invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam ret .endif xor eax,eax

ret EditWndproc endp end start

Анализ:

invoke SetWindowLong,hwndEdit,GWL_WNDpROC,addr EditWndproc mov OldWndproc,eax

После того, как edit control создан, мы сабклассим его, вызывая SetWindowLong и замещая адрес оригинальной процедуры окна нашим собственным адресом. Заметьте, что мы сохраняем значение адреса оригинальной процедуры, чтобы впоследствии использовать его при вызове CallWindowproc. Заметьте, что EditWndрroc - это обычная оконная процедура.

.if uMsg==WM_CHAR mov eax,wparam .if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") || al==VK_BACK

.if al>="a" && al<="f" sub al,20h .endif invoke CallWindowproc,OldWndproc,hEdit,uMsg,eax,lparam

ret .endif

Внутри EditWndрroc, мы фильтруем сообщения WM_CHAR. Если введен символ в диапазоне 0-9 или a-f, мы передаем его оригинальной процедуре окна. Если это символ нижнего регистра, мы конвертируем его в верхний, добавляя 20h. Заметьте, что если символ не тот, который мы ожидали, мы пропускаем его. Мы не передаем его оригинальной процедуре окна. Поэтому, когда пользователь печатате что-нибудь отличное от 0-9 или a-f, символ не появляется в edit control'е.

.elseif uMsg==WM_KEYDOWN mov eax,wparam .if al==VK_RETURN

invoke MessageBox,hEdit,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION invoke SetFocus,hEdit .else

invoke CallWindowproc,OldWndproc,hEdit,uMsg,wparam,lparam ret .end

Я хочу продемонстрировать силу сабклассинга через перехват клавиши Enter. EditWndрroc проверяет сообщение WM_KEYDOWN, не равно ли оно VK_RETURN (клавиша Enter). Если это так, она отображает окно с сообщением "You pressed the Enter key in the text box!". Если это не клавиша Enter, она передает сообщение оригинальной процедуре.

Вы можете использовать сабклассинг окна, чтобы получить контроль над другими окнами. Эту мощную технику вам следует иметь в своем арсенале.

[C] Iczelion, пер. Aquila.






Содержание  Назад  Вперед