开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 500|回复: 7
收起左侧

[易语言模块源码] 全网最小的多线程下载工具exe大小14KB使用VS2013工具win32编程

[复制链接]
发表于 2024-12-11 22:41:17 | 显示全部楼层 |阅读模式   湖南省岳阳市
分享例程
界面截图:
备注说明: -
本帖最后由 2533 于 2024-12-11 22:47 编辑

全网最小的多线程下载工具exe文件大小14KB使用VS2013工具win32编程
你没有看错 就一个CPP 文件就可以编写窗口程序
VS 2013 新建win32应用程序 选择空程序 然后 在新建一个CPP 文件
0.png

设置我们使用组建  添加 (控件) 的静态库 其实和易语言的 添加支持库是 一个道理
选择项目属性
1.png

选择项目属性---》连接器 ----》输入 ------添加控件的LIB静态库名称 以分号结尾
2.png

3.png

下面是 演示
456.gif



[C++] 纯文本查看 复制代码
#include <windows.h>
#include <commctrl.h> // 包含Common Controls库的头文件
#include <wininet.h>  // 包含WinInet库的头文件
#include <tchar.h>
#include <shlobj.h> // 包含文件对话框相关的头文件
#include <shlwapi.h>
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "shell32.lib") // 添加shell32.lib以支持SHGetFolderPath

// 定义按钮和进度条的ID
#define ID_BUTTON 1
#define ID_EDIT_URL 2
#define ID_PROGRESSBAR 3
#define ID_STATUS_LABEL_TOTAL 4
#define ID_STATUS_LABEL_SPEED 5
#define ID_STATUS_LABEL_REMAINING 6

// 定义 ThreadParams 结构体
struct ThreadParams {
        HWND hWnd;
        const TCHAR* url;
        const TCHAR* filePath;
        volatile bool* isDownloading;
        LARGE_INTEGER startTime; // 下载开始时间
        LARGE_INTEGER frequency; // 性能计数器频率
};

// 全局变量
HWND hwndProgressBar = NULL;
HWND hwndStatusLabelTotal = NULL;
HWND hwndStatusLabelSpeed = NULL;
HWND hwndStatusLabelRemaining = NULL;
HWND hwndEditUrl = NULL;
HANDLE hDownloadThread = NULL;
DWORD downloadThreadId = 0;
volatile bool isDownloading = false;

// 线程函数声明
DWORD WINAPI DownloadThread(LPVOID lpParam);

// 窗口过程函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        const wchar_t* CLASS_NAME = L"Sample Window Class";

        // 初始化Common Controls库
        INITCOMMONCONTROLSEX icex;
        icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
        icex.dwICC = ICC_BAR_CLASSES; // 初始化进度条控件
        InitCommonControlsEx(&icex);

        // 注册窗口类
        WNDCLASSEX wc = { 0 };
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WndProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszClassName = CLASS_NAME;

        if (!RegisterClassEx(&wc)) {
                MessageBox(NULL, L"Window Registration Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建窗口
        HWND hwnd = CreateWindowEx(
                0,                              // 扩展样式
                CLASS_NAME,                     // 窗口类名
                L"Learn to Program Windows",    // 窗口标题
                WS_OVERLAPPEDWINDOW,            // 窗口样式
                CW_USEDEFAULT, CW_USEDEFAULT,   // 窗口位置
                544, 375,                       // 窗口大小
                NULL,                           // 父窗口
                NULL,                           // 菜单
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwnd == NULL) {
                MessageBox(NULL, L"Window Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建编辑框
        hwndEditUrl = CreateWindowEx(
                WS_EX_CLIENTEDGE,               // 扩展样式
                L"EDIT",                         // 控件类名
                L"",                           // 初始文本为空
                WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, // 样式
                10,                             // x位置
                10,                             // y位置
                300,                            // 宽度
                20,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_EDIT_URL,             // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndEditUrl == NULL) {
                MessageBox(NULL, L"Edit Box Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建按钮
        HWND hwndButton = CreateWindowEx(
                0,                              // 扩展样式
                L"BUTTON",                      // 控件类名
                L"Start Download",              // 按钮文本
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // 样式
                320,                            // x位置
                10,                             // y位置
                100,                            // 宽度
                30,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_BUTTON,               // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndButton == NULL) {
                MessageBox(NULL, L"Button Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建进度条
        hwndProgressBar = CreateWindowEx(
                0,                              // 扩展样式
                PROGRESS_CLASS,                 // 控件类名
                NULL,                           // 进度条没有文本
                WS_VISIBLE | WS_CHILD | PBS_SMOOTH, // 样式,添加 PBS_SMOOTH
                10,                             // x位置
                50,                             // y位置
                520,                            // 宽度
                20,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_PROGRESSBAR,          // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndProgressBar == NULL) {
                MessageBox(NULL, L"Progress Bar Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建总进度标签
        hwndStatusLabelTotal = CreateWindowEx(
                0,                              // 扩展样式
                L"STATIC",                     // 控件类名
                L"",                           // 初始文本为空
                WS_VISIBLE | WS_CHILD,          // 样式
                10,                             // x位置
                80,                             // y位置
                520,                            // 宽度
                20,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_STATUS_LABEL_TOTAL,   // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndStatusLabelTotal == NULL) {
                MessageBox(NULL, L"Status Label Total Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建速度标签
        hwndStatusLabelSpeed = CreateWindowEx(
                0,                              // 扩展样式
                L"STATIC",                     // 控件类名
                L"",                           // 初始文本为空
                WS_VISIBLE | WS_CHILD,          // 样式
                10,                             // x位置
                110,                            // y位置
                520,                            // 宽度
                20,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_STATUS_LABEL_SPEED,   // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndStatusLabelSpeed == NULL) {
                MessageBox(NULL, L"Status Label Speed Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 创建剩余时间标签
        hwndStatusLabelRemaining = CreateWindowEx(
                0,                              // 扩展样式
                L"STATIC",                     // 控件类名
                L"",                           // 初始文本为空
                WS_VISIBLE | WS_CHILD,          // 样式
                10,                             // x位置
                140,                            // y位置
                520,                            // 宽度
                20,                             // 高度
                hwnd,                           // 父窗口句柄
                (HMENU)ID_STATUS_LABEL_REMAINING, // 控件ID
                hInstance,                      // 实例句柄
                NULL                            // 附加应用数据
                );

        if (hwndStatusLabelRemaining == NULL) {
                MessageBox(NULL, L"Status Label Remaining Creation Failed!", L"Error!",
                        MB_ICONEXCLAMATION | MB_OK);
                return 0;
        }

        // 设置进度条的范围和初始位置
        SendMessage(hwndProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); // 设置范围为0到100
        SendMessage(hwndProgressBar, PBM_SETPOS, 0, 0);                  // 设置当前位置为0

        ShowWindow(hwnd, nCmdShow);

        // 消息循环
        MSG msg = { 0 };
        while (GetMessage(&msg, NULL, 0, 0)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return (int)msg.wParam;
}

// 定义 StartDownload 函数
void StartDownload(HWND hWnd, const TCHAR* url, const TCHAR* filePath, volatile bool& isDownloading) {
        ThreadParams* params = new ThreadParams{ hWnd, url, filePath, &isDownloading };
        QueryPerformanceFrequency(¶ms->frequency); // 初始化性能计数器频率
        LARGE_INTEGER startCounter;
        QueryPerformanceCounter(&startCounter); // 记录开始时间
        params->startTime.QuadPart = startCounter.QuadPart;
        hDownloadThread = CreateThread(NULL, 0, DownloadThread, params, 0, &downloadThreadId);
        if (hDownloadThread == NULL) {
                MessageBox(NULL, L"CreateThread failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
                isDownloading = false;
                delete params; // 释放内存
        }
}

// 线程函数定义
DWORD WINAPI DownloadThread(LPVOID lpParam) {
        ThreadParams* params = static_cast<ThreadParams*>(lpParam);
        HWND hWnd = params->hWnd;
        const TCHAR* url = params->url;
        const TCHAR* filePath = params->filePath;
        volatile bool* isDownloading = params->isDownloading;
        LARGE_INTEGER frequency = params->frequency;

        HINTERNET hInternet = InternetOpen(_T("MyApp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        if (hInternet == NULL) {
                MessageBox(hWnd, L"InternetOpen failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
                *isDownloading = false;
                delete params;
                return 1;
        }

        HINTERNET hUrl = InternetOpenUrl(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
        if (hUrl == NULL) {
                InternetCloseHandle(hInternet);
                MessageBox(hWnd, L"InternetOpenUrl failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
                *isDownloading = false;
                delete params;
                return 1;
        }

        DWORD fileSize = 0;
        DWORD size = sizeof(fileSize);

        // 获取文件大小
        if (!HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &fileSize, &size, 0)) {
                fileSize = 0; // 如果无法获取文件大小,则设为0
        }

        HANDLE hFile = CreateFile(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE) {
                InternetCloseHandle(hUrl);
                InternetCloseHandle(hInternet);
                MessageBox(hWnd, L"CreateFile failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
                *isDownloading = false;
                delete params;
                return 1;
        }

        DWORD bytesRead = 0;
        DWORD totalBytesRead = 0;
        char buffer[4096];
        LARGE_INTEGER previousTime;
        LARGE_INTEGER currentTime;
        double elapsedTime;
        double downloadSpeed;
        double remainingTime;
        TCHAR statusTextTotal[256];
        TCHAR statusTextSpeed[256];
        TCHAR statusTextRemaining[256];

        QueryPerformanceCounter(&previousTime); // 初始化上一次时间

        while (InternetReadFile(hUrl, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
                WriteFile(hFile, buffer, bytesRead, &bytesRead, NULL); // bytesRead 用于接收实际写入的字节数
                totalBytesRead += bytesRead; // 累加实际写入的字节数

                if (fileSize > 0) {
                        int progress = (int)((static_cast<double>(totalBytesRead) / fileSize) * 100); // 计算进度百分比
                        PostMessage(hWnd, WM_USER + 1, progress, 0); // 更新进度条位置

                        QueryPerformanceCounter(¤tTime);
                        elapsedTime = (currentTime.QuadPart - previousTime.QuadPart) / (double)frequency.QuadPart; // 计算经过的时间(秒)
                        if (elapsedTime > 0.001) { // 避免除零错误
                                downloadSpeed = bytesRead / elapsedTime; // 计算瞬时下载速度(字节/秒)
                                remainingTime = (fileSize - totalBytesRead) / downloadSpeed; // 计算剩余时间(秒)

                                // 将字节转换为MB
                                double totalBytesReadMB = totalBytesRead / 1024.0 / 1024.0;
                                double fileSizeMB = fileSize / 1024.0 / 1024.0;
                                double downloadSpeedMBps = downloadSpeed / 1024.0 / 1024.0;

                                _stprintf_s(statusTextTotal, 256, _T("%.2fMB/%.2fMB"), totalBytesReadMB, fileSizeMB);
                                _stprintf_s(statusTextSpeed, 256, _T("速度 %.2fMB/s"), downloadSpeedMBps);
                                _stprintf_s(statusTextRemaining, 256, _T("剩余 %.2f秒"), remainingTime);

                                PostMessage(hWnd, WM_USER + 2, 0, (LPARAM)statusTextTotal); // 发送总进度文本
                                PostMessage(hWnd, WM_USER + 3, 0, (LPARAM)statusTextSpeed); // 发送速度文本
                                PostMessage(hWnd, WM_USER + 4, 0, (LPARAM)statusTextRemaining); // 发送剩余时间文本

                                previousTime = currentTime; // 更新上一次时间
                        }
                }
                else {
                        // 如果无法获取文件大小,直接显示已读取的字节数
                        double totalBytesReadMB = totalBytesRead / 1024.0 / 1024.0;
                        _stprintf_s(statusTextTotal, 256, _T("%.2fMB"), totalBytesReadMB);
                        PostMessage(hWnd, WM_USER + 2, 0, (LPARAM)statusTextTotal); // 发送总进度文本
                }
        }

        CloseHandle(hFile);
        InternetCloseHandle(hUrl);
        InternetCloseHandle(hInternet);

        *isDownloading = false;
        PostMessage(hWnd, WM_USER + 1, 100, 0);
        delete params;
        return 0;
}

// 示例按钮点击事件处理函数
void OnDownloadButtonClick(HWND hWnd) {
        TCHAR url[1024];
        GetWindowText(hwndEditUrl, url, 1024); // 从编辑框中获取URL

        if (_tcslen(url) == 0) {
                MessageBox(hWnd, L"Please enter a valid URL.", L"Information", MB_OK | MB_ICONINFORMATION);
                return;
        }

        if (isDownloading) {
                MessageBox(hWnd, L"Download is already in progress.", L"Information", MB_OK | MB_ICONINFORMATION);
                return;
        }

        // 使用文件对话框选择保存位置
        OPENFILENAME ofn;
        TCHAR szFile[MAX_PATH] = { 0 };

        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = hWnd;
        ofn.lpstrFilter = L"All Files (*.*)\0*.*\0";
        ofn.lpstrFile = szFile;
        ofn.nMaxFile = MAX_PATH;
        ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;

        // 解析URL以获取文件名
        LPCTSTR pszFileName = PathFindFileName(url);
        if (pszFileName && _tcslen(pszFileName) > 0) {
                lstrcpy(szFile, pszFileName);
        }
        else {
                lstrcpy(szFile, _T("downloaded_file")); // 默认文件名
        }

        // 提取文件扩展名
        LPCTSTR pszFileExt = PathFindExtension(pszFileName);
        if (pszFileExt && _tcslen(pszFileExt) > 0) {
                // 如果URL中包含扩展名,则直接使用
                lstrcat(szFile, pszFileExt);
        }
        else {
                // 如果URL中不包含扩展名,则尝试从HTTP响应头中获取
                HINTERNET hInternet = InternetOpen(_T("MyApp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
                if (hInternet != NULL) {
                        HINTERNET hUrl = InternetOpenUrl(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
                        if (hUrl != NULL) {
                                TCHAR contentType[256];
                                DWORD contentTypeSize = sizeof(contentType);
                                if (HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_DISPOSITION | HTTP_QUERY_FLAG_REQUEST_HEADERS, contentType, &contentTypeSize, 0)) {
                                        // 解析Content-Disposition头以获取文件名
                                        TCHAR* pszFilename = PathFindFileName(contentType);
                                        if (pszFilename && _tcslen(pszFilename) > 0) {
                                                LPCTSTR pszFilenameExt = PathFindExtension(pszFilename);
                                                if (pszFilenameExt && _tcslen(pszFilenameExt) > 0) {
                                                        lstrcpy(szFile, pszFilename);
                                                }
                                        }
                                }
                                InternetCloseHandle(hUrl);
                        }
                        InternetCloseHandle(hInternet);
                }
        }


        // 获取桌面路径作为默认路径
        TCHAR desktopPath[MAX_PATH];
        SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, desktopPath);
        PathCombine(szFile, desktopPath, szFile);




        if (GetSaveFileName(&ofn)) {
                isDownloading = true;
                StartDownload(hWnd, url, szFile, isDownloading);
        }
}


// 窗口过程函数定义
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        switch (msg) {
        case WM_COMMAND:
                if (LOWORD(wParam) == ID_BUTTON) {
                        OnDownloadButtonClick(hwnd);
                }
                break;
        case WM_USER + 1:
                SendMessage(hwndProgressBar, PBM_SETPOS, wParam, 0); // 更新进度条位置
                break;
        case WM_USER + 2:
                SetWindowText(hwndStatusLabelTotal, (LPCTSTR)lParam); // 更新总进度标签文本
                break;
        case WM_USER + 3:
                SetWindowText(hwndStatusLabelSpeed, (LPCTSTR)lParam); // 更新速度标签文本
                break;
        case WM_USER + 4:
                SetWindowText(hwndStatusLabelRemaining, (LPCTSTR)lParam); // 更新剩余时间标签文本
                break;
        case WM_DESTROY:
                if (hDownloadThread != NULL) {
                        WaitForSingleObject(hDownloadThread, INFINITE);
                        CloseHandle(hDownloadThread);
                }
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
}



下面是 程序和源码
Win32Project1.rar (214.02 KB, 下载次数: 2)

友情提醒:请选择可信度高的模块,勿用未知模块,防止小人在模块内加入木马程序。【发现问题模块请到站务投诉】。

签到天数: 14 天

发表于 2024-12-17 09:25:26 | 显示全部楼层   湖北省宜昌市
这是不是易语言源码
回复 支持 反对

使用道具 举报

签到天数: 10 天

发表于 2024-12-13 11:35:03 | 显示全部楼层   湖南省娄底市
支持一下
回复 支持 反对

使用道具 举报

签到天数: 9 天

 楼主| 发表于 2024-12-12 22:14:18 | 显示全部楼层   湖南省岳阳市
wq880212 发表于 2024-12-12 20:54
这里是精易论坛,你发c++的代码是什么意思

你好兄弟, 请问精易公司有没有规定不能发C++的,有的话请告诉我
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 27 天

发表于 2024-12-12 21:07:19 | 显示全部楼层   河北省张家口市
写的真好,支持,感谢大佬
回复 支持 反对

使用道具 举报

签到天数: 2 天

发表于 2024-12-12 20:54:09 高大上手机用户 | 显示全部楼层   广西壮族自治区百色市
这里是精易论坛,你发c++的代码是什么意思
回复 支持 反对

使用道具 举报

签到天数: 2 天

发表于 2024-12-12 13:21:18 | 显示全部楼层   浙江省温州市
学习一下学习一下
回复 支持 反对

使用道具 举报

签到天数: 25 天

发表于 2024-12-12 10:43:43 | 显示全部楼层   新疆维吾尔自治区乌鲁木齐市
66666666666666666666
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表