О сабклассинге
Сабклассинг - техника, позволяющая приложению перехватывать и обрабатывать сообщения (messages), посылаемые или поставляемые в очередь (posted) определенному окну перед тем, как само окно будет иметь возможность их обработать. В windows практически все, что мы видим - окна (формы, контролы и т.д.). Каждое окно имеет свою "оконную процедуру" (window proc). В обязанности оконной процедуры входит обработка "сообщений", пришедших этому окну. У каждого созданного в системе окна зарегистрированного класса ("editbox", "button" и т.д.) есть "оконная процедура по умолчанию" (default window proc), которая и отвечает за обработку сообщений, приходящих этому окну. Если мы напишем свою оконную процедуру для какого-то окна и заменим ей процедуру по умолчанию, то значит мы произвели subclass этого окна. Это и есть сабклассинг. Сабклассинг производится вызовом следующих api функций: GetWindowLong - для выяснения адреса default window proc (в принципе не обязательна) SetWindowLong - для указания адреса новой window proc (эта функция возвращает указатель на предыдущую функцию окна) CallWindowProc - для последующего вызова default window proc, если надо (см. также DefWindowProc). Сама оконная процедура должна иметь определенный вид: Function WindowProc(ByVal hWnd As Long, ByVal uMsg As _ где: Ну и пример. Private Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Const GWL_WNDPROC = -4 Private lpPrevWndProc As Long ' тут будет указатель на default proc Public Sub start_subclass(hwnd As Long) Public Sub stop_subclass(hwnd As Long) Function WindowProc(ByVal hw As Long, ByVal uMsg As _ '"обрабатываем" сообщение WM_MOVE 'поскольку мы не написали "полноценной" оконной Теперь в форму: Private Sub Form_Load() Private Sub Form_Unload(Cancel As Integer) Ну и напоследок - несколько предостережений: · Пользоваться этим надо очень аккуратно. · Не забывать возращать на место дефолтную функцию. · Не задерживать обработку сообщений (они могут валится сотнями в секунду), что чревато переполнением стека.
Страница сайта http://silicontaiga.ru
Оригинал находится по адресу http://silicontaiga.ru/home.asp?artId=6476 |