Программирование на Visual Basic

visual basic ооп

    Интерфейс Windows основан на функциях окон и системе сообщений. Работа с окном осуществляется по следующий схеме.
  1. Вызывается функция окна, которая получает сообщение.
  2. Функция окна обрабатывает сообщение.
  3. Сообщение передаётся стандартной функции окна.

Сообщения окнам приходят от различных объектов: меню, элементов управления, мыши, клавиатуры... VB также работает по этой схеме, но программисту достаётся не сама функция окна, а событие вызываемое этой функцией. Эта система удобна, но она ограничивает опытных программистов, заставляя идти на различные ухищрения. Одним из способов преодолеть ограниченные стандарты является субклассирование.
    Субкласирование - это метод перехвата сообщений, с помощью собственной функции окна, подменяющей исходную. Другими словами. Вы подсовываете Windows собственную функцию, которая выполнив все пункты схемы обработки сообщений, передаёт сообщение настоящей функции окна.
    Как очевидно функция должна иметь строго определённый вид:

Function WndProc (Byval hWnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long,ByVal lParam As Long) As Long

Эта функция может работать как угодно, но она НЕ ДОЛЖНА изменять параметры сообщений, если это действительно не требуется, и в конце работы она должна вызывать заменённую функцию окна.
    Способы субклассирования можно разделить на три группы:

  1. Использование ActiveX элементов управления. Этот вариант наиболее безопасен.
  2. Подмена функции окна вручную. Это избавляет от проблем при использовании OCX. Однако этот способ менее надёжен.
  3. Этот способ по сути не является настоящим субклассированием, однако он не менее полезен чем предыдущие. Суть его в том, что средствами API создаётся класс окна, и само окно, которое используется для приёма сообщений.

Если Вы хотите использовать субклассирование, Вам нужно придерживаться определённых правил безопасности:

  1. Субклассированное окно должно быть возвращено в нормальное состояние перед выгрузкой(уничтожением). Для этого подходит событие Unload (Terminate).
  2. Не завершать программу с помощью команды End или кнопки Стоп до выгрузки субклассированного окна. Также нужно внимательно отследить все ошибки, способные вызвать такое завершение.
  3. Если Вы этого не сделаете наступит крах IDE. Поэтому чаще сохраняйте свой проект.

Теперь перейдём к техническим подробностям.
Для подмены функции окна, нам понадобиться следующий набор:

GetWindowLong
SetWindowLong
CallWindowProc
GWL_WNDPROC

Итак, действуем по следующему плану:

" При подмене функции (Чаще всего Событие Form_Load)
" Сохраняем адрес оконной функции в глобальной переменной
hOldProc = GetWindowLong(hWnd, GWL_WNDPROC)
" Заменяем оконную функцию.
SetWindowProc hWnd, GWL_WNDPROC, AdressOf WndProc
" Функция WndProc должна быть определена в МОДУЛЕ, методы объектов не допускаются.

" При восстановлении (Form_Unload)
" Теперь - обратный ход.
SetWindowLong hWnd, GWL_WNDPROC, hOldProc.

  Рассмотрим требования к подменяющей функции.
Она должна заканчиваться подобным кодом:
WndProc=CallWindowProc(hOldProc,hWnd,wMsg,wParam,lParam)
При этом НЕЛЬЗЯ использовать Exit Function до этого вызова.
Если Вы используете обработчик ошибок, он должен вызывать CallWindowProc.
То есть, во всех точках выхода новой оконной функции должна вызываться CallWindowProc.

   Вот в общем-то и всё что я хотел сообщить о субклассировании. В завершение добавлю. Эта техника применима в VB версии 5 и старше. В "более младших" версиях так или иначе придётся использовать ActiveX элементы управления.
   И наконец. Если Вам не нужно перехватывать сообщения некоего конкретного окна, то лучше будет, создав окно средствами API, использовать его для обработки сообщений. Этот способ подходит для иконки в TrayBar.

Hosted by uCoz