GetOpenFileName函数打开选择文件的对话框,“我的电脑”里面什么都显示不出来的解决办法

博客讨论了在使用GetOpenFileName函数时遇到的问题,即该函数与COINIT_MULTITHREADED初始化不兼容,导致‘我的电脑’中无法显示内容。解决方案是将初始化改为COINIT_APARTMENTTHREADED,或者删除CoInitializeEx和CoUninitialize调用。文章提醒开发者注意在多线程环境中调用Shell函数和接口的潜在问题。

如下图所示,其他文件夹都正常,就是“我的电脑”里面什么都没有。

#include <tchar.h>
#include <Windows.h>
#include <CommCtrl.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 WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	char szFileName[MAX_PATH] = {0};
	OPENFILENAMEA ofn = {0};

	InitCommonControls();
	CoInitializeEx(NULL, COINIT_MULTITHREADED);

	ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
	ofn.hInstance = hInstance;
	ofn.hwndOwner = NULL;
	ofn.lStructSize = sizeof(OPENFILENAMEA);
	ofn.lpstrDefExt = "hex";
	ofn.lpstrFile = szFileName;
	ofn.lpstrFilter = "HEX文件 (*.hex)\0*.HEX\0所有文件 (*.*)\0*.*\0";
	ofn.nMaxFile = sizeof(szFileName);
	GetOpenFileNameA(&ofn);

	CoUninitialize();
	return 0;
}

原因是因为GetOpenFileName函数和COINIT_MULTITHREADED不兼容。把COINIT_MULTITHREADED改成COINIT_APARTMENTTHREADED,或者把CoInitializeEx和CoUninitialize删了,问题就解决了。


 

Calling shell functions and interfaces from a multithreaded apartment

When you call or access a shell function or shell interface from a thread that has been initialized as a multithreaded apartment, the function or interface may have its functionality impaired or completely fail.

https://docs.microsoft.com/en-us/troubleshoot/windows/win32/shell-functions-multithreaded-apartment

在 Qt 中实现点击按钮后打开系统文件对话框,并将选中文件路径显示在 `QLineEdit` 中,主要依赖于 `QFileDialog` 类。该类提供了与操作系统交互的标准文件对话框,允许用户选择文件或目录[^2]。 ### 实现方式 首先,在 UI 设计中添加一个 `QPushButton` 作为触发文件选择的按钮,以及一个 `QLineEdit` 用于显示所选文件路径。 在按钮的点击信号 `clicked()` 与自定义的槽函数之间建立连接。槽函数中使用 `QFileDialog::getOpenFileName()` 方法打开文件选择对话框,并返回用户选中的文件路径。 以下为完整实现示例: ```cpp #include <QFileDialog> #include <QLineEdit> #include <QPushButton> // 假设在 Widget 类中实现 Widget::Widget(QWidget *parent) : QWidget(parent) { setupUI(); // 初始化 UI,包含 QPushButton 和 QLineEdit connect(ui->selectButton, &QPushButton::clicked, this, &Widget::openFileDialog); } void Widget::openFileDialog() { QString filePath = QFileDialog::getOpenFileName(this, tr("选择文件"), "", tr("所有文件 (*.*);;文本文件 (*.txt)")); // 打开文件对话框[^2] if (!filePath.isEmpty()) { ui->lineEdit->setText(filePath); // 将选中的文件路径显示在 QLineEdit 中 } } ``` 上述代码中,`QFileDialog::getOpenFileName()` 提供了一个模态对话框,用于选择单个文件。其参数包括父窗口指针、对话框标题、默认路径文件类型过滤器。返回值为选中的文件路径字符串,若用户未选择任何文件则返回字符串。 ### 文件路径处理 为了增强程序的健壮性,建议在设置路径前对返回值进行非判断。这样可以避免在 `QLineEdit` 中显示字符串,从而提升用户体验。 此外,若需要支持多文件选择,可以使用 `QFileDialog::getOpenFileNames()` 方法,它返回一个 `QStringList`,包含用户选中的多个文件路径。 ### 自定义文件对话框 除了使用 `getOpenFileName()` 这种静态方法,还可以创建 `QFileDialog` 实例并自定义其行为。例如设置多选、目录选择文件预览等功能: ```cpp void Widget::openFileDialog() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::ExistingFiles); // 允许选择多个文件 dialog.setNameFilter(tr("文本文件 (*.txt);;所有文件 (*.*)")); if (dialog.exec()) { QStringList filePaths = dialog.selectedFiles(); if (!filePaths.isEmpty()) { ui->lineEdit->setText(filePaths.first()); // 显示第一个文件路径 } } } ``` 这种方式提供了更高的灵活性,适用于需要定制文件对话框行为的场景[^2]。 --- ### 注意事项 - 确保 `QLineEdit` 和 `QPushButton` 的指针在类中已正确初始化。 - 若对话框需要支持中文路径,应确保程序使用的是 UTF-8 编码。 - 在跨平台开发中,`QFileDialog` 会自动适配同操作系统的文件选择器样式。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值