2


1

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

パブリックSub HookClaimFinderCall()lpPrevWndProc = SetWindowLong(gHW、GWL_WNDPROC、AddressOf WindowProc)End Sub

Public Sub UnhookClaimFinderCall()もしgHW <> 0ならばTemp = SetWindowLong(gHW、GWL_WNDPROC、lpPrevWndProc)ならば、Tempを長くします。End Sub

プライベート関数WindowProc(ByVal hwの長さ、ByValのuMsgの長さ、ByValのwParamの長さ、ByValのlParamの長さ)関数

ただし、これには2つの問題があります。 1つ目はVisual Studio 6に関するものです。 コードのデバッグ中にエラーが発生して[デバッグのヘルプの続行]ダイアログボックスが表示された場合は、[終了]を押すと即座にVisual Studioが終了します(保存されていない変更は失われます)。 メッセージフックがまだ有効になっていない場合、これは起こりません。 何がこれを引き起こします、そしてフックをロードするコードをコメントアウトすること以外に私がそれを止めるためにできることは何ですか?

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

私は上記のすべての用語が正しいことを願っています…​

2 Answer


5


  1. グローバルフックを開始してVB6でデバッグを試みると、クラッシュする(またはVB6が消える)ことになります。 VB6はシミュレータのようなもので、VB6アプリケーションのランタイムを正確には再現していません。フッキングは惨めに失敗する分野の1つです(実際に何が起こっているのか理解できれば非難できません)。 私たちのアプリケーションで使用しているすべてのグローバルフックについて、VB6がIDEモードで実行されているかどうかを確認し(実行する方法がいくつかあります)、実行されている場合はグローバルフックを実行しないでください。 グローバルフックを絶対に実行する必要がある場合は、デバッガ内でアプリケーションを停止しないでください。debug.printなどの方法を使用してください。

  2. アプリケーションを終了する前にフック解除する必要がありますが、メッセージポンプがフックにヒットし、フックが発生するアプリケーションのハンドルが存在しなくなった場合、そのフックを無視するのはかなり簡単な操作です。 これで、アプリケーションを実行して何千回も終了しても、おそらくそれは増えていくでしょう。


3


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

  • 厳密に言うと、これはメッセージのフックではなくサブクラス化です。

  • あなたの `WindProc`ではWM_NCDESTROYを検出してそのメッセージが受信された時にアンフックするのも良い習慣です。 このメッセージは、ウィンドウが破壊されようとしていることを意味します。ユーザーがどのように操作しても、ユーザーがアプリを終了した場合は受信されるはずです。

  • Windows 2000以降には、サブクラス化の管理を容易にするAPI呼び出しがいくつかあります。 いつものように、Karl Petersonは優れたVB6コード hereに関する優れた記事を持っています。