Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

winAPI i wycinanie, kopiowanie plików

14 Maj 2007 01:27 1538 2
  • Poziom 22  
    Temat może wprowadzać lekko w błąd ale krótko tego nie da się sformułować, więc z góry sorki. Bardzo proszę o odpowiedź, bo to pytanie jest chyba dla naprawdę fachowców :). Trochę się naszukałem i nie znalazłem rozwiązania tego problemu.

    Sprawa wygląda tak, że mój program musi rozróżnić 2 operacje:
    1) kopiuj (w schowku znajdują się skopiowane pliki)
    2) wytnij (w schowku znajdują się pliki wycięte)

    Czyli krótko mówiąc, chciałbym w żeby mój program po wciśnięciu wklej (pliki ze schowka) wklejał je do jakiegoś katalogu przy czym kiedy pliki w explorerze były skopiowane to ma utworzyć kopię, a jak wycięte to ma je przenieść w dane miejsce.

    Moje pytanie brzmi: Jak rozróżnić czy w schowku znajdują się pliki umieszczone tam po wciśnięciu "Wytnij" w explorerze a jak po wciśnięciu "Kopiuj".

    Dla ewentualnego uproszczenia jeszcze tej sytuacji zapytać mogę w odwrotną stronę. Jak w moim programie ustawić jakiś plik w tryb "wytnij" tak aby po wciśnięciu w explorerze "wklej" plik ten został przeniesiony a nie skopiowany.

    PS. Zaznaczam i to wyraźnie że wiem jak kopiować i przenosić i nie to jest problemem, a tylko rozróżnienie tych dwóch sytuacji, tak aby mój program był kompatybilny z operacjami std. explorera.
  • Pomocny post
    Poziom 27  
    Odpowiem na pierwszą część - jak sprawdzić czy należy skopiować, czy wyciąć:
    Code:
    #include <ole2.h>
    
    #include <shlobj.h>
    #include <oleidl.h>
    #include <conio.h>
    #include <stdio.h>

    int main()
    {
       FORMATETC etc;
       STGMEDIUM medium[2];
       IDataObject *dataobject;

       OleInitialize(0);
       if (!OleGetClipboard(&dataobject))
       {
          etc.cfFormat = CF_HDROP;
          etc.ptd = NULL;
          etc.dwAspect = DVASPECT_CONTENT;
          etc.lindex = -1;
          etc.tymed = TYMED_HGLOBAL;

          if (!dataobject->GetData(&etc, &medium[0]))
          {
             printf("CF_HDROP ok\n");
             etc.cfFormat = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
             etc.tymed = TYMED_ISTREAM;

             if (!dataobject->GetData(&etc, &medium[1]))
             {
                printf("CFSTR_PREFERREDDROPEFFECT ok\n");
                IStream *pstm = medium[1].pstm;

                LARGE_INTEGER li;
                li.QuadPart = 0l;
                pstm->Seek(li, STREAM_SEEK_SET, 0); // na początek strumienia

                int effect = 0;
                pstm->Read(&effect, 4, 0);

                if (effect & DROPEFFECT_MOVE)
                {
                   printf(" move !\n");
                   // MoveFile()
                   OleSetClipboard(0);
                }
                else
                {
                   printf(" copy\n");
                   // CopyFile()
                }
                ReleaseStgMedium(&medium[1]);
             }
             ReleaseStgMedium(&medium[0]);
          }
          dataobject->Release();
       }
       OleUninitialize();
       return getch();
    }


    Na drugą część odpowiem inaczej: musisz stworzyć klasę IDataObject i w niej umieścić standardowo plik w CF_HDROP(TYMED_HGLOBAL), a efekt w dodatkowym formacie CFSTR_PREFERREDDROPEFFECT(TYMED_ISTREAM) z bajtem równym odpowiedniej kombinacji DROPEFFECT. No i oczywiście OleSetClipboard(twoja klasa)

    http://www.codeproject.com/csharp/Explorer_Drag_Drop.asp
    http://msdn2.microsoft.com/en-us/library/aa969396.aspx
  • Poziom 22  
    Wielkie dzięki, działa.