C++打开文件选择框多选文件

目录

效果图

项目与工具

创建项目步骤

​代码

运行结果

参考链接

后记


效果图

项目与工具

Visual Studio 2019

创建项目步骤

1、创建新项目,选择控制台应用

2、设置项目名称

3、创建成功,效果如下

代码

ChooseFiles.cpp

// ChooseFiles.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <windows.h>
#include <tchar.h>

using namespace std;

/*
TCHAR*转char*
*/
char* LPWSTR2LPSTR(LPWSTR lpwszStrIn)
{
    LPSTR pszOut = NULL;
    if (lpwszStrIn != NULL) {
        int nInputStrLen = wcslen(lpwszStrIn);
        int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
        pszOut = new char[nOutputStrLen];
        if (pszOut != NULL) {
            memset(pszOut, 0x00, nOutputStrLen);
            WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
        }
    }
    return  pszOut;
}

char* chooseFiles() {

    OPENFILENAME ofn;
    TCHAR szOpenFileNames[80 * MAX_PATH] = { 0 };
    TCHAR szPath[MAX_PATH];
    TCHAR szFileName[80 * MAX_PATH];

    int nLen = 0;
    TCHAR* p = NULL;
    ZeroMemory(&ofn, sizeof(ofn));

    // 结构体大小
    ofn.lStructSize = sizeof(ofn);
    
    // 拥有着窗口句柄
    ofn.hwndOwner = NULL;
    
    // 接收返回的文件名,注意第一个字符需要为NULL
    ofn.lpstrFile = szOpenFileNames;
    
    // 缓冲区长度
    ofn.nMaxFile = sizeof(szOpenFileNames);

    // _T可替换为TEXT,使用_T需要引tchar.h
    ofn.lpstrFile[0] = _T('\0');

    // 设置过滤
    ofn.lpstrFilter = _T("All\0*.*\0.mp4\0*.mp4\0.avi\0*.avi\0.mkv\0*.mkv\0.rmvb\0*.rmvb\0.f4v\0*.f4v\0.flv\0*.flv\0.m4v\0*.m4v\0.mpg\0*.mpg\0\0");
    
    // 过滤器索引
    ofn.nFilterIndex = 1;

    // 窗口标题
    ofn.lpstrTitle = _T("请选择视频");

    // 文件必须存在、允许多选、隐藏只读选项、对话框使用资源管理器风格的用户界面
    // 官方文档:https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamea
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_EXPLORER;

     // 如果打开文件失败,则不操作
    if (!::GetOpenFileName(&ofn)) {
        return new char[0];
    }

    // 把第一个文件名前的复制到szPath,即:  
    // 如果只选了一个文件,就复制到最后一个'/'  
    // 如果选了多个文件,就复制到第一个NULL字符  
    lstrcpyn(szPath, szOpenFileNames, ofn.nFileOffset);

    // 当只选了一个文件时,下面这个NULL字符是必需的.  
    // 这里不区别对待选了一个和多个文件的情况
    szPath[ofn.nFileOffset] = '\0';
    nLen = lstrlen(szPath);

    // 如果选了多个文件,则必须加上'//'  
    if (szPath[nLen - 1] != '\\') {
        lstrcat(szPath, _T("\\"));
    }

    // 把指针移到第一个文件  
    p = szOpenFileNames + ofn.nFileOffset;  

    // 对szFileName进行清零
    ZeroMemory(szFileName, sizeof(szFileName));

    // 定义字符串,用于拼接所选的所有文件的完整路径
    string str = "";

    while (*p) {
        // 读取文件名
        string fileName = LPWSTR2LPSTR(p);
        
        // 读取文件所在文件夹路径
        string filePath = LPWSTR2LPSTR(szPath);
        
        // 拼接文件完整路径
        string completePath = filePath + fileName;
   
        // 拼接字符串
        str += completePath + "***";

        //移至下一个文件
        p += lstrlen(p) + 1;             
    }

    // 将string转为char*
    char* strc = new char[strlen(str.c_str()) + 1];
    const char* cc = str.c_str();
    strcpy_s(strc, str.size() + 1, cc);

    return strc;
}

int main() {
    cout << "chooseFiles: " << chooseFiles() << endl;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

运行结果

参考链接

[1] skye1221.C++ 打开文本对话框,获取选中文件的路径、名称和后缀名.2018-12-25 10:06:55
C++ 打开文本对话框,获取选中文件的路径、名称和后缀名_skye1221的博客-CSDN博客

[2] 言止予思.getopenfilename多选文件/文件夹问题和getsavefilename另存为路径.2015-12-02 09:49
getopenfilename多选文件/文件夹问题和getsavefilename另存为路径 - 言止予思 - 博客园

[3] OPENFILENAMEA structure (commdlg.h)
OPENFILENAMEA (commdlg.h) - Win32 apps | Microsoft Docs

[4] weixin_30559481.char与TCHAR相互转换(拒绝中文乱码,好用!).2018-07-31 14:48:00
char与TCHAR相互转换(拒绝中文乱码,好用!)_weixin_30559481的博客-CSDN博客

后记

不擅长C++的我,通过查阅各种资料终于折腾出来了,唉,基本上都是我的盲区,尚不明确是否有隐藏问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值