-->

Is there a Windows API to programmatically Cut / C

2019-06-16 09:55发布

问题:

I know that SHFileOperation can be used to perform file operatons with Windows Explorer, but it only performs complete file operations where both the source and destination are known.

Is there an API that allows a application to cut, copy, or paste in Windows Explorer from an application?

To answer a couple of questions:

  • Using Windows Explorer to perform file/folder operations would greatly simplify moving multiple objects. This is particularly important for moving folders and their contents since MoveFile does not support moving folders to different volumes.

  • Using Windows Explorer to perform file/folder operations would allow the operations to be added to Windows Explorer’s undo buffer so that they can be undone, otherwise operations done with console applications/the command-prompt cannot be undone.

I am sure that I have seen it possible to perform Windows Explorer verbs programmatically, but I can’t seem to find a way to do so for these.

回答1:

It's difficult to imagine why such a function would exist, or what good it would be if it did.

Cut/copy and paste are provided for the convenience of the user. It allows them to move/copy something somewhere else at a later date. The application that implements cut/copy and paste functionality may not know where the data is ultimately going to be pasted, but that's okay because the user still knows.

But an application doing a cut/copy-paste action doesn't make a lot of sense because in order for the "paste" part to work, the application has to know where the item is going to be pasted. And if it knows that, then it could just call the SHFileOperation function that you already know about.

If you are really just talking about providing the user with the ability to cut/copy/paste an item, then you will want to use the clipboard—just like Windows does. When an item is cut or copied, it's placed on the clipboard. When an item is pasted, the current contents of the clipboard are retrieved. Use the Windows clipboard API functions to interact with the clipboard.



回答2:

I implemented it in my file manager, here's the link to the GitHub source for the copy function. Paste is nearby.

It works by creating an invisible Explorer context menu for the file system items of interest, and then invoking the Cut, Copy, or Paste command from that menu. It's in C++ (because COM), but I'm sure you can use COM from other languages as well somehow.

bool copyObjectsToClipboard(std::vector<std::wstring> objects, void * parentWindow)
{
    ComInitializer comInitializer;

    IContextMenu * imenu = 0;
    HMENU hMenu = NULL;
    if (!prepareContextMenuForObjects(objects, parentWindow, hMenu, imenu) || !hMenu || !imenu)
        return false;

    CComInterfaceReleaser menuReleaser(imenu);

    const char command[] = "Copy";

    CMINVOKECOMMANDINFO info = { 0 };
    info.cbSize = sizeof(info);
    info.hwnd = (HWND)parentWindow;
    info.lpVerb = command;
    info.nShow = SW_SHOWNORMAL;
    const auto result = imenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);

    DestroyMenu(hMenu);

    return SUCCEEDED(result);
}


回答3:

// https://docs.microsoft.com/ja-jp/windows/desktop/dataxchg/standard-clipboard-formats
const char* wichStandardClipboardFormatsIsAvailable()
{
    // Standard Clipboard Formats
    // CF_BITMAP            : 2
    // CF_DIB               : 8
    // CF_DIBV5             :17
    // CF_DIF               : 5
    // CF_DSPBITMAP         :0x0082
    // CF_DSPENHMETAFILE    :0x008E
    // CF_DSPMETAFILEPICT   :0x0082
    // CF_DSPTEXT           :0x0081
    // CF_ENHMETAFILE       :14
    // CF_GDIOBJFIRST       :0x0300
    // CF_GDIOBJLAST        :0x03FF
    // CF_HDROP             :15
    // CF_LOCALE            :16
    // CF_METAFILEPICT      :3
    // CF_OEMTEXT           :7
    // CF_OWNERDISPLAY      :0x0080
    // CF_PALETTE           :9
    // CF_PENDATA           :10
    // CF_PRIVATEFIRST      :0x0200
    // CF_PRIVATELAST       :0x02FF
    // CF_RIFF              :11
    // CF_SYLK              :4
    // CF_TEXT              :1
    // CF_TIFF              :6
    // CF_UNICODETEXT       :13
    // CF_PRIVATELAST       :0x02FF
    // CF_WAVE              :12

    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_BITMAP";
    }
    if ( IsClipboardFormatAvailable(CF_DIB) ) {
        return "CF_DIB";
    }
    if ( IsClipboardFormatAvailable(CF_DIBV5) ) {
        return "CF_DIBV5";
    }
    if ( IsClipboardFormatAvailable(CF_DIF) ) {
        return "CF_DIF";
    }
    if ( IsClipboardFormatAvailable(CF_DSPBITMAP) ) {
        return "CF_DSPBITMAP";
    }
    if ( IsClipboardFormatAvailable(CF_DSPENHMETAFILE) ) {
        return "CF_DSPENHMETAFILE";
    }
    if ( IsClipboardFormatAvailable(CF_DSPMETAFILEPICT) ) {
        return "CF_DSPMETAFILEPICT";
    }
    if ( IsClipboardFormatAvailable(CF_HDROP) ) {
        return "CF_HDROP";
    }
    if ( IsClipboardFormatAvailable(CF_GDIOBJFIRST) ) {
        return "CF_GDIOBJFIRST";
    }
    if ( IsClipboardFormatAvailable(CF_GDIOBJLAST) ) {
        return "CF_GDIOBJLAST";
    }
    if ( IsClipboardFormatAvailable(CF_HDROP) ) {
        return "CF_HDROP";
    }
    if ( IsClipboardFormatAvailable(CF_LOCALE) ) {
        return "CF_LOCALE";
    }
    if ( IsClipboardFormatAvailable(CF_METAFILEPICT) ) {
        return "CF_METAFILEPICT";
    }
    if ( IsClipboardFormatAvailable(CF_OEMTEXT) ) {
        return "CF_OEMTEXT";
    }
    if ( IsClipboardFormatAvailable(CF_OWNERDISPLAY) ) {
        return "CF_OWNERDISPLAY";
    }
    if ( IsClipboardFormatAvailable(CF_PALETTE) ) {
        return "CF_PALETTE";
    }
    if ( IsClipboardFormatAvailable(CF_RIFF) ) {
        return "CF_RIFF";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_SYLK";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_TEXT";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_UNICODETEXT";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_PRIVATELAST";
    }
    if ( IsClipboardFormatAvailable(CF_BITMAP) ) {
        return "CF_WAVE";
    }

    return "CF_NOT_STANDARD";
}

https://github.com/WaitrudWeber/source_zip/blob/master/winmain-20190111.zip

  1. execute winmain_001.exe.
  2. copy file in the explore.
  3. press ctl and then v
  4. you could see CF_HDROP

you see the function: wichStandardClipboardFormatsIsAvailable in winmain_001.cpp and https://docs.microsoft.com/ja-jp/windows/desktop/dataxchg/standard-clipboard-formats

once I misslead you and am so sorry to everyone.