2010-08-01 7 views
5

Ehi ragazzi provo ad ottenere i file selezionati di una cartella che l'utente sta usando. Ho il seguente codice che è già in esecuzione, ma solo su file desktop:Ottieni gli elementi selezionati della cartella con WinAPI

private string selectedFiles() 
{ 
    // get the handle of the desktop listview 
    IntPtr vHandle = WinApiWrapper.FindWindow("Progman", "Program Manager"); 
    vHandle = WinApiWrapper.FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", null); 
    vHandle = WinApiWrapper.FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView"); 

    //IntPtr vHandle = WinApiWrapper.GetForegroundWindow(); 

    //Get total count of the icons on the desktop 
    int vItemCount = WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMCOUNT, 0, 0); 
    //MessageBox.Show(vItemCount.ToString()); 
    uint vProcessId; 
    WinApiWrapper.GetWindowThreadProcessId(vHandle, out vProcessId); 
    IntPtr vProcess = WinApiWrapper.OpenProcess(WinApiWrapper.PROCESS_VM_OPERATION | WinApiWrapper.PROCESS_VM_READ | 
    WinApiWrapper.PROCESS_VM_WRITE, false, vProcessId); 
    IntPtr vPointer = WinApiWrapper.VirtualAllocEx(vProcess, IntPtr.Zero, 4096, 
    WinApiWrapper.MEM_RESERVE | WinApiWrapper.MEM_COMMIT, WinApiWrapper.PAGE_READWRITE); 
    try 
    { 
     for (int j = 0; j < vItemCount; j++) 
     { 
      byte[] vBuffer = new byte[256]; 
      WinApiWrapper.LVITEM[] vItem = new WinApiWrapper.LVITEM[1]; 
      vItem[0].mask = WinApiWrapper.LVIF_TEXT; 
      vItem[0].iItem = j; 
      vItem[0].iSubItem = 0; 
      vItem[0].cchTextMax = vBuffer.Length; 
      vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(WinApiWrapper.LVITEM))); 
      uint vNumberOfBytesRead = 0; 
      WinApiWrapper.WriteProcessMemory(vProcess, vPointer, 
      Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), 
      Marshal.SizeOf(typeof(WinApiWrapper.LVITEM)), ref vNumberOfBytesRead); 
      WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMW, j, vPointer.ToInt32()); 
      WinApiWrapper.ReadProcessMemory(vProcess, 
      (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(WinApiWrapper.LVITEM))), 
      Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), 
      vBuffer.Length, ref vNumberOfBytesRead); 
      string vText = Encoding.Unicode.GetString(vBuffer, 0, 
      (int)vNumberOfBytesRead); 
      string IconName = vText; 

      //Check if item is selected 
      var result = WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMSTATE, j, (int)WinApiWrapper.LVIS_SELECTED); 
      if (result == WinApiWrapper.LVIS_SELECTED) 
      { 
       return vText; 
      } 
     } 
    } 
    finally 
    { 
     WinApiWrapper.VirtualFreeEx(vProcess, vPointer, 0, WinApiWrapper.MEM_RELEASE); 
     WinApiWrapper.CloseHandle(vProcess); 
    } 
    return String.Empty; 
} 

ho cercato di ottenere l'handle finestra con GetForegroundWindow() e quindi chiamare lo SHELLDLL_DefView senza successo.

Quindi, come posso modificare le prime 3 righe per ottenere l'handle della cartella corrente in uso?

+0

Hai idea del motivo per cui vText è sempre vuoto? restituisce "\ 0 \ 0 \ 0 \ 0 \ 0" – Leila

+0

@abatishchev sai perché i nomi dei file vengono restituiti come \ 0 \ 0 \ 0 – Leila

risposta

4

Questo è un sacco di hacking per fare qualcosa che è esplicitamente supportato dai vari oggetti e interfacce della shell. Garantita la documentazione non lo rende facilmente individuabile, ma la funzionalità è lì. Raymond Chen wrote a great article sull'utilizzo di queste interfacce. Non sembra essere un modo per ottenere la cartella "corrente", anche se penso che potresti ottenere gli HWND e vedere se c'è una finestra in primo piano.

+0

Thx per il collegamento Lo controllerò! – MUG4N

2

grazie mille. Mi hai dato la giusta direzione. È possibile ottenere i file selezionati di una cartella:

/// <summary> 
/// Get the selected file of the active window 
/// </summary> 
/// <param name="handle">Handle of active window</param> 
/// <returns></returns> 
public String getSelectedFileOfActiveWindow(Int32 handle) 
{ 
    try 
    { 
     // Required ref: SHDocVw (Microsoft Internet Controls COM Object) 
     ShellWindows shellWindows = new SHDocVw.ShellWindows(); 

     foreach (InternetExplorer window in shellWindows) 
     { 
      if (window.HWND == handle) 
       return ((Shell32.IShellFolderViewDual2)window.Document).FocusedItem.Path; 
     }     
    } 
    catch (Exception) 
    { 
     return null; 
    } 
    return null; 
} 
+1

Dovrai aggiungere l'oggetto COM SHDocVw (Microsoft Internet Controls) come riferimento al tuo progetto. – boulaycote

+0

puoi per favore mostrare il codice per ottenere la variabile handle e dire come la funzione getSelectedFileOfActiveWindow deve essere chiamata in main() – akki

+0

@ MUG4N In realtà sto avendo problemi nel creare un handle, forse perché sono molto nuovo a C#. Puoi per favore indicarmi in qualche direzione. Qualsiasi aiuto è molto apprezzato. Grazie – akki

Problemi correlati