Выход VB6 во время отладки с активным крючком сообщений Windows


Одно из наших самых больших старых приложений VB6 имеет некоторый код в нем, чтобы позволить другим приложениям (включая некоторые dotNET) передать ему идентификатор через сообщение Windows - этот идентификатор затем используется приложением VB6 для загрузки записи в обычную форму Windows. Крюк сообщения добавляется после того, как пользователь вошел в систему и прошел проверку подлинности, и удаляется после выхода из системы.

Public Sub HookClaimFinderCall()
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub UnhookClaimFinderCall()
    Dim temp As Long
    If gHW <> 0 Then temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub

Private Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If uMsg = WM_FINDCLAIM Then
        MasterFindClaim lParam
    End If
    WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function
Однако здесь есть две проблемы. Первый относится к Visual Studio 6. Если код отлаживается, и возникает ошибка, чтобы вызвать диалоговое окно "Continue End Debug Help", нажав кнопку End, мгновенно завершает работу Visual Studio (теряя все несохраненные изменения). Этого не происходит, если крюк сообщения еще не был активирован. Что вызывает это, и есть ли что-нибудь, что я могу сделать, чтобы остановить его, не комментируя код, который загружает крюк?

Во-вторых, если пользователи покидают приложение, не выходя из него должным образом (любыми средствами), что происходит с крючком сообщения?

Надеюсь, что я правильно понял все термины, приведенные выше...

2 2

2 ответа:

  1. вы получите сбой (или исчезновение VB6), если инициируете глобальный крюк и попытаетесь выполнить отладку в VB6. VB6 - это своего рода симулятор, он точно не дублирует время выполнения приложения VB6, и зацепление-одна из областей, в которой он с треском проваливается (хотя его нельзя винить, если вы понимаете, что происходит). Для всех глобальных крючков, которые мы используем в наших приложениях, мы проверяем, работает ли VB6 в режиме IDE (есть несколько способов сделать это), и если да, то, не запускайте глобальный крюк. Если вам абсолютно необходимо запустить глобальный крюк, не останавливайте приложение в отладчике-используйте debug.печать или другие средства, но не останавливайте приложение, иначе у вас будут миллисекунды до секунд, прежде чем оно "уйдет".
  2. хотя вы должны отцепиться перед выходом из приложения, когда насос сообщения попадает на крюк и ручка приложения, где происходит крюк, больше не существует, это довольно скверная операция, чтобы игнорировать этот крюк. Теперь, если вы запустили приложение и вышли из него тысячи раз, оно, вероятно, будет расти, но я думаю, что это наименьшая из ваших проблем.

Ответ Криса верен. Еще пара дополнительных моментов.

  • Строго говоря, это подклассы, а не подсоединение сообщений.
  • это также хорошая практика в вашем WindProc, чтобы обнаружить WM_NCDESTROY и отцепить, когда это сообщение получено. Сообщение означает, что окно вот - вот будет уничтожено-оно должно быть получено, если пользователь выйдет из приложения, независимо от того, как он это сделает.
  • в Windows 2000 и более поздних версиях есть некоторые вызовы API, которые облегчают управление подклассами. Как всегда, Карл У Петерсона есть отличная статья с отличным кодом VB6 здесь.