2010-08-01 40 views
5

Xin chào các bạn, tôi sẽ cố gắng lấy các tệp đã chọn của một thư mục mà người dùng đang sử dụng. Tôi có đoạn mã sau đó vẫn đang chạy, nhưng chỉ trên các tập tin máy tính để bàn:Nhận các mục đã chọn trong thư mục với 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; 
} 

Tôi cố gắng để có được xử lý cửa sổ với GetForegroundWindow() và sau đó gọi các SHELLDLL_DefView không thành công.

Vậy làm cách nào tôi có thể thay đổi 3 hàng đầu tiên để giúp tôi xử lý thư mục hiện tại đang sử dụng?

+0

Bạn có biết tại sao vText luôn trống không? trả về "\ 0 \ 0 \ 0 \ 0 \ 0" – Leila

+0

@abatishchev bạn có biết tại sao tên tập tin được trả về là \ 0 \ 0 \ 0 – Leila

Trả lời

4

Đó là rất nhiều hack để làm một cái gì đó được hỗ trợ rõ ràng bởi các đối tượng vỏ và giao diện khác nhau. Cấp các tài liệu không làm cho nó dễ dàng phát hiện, nhưng chức năng là có. Raymond Chen wrote a great article về việc sử dụng các giao diện này. Có vẻ như không phải là một cách để có được thư mục "hiện tại", mặc dù tôi đoán bạn có thể nhận được HWNDs và xem nếu có là cửa sổ nền trước.

+0

Thx cho liên kết tôi sẽ kiểm tra xem! – MUG4N

2

cảm ơn bạn rất nhiều. Bạn đã cho tôi đúng hướng. Có thể tải các tệp đã chọn của một thư mục:

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

Bạn sẽ phải thêm đối tượng COM SHDocVw (Microsoft Internet Controls) làm tham chiếu đến dự án của bạn. – boulaycote

+0

bạn có thể vui lòng hiển thị mã để có được biến xử lý và cho biết chức năng getSelectedFileOfActiveWindow phải được gọi trong chính() – akki

+0

@ MUG4N Tôi thực sự gặp vấn đề trong việc tạo ra một xử lý, có lẽ vì tôi rất mới với C#. Bạn có thể vui lòng chỉ cho tôi theo một hướng nào đó. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao. Cảm ơn – akki

Các vấn đề liên quan