2010-08-01 5 views
5

안녕하세요 여러분, 사용자가 사용하고있는 폴더의 선택된 파일을 가져 오려고합니다.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; 
} 

내가 GetForegroundWindow()와 창 핸들을 얻을하고 성공없이 SHELLDLL_DefView 전화를 시도 : 이미,하지만 바탕 화면 파일에서 실행되는 다음과 같은 코드가 있습니다.

그래서 현재 사용중인 폴더의 핸들을 가져 오려면 처음 세 줄을 어떻게 바꿀 수 있습니까?

+0

vText가 항상 비어있는 이유는 무엇입니까? "\ 0 \ 0 \ 0 \ 0 \ 0"을 반환합니다. – Leila

+0

@abatishchev 파일 이름이 \ 0 \ 0 \ 0으로 반환되는 이유를 알고 계십니까? – Leila

답변

4

다양한 쉘 개체와 인터페이스에 의해 명시 적으로 지원되는 해킹 작업이 많이 있습니다. 문서에서 쉽게 발견 할 수는 없지만 기능이 있습니다. 이 인터페이스를 사용하는 Raymond Chen wrote a great article. "현재"폴더를 가져 오는 방법이없는 것처럼 보이지만 HWND를 가져 와서 전경 창이 있는지 확인할 수 있습니다.

+0

링크를 Thx로 확인합니다! – MUG4N

2

대단히 감사합니다. 당신은 내게 올바른 방향을 제시했습니다. 폴더의 선택한 파일을 가져올 수 있습니다.

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

SHDocVw (Microsoft 인터넷 컨트롤) COM 개체를 프로젝트에 대한 참조로 추가해야합니다. – boulaycote

+0

변수 핸들을 얻고 main()에서 getSelectedFileOfActiveWindow 함수를 호출해야하는 코드를 보여 주시겠습니까? – akki

+0

@ MUG4N 핸들을 만드는 데 실제로 문제가 있습니다. 아마도 C#에 익숙하지 않기 때문일 수 있습니다. 어떤 방향으로 나를 가리켜 주시겠습니까? 어떤 도움도 크게받지 못했습니다. 감사합니다 – akki

관련 문제