【程序运行效果】
【程序代码】
main.c:
#define COBJMACROS
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <windowsx.h>
#include <CommCtrl.h>
#include <ShlObj.h>
#include "resource.h"
#pragma comment(lib, "comctl32.lib")
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' language='*' publicKeyToken='6595b64144ccf1df'\"")
int CALLBACK bff_callback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED && lpData != 0) // 当对话框刚初始化成功时
SendMessage(hwnd, BFFM_SETSELECTIONA, TRUE, lpData); // 选择指定的默认文件夹
return 0;
}
// 浏览文件夹
void bff(HWND parent_dialog)
{
char name[MAX_PATH]; // MAX_PATH专门表示路径的最大长度
char path[MAX_PATH];
char text[MAX_PATH + 100];
BROWSEINFOA info = {0};
HRESULT hr;
HWND textbox;
IMalloc *shell_malloc;
LPITEMIDLIST item_list;
// 获取文本框输入的文件夹路径
textbox = GetDlgItem(parent_dialog, IDC_EDIT1);
GetWindowTextA(textbox, path, MAX_PATH);
info.hwndOwner = parent_dialog; // 指定父窗口
info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; // 禁止选择像"回收站"这种非正常文件夹(此选项在XP系统下无效); 使用新式对话框
info.pszDisplayName = name; // 用于接收选择的文件夹名称的变量
info.lpszTitle = "请选择一个文件夹:"; // 提示文字
info.lpfn = bff_callback; // 设置回调函数
info.lParam = (LPARAM)path; // 设置默认选择的文件夹为文本框输入的文件夹
item_list = SHBrowseForFolderA(&info);
if (item_list != NULL)
{
// 将选择的文件夹路径显示到文本框中
SHGetPathFromIDListA(item_list, path);
if (path[0] == '\0' && name[0] != '\0')
strcpy_s(path, MAX_PATH, name);
SetWindowTextA(textbox, path);
// 全选
SetFocus(textbox);
Edit_SetSel(textbox, 0, -1);
// 将选择的文件夹名称显示到文本框下方
_snprintf_s(text, sizeof(text), sizeof(text) - 1, "您选择的文件夹的名称是: %s", name);
SetDlgItemTextA(parent_dialog, IDC_STATIC2, text);
// 释放item_list占用的内存
hr = SHGetMalloc(&shell_malloc);
if (SUCCEEDED(hr))
{
IMalloc_Free(shell_malloc, item_list);
IMalloc_Release(shell_malloc);
}
}
}
// 显示窗口图标
void init_icons(HWND dlg)
{
HICON icon;
HMODULE instance;
instance = GetModuleHandle(NULL);
icon = LoadImage(instance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM)icon);
icon = LoadImage(instance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM)icon);
}
// 获取并显示当前exe文件所在的文件夹
void init_default_path(HWND dlg)
{
char path[MAX_PATH];
char *p;
GetModuleFileNameA(NULL, path, MAX_PATH);
p = strrchr(path, '\\');
if (p != NULL)
*p = '\0';
SetDlgItemTextA(dlg, IDC_EDIT1, path);
SetDlgItemTextA(dlg, IDC_STATIC2, "");
}
INT_PTR CALLBACK dlg_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int id;
switch (uMsg)
{
case WM_COMMAND:
id = LOWORD(wParam);
switch (id)
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg, 0);
break;
case IDC_BUTTON1:
bff(hDlg);
break;
}
break;
case WM_INITDIALOG:
init_icons(hDlg);
init_default_path(hDlg);
break;
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
int ret;
InitCommonControls();
ret = (int)DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, dlg_proc);
return ret;
}
【开发环境截图】
【C++语言写法】
(1)源文件扩展名由c改为cpp。
(2)去除顶部的#define COBJMACROS。
(3)bff函数中:
IMalloc_Free(shell_malloc, item_list)改成shell_malloc->Free(item_list)。
IMalloc_Release(shell_malloc)改成shell_malloc->Release()。
(4)init_icons函数中:LoadImage前加上(HICON)强制转换。