C++ 获取windows活动窗口

文章介绍了如何遍历Windows系统中的可见窗口,排除不需要的如工具栏、隐藏窗口等,通过EnumWindowsProc回调函数和DwmGetWindowAttribute检查窗口属性,实现类似Alt+Tab的预览功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 前言

最近为了能够共享windows应用窗口内容,需要遍历桌面所有窗口,其中也遇到了不少的坑,比如遇到了很多不需要的窗口,无标题窗口,windows设置,邮件和计算器。好在最后还是实现了。这里直接上主要功能代码,避免大家踩坑。 

代码

windowIterator.h

class CWindowIterator
{

private:
    static char* wchar2char(const wchar_t* wchar);
    static BOOL CALLBACK EnumWindowsProc(HWND window, LPARAM lParam);

public:
    using EnumCallback = std::function<void(std::string &str)>;
    
    void EnumWindow(EnumCallback callback);

};

 windowIterator.cpp

char* CWindowIterator::wchar2char(const wchar_t* wchar)
{
    char* pchar;
    int len = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL);
    pchar = new char[len + 1];
    WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), pchar, len, NULL, NULL);
    pchar[len] = '\0';
    return pchar;
}

BOOL CALLBACK CWindowIterator::EnumWindowsProc(HWND window, LPARAM lParam)
{
    if (!IsWindow(window))
        return TRUE;

    if (!IsWindowVisible(window))
        return TRUE;

    DWORD flag = 0;
    DwmGetWindowAttribute(window, DWMWA_CLOAKED, &flag, sizeof(flag));
    if (flag)
        return TRUE;

    UINT wnd_style_ex = GetWindowLong(window, GWL_EXSTYLE);
    if ((WS_EX_TOOLWINDOW & wnd_style_ex) == WS_EX_TOOLWINDOW)
        return TRUE;

    TCHAR szTitle[MAX_PATH] = { 0 };
    ::GetWindowText(window, szTitle, MAX_PATH); // 获取标题
    if (wcslen(szTitle) == 0)
        return TRUE;

    std::string str = wchar2char(szTitle);
    if (lParam) {
        EnumCallback* cb = reinterpret_cast<EnumCallback*>(lParam);
        (*cb)(str);
    }

    return TRUE;
}

void CWindowIterator::EnumWindow(EnumCallback callback)
{
    ::EnumWindows(EnumWindowsProc, (LPARAM)&callback);
}

windowIteratorTest.cpp 

#include <iostream>
#include "windowIterator.h"

int main()
{
    CWindowIterator wi;
    wi.EnumWindow([](std::string &str) {
        std::cout << str << std::endl;
        });
    return 0;
}

总结

总结了一下过程,需要能够获取类似alt + tab一样的预览窗口,主要是注意以下几点

1) 窗口必须可见 - 使用 GetWindowVisible

2) 窗口不能是工具栏窗口 - 使用 GetWindowLong

3) 不得隐藏窗口 - 使用 DwmGetWindowAttribute

<think>我们要求:提取指定目录下所有子文件夹中的视频文件名,并将每个文件夹的文件名列表输出到一个同名的Excel表格文件中,存储到指定文件夹并自动打开。 步骤分解: 1. 遍历指定目录下的所有子文件夹。 2. 对于每个子文件夹,获取其中所有的视频文件(根据扩展名判断)。 3. 为每个子文件夹创建一个Excel文件,文件名与子文件夹同名,存储到指定的输出文件夹中。 4. Excel文件包含两列:序号和视频文件名(可以加上其他信息如大小、修改日期等,但问题要求的是文件名,不过用户之前有相关问题的需求,所以可以扩展)。 5. 存储后自动打开该Excel文件。 注意:用户要求自动打开生成的Excel文件。 根据引用[3]和引用[4]中的思路,我们可以使用os.walk遍历子文件夹,然后对每个文件夹进行处理。 另外,用户要求表格文件存储在指定位置(不是原文件夹,而是另一个指定文件夹),且文件名与文件夹一致。 我们将设计: - 输入:源文件夹路径(包含多个子文件夹),输出文件夹路径(用于存放所有生成的Excel文件) - 遍历源文件夹下的每个子文件夹(不处理源文件夹根目录下的文件,只处理子文件夹?用户要求的是“文件夹内所有视频文件名”,并且是“每个文件夹”) - 对于每个子文件夹,生成一个Excel文件,命名为:子文件夹名.xls(或.xlsx),保存到输出文件夹。 同时,在生成后自动打开每个Excel文件?但是如果有多个子文件夹,就会生成多个Excel文件,全部打开可能不太合适。我们可以选择只打开第一个?或者询问用户?但用户要求“自动打开该表格”,这里理解为每个生成的Excel文件都要打开?或者只打开最后一个?但这样可能同时打开太多。 考虑到实际使用,我们可能只需要打开最后一个生成的Excel文件作为示例,或者让用户选择。但为了满足要求,我们可以打开每一个,但这样可能会同时打开很多窗口,不太友好。 因此,我们可以改为:在生成所有Excel文件后,询问用户是否要打开其中一个?或者只打开第一个?但是用户要求是“自动打开”,所以我们先按照打开每一个来实现,然后根据运行情况再调整(如果太多,可能会卡顿,所以我们可以选择只打开第一个)。 但用户要求是“自动打开该表格”,这里我们理解为每个生成的Excel文件都要打开。我们可以使用os.startfile(Windows)或subprocess打开。 然而,如果子文件夹数量很多,打开所有Excel文件可能会造成系统负担。因此,我们可以添加一个选项,或者按照用户要求,只打开最后一个?但是用户没有明确说明。 考虑到用户可能只是想查看一下结果,我们可以选择打开第一个生成的Excel文件,或者让用户选择。但为了严格满足要求,我们选择打开每一个生成的Excel文件。但是,我们可以给出提示,如果用户不希望打开,可以注释掉打开代码。 实现步骤: 1. 定义视频扩展名列表。 2. 定义源文件夹路径(包含多个子文件夹)和输出文件夹路径(用于存放Excel文件)。 3. 使用os.walk遍历源文件夹,但我们只想要第一层子文件夹(即源文件夹下的直接子文件夹),所以我们可以使用os.listdir然后判断是否为文件夹。 4. 对于每个子文件夹: a. 获取该文件夹下的所有视频文件。 b. 创建Excel工作簿,写入表头(序号,文件名,还可以包括大小、修改日期等,根据引用1和3,用户可能还需要其他信息,但原问题只要求文件名,不过之前有相关问题,这里扩展一下,同时输出文件大小和修改日期)。 c. 将视频文件的信息逐行写入Excel。 d. 将Excel文件保存到输出文件夹,文件名为子文件夹名.xls。 e. 自动打开这个Excel文件。 5. 如果输出文件夹不存在,则创建。 注意:用户要求输出到指定位置,所以输出文件夹需要预先指定。 根据引用[3]和[4],我们使用xlwt来写Excel(xls格式),但注意xlwt只能写xls格式,且最大行数限制为65536。如果视频文件数量很大,可能会超出,但通常一个文件夹内视频文件不会那么多。如果需要xlsx,可以使用openpyxl,但这里为了简单,使用xlwt。 但是,用户要求表格文件名与文件夹一致,注意文件夹名可能包含特殊字符,我们直接使用,如果包含非法字符(如冒号、斜杠等),需要替换,但通常文件夹名不会包含这些。如果包含,我们可以替换掉,但为了简单,先直接使用,如果出错再处理。 另外,自动打开文件:在Windows上,我们可以使用os.startfile(文件路径),在Mac上使用open命令,Linux上使用xdg-open。这里我们判断操作系统。 由于用户没有说明操作系统,我们写一个跨平台的打开方式。 代码结构: 1. 导入模块 2. 定义路径和扩展名 3. 创建输出文件夹(如果不存在) 4. 遍历源文件夹下的每个子文件夹 5. 对每个子文件夹,获取视频文件列表 6. 创建Excel并写入 7. 保存Excel并打开 注意:为了避免打开太多文件,我们可以询问用户是否要打开,但用户要求自动打开,所以我们先打开,如果用户觉得困扰,可以注释掉打开部分的代码。 由于用户要求自动化,我们按每个都打开来实现。 但是,如果子文件夹数量很多,打开所有Excel文件可能会很慢,所以我们可以选择只打开第一个,或者最后一个,或者不打开?这里我们按照每个都打开来实现,但在循环中打开每个文件,用户可能会看到连续弹出很多Excel窗口。 因此,我们可以考虑在循环结束后打开所有文件?但这样我们只能记住最后一个文件。所以还是每个生成后立即打开。 代码实现: 我们将使用: - os.listdir 遍历源文件夹,然后判断是否是文件夹 - 对于每个文件夹,使用os.listdir获取文件,并判断扩展名 - 使用xlwt创建Excel 同时,我们添加文件大小和修改日期两列。 表头:序号,文件名,文件大小(KB),修改日期 修改日期格式化为字符串。 步骤: 1. 获取文件夹路径下的所有文件(包括子文件夹,但我们只处理直接子文件夹)。 2. 对每个子文件夹,获取其绝对路径。 3. 列出该文件夹下的所有文件,过滤出视频文件。 4. 为每个视频文件获取:文件名(带扩展名)、文件大小(转换为KB,保留两位小数)、修改日期(格式化为YYYY-MM-DD HH:MM:SS)。 代码: 注意:文件大小我们转换为KB,也可以转换为MB,这里用KB。 修改日期使用os.path.getmtime,然后转换为时间字符串。 开始写代码:</think>### 自动化解决方案:提取子文件夹视频文件名并输出到Excel 我将设计一个完整的自动化脚本,实现以下功能: 1. 遍历指定目录下所有子文件夹 2. 提取每个子文件夹中的视频文件名 3. 为每个子文件夹创建同名Excel文件 4. 将Excel文件保存到指定位置 5. 自动打开生成的Excel文件 ```python import os import xlwt import subprocess from datetime import datetime def extract_video_filenames_to_excel(): # ===== 用户配置区域 ===== source_dir = "D:/视频库" # 替换为你的视频文件夹路径 output_dir = "D:/视频清单" # 替换为Excel输出路径 # ===================== # 支持的视频格式(可扩展) video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv', '.mpg', '.mpeg', '.rmvb'] # 创建输出目录(如果不存在) os.makedirs(output_dir, exist_ok=True) # 遍历源目录下的所有子文件夹 for folder_name in os.listdir(source_dir): folder_path = os.path.join(source_dir, folder_name) # 跳过文件,只处理文件夹 if not os.path.isdir(folder_path): continue print(f"正在处理文件夹: {folder_name}") # 获取文件夹内所有文件 all_files = os.listdir(folder_path) # 筛选视频文件并获取详细信息 video_files = [] for filename in all_files: file_path = os.path.join(folder_path, filename) # 跳过子文件夹 if os.path.isdir(file_path): continue # 检查文件扩展名 file_ext = os.path.splitext(filename)[1].lower() if file_ext in video_extensions: # 获取文件详细信息 file_size = os.path.getsize(file_path) / (1024 * 1024) # 转换为MB mod_time = datetime.fromtimestamp(os.path.getmtime(file_path)) video_files.append({ 'filename': filename, 'size_mb': round(file_size, 2), 'modified': mod_time.strftime("%Y-%m-%d %H:%M:%S") }) # 创建Excel工作簿 workbook = xlwt.Workbook(encoding='utf-8') worksheet = workbook.add_sheet('视频文件列表') # 设置列宽 worksheet.col(0).width = 3000 # 序号列 worksheet.col(1).width = 10000 # 文件名列 worksheet.col(2).width = 3000 # 大小列 worksheet.col(3).width = 5000 # 修改时间列 # 写入表头(带样式) header_style = xlwt.easyxf( 'font: bold on, height 240; align: horiz center; borders: left thin, right thin, top thin, bottom thin' ) headers = ["序号", "文件名", "大小(MB)", "修改时间"] for col, header in enumerate(headers): worksheet.write(0, col, header, header_style) # 写入视频文件数据 row_style = xlwt.easyxf('align: wrap on; borders: bottom dashed') for row, video in enumerate(video_files, start=1): worksheet.write(row, 0, row) # 序号 worksheet.write(row, 1, video['filename'], row_style) # 文件名 worksheet.write(row, 2, video['size_mb'], row_style) # 文件大小 worksheet.write(row, 3, video['modified'], row_style) # 修改时间 # 保存Excel文件(文件名与文件夹同名) excel_filename = f"{folder_name}_视频清单.xls" excel_path = os.path.join(output_dir, excel_filename) workbook.save(excel_path) print(f"已生成: {excel_path}") # 自动打开Excel文件 try: if os.name == 'nt': # Windows os.startfile(excel_path) elif os.name == 'posix': # macOS/Linux subprocess.call(('open', excel_path)) print(f"已自动打开文件: {excel_filename}") except Exception as e: print(f"打开文件失败: {str(e)}") print("所有文件夹处理完成!") # 执行函数 if __name__ == "__main__": extract_video_filenames_to_excel() ``` ### 使用说明 1. **修改配置**: - 设置 `source_dir` 为你的视频文件夹路径 - 设置 `output_dir` 为Excel输出路径 2. **运行脚本**: ```bash pip install xlwt python video_to_excel.py ``` 3. **输出结果**: - 每个子文件夹会生成一个同名Excel文件 - Excel文件包含四列数据: | 序号 | 文件名 | 大小(MB) | 修改时间 | |------|--------------|----------|-------------------| | 1 | 电影预告.mp4 | 245.32 | 2023-08-15 14:30 | | 2 | 教程视频.mov | 78.45 | 2023-08-10 09:15 | ### 功能特点 1. **智能识别子文件夹**:自动遍历所有子目录[^3] 2. **完整文件信息**:包含文件名、大小和修改时间 3. **跨平台支持**:Windows/macOS/Linux自动打开文件 4. **自定义格式**:支持扩展视频格式列表 5. **美观的表格样式**:自动设置列宽和边框格式 ### 注意事项 1. 如需处理大量文件,可添加进度显示: ```python # 在循环中添加 if row % 10 == 0: print(f"已处理 {row}/{len(video_files)} 个文件") ``` 2. 对于超大型文件夹(>10,000文件),建议使用 `openpyxl` 替代 `xlwt` 3. 文件打开行为取决于系统默认程序设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值