ダイアログベースで開発しているのですが、
ツリービューでドラッグアンドドロップしたアイテムを
ウィンドウ外に移動させたときにドロップ禁止イメージ
(エクスプローラで表示される円の中に斜線)をドラッグ
イメージに重ねて表示させたいと思っています。
質問1. ドロップ禁止イメージの描画方法
通常のドラッグイメージは表示出来ているのですが、
このドロップ禁止イメージ(マーク)を(重ねて)表示させる
ことが出来ません。
質問2. ウィンドウ外でマウスカーソルとドラッグイメージを
同じ位置に描画する方法
ウィンドウ内でドラッグイメージの描画は出来たのですが
ウィンドウ外に出たときにうまく描画が行えません。
SetCapture()でウィンドウ外の情報を取得し、マウスカーソルの
座標は取得出来ているのですが、その座標を使って、
"DragEnter(NULL, 座標)"でドラッグイメージ(まだ通常の
ドラッグイメージ)を表示させるとマウスカーソルの位置と
表示されるドラッグイメージの位置がずれて表示されてしまいます。
マウスカーソルは座標をウィンドウの左上が"0,0"とした位置からの
相対する位置に描画しているが、ドラッグイメージはデスクトップの
左上を"0,0"とした位置から相対した位置に描画しているようです。
マウスカーソルとドラッグイメージが重なるように表示させる方法
を教えてください。
以上、ご指導宜しくお願い致します。
開発環境は Windows Xp, VC++6.0, MFC使用です。
"質問1"が解決しました。
リソースにデフォルトで用意されているドロップ禁止カーソル
(IDC_NODROP)を保存し、ソースコードからLoadCursor()で
取得します。それをカーソルにセットすれば表示出来ました。
以下、ソースコード
HCURSOR hcursor = AfxGetApp()->LoadCursor(IDC_NODROP);
SetCursor(hcursor);
"質問1"は解決です。ありがとうございました。
試していないですが
ScreenToClient、ClientToScreen
どちらかでどうでしょう。
#未確認です。駄目だったらゴメンナサイ
とおりさんこんばんわ、いつも貴重なアドバイス
ありがとうございます。
ClientToScreenとScreenToClientを試してみました。
どちらも座標(らしき)を取得出来ています。
ScreenToClientの場合、その座標をドラッグイメージを
描画するDragEnterに渡すと、ドラッグイメージが
マウスカーソルに対しデスクトップのかなり左上の方から
現われます。
ClientToScreenで同様に試すとドラッグイメージは最初出て
いないのですが、マウスカーソルをデスクトップの左上に
移動させると、ドラッグイメージがいきなり現われます。
現われる位置もマウスカーソルと一致しています。
しかしこの状態では使えないので、使える方法を検討中です。
座標は取れているのでドラッグイメージの描写を工夫しないと
いけないのかも知れません。
もう少し色々やってみます。
ここでははじめましてのあいるです。
たぶん・・・ですが、単純にDragMove してないだけとか??
----- TreeView の OnMouseMove 内 -----
CTreeCtrl *pCtrl = &GetTreeCtrl();
UINT flags;
HTREEITEM hTargetItem = pCtrl->HitTest( point,&flags );
// メンバで CImageList *m_pDragImageList; と定義されていて初期化済
m_pDragImageList->DragLeave( this );
pCtrl->SelectDropTarget( hTargetItem );
// ここで条件に合わせてカーソル変更
::SetCursor( AfxGetApp()->LoadStandardCursor( IDC_NO ) );
m_pDragImageList->DragEnter( this,point );
m_pDragImageList->DragMove( point );
----
こんな感じの手順でいいかと
SetCaputure してるなら、DragEnter(NULL,point) ではなくthisでいいかと。
あいるさんご指導ありがとうございます。
返信が遅くなりまして大変申し訳ありません。
最初にちょっと気になったのですが・・・
>ここでははじめましてのあいるです。
これは別の所で知り合っているという意味でしょうか?
それともあいるさんがこの掲示板では初めて発言する
という意味の挨拶なのでしょうか?
すみません、本題に入ります。
原因がわかりました。単純なコーディングミスでした。
あいるさんに書いて頂いたソースコードと
自分のソースコードを見比べていて気づいたのですが、
私はドラッグイメージの描画とドロップ禁止イメージの描画を
if文で分岐して記述しているのですが、ドラッグイメージの
描画の方ではDragEnterとDragMoveを行っていたが、
ドロップ禁止イメージの描画の方では行っていなかった
というの原因でした。
以下間違っていたソースコード。
if ((hitem = HitTest(point, &flags)) != NULL)
{
m_pimagelist->DragLeave(this);
SelectDropTarget(hitem);
m_pimagelist->DragEnter(NULL, m_ScreenPoint);
m_pimagelist->DragMove(m_ScreenPoint);
} else {
SetCursor(AfxGetApp()->LoadCursor(IDC_NODROP));
}
↑これではドロップ禁止場所でドラッグイメージの描画が
行われないのは当たり前でした。失礼致しました。
ただ、DragEnterの第一引数が"this"ではやはりウィンドウ内
での描画指定になっているようでしたので"NULL"にしました。
以下修正後のソースコード。
----OnMouseMove内----
HTREEITEM hitem;
UINT flags;
//ドラッグ状態にある。
if (m_bDragging)
{
SetCapture();
m_ScreenPoint.x = point.x;
m_ScreenPoint.y = point.y;
ClientToScreen( &m_ScreenPoint );
static HCURSOR oldCursol;
static bool flag = false;
//ドロップ禁止場所からドロップ許可場所へ戻ってきた場合、
//通常のカーソルに戻す。
if (flag == true) {
SetCursor(oldCursol);
}
//ドロップ許可場所では通常のカーソルを設定。
if ((hitem = HitTest(point, &flags)) != NULL)
{
m_pimagelist->DragLeave(this);
SelectDropTarget(hitem);
m_hitemDrop = hitem;
flag = false;
} else {
//ドロップ禁止場所ではドロップ禁止イメージのカーソルを設定。
oldCursol = SetCursor(AfxGetApp()->LoadCursor(IDC_NODROP));
flag = true;
}
//ドラッグイメージの描画。
m_pimagelist->DragEnter(NULL, m_ScreenPoint);
m_pimagelist->DragMove(m_ScreenPoint);
}
---------------------
と言った具合に致しました。
一応やりたい動きは出来ましたので、[解決]チェックは
入れておきますが、おかしな点がありましたらご指摘を
宜しくお願い致します。
とおりさん、あいるさんありがとうございました。
↑と言っておきながら[解決]を押し忘れました。
失礼致しました。
ツイート | ![]() |