マウスメッセージを裏のウィンドウに渡したい – プログラミング – Home

マウスメッセージを裏のウィンドウに渡し...
 
通知
すべてクリア

[解決済] マウスメッセージを裏のウィンドウに渡したい


亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

VC6 MFCで、自作の画像表示ツールに虫眼鏡の機能を付けようとしています。
マウス位置を中心に、表示画像ウィンドウの上に、
虫眼鏡ウィンドウ(拡大画像やテキスト情報を持たせたモードレスダイアログ)を
かぶせるという方法です。
マウス移動に合わせて拡大画像を更新し、虫眼鏡ウィンドウも追尾します。

この場合、表示画像ウィンドウのWM_MOUSEMOVEメッセージに合わせて
虫眼鏡ウィンドウを移動、更新させることになると思いますが、
マウス位置に虫眼鏡ウィンドウをかぶせるため、
マウス関連のメッセージはすべてそちらに行ってしまいます。
虫眼鏡ウィンドウではマウスメッセージを一切受け取らない
(すべて裏のウィンドウにそのまま通過させる)という方法はありますでしょうか?

WM_NCHITTESTメッセージでHTTRANSPARENTを返す方法を見つけたのですが、
これはダイアログ上のスタティックテキストのような
親子関係を持ったウィンドウでのスタイルですよね?

やはり表示画像ウィンドウのほうで
SetCaptureをコールしてしまうしかないのでしょうか?
やってることはただのマウス移動対応(ドラッグではない)ですし、
アクセラレータキーで虫眼鏡ウィンドウの表示オンオフを切り替えたいので、
できればマウスキャプチャをせずに
裏にメッセージ(WM_MOUSELEAVEも)が来るようにしたいのですが…。


引用未解決
トピックタグ
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

以下のような案を思いつきましたが、いかがでしょうか。

1)EnumWindows/ChildWindowFromPointでカーソル下のウィンドウを探し、
 メッセージを丸投げする。
 (WindowFromPointは一番上のウィンドウしか見つけてくれないので、
 自分自身が見つかってしまい、使えないと思われる。)
 WM_MOUSELEAVEは難しいかも。

2)SetWindowRgnで、自分自身の真ん中に穴を開ける。
 カーソルが常に穴の部分を指すように自ウィンドウを移動させる。
 ただし、素早い操作に反応できるかは不明。

3)自分自身をウィンドウとせず、デスクトップに直接描画する。
 ちらつきが心配。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

いろいろな方法を提示していただき、ありがとうございます。

> 1)EnumWindows/ChildWindowFromPointでカーソル下のウィンドウを探し、
> メッセージを丸投げする。
> WM_MOUSELEAVEは難しいかも。

やはりこのメッセージ丸投げ方法だと、
WM_MOUSELEAVEは来なくなってしまいますよね。

でもこの場合は、逆に虫眼鏡側で「マウス位置が表示画像から離れた」こと自体は
ChildWindowFromPointの結果でわかるでしょうし、
そのときに虫眼鏡を非表示にすればよいかもしれません。

2~3についても情報ありがとうございます。
リージョンやデスクトップへの描画は恥ずかしながらまだ詳しくないので、
「素早い操作」や「ちらつき」の問題も含めてじっくり調べてみたいと思います。


返信引用
亀山
 亀山
(@亀山)
ゲスト
結合: 18年前
投稿: 133
Topic starter  

すみません、今回の件の関連でもう一つお伺いしたいことがあります。
ダイアログベースのプロジェクトを作成し、

void CTestDlg::OnPaint()
{
if (IsIconic())
{
...
}
else
{
/* 描画更新処理のかわり */
CPaintDC dc(this);
for (int i = 0; i < 10000; i++) {
dc.MoveTo(0, 0);
dc.LineTo(100, 100);
}
}
}

void CTestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rect;
GetWindowRect(rect);

ClientToScreen(&point);
MoveWindow(point.x - 300, point.y - 300, 600, 600);

CWnd::GetDesktopWindow()->RedrawWindow(rect, NULL, RDW_ALLCHILDREN | RDW_ERASE
| RDW_ERASENOW | RDW_INVALIDATE | RDW_UPDATENOW);

CDialog::OnMouseMove(nFlags, point);
}

と、虫眼鏡移動の試作をしてみたのですが、
マウスを動かしつづけている間は、デスクトップや
エクスプローラなどの他のウィンドウ上に残像が出てしまいます。
停めたりした時点で再描画されるようです。

デスクトップにRedrawWindowをコールしても、再描画はかからないものなのでしょうか?


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました