ウインドウ内外でのD&D操作をマスターした〜い!

[戻る]
つんた 2002/11/21(木) 09:51:24
はじめまして、よろしくお願いします。
いま、D&Dの実装を試みているのですが、どこをどのように修正すればいいのか・・・


<実施例>

//ツリーの雛型)  猫でも〜
//D&Dの参考例)   MSDN Tree-View Controls 
help://MS.VSCC/MS.MSDNVS.1041/shellcc/platform/CommCtls/TreeView/TreeView.htm


・・・前半省略


//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg) {
        case WM_CREATE:
            InitCommonControls(); //コモンコントロールの初期化
            himl = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 2, 0);
            ImageList_AddIcon(himl, LoadIcon(hInst,(LPCSTR)MYICONS));
            ImageList_AddIcon(himl, LoadIcon(hInst,(LPCSTR)MYICONN));
            if (himl == NULL)
                MessageBox(hWnd, "イメージリスト作成失敗", "OK", MB_OK);
            hTree = CreateWindowEx(0, WC_TREEVIEW, "",
                WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES |
                TVS_HASBUTTONS | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |    
        TVS_TRACKSELECT,
                0, 0, 0, 0,
                hWnd, (HMENU)ID_MYTREE, hInst, NULL);
            DragAcceptFiles(hTree,TRUE);
            TreeView_SetImageList(hTree, himl, TVSIL_NORMAL);
            AddItem(hTree);
      TreeView_SetItemHeight(hTree,20);    //追加    
            break;
            
        case WM_MOUSEMOVE:
            GetCursorPos(&pt);
            ClientToScreen(hWnd,&pt);
            Main_OnMouseMove(hWnd,hTree,pt.x,pt.y); 
            return 0;
 
        case WM_LBUTTONUP:
            Main_OnLButtonUp();
            return 0;

        case WM_NOTIFY:
             switch (((LPNMHDR)lp)->code)
        {
             case TVN_BEGINDRAG:
                  Main_OnBeginDrag(hTree, (LPNMTREEVIEW) lp); 
                  return 0;
      
・・・省略 

}

void AddItem(HWND hTree)
{
・・・省略
}

void Main_OnBeginDrag(HWND hTree, LPNMTREEVIEW lpnmtv) 
{ 
    RECT rcItem;        
    DWORD dwLevel;      
    DWORD dwIndent;     

    himl = TreeView_CreateDragImage(hTree, lpnmtv->itemNew.hItem); 
    TreeView_GetItemRect(hTree, lpnmtv->itemNew.hItem, &rcItem, TRUE); 
    dwLevel = lpnmtv->itemNew.lParam; 
    dwIndent = (DWORD) SendMessage(hTree, TVM_GETINDENT, 0, 0); 
    ImageList_BeginDrag(himl, 0, 0, 0); 
    ImageList_DragEnter(hTree, 0, 0);
    ShowCursor(FALSE); 
    SetCapture(GetParent(hTree)); 
    g_fDragging = TRUE; 
    return; 
} 

void Main_OnMouseMove(HWND hWnd, HWND hTree, LONG xCur, LONG yCur) 
{ 
    HTREEITEM htiTarget;  
    TVHITTESTINFO tvht;  
 
    if (g_fDragging) { 
       ImageList_DragMove(xCur, yCur); 
       tvht.pt.x = xCur; 
        tvht.pt.y = yCur; 
        if ((htiTarget = TreeView_HitTest(hTree, &tvht)) != NULL) { 
            TreeView_SelectDropTarget(hTree, htiTarget); 
        } 
    } 
    return; 
} 
void Main_OnLButtonUp(void) 
{ 
    if (g_fDragging) { 
        ImageList_EndDrag(); 
        ImageList_DragLeave(hTree);
        ReleaseCapture(); 
        ShowCursor(TRUE); 
        g_fDragging = FALSE; 
    } 
    return; 
}

長文になってすいません。コンパイル通って実行できるのですが、D&Dとなりません。
必要な関数などは使っているとおもうのですが・・・
どなたか修正箇所などのご指摘、ご教授お願いできないでしょうか。

WinXP;
VC++.NET;
C言語(APIのみ);

つんた 2002/11/22(金) 10:41:51
あっー、放置されてるぅ〜。
そんなんいややぁ〜・・・。 グスンッ _(ToT)/

dairygoods 2002/11/22(金) 11:01:28
これの、どこを修正するかを調べるには、
1) 新しくSDKのプロジェクトを作り、
2) 「猫でも…」の該当ページを読んで雛型を取り込み、
3) 上記のソースをコピー&ペーストで貼り付け、
4) 省略されてる部分をちゃんと動くように補完し、
5) いったい何がおかしいのか調べる
必要がありますけど、大抵の人は面倒だと思ってやらないでしょう。

まずは、
> D&Dとなりません。
が、具体的に期待する動きとどう違うのかはっきりさせ、
コードのどの部分が期待通りの動きをしていないのかを明示してみてください。

つんた 2002/11/23(土) 07:39:00
dairygoodsさん、助言いただきありがとうございます。

 アイテムをドラッグしたときに、そのアイコンと名前が半透明になってウインドウ外
に持っていけることを期待していたのですが、実際には、何の反応も無くただ単にカー
ソルが動いているだけなんです。
 期待通りの動きを妨げているのは、なんとなく、Main_OnMouseMove関数の第3、第4
引数のとり方のような気がするのですが・・・。でも、WM_MOUSEMOVE以下では、
GetCursorPos(&pt)とClientToScreen(hWnd,&pt)とから持ってくることしか浮かばなかっ
たので・・・。全くの検討はずれだったらすみません。何か助言いただけたら幸いで
す。

つんた 2002/11/23(土) 09:13:31
あっ、出来ました!
ウインドウのスタイルとClientToScreen関数を変えることでOKでした。でも、まだ期待
通りではなく、SetCaptureしているのにウインドウ内でしかドラッグできません。ウイ
ン外にもドラッグするにはどうすればいいのでしょうか?ご教授お願いします。

dairygoods 2002/11/25(月) 10:39:37
SetCapture()を使用することで可能なはずです。

> SetCaptureしているのにウインドウ内でしかドラッグできません。

どうなるのでしょうか?
ウィンドウ外に出てしまうと、WM_MOUSEMOVEメッセージが届かないのでしょうか?
WM_MOUSEMOVEは来るが、Main_OnMouseMove()関数内の処理が
期待したように動かないのでしょうか?

つんた 2002/11/26(火) 20:35:03
自己分析なので間違っているかもしれないのですが・・・。

 Spy++で調べてみると、ウインドウ外でもWM_MOUSEMOVEメッセージが届いているみたい
です。なのに、アイテムをズズッーとドラッグしていくとウインドウ外に出たとたんに
消えてみえなくなってしまします。ウインドウ外でも半透明のアイテムが表示されてい
ることを期待していたのですが。これはそのようにプログラムされていないからなんで
すよね?いずれアイテムの情報をドロップ先に渡せるようにしたいので、これらについ
て調べてみることにします。また疑問点が生じたら題を変えるなりしてご相談します。
ありがとうございました。

古いスレッドには追加発言できません。