C语言用SHBrowseForFolder弹出选择文件夹的对话框

【程序运行效果】

【程序代码】

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)强制转换。

最近更新

  1. TCP协议是安全的吗?

    2024-01-30 23:48:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-30 23:48:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-30 23:48:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-30 23:48:01       18 阅读

热门阅读

  1. C++入门

    C++入门

    2024-01-30 23:48:01      31 阅读
  2. ESLint代码检查系列 ——入门篇

    2024-01-30 23:48:01       36 阅读
  3. ERD Online后端源码:构建你的数据建模引擎️

    2024-01-30 23:48:01       42 阅读
  4. Python计算机二级/Python期末考试 刷题(一)

    2024-01-30 23:48:01       24 阅读
  5. BGAD文章复现笔记-1

    2024-01-30 23:48:01       37 阅读
  6. CSS Transition:变魔术的艺术

    2024-01-30 23:48:01       29 阅读
  7. Shaastra CTF 2024

    2024-01-30 23:48:01       41 阅读
  8. Linux的中断和中断处理

    2024-01-30 23:48:01       33 阅读