2010-08-01 13 views
5

Hola chicos, trato de obtener los archivos seleccionados de una carpeta que el usuario está utilizando. Tengo el siguiente código que ya está en marcha, pero sólo en los archivos de escritorio:Obtener elementos seleccionados de la carpeta 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; 
} 

He intentado conseguir el identificador de ventana con GetForegroundWindow() y luego llamar al SHELLDLL_DefView sin éxito.

Entonces, ¿cómo puedo cambiar las 3 primeras filas para conseguirme el mango de la carpeta actual en uso?

+0

¿Tiene alguna idea de por qué vText siempre está vacío? devuelve "\ 0 \ 0 \ 0 \ 0 \ 0" – Leila

+0

@abatishchev ¿sabe por qué los nombres de los archivos se devuelven como \ 0 \ 0 \ 0 – Leila

Respuesta

4

Eso es un montón de piratería de hacer algo que es apoyada explícitamente por los diversos objetos de concha y las interfaces. De acuerdo, la documentación no lo hace fácil de detectar, pero la funcionalidad está ahí. Raymond Chen wrote a great article sobre el uso de estas interfaces. No parece haber una manera de obtener la carpeta "actual", aunque supongo que podría obtener los HWND y ver si alguno es la ventana de primer plano.

+0

Thx para el enlace lo verificaré! – MUG4N

2

muchas gracias. Me diste la dirección correcta. Es posible obtener los archivos seleccionados de una carpeta:

/// <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

Deberá agregar el objeto COM SHDocVw (Microsoft Internet Controls) como referencia para su proyecto. – boulaycote

+0

puede mostrar el código para obtener el identificador variable y decir cómo se debe llamar a la función getSelectedFileOfActiveWindow en main() – akki

+0

@ MUG4N En realidad tengo problemas para crear un identificador, tal vez porque soy muy nuevo en C#. ¿Puede por favor señalarme en alguna dirección? Cualquier ayuda es muy apreciada. Gracias – akki

Cuestiones relacionadas