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

news2024/9/23 21:22:04

【程序运行效果】

【程序代码】

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1421005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM-类的生命周期

类的生命周期概述 类的生命周期描述了一个类加载、使用、卸载的整个过程。整体可以分为&#xff1a; 加载 连接&#xff0c;其中又分为验证、准备、解析三个子阶段 初始化 使用 卸载 加载阶段 加载(Loading)阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方…

深入玩转Playwright:高级操作解析与实践

playwright高级操作 iframe切换 ​ 很多时候&#xff0c;网页可能是网页嵌套网页&#xff0c;就是存在不止一个html标签&#xff0c;这时候我们的selenium或者playwright一般来说定位不到&#xff0c;为什么呢&#xff1f; ​ 因为默认是定位到第一个标准的html标签内部。 …

费一凡:土木博士的自我救赎之道 | 提升之路系列(五)

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

五、防御保护---防火墙出口选路篇

五、防御保护---防火墙智能选路篇 一、就近选路二、策略路由选路1.策略路由的概念1.1匹配条件&#xff08;通过ACL定义&#xff09;1.2动作 三、智能选路 --- 全局路由策略1.基于链路带宽的负载分担2.基于链路质量进行负载分担3.基于链路权重进行负载分担4.基于链路优先级的主备…

股票市场

&#xff08;一&#xff09;股票市场 顾名思义&#xff0c;就是买卖股票的场所。就是为了撮合想发展但缺钱的企业与有钱但想投资的投资者。 股票市场按照交易场所&#xff0c;可分为场内市场和场外市场&#xff1a; 场内市场是指证券交易所&#xff0c; 场外市场就是证券交易…

比Filebeat更强大的日志收集工具-Fluent bit的http插件实战

文章目录 1.前言2. fluent bit http插件配置以及参数详解3. Http 接口服务3.1 开发Http 接口服务3.2 重启fluent bit向http web服务发送数据 1.前言 Fluent Bit 的 HTTP 插件提供了一种灵活而通用的机制&#xff0c;可用于将日志数据 从各种环境中传输到指定的远程服务器&#…

Python算法题集_滑动窗口最大值

本文为Python算法题集之一的代码示例 题目239&#xff1a;滑动窗口最大值 说明&#xff1a;给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗…

常见的网络安全威胁和防护方法

随着数字化转型和新兴技术在各行业广泛应用&#xff0c;网络安全威胁对现代企业的业务运营和生产活动也产生了日益深远的影响。常见的网络安全威胁通常有以下几种&#xff1a; 1. 钓鱼攻击 攻击者伪装成合法的实体&#xff08;如银行、电子邮件提供商、社交媒体平台等&#xf…

C++实现通讯录管理系统

目录 1、系统需求 2、创建项目 2.1 创建项目 3、菜单功能 4、退出功能 5、添加联系人 5.1 设计联系人结构体 5.2 设计通讯录结构体 5.3 main函数中创建通讯录 5.4 封装联系人函数 5.5 测试添加联系人功能 6、显示联系人 6.1 封装显示联系人函数 7、删除联系人 7.1…

获取依赖aar包的两种方式-在android studio里引入 如:glide

背景&#xff1a;我需要获取aar依赖到内网开发&#xff0c;内网几乎代表没网。 一、 如何需要获取依赖aar包 方式一&#xff1a;在官方的github中下载,耗时不建议 要从开发者网站、GitHub 存储库或其他来源获取 ‘com.github.bumptech.glide:glide:4.12.0’ AAR 包&#xff…

MySQL:MVCC原理详解

MySQL是允许多用户同时操作数据库的&#xff0c;那么就会出现多个事务的并发场景。那么再并发场景会出现很多问题&#xff1a;脏读、不可重复读、幻读的问题。 而解决这些问题所用到的方法就是&#xff1a;MVCC 多版本并发控制。而这个MVCC的实现是基于read_view、undoLog 如…

大规模机器学习(Large Scale Machine Learning)

1.大型数据集的学习 案例&#xff1a; 如果我们有一个低方差的模型&#xff0c;增加数据集的规模可以帮助你获得更好的结果。我们应该怎样应对一个有 100 万条记录的训练集&#xff1f; 以线性回归模型为例&#xff0c;每一次梯度下降迭代&#xff0c;我们都需要计算训练集的误…

古建筑电气火灾的防控与管理

摘要:我国古建筑多为砖木结构&#xff0c;当发生火灾事故时具有蔓延快、扑救难的特点&#xff0c;而火灾对古建筑的损害性很大&#xff0c;电气火灾事故在我国火灾事故中比重居高不下。本文通过对古建筑电气火灾成因进行分析&#xff0c;有针对性地提出了古建筑电气火灾防控对策…

日志之Loki详细讲解

文章目录 1 Loki1.1 引言1.2 Loki工作方式1.2.1 日志解析格式1.2.2 日志搜集架构模式1.2.3 Loki部署模式 1.3 服务端部署1.3.1 AllInOne部署模式1.3.1.1 k8s部署1.3.1.2 创建configmap1.3.1.3 创建持久化存储1.3.1.4 创建应用1.3.1.5 验证部署结果 1.3.2 裸机部署 1.4 Promtail…

炒黄金 vs 炒股:探寻投资路线的差异和各自的优势

在当前不景气的股市&#xff0c;人们越来越关注分散投资的方式&#xff0c;以期降低风险并稳定资产。炒黄金成为了一个备受关注的投资选择&#xff0c;与传统炒股相比&#xff0c;它到底有什么区别呢&#xff1f;本文将从多个维度深入分析这两种投资方式的差异以及各自的优势。…

微信开发者工具 git 拉取 failed invalid authentication scheme

微信开发者工具 git 拉取 failed invalid authentication scheme 拉取代码时报错,无效身份认证 解决方案: 1.检查git地址是否正常 2.检查git用户名密码是否正确

ElementUI组件:Button 按钮

button按钮 点击下载learnelementuispringboot项目源码 效果图 el-button.vue页面效果图 项目里el-button.vue代码 <script> export default {name: "el_button",// 注意这里的名称不能和 router inex.js里的name一样methods: {sendMsg() {// alert(1)xthi…

(2024,双流编码器,文本引导的风格迁移,调制,FFT 和低频滤波)FreeStyle:使用扩散模型进行文本引导风格迁移

FreeStyle: Free Lunch for Text-guided Style Transfer using Diffusion Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 方法 3.1 LDM 3.2 FreeStyle 的模型结构…

数据结构——并查集

1.并查集的定义 并查集其实也是一种树形结构&#xff0c;在使用中通常用森林的方式来表示 并查集的逻辑结构其实就是集合 并查集一般可以通过双亲写法&#xff08;顺序结构&#xff09;来完成&#xff0c;即通过一个数组存储父亲结点的下标 int s[10005]; int main() {for(…

共享的IP隔一段时间就变?用这种方法可以不需要知道电脑IP

前言 一般来说,电脑接入路由器之后,IP是由路由器自动分配的(DHCP),但如果隔一段时间不开机连接路由器,或者更换了别的网卡进行连接,自动分配的IP就会更改。 比如你手机连接着电脑的共享IP:192.168.1.10,但过段时间之后,电脑的IP突然变成了192.168.1.11,那么你的所有…