带快速选择的浏览文件夹






4.52/5 (7投票s)
定制版本的“浏览文件夹”对话框。它会创建您选定目录的快速选项。

引言
我当时正在做 SizeMe 项目,一位用户要求增加一个功能。他要求一个预定义目录列表,他想扫描这些目录。我刚读完文章 定制“浏览文件夹”对话框,就萌生了定制通用对话框的想法。这是结果。
请记住,通用对话框会以 Windows 安装的语言显示。图片显示的是我使用挪威语的对话框。我还想感谢 Hans Dietrich 的文章 XBrowseForFolder - SHBrowseForFolder 的包装器。项目中使用的部分代码受到了他的工作的启发。
Using the Code
该项目可以在 MFC 项目或 Win32 项目中使用。(该项目仅在 Visual Studio 6.0 环境下进行过测试。我不知道它是否会在更新的 Visual Studio 版本上运行,但我猜应该可以)。
首先将文件 Dirbrowse.cpp 和 DirBrowse.h 添加到您的项目中,然后包含 DirBrowse.h。有两个公共函数需要您使用
BOOL Show(char *szInitDir="");
函数 Show
在用户按下“确定”时返回 TRUE
,按下“取消”/“关闭”时返回 FALSE
。szInitDir
是可选的,用于选择浏览器的起始目录。
char* GetSelectedDir();
函数 GetSelectedDir
返回一个 string
,其中包含选定的路径。
示例
这是我为处理该类而编写的快速 Win32 示例
#include "stdafx.h"
#include "..\DirBrowse.h"
#include <stdio.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
CDirBrowse m_dirbrowser(NULL, hInstance);
if(m_dirbrowser.Show()==TRUE)
{
char Text[MAX_PATH*2];
sprintf(Text, "You selected folder: %s", m_dirbrowser.GetSelectedDir());
MessageBox(NULL, Text, "Browse for folder", MB_OK);
}
else
{
MessageBox(NULL, "You pressed the cancel button!", "Browse for folder", MB_OK);
}
return 0;
}
就是这么简单。看看项目就知道相同的 MFC 版本了。
头文件定制
当我创建可重用类时,我总是创建很多 #defines
。这个类也不例外。这是 define
s 列表
//#1
#define BROWSE_WIDTH 640
#define BROWSE_HEIGHT 420
#define BROWSE_LISTVIEW_SIZE 0.65
#define BROWSE_BORDER_VERT 4
#define BROWSE_BORDER_HORI 2
#define BROWSE_MAXENTRIES 20
//#2
//This is the message that we start with
#define BROWSE_MESSAGE 10101
//#3
//The name of our hypertext class
#define STATIC_HYPERTEXT_WINDOW_CLASS "STATIC_HYPERTEXT"
//#4
//This is the font & size we use for showing the info
#define BROWSE_FONTNAME "Verdana"
#define BROWSE_FONTSIZE 12
//#5
//The colors used
#define BROWSE_SELECTCOLOR RGB(0,0,255)
#define BROWSE_SELECTCOLORHOVER RGB(50,105,255)
#define BROWSE_DIRCOLOR RGB(0,0,200)
#define BROWSE_DIRCOLORHOVER RGB(100,100,250)
//#6
//The registry variables
#define BROWSE_REGISTRY_ROOT HKEY_CURRENT_USER
#define BROWSE_REGISTRY_PATH "Software\\DirBrowser"
//#7
//Strings used
#define BROWSE_TEXT_SHORTCUTS "Shortcuts"
#define BROWSE_TEXT_HELP "Please select a folder in the list and press the
arrow to save the directory for a quickpick later on"
#define BROWSE_TEXT_HELP_CAPTION "Browse for folder help"
#define BROWSE_TEXT_HELP_TOOLTIP "Press this to save selected path as a shortcut"
//Must not exceed 79 chars!!!
下面将解释每个组
定义 | 描述 | 默认值 |
第 1 组 | ||
BROWSE_WIDTH 、BROWSE_HEIGHT 、BROWSE_LISTVIEWSIZE |
WIDTH /HEIGHT 是窗口的大小。ListView -size 是 dirlist 宽度的一个百分比。 |
640、420、0.65(宽度百分比!) |
BROWSE_BORDER_VERT 、BROWSE_BORDER_HORI |
边框变量是控件之间垂直和水平方向的像素间隔。 | 4,2 |
BROWSE_MAXENTRIES |
MaxEntries 是我们可以在屏幕上显示的快速选项的数量(不应超过屏幕能显示的条目数) |
20(应该够所有人用了) |
第 2 组 | ||
BROWSE_MESSAGE |
Message 是我们用于控件的内部消息。它会递增,所以它从 10101 开始,然后是 10102,依此类推。 | 10101 |
第 3 组 | ||
STATIC_HYPERTEXT_WINDOW_CLASS |
超文本窗口类只是处理超文本类的类的内部名称。如果您的项目中存在重复的名称,请更改此项。 | "STATIC_HYPERTEXT " |
第 4 组 | ||
BROWSE_FONTNAME 、BROWSE_FONTSIZE |
这是超文本类使用的字体和大小。它不会检查字体是否真的存在,所以请确保输入一个有效的名称。 | "Verdana", 12 |
第 5 组 | ||
BROWSE_SELECTCOLOR 、BROWSE_SELECTCOLORHOVER 、BROWSE_DIRCOLOR 、BROWSE_DIRCOLORHOVER |
超文本类的颜色。分为选择器和实际目录。 | RGB(0,0,255)、RGB(50,105,255)、RGB(0,0,200)、RGB(100,100,250) |
第 6 组 | ||
BROWSE_REGISTRY_ROOT 、BROWSE_REGISTRY_PATH |
您希望配置保存到的路径。这通常需要更改,因为您不希望 dirbrowser 加载您在不同项目中使用的相同位置存储的变量。 | HKEY_CURRENT_USER 、"Software\\DirBrowser"(这个应该始终更改!) |
第 7 组 | ||
BROWSE_TEXT_SHORTCUTS 、BROWSE_TEXT_HELP 、BROWSE_TEXT_HELP_CAPTION 、BROWSE_TEXT_HELP_TOOLTIP |
由于我没有在此项目中实现“多语言”支持,因此您可以更改此处使用的文本。 | "Shortcuts", "Please select a folder in the list and press the arrow to save the directory for a quickpick later on", "Browse for folder help", "Press this to save selected path as a shortcut" (Must not exceed 79 chars) |
兴趣点
在编译项目发布版本时,我发现了一个小错误。看看这段代码
if(pMe->MessageIsOdd == FALSE)
{
if(nID % 2 == 0)
MsgIsOdd = FALSE;
else
MsgIsOdd = TRUE;
}
else
{
if(nID % 2 == 0)
MsgIsOdd = TRUE;
else
MsgIsOdd = FALSE;
}
这里不应该有任何错误,但经过一些研究,我注意到 if
语句的第一部分是唯一被调用的部分。我需要将其拆分以避免此错误,如下所示
if(pMe->MessageIsOdd == FALSE)
{
//...
}
if(pMe->MessageIsOdd == TRUE)
{
//...
}
如果有人对此有好的答案,请告诉我。我正在使用 Visual Studio 6.0 C++ SP5 + UINT64 处理器包补丁。
历史
- v1.0 - 初始发布