
右ダブルクリックで呼び出すランチャプログラムを作成したいのですが、
システムフックをかけてWM_RBUTTONDBLCLKをアプリ側に送り,それに反応させる形でランチャのウィンドウを最前面に持ってきたいのですが上手くいきません。
フックされたメッセージが送られてきた場合の処理は以下のようになっています。
~省略
case WM_USER+100://ダブルクリックが送られてきた場合のメッセージコード
//任意文字列を別ウィンドウのリストボックスに吐く自作関数
Add("dblclk");
//以下でウィンドウを最前面に持ってくる。
//lpにクリックされた座標が入っている
SetWindowPos(hWnd , HWND_TOP,(int)LOWORD(lp),(int)HIWORD(lp), NULL,NULL,SWP_NOSIZE|SWP_SHOWWINDOW);SetForegroundWindow(hWnd);
UpdateWindow(hWnd);
break;
~省略
このコードの場合、ウィンドウの位置は変更されるのですが、最前面に来てくれません。
Add関数が呼ばれているのでフック自体は成功しているようなのですが、何かおかしな点はありますでしょうか?
No.1ベストアンサー
- 回答日時:
★気になった点を2つとアドバイスを1つします。
・1つ目は、
『(int)LOWORD(lp)』は『(SHORT)LOWORD(lp)』にするか、『GET_X_LPARAM(lp)』にします。
『GET_X_LPARAM(lp)』、『GET_Y_LPARAM(lp)』マクロ関数は『WindowsX.h』で定義されています。
・2つ目は、
『SetWindowPos』関数の引数5、引数6が『NULL』ですが、ポインタではないので『0』とします。
・3つ目は、
配置順序のハンドルを『HWND_TOP』ではなく『HWND_TOPMOST』にしてみたらどうでしょうか?
つまり:
SetForegroundWindow( hWnd ); ←先に記述
SetWindowPos( hWnd, HWND_TOPMOST, (SHORT)LOWORD(lp), (SHORT)HIWORD(lp), 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW );
UpdateWindow( hWnd );
最後に:
・マウスの右ダブルクリックでランチャーを起動させる仕様ですが、通常の右メニューが出ると
右ダブルクリックの『WM_RBUTTONDBLCLK』がうまく表示できますか?
・『WM_RBUTTONDBLCLK』の次のタイミングの『WM_RBUTTONUP』でランチャーを表示するように
してみたらどうなりますか?→いろいろ試してみて下さい。
・以上。おわり。
回答ありがとうございます。
2つ目に付いては座標がマイナスの時のための処置と認識してよろしいのでしょうか?
「HWND_TOPMOST」を利用してやろうとしてみたのですが、この設定の場合指定したウィンドウを常に最前面とするので、直後にこれを解除するために
SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
として最前面設定を解除するよう試みました。
しかし、この場合直前のアクティブウィンドウとアプリケーションのキャプションバーが両方ともアクティブ時の色となってしまい、アプリケーションのウィンドウを一度クリックしてから他の操作を行わないと最前面に固定されたままになってしまいます。
SetActiveWindow関数を用いてもこれは解消できませんでした。
最後に示唆していただいたように右メニューも出てしまうために、右クリックの入力を全てフックプロシージャ側で止めた後、WM_RBUTTONUPからランチャを呼び出すよう変更してテストしてみましたが、この場合も結果は同じでした。
HWND_TOPMOSTを用いれば最前面へ出てくるため、一旦この路線でいろいろ試してみます。
No.4
- 回答日時:
★アドバイス
・『SetForegroundWindow( hWnd );』の部分を
『SetForegroundWindow( GetLastActivePopup(hWnd) );』としたら、どうなる?
・また、タスクトレイ(通知領域)の左クリックで問題なくウィンドウが前面に出るのならば
『SendMessage』関数などでタスクトレイの左クリックのメッセージを送信してみるのは?
・あと、非表示の『HWND_DESKTOP』で作られたウインドウを『CloseWindow』で最小化すると
メモリがコンパクト化されると思います。
・以上。3つほどアドバイスしてみました。→参考にして下さい。
ありがとうございます。
自分でもいろいろと調べてみた結果、
http://techtips.belution.com/ja/vc/0012/
を参考にして目的を達成することが出来ました。
タスクトレイのクリックで上手くいった理由は、タスクトレイをクリックすることで自分のアプリケーションがフォアグラウンドスレッドになっていたからのようです。
質問事項以外のことも親切に教えていただき、本当にありがとうございました。
No.3
- 回答日時:
> このコードの場合、ウィンドウの位置は変更されるのですが、最前面に来てくれません。
指定したウィンドウが最前面に来ない、アクティブにならないということでよいでしょうか?
ソース上であれこれ試しても効果なしの可能性が大です。
レジストリの設定で問題が解決しそうですのでお試しあれ。
HKEY_CURRENT_USER\Control Panel\Desktop キーの
ForegroundLockTimeout の値を 0 に設定してみてください。
「ForegroundLockTimeout」で検索してもらえばいろいろ出てくると思います。
参考URL:http://support.microsoft.com/kb/886217/ja
回答ありがとうございます。
今回の場合、新しく起動するウィンドウではなくランチャのウィンドウを最前面に持ってきたいため、この方法では解決できませんでした。
念のためForegroundLockTimeoutの値を確認してみましたところ、既に0に設定されていました。
言葉が足りずに申し訳ありません。
No.2
- 回答日時:
★また気になったので1つ補足要求いいですか?
・呼び出すランチャは『ショートカットメニュー』タイプですか?
それとも『ダイアログ』タイプですか?
・以上。補足要求します。
この回答への補足
ショートカット、という形になると思います。
h = CreateWindow(
szClassname,
szClassname,
~WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hInstance,
NULL);
hWnd=
CreateWindow(
szClassname,
szClassname,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
h,
NULL,
hInstance,
this);
このようにしてタスクバー上のアイコンを殺して、その後通知領域にアイコンを登録しています。
また、hWndへ送られるメッセージのみを処理させています。
これを用いずに、普通にCreateWindowをしても結果に変化はありませんでした。
通知領域のアイコンを左クリックしたとき、
SetWindowPos(hWnd , HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
SetForegroundWindow(hWnd);
UpdateWindow(hWnd);
という処理をしていますが、この場合は問題なくウィンドウは最前面へ呼び出すことが出来ます。
これは書いておくべきでした。申し訳ありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- その他(プログラミング・Web制作) pythonで、tkinterとpillowの組み合わせ 2 2022/08/16 17:42
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Access(アクセス) Vba Userformを前面に出すについて 3 2022/04/15 12:29
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
VBA .Value=.Value ?
-
ラジオボタンの初期指定
-
VBAで単一ブック複数窓を閉じる...
-
【VB2008】 マウス操作の一時的...
-
vc++(MFCなし)でタスクバーに...
-
常に非アクティブなウィンドウ...
-
指定したインアクティブウィン...
-
エクセルで保存したものを開く...
-
ExcelのBOOKが消えた!
-
他アプリのアクティブな子ウイ...
-
UWSCでランダムな処理をする場合
-
ダイアログでのDragDropでマウ...
-
勝手にウィンドウが開いて止ま...
-
c言語win32apiで孫ウインドウか...
-
ゲームでは結局どっちが良いの?
-
フリーのデータ消去ソフト「DES...
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
ラジオボタンの初期指定
-
勝手にウィンドウが開いて止ま...
-
Vba LongPtrについて教えてくだ...
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
-
ExcelのBOOKが消えた!
-
[VBA] UserForm を Excel の W...
-
VBA .Value=.Value ?
-
作成したウインドウのサイズを...
-
Console.WriteLine で表示されない
-
エクセルで1行目から3行目が消...
-
「&HFFFF」「&H1A」とは?
-
【VB2008】 マウス操作の一時的...
-
UWSCで特定のChromeのタブをア...
-
MFCでハンドルを取得するには
-
他のアプリケーションの終了処理
-
VBAで単一ブック複数窓を閉じる...
-
EnumChildWindowsの使い方(VBA)
おすすめ情報