2020年5月13日水曜日

ファイルをカットしてクリップボードに送る c++


プログラム内でファイルを移動するのは簡単だけど、エクスプローラの操作のように違うプログラム間でファイルの切り取りを実現したかった
具体的には、EverythingでカットしたファイルをTCDに貼り付けたい
これがかなり難しい
かろうじてコピーは出来たんだけど、切り取りはさらにハードルが上がる
webで検索するとC#やVBの方法は見つかるがc++の情報が探せない
でも何とか出来たので残しておきます

大まかな流れは
・切り取るファイル名のデータをCH_HDROP形式で作成する
・"PreferredDropEffect" のコード(uint)をRegisterClipboardFormatで取得する
・"PreferredDropEffect"の設定データを作成する(dropeffect_move~2です)
・クリップボードを開いてクリアする
・ファイル名をCF_HDROPでクリップにセットする
・[2]を"PreferredDropEffect"でクリップにセットする
・クリップボードを閉じる

<コード>
void CutFile(HWND hwnd , wchar_t *buffer) {
    DROPFILES dobj;
    dobj.pFiles = sizeof(DROPFILES); // 20
    dobj.pt.x = 0;
    dobj.pt.y = 0;
    dobj.fNC = 0;
    dobj.fWide = 1;

    HGLOBAL hGbl = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE,
        sizeof(DROPFILES) + wcslen(buffer) * 2 + 2 ); <---- ここ
    char* sData = (char*)::GlobalLock(hGbl);
    memcpy(sData, &dobj, sizeof(DROPFILES));
    memcpy(sData + sizeof(DROPFILES), buffer, wcslen(buffer)*2 ); // 後ろにファイルを付加
    ::GlobalUnlock(hGbl);

    HGLOBAL hGbl2 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, 4);
    char* sData2 = (char*)::GlobalLock(hGbl2);
    *sData2 = 2;
    ::GlobalUnlock(hGbl2);

    if (!OpenClipboard(hwnd)) return ;
    EmptyClipboard();
    SetClipboardData(CF_HDROP, hGbl);
    SetClipboardData(RegisterClipboardFormat(L"Preferred DropEffect"), hGbl2);
    CloseClipboard();

================
20/09/22 手直し
最後の+2は+4になる

0 件のコメント:

コメントを投稿