Exemplo n.º 1
0
        /// <summary>
        /// Callback method for the handling of messages to be sent to/from the folder browser dialog.
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="msg"></param>
        /// <param name="lParam"></param>
        /// <param name="lpData"></param>
        /// <returns></returns>
        private int FolderBrowserDialog_BrowseCallbackProc(IntPtr hwnd, int msg, IntPtr lParam, IntPtr lpData)
        {
            switch (msg)
            {
            case NativeWindowCommon.BFFM_INITIALIZED:
                // We get in here when the dialog is first displayed. If an initial directory
                // has been specified we will make this the selection now, and also make sure
                // that directory is expanded.
                if (this.selectedPath.Length != 0)
                {
                    NativeWindowCommon.SendMessage(hwnd, NativeWindowCommon.BFFM_SETSELECTIONW, 1, this.selectedPath);
                }
                break;

            case NativeWindowCommon.BFFM_SELCHANGED:
            {
                IntPtr pidl = lParam;
                if (pidl != IntPtr.Zero)
                {
                    StringBuilder sb   = new StringBuilder(MAX_PATH * Marshal.SystemDefaultCharSize);
                    bool          flag = NativeWindowCommon.SHGetPathFromIDList(pidl, sb);
                    NativeWindowCommon.SendMessage(hwnd, NativeWindowCommon.BFFM_ENABLEOK, 0, flag ? 1 : 0);
                }

                if (!doneScrolling)
                {
                    IntPtr hbrowse = NativeWindowCommon.FindWindowEx(hwnd, IntPtr.Zero, "SHBrowseForFolder ShellNameSpace Control", null);
                    IntPtr htree   = NativeWindowCommon.FindWindowEx(hbrowse, IntPtr.Zero, "SysTreeView32", null);
                    IntPtr htis    = NativeHeader.SendMessage(htree, NativeWindowCommon.TVM_GETNEXTITEM, NativeWindowCommon.TVGN_CARET, IntPtr.Zero);

                    IntPtr htir = NativeHeader.SendMessage(htree, NativeWindowCommon.TVM_GETNEXTITEM, NativeWindowCommon.TVGN_ROOT, IntPtr.Zero);
                    IntPtr htic = NativeHeader.SendMessage(htree, NativeWindowCommon.TVM_GETNEXTITEM, NativeWindowCommon.TVGN_CHILD, htir);

                    //we actually go into the BFFM_SELCHANGED case three times when the dialog is first shown, and it's only on the third one that we actually scroll,
                    //since before this htic is always zero, so you need to cope with this
                    //- i.e. don't set 'doneScrolling' flag until htic has been non - zero(or until you've gone into the BFFM_SELCHANGED three times).
                    if ((int)htic != 0)
                    {
                        doneScrolling = true;
                        //The only solution I've found that works consistently is to send a TVM_ENSUREVISIBLE to the tree, using TVM_GETNEXTITEM/TVGN_CARET, from BFFM_SELCHANGED.
                        //That works. Every time.
                        NativeHeader.SendMessage(htree, NativeWindowCommon.TVM_ENSUREVISIBLE, 0, htis);

                        //Active the tree view control window inside the folder browser dialog to set the focus on it.
                        NativeWindowCommon.SendMessage(htree, NativeWindowCommon.WM_ACTIVATE, 1, 0);
                    }
                }
            }
            break;
            }
            return(0);
        }