• 締切済み

宣言による処理の重さ

第161章 キーボード・フック http://www.kumei.ne.jp/c_lang/sdk2/sdk_161.htm このサイトのLRESULT CALLBACK MyHookProc(int nCode, WPARAM wp, LPARAM lp)で {   char str[256];   if (nCode < 0)     return CallNextHookEx(hMyHook, nCode, wp, lp);   if (wp >= 0x30 && wp <= 0x39) {     wsprintf(str, "hMyHook = %d", hMyHook);     MessageBox(NULL, str, "MyHookProc", MB_OK);     return CallNextHookEx(hMyHook, nCode, wp, lp);   }   wsprintf(str, "キー入力はインターセプトされました\n フックハンドル= %d", hMyHook);   MessageBox(NULL, str, "インターセプト", MB_OK);   return TRUE; } と書いてありますが、char str[256];をstatic char str[256];にしたり、 {   if (nCode < 0)     return CallNextHookEx(hMyHook, nCode, wp, lp);   if (wp >= 0x30 && wp <= 0x39) {     char str[256];     wsprintf(str, "hMyHook = %d", hMyHook);     MessageBox(NULL, str, "MyHookProc", MB_OK);     return CallNextHookEx(hMyHook, nCode, wp, lp);   }   wsprintf(str, "キー入力はインターセプトされました\n フックハンドル= %d", hMyHook);   MessageBox(NULL, str, "インターセプト", MB_OK);   return TRUE; } にするとアプリケーションのパフォーマンスはよくなりますか?

みんなの回答

  • nitscape
  • ベストアンサー率30% (275/909)
回答No.2

コンパイラやコンパイルオプションによっても違うと思いますが、私の環境では... staticにするとアセンブラでのlea命令1つ分ですが消費クロック数は減ります。ただしMessageBox表示直前の処理なので...減る意味はほとんどないです。 charの宣言位置は変えてもパフォーマンスは変わりません。 またstaticにした場合はもしかしたらcriticalsectionが必要になるかもしれません。その場合はlock,unlock処理が必要になるので逆にパフォーマンスが落ちます。 何にせよこの手のフックはパフォーマンスを落とす処理です。フックを使わない方法を考えた方が速度的にもいいと思います。

ninmurai
質問者

お礼

ありがとうございました。

  • MetalKing
  • ベストアンサー率57% (15/26)
回答No.1

>と書いてありますが、char str[256];をstatic char str[256];にしたり、  略 > にするとアプリケーションのパフォーマンスはよくなりますか? なりません 特に、staticはやめたほうがいい

関連するQ&A

  • システムメニューのフック(SDK)

    はじめまして。 開いている全てのウィンドウのシステムメニューに 項目を追加するプログラムを作っているのですが、 例えばSC_TESTというIDの項目を追加して、 そのSC_TESTが押されたという判断はどうすればいいのかわかりません。 WH_CALLWNDPROCフックをしているのですが、 さすがに下のコードではSC_TESTの部分は動きません。 どの項目がクリックされたかまでは調べられないので しょうか? EXPORT LRESULT CALLBACK MyHookProc(int nCode, WPARAM wp, LPARAM lp) { CWPSTRUCT *pcwp; char str[256]; if (nCode < 0) { return CallNextHookEx(hHook, nCode, wp, lp); } if (nCode == HC_ACTION) { if (wp == NULL) { pcwp = (CWPSTRUCT *)lp; switch(pcwp->message){ case WM_CLOSE: MessageBox(pcwp->hwnd, "CLOSE", "OK", MB_OK); break; case WM_CREATE: SetExtWindowEx(pcwp->hwnd); break; case SC_TEST: MessageBox(pcwp->hwnd,"AAA","AAA",MB_OK); break; default: break; } } } return CallNextHookEx(hHook, nCode, wp, lp); }

  • WM_INITDIALOGのフック

    どこにも載っていないため質問させていただきます。 次のようなコードを書いたとき、ダイアログの出現の検知ができるWM_INITDIALOGを検知できないのはなぜでしょうか。 hHookForDialog = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProcForDialog, hDll, 0); LRESULT CALLBACK CallWndRetProcForDialog(int nCode, WPARAM wp, LPARAM lp) { if(nCode < 0) return CallNextHookEx(hHookForDialog, nCode, wp, lp); PCWPRETSTRUCT Wmes = (PCWPRETSTRUCT)lp; if(nCode == HC_ACTION) { if(Wmes->message == WM_INITDIALOG) { PostMessage(hWndToSendMessage, mesDialogCreated, (WPARAM)(Wmes->hwnd), NULL); } } return CallNextHookEx(hHookForDialog, nCode, wp, lp); } フック自体は成功しているようで、条件文を外すとメッセージはたくさん飛んできます。 けれども目的のWM_INITDIALOGは無いようです。 どうすればいいのかご教授お願いします。

  • 変数のプロセス間共有について

    現在マウスフックを利用して、マウスの左ボタンが上げられた座標を エディットコントロールに表示するプログラミングを作成しています。 自作ウインドウ上でマウスを押したところ、座標はしっかりと表示されたのですが、 他のアプリケーション上やデスクトップ上で押しても反応してくれません。 いろいろググってみると、#pragma data_seg()を使って変数を共有する必要があるとのこと…。 しかしどうやっても解決しません。 どなたか助けて下さい!! #pragma data_seg("MY_DATA") POINT pt[100] = {0}; HWND hEdit = 0; int top = 0; TCHAR szBuf[1024] = {0}; #pragma data_seg() …… EXPORT LRESULT CALLBACK MyHookProc(int nCode, WPARAM wp, LPARAM lp) { TCHAR str[100]; MOUSEHOOKSTRUCT *pmh; pmh = (MOUSEHOOKSTRUCT *) lp; if(nCode < 0) return CallNextHookEx(hHook, nCode, wp, lp); if(wp == WM_LBUTTONUP){ pt[top].x = pmh->pt.x; pt[top].y = pmh->pt.y; wsprintf(str, TEXT("x: %d, y: %d, top: %d\r\n"), pt[top].x, pt[top].y, top); lstrcat(szBuf, str); SetWindowText(hEdit, szBuf); top++; return CallNextHookEx(hHook, nCode, wp, lp); } return CallNextHookEx(hHook, nCode, wp, lp); } <環境> Visual C++ 2005 Express Edition

  • CallNextHookEx( ) == FALSE

    1つのアプリの中で、メインプロージャとフックプロージャを作りました。 フックはキーボードフックです。 HHOOK hHook; LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam){  if(nCode < 0)return CallNextHookEx(hHook, nCode, wParam, lParam);  if(wParam == 0x31)return FALSE;  return TRUE; } フックしていても 「ぬ」 のキーは使えるようにしました。  if(wParam == 0x31)return FALSE; は  if(wParam == 0x31)return CallNextHookEx(hHook, nCode, wParam, lParam); にしても違いが分かりませんでした。 return FALSE では、メッセージをキューから削除らしいけど、メインの プロージャで LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){  switch(msg){  case WM_KEYDOWN:   if(wParam == 0x31)MessageBox(hWnd, "メインプロージャから", "", MB_OK);  break; にしても、フックプロージヤの戻り値は CallNextHookEx( ) でも FALSE でも MessageBox() は表示されました。 CallNextHookEx( ) にした場合と FALSE にした場合、何が違うのか、 どういうソースなら違いを確かめられるのか教えてください。

  • case で宣言コンパイルエラー

     switch (msg){  case WM_LBUTTONDOWN:   char *p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; がエラーで  switch (msg){  case WM_LBUTTONDOWN:   char *p;   p = new char[1000];   wsprintf(p, "%d" , i);   MessageBox(hWnd , p , "" , MB_OK);   delete[] p;  break; と  switch (msg){  case WM_KEYDOWN:   if( wParam == VK_RETURN ){    char *p = new char[1000];    wsprintf(p, "%d" , i);    MessageBox(hWnd , p , "" , MB_OK);    delete[] p;   }  break; ならエラーじゃなかったんだけど、理由がよく分かりません。 case のすぐ下で宣言と同時に値を代入してはいけないんですか?

  • グローバルフックについて

    VC++6.0でグローバルフック用のDLLを作っていて、どうしてもわからないので質問させていただきます。 フックの内容は、ウィンドウが最前面にあるかどうか常に監視したいので、状態が変わるメッセージをフックしています。 フック対象はとあるゲームなんですが、テストのためにメモ帳を対象にテストをしました。 まず、spy++でウィンドウの状態を変化させたときに送られてくるメッセージを調べた結果。 WM_ACTIVATEが送られてくるので、これをフックしてみたのですが、spy++だとバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したときにWM_ACTIVATEが送られてくるんですが、いざフックしてみると最小化するときと最小化から復帰したときにしかフックが作動しません。 spy++ではWM_SETFOCUSも送られてくるようだったので、そちらも試してみたのですが、まったく反応がありません。 逆に、spy++では検知してくれないWM_SHOWWINDOWではバックグラウンドに行った時、フォアグラウンドに行った時、最小化したとき、最小化から復帰したとき、すべてに反応してくれました。 このWM_SHOWWINDOWをフックしたときのようになれば問題無いのですが、フック対象をメモ帳からとあるゲームにしたときに、バックグラウンドに行った時と最小化したときは反応してくれたものの、フォアグラウンドに行った時と最小化から復帰したときは反応してくれません。 それと、WM_SHOWWINDOWのメッセージをフックした時のwparamの値なんですが、ネットで調べてみると 表示されようとしているとき 1 非表示されようとしているとき 0 となっているはずなのですが、自分のをみてみると常に647で固定されています。 どなたか解決策をご教授お願いします。 LRESULT CALLBACK WndProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < 0) { return CallNextHookEx(hHook, nCode, wParam, lParam); } else if (nCode == HC_ACTION) { MSG *lmsg; lmsg = (MSG *)lParam; switch (lmsg->message){ case WM_SHOWWINDOW: MessageBox(NULL,"showwindow","info",MB_OK | MB_TOPMOST); return CallNextHookEx(hHook, nCode, wParam, lParam); break; } } return CallNextHookEx(hHook, nCode, wParam, lParam); }

  • ドロップで起動するけどパスは?

    ファイルをEXEにドロップして起動させます。 ドロップしたファイルのパスを GetCommandLine( ) から 取り出すために、" の位置を調べます。 "EXEのパス" ドロップファイルのパス となっているから、2番目の " の位置を調べました。 でも、for でのループが1回で終わってしまいます。 おかしいところを教えてください。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) {  char *p = GetCommandLine();  char str[200];  switch(msg){  case WM_CREATE:   int i;   for(i = 1; p[i] == '"'; i++);{    wsprintf(str, "%d", p[i]);    MessageBox(hWnd, chStr, "", MB_OK);   }   wsprintf(chStr, "%d", i);   MessageBox(hWnd, str, "", MB_OK); //結果は1   wsprintf(chStr, "%#x", p[0]);   MessageBox(hWnd, str, "1文字目", MB_OK); //結果は34   wsprintf(chStr, "%#x", p[1]);   MessageBox(hWnd, str, "2文字目", MB_OK); //結果は67   wsprintf(chStr, "%#x", p[2]);   MessageBox(hWnd, str, "3文字目", MB_OK); //結果は58

  • static で宣言

    LRESULT CALLBACK WinProc(HWND hWnd, UINT msg,WPARAM wP, LPARAM lP){ static char str = 'a'; 1回目の WinProc() 実行の時しか static char str = 'a'; は実行されない。 LRESULT CALLBACK WinProc(HWND hWnd, UINT msg,WPARAM wP, LPARAM lP){ char str = 'a'; としても、1回目の WinProc() 実行の時しか char str = 'a'; は 実行されないんですか?

  • グローバルフック(SetWindowsHookEx)でのEM_REPLACESELの取得について

    はじめまして。 グローバルフック(SetWindowsHookEx)を使って別アプリ(exe)がEDITボックスに出力している 文字列を取得しようとしています。 SPY++で確認すると別アプリではEM_REPLACESELを用いていることがわかりました。 フックするDLLを以下のように作成しメッセージをフックすることはできました。 1. フックのセット   SetWindowsHookEx(WH_CALLWNDPROC, MyHookProc, hInst, dwThreadId);      // hInst はDllMainでアタッチ時に保存したもの      // dwThreadIdは別アプリのスレッドID(以下の方法で取得)      // HWND pWnd = ::FindWindow(NULL, 別アプリのフォームのキャプション) ;      // HWND pEdt = ::FindWindowEx(pWnd,0,"Edit",0);      // DWORD dwThreadId= ::GetWindowThreadProcessId(pEdt, NULL); 2. コールバック   LRESULT CALLBACK MyHookProc(int nCode, WPARAM wp, LPARAM lp)   {    if( EM_REPLACESELの判定 ){      メッセージの保存処理     }     return CallNextHookEx(hMyHook, nCode, wp, lp);   } 上記のコールバックの中で”EM_REPLACESELの判定”をどのようにしたら良いかわからずに困っています。 if分をはずしてファイルにダンプすると何かメッセージが取得できているのは確認できています。 他のサイトを見て、 MSG* pMSG = (MSG*)lp; として、pMSG->lParam を参照してもEM_REPLACESELになっているメッセージがありませんでした。 何か思いつくことがある方、根本的な間違いがあるという方、 アドバイアスをお願いします。

  • windows2000 フックについて

    教えてください。 Ctrl + Esc、Alt + Tab、 Alt + Escを使用不可にしたいと思いフックを使用し作成しています。 それをDLLにして、VBにて呼び出そうとしているのですが、うまくいきません。 まず、はじめにKeyboardProcを作成したのですが、KBDLLHOOKSTRUCTが宣言されていないとでます。 呼び出し関数とかあるのでしょうか? [環境] OS windows2000 VC++6.0 DLL化 [ソース] LRESULT CALLBACK KeyboardProc(int p_nCode, WPARAM p_wParam, LPARAM p_lParam) { KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam; //<--ここでエラーがでる。 BOOL bControlKeyDown = 0; if( p_nCode < 0 || p_nCode == HC_NOREMOVE ){ return CallNextHookEx( hHook, p_nCode, p_wParam, p_lParam ); } switch (p_nCode) { case HC_ACTION: { bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); if (pkbhs->vkCode == VK_ESCAPE && bControlKeyDown) return 1; if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN) return 1; if (pkbhs->vkCode == VK_ESCAPE && pkbhs->flags & LLKHF_ALTDOWN) return 1; break; } default: break; } CallNextHookEx( hHook, p_nCode, p_wParam, p_lParam ); return TRUE; } EXPORT long __stdcall HookSet() { hHook = ::SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, NULL, 0 ); return 1; } DLL化やフックについていろいろ調べたのですが、初めてのため、可笑しい個所があるかとは思いますが、すみませんが教えてください。よろしくお願いします。