예제 #1
0
        public Result <string> Ask()
        {
            IntPtr pidlRoot;
            IntPtr hWndOwner;

            if (mOwner is Window window)
            {
                var iw = new WindowInteropHelper(window);
                hWndOwner = iw.Handle;
            }
            else if (mOwner is IWin32Window win32Window)
            {
                hWndOwner = win32Window.Handle;
            }
            else
            {
                hWndOwner = GetActiveWindow();
            }

            SHGetSpecialFolderLocation(hWndOwner, (int)mRoot, out pidlRoot);

            if (pidlRoot == IntPtr.Zero)
            {
                return(Result.CreateError <Result <string> >("Error reading the root directory of the user profile. Perhaps there are no sufficient permissions to perform this action or the user profile is corrupted."));
            }

            var mergedOptions = mPublicOptions | mPrivateOptions;

            if ((mergedOptions & (int)BrowseForFolderStyles.NewDialogStyle) != 0)
            {
                if (System.Threading.ApartmentState.MTA == System.Windows.Forms.Application.OleRequired())
                {
                    mergedOptions = mergedOptions & ~(int)BrowseForFolderStyles.NewDialogStyle;
                }
            }

            var pidlRet = IntPtr.Zero;

            try
            {
                var bi     = new BrowseForFolderDialogInfo();
                var buffer = Marshal.AllocHGlobal(mMaxPathLength);

                bi.pidlRoot       = pidlRoot;
                bi.hwndOwner      = hWndOwner;
                bi.pszDisplayName = buffer;
                bi.lpszTitle      = mPrompt;
                bi.ulFlags        = mergedOptions;
                bi.lpfn           = BrowseDialogCallback;

                pidlRet = SHBrowseForFolder(ref bi);
                Marshal.FreeHGlobal(buffer);

                if (pidlRet == IntPtr.Zero)
                {
                    return(Result.CreateError <Result <string> >(new OperationCanceledException()));
                }

                var sb = new StringBuilder(mMaxPathLength);
                if (0 == SHGetPathFromIDList(pidlRet, sb))
                {
                    return(Result.CreateError <Result <string> >(new OperationCanceledException()));
                }

                mPath = sb.ToString();
            }
            finally
            {
                IMalloc malloc;
                SHGetMalloc(out malloc);
                malloc.Free(pidlRoot);

                if (pidlRet != IntPtr.Zero)
                {
                    malloc.Free(pidlRet);
                }
            }

            return(new Result <string>(mPath));
        }
예제 #2
0
 [DllImport("shell32.dll", CharSet = CharSet.Auto)] static extern IntPtr SHBrowseForFolder(ref BrowseForFolderDialogInfo bi);