システムフック?

解決


Sin  2004-10-30 01:26:04  No: 54930

VBのGUIから、アンマネージDLLのRS-232Cのシリアル通信処理を呼び出しています。
それで、シリアル受信の待機中に、キーボードからESCキーを
押された場合は処理を中断してVB側に制御を返したいのですが、
こういう場合はアンマネージDLL側でシステムフックを使用して
やればいいのでしょうか?

よろしくお願いします。
環境 WinXP Pro、.NET 2003 VB、VC++


シャノン  2004-10-31 03:56:42  No: 54931

システムフックまでせずとも、ホットキーでできるんじゃなかろうか。
ホットキーで Esc 捕まえられなかったらごめんなさい。


Sin  2004-11-04 18:34:55  No: 54932

お返事遅くなり申し訳ありません。

どうやら「エスケープ、スペース、タブキー」はホットキーにすることはできないようなので、やはりシステムフックを使おうと思います。

そこで、プロジェクト構成なんですが、下記の方向性で可能でしょうか?
・VB(起動用EXE)
・VB(画面DLL)
・VC(シリアル受信DLL(アンマネージ))
・VC(システムフックDLL(アンマネージ))

ここで、DLLを一つにまとめてもいいのか、
システムフックのDLLは独立していないといけないのかが疑問になっています。

よろしくお願いします。
環境 WinXP Pro、.NET 2003 VB、VC++


Sin  2004-11-04 20:57:01  No: 54933

ちなみに、シリアル受信とフックのスレッドは個別に立てないといけないでしょうか?

現在シリアル受信は、受信バッファにEXT(終止符号)が現れるまでループするスレッドを立てます。
CWinThread *m_receiveThread m_receiveThread = AfxBeginThread(ReceiveFunc, this);

そこで、フックのセットするタイミングと、フックされたキーを拾って、
受信処理を中止しループを抜けるタイミングを何処で行うのかがよく分かりません。
(受信バッファのスレッド内でフックDLLのクラスインスタンスを生成して、受信ループの中で、キー押下フラグが立っていればループを抜けるという
処理を入れてますが、キーを押下してもこの処理に入ってきません)

すみませんが宜しくお願いします。


シャノン  2004-11-04 22:59:46  No: 54934

DLL は(まとめることの良し悪しは別として、技術的に大丈夫かダメかと言うなら)まとめても大丈夫です。

フックはコールバック関数の形を取りますが、その関数がどのスレッドで呼ばれるかは定かではありません。
おそらくはフックをセットしたスレッドのコンテキストで呼ばれるのではないかと思われますが、コールバック関数内で GetCurrentThreadId など使って検証してみてください。
フックをセットしたスレッドで呼ばれるとすると、無限ループ状態になっている受信スレッドでセットするのは好ましくないと思います。
フックをセットするタイミングは受信スレッドを立ち上げる前、ループを抜ける方法は現在のようにフラグを見る形になるんではないでしょうか。


Sin  2004-11-05 23:45:36  No: 54935

ありがとうございます。
一応動作は正しい挙動を示すようになりました。
DLLはメンテ性を考慮して、シリアル受信DLLとキーフックDLLで分けておくことにしました。
キーフックについては認識があいまいな所があるので、再度調査します。
どうもありがとうございました。

----------------------
  // インスタンス生成
  CKeyboardHook *KeyHook = new CKeyboardHook();  // フック(システムフック)
  CSerialCom *com = new CSerialCom();  // シリアル通信

  KeyHook->Set();  // キーフックのセット

  com->Open( PORTNO );  // COMポートオープン
  com->ComRead();      // 受信スレッド開始

  while(1) {
    // キーフックの監視
    if ( GetMessage( &msg, NULL, 0, 0 )) {
      if( KeyHook->GetKeyHookStatus() == TRUE ){  // 該当するキーが押下されたかチェック
        break;
      }
    }

    // シリアル受信処理
    if( com->m_isReceiving == FALSE ) {    // データ受信が終わるまで待機
      break;
    }
  }

  com->Close();  // COMポートクローズ

  // 後始末
  delete com;
  delete KeyHook;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加