3

私たちの最大の古い VB6 アプリの 1 つには、他のアプリ (一部の dotNET アプリを含む) が Windows メッセージを介して ID を渡すことができるようにするためのコードが含まれています。形。メッセージフックは、ユーザーがログインして認証された後に追加され、ログアウトすると削除されます。

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

ただし、これには 2 つの問題があります。The first related to Visual Studio 6. コードのデバッグ中にエラーが発生して [Continue End Debug Help] ダイアログ ボックスが表示された場合、End キーを押すとすぐに Visual Studio が終了します (保存されていない変更は失われます)。メッセージ フックがまだアクティブ化されていない場合、これは発生しません。何が原因で、フックをロードするコードをコメントアウトする以外に、それを止めるためにできることはありますか?

次に、ユーザーが適切にログアウトせずにアプリを終了した場合 (何らかの方法で)、メッセージ フックはどうなりますか?

上記のすべての用語が正しいことを願っています...

4

2 に答える 2

5
  1. グローバル フックを開始して VB6 でデバッグしようとすると、クラッシュする (または VB6 が消える) ことになります。VB6 は一種のシミュレーターのようなもので、VB6 アプリケーションのランタイムを正確に複製するわけではなく、フックは惨めに失敗する領域の 1 つです (何が起こっているのかを理解していれば、それを非難することはできませんが)。アプリケーションで使用するすべてのグローバル フックについて、VB6 が IDE モードで実行されているかどうかを確認し (これにはいくつかの方法があります)、実行されている場合はグローバル フックを実行しません。絶対にグローバル フックを実行する必要がある場合は、デバッガーでアプリケーションを停止しないでください。debug.print またはその他の手段を使用してください。
  2. アプリケーションを終了する前にフックを解除する必要がありますが、メッセージ ポンプがフックにヒットし、フックが発生するアプリケーションのハンドルが存在しなくなった場合、そのフックを無視するのはかなり安っぽい操作です。アプリケーションを実行して何千回も終了すると、おそらく蓄積されますが、それはあなたの懸念の中で最も少ないと思います.
于 2009-09-08T15:40:26.020 に答える
3

クリスの答えは正しいです。いくつかの追加ポイント。

  • 厳密には、これはメッセージ フックではなくサブクラス化です。
  • WindProcWM_NCDESTROY を検出し、そのメッセージを受信したときにフックを解除することもお勧めします。このメッセージは、ウィンドウが破棄されようとしていることを意味します。ユーザーがアプリを終了した場合は、その方法に関係なく、メッセージを受信する必要があります。
  • Windows 2000 以降には、サブクラス化の管理を容易にする API 呼び出しがいくつかあります。いつものように、Karl Peterson は優れた VB6 コードを含む優れた記事をここに掲載しています。
于 2009-09-08T16:10:24.773 に答える