Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831316
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-14 16:27:58

【标题】    :目录选择对话框 for C# ( 本文曾在VCKBASE发表,但时日过久,已然不见 )
【预期读者】:闲得无事的家伙
【申明】    :文章和代码转载时请标明出处,因为编写这些代码耗费了我不少时间,但实在不想标明出处也无所谓。
【题外话】  :凭空说C#难或易本无意义,有其易用处则亦必有难用之处,能将API调用搞得如此繁琐正应了那句话“将简单的问题搞复杂了也是能耐”,见识了C#之后不得不再次赞叹C/C++的精妙。
【友情提醒】:代码中的WinAPI申明不具有复用性(不得不说C#很弱智)
【正文】    :
C#中没有目录选择对话框,Window API中有,C#难于调用WinAPI,故给出封装好的代码。

//***********************************
// 功能:目录选择对话框
// 作者: 之 [周星星]
// 日期:2003-06-17
// 版权申明:随意拷贝、修改、发布
//***********************************
namespace FolderDlgs
{
 using System;
 using System.Text;
 using System.Runtime.InteropServices;

 public class OpenFolderDialog
 {
  /*
  private struct SHITEMID
  {
   ushort cb;
   byte adID; // BYTE abID[1];
  }
  private struct ITEMIDLIST
  {
   SHITEMID mkid;
  }
  */
  [StructLayout(LayoutKind.Sequential)]
  private struct BROWSEINFO
  {
   public IntPtr hwndOwner; // HWND hwndOwner
   public IntPtr pidlRoot; // const ITEMIDLIST* pidlRoot
   [MarshalAs(UnmanagedType.LPTStr)]
   public string pszDisplayName;
   [MarshalAs(UnmanagedType.LPTStr)]
   public string lpszTitle;
   public int ulFlags;
   [MarshalAs(UnmanagedType.FunctionPtr)]
   public BrowseCallBackProc lpfn;
   [MarshalAs(UnmanagedType.LPTStr)]
   public string lParam;
   public int iImage;
  }

  [DllImport("User32.Dll")]
  [return : MarshalAs(UnmanagedType.Bool)]
  private extern static bool SendMessage( IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPTStr)] string lParam );
  [DllImport("Shell32.dll", CharSet=CharSet.Auto)]
  private extern static IntPtr SHBrowseForFolder( ref BROWSEINFO lpbi );
  [DllImport("Shell32.dll", CharSet=CharSet.Auto)]
  [return : MarshalAs(UnmanagedType.Bool)]
  private extern static bool SHGetPathFromIDList( IntPtr pidl, StringBuilder pszPath );
  private delegate int BrowseCallBackProc( IntPtr hwnd, uint msg, IntPtr lParam, [MarshalAs(UnmanagedType.LPTStr)] string lpData );
  private static int BrowseCtrlCallback( IntPtr hwnd, uint uMsg, IntPtr lParam, [MarshalAs(UnmanagedType.LPTStr)] string lpData )
  {
   if( uMsg == 1 ) // BFFM_INITIALIZED
   {
    string szPath = lpData;
    if( szPath!=null && szPath!="" )
    {
     if( szPath[szPath.Length-1] != '\\' )
      szPath += '\\';
     SendMessage( hwnd, 0x400+103, 1, szPath ); // BFFM_SETSELECTION
    }
   }

   return 0;

  }

  // hwndOwner:父窗体句柄
  // Title:标题;可以为null,也可以为""
  // lpszInitPath:初始目录;可以为null,也可以为"";为null或""时指向“我的电脑”
  // return:如果按下了“确定”按钮则为用户选择的目录,否则返回null
  public static string ShowDialog( IntPtr hwndOwner, string Title, string lpszInitPath )
  {
   BROWSEINFO BrInfo;
   BrInfo.hwndOwner = hwndOwner;
   BrInfo.pidlRoot = IntPtr.Zero;
   BrInfo.pszDisplayName = null;
   BrInfo.lpszTitle = Title;
   BrInfo.ulFlags = 0x0001; // BIF_RETURNONLYFSDIRS
   BrInfo.lpfn = new BrowseCallBackProc( BrowseCtrlCallback );
   BrInfo.lParam = lpszInitPath;
   BrInfo.iImage = 0;

   IntPtr pidlDestination = SHBrowseForFolder( ref BrInfo );
   string folderName = null;
   if( pidlDestination != IntPtr.Zero )
   {
    StringBuilder tmp = new StringBuilder( 260 ); // MAX_PATH
    SHGetPathFromIDList( pidlDestination, tmp );
    folderName = tmp.ToString();
   }
   return folderName;
  }
 }
}

////////////////////////////////////////////////////
测试代码:
 string str = FolderDlgs.OpenFolderDialog.ShowDialog( this.Handle, "选择目录", @"F:\" );
 if( str!=null ) MessageBox( "你选择了目录:"+str );
 else MessageBox( "靠,你按了“取消”按钮,啥也没选" );

阅读(1248) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-14 16:29:24

周星星
C++:
extern "C" __declspec(dllexport) int __stdcall cpp_dll( int arr[], int& len )
{
    arr[0] = 1;
    arr[1] = 2;
    int ret = len;
    len = 3;
    return ret;
}
def: // ALT+F7 -> Linker -> Input -> Module Definition File 中加 .\cpp_dll.def
EXPORTS
    cpp_dll

C#:
namespace cs_exe
{