C/C++中Windows API 简单的(Callback)回调机制

来源:互联网 发布:net软件开发培训 编辑:程序博客网 时间:2024/05/16 12:53

首先来说说什么是调用和回调

当一个程序调用windows API时的过程称为Call

当windows API调用程序里面的函数时这称之为Callback

下面举一个简单的例子来说明回调的用途

编写一个程序实现把resource/404dog.rar

复制到resource/404dog_copy.rar

当然这个文件只有几兆。

因此我们可以这么写:

#include <stdio.h>#include <Windows.h>int main(){const char* source = "resource/404dog.rar";const char* destination = "resource/404dog_copy.rar";printf("复制开始!\n");bool result = CopyFile(source, destination, FALSE);printf("运行结果:%s\n", result ? "成功" : "失败");getchar();return 0}

其中CopyFile函数为windows API

下面对此函数做出一定的说明:

BOOL WINAPI CopyFile(  _In_ LPCTSTR lpExistingFileName,  _In_ LPCTSTR lpNewFileName,  _In_ BOOL    bFailIfExists);


大体上的意思就是为TRUE表示如果文件夹有同名的文件则无法复制,为FALSE则表面覆盖此文件。

下面是程序的演示和结果用截图来表示:


但是如果一个程序很大,有几个G的话,那不是控制台程序会卡住,造成假死。我们自己会知道这是假死

但用户不知道,所以微软更新了一个CopyFile函数叫CopyFileEx,可以理解为CopyFile的升级

下面来看看CopyFileEx函数


BOOL WINAPI CopyFileEx(  _In_     LPCTSTR            lpExistingFileName,  _In_     LPCTSTR            lpNewFileName,  _In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine,  _In_opt_ LPVOID             lpData,  _In_opt_ LPBOOL             pbCancel,  _In_     DWORD              dwCopyFlags);

传递callback函数的参数

 

第三个参数:就是回调函数

下面我们来看 CopyProgressRoutine的函数

DWORD CALLBACK CopyProgressRoutine(  _In_     LARGE_INTEGER TotalFileSize,    // 文件总大小,字节  _In_     LARGE_INTEGER TotalBytesTransferred,    // 已复制的文件大小,字节  _In_     LARGE_INTEGER StreamSize,    // 当前流的总字节数              _In_     LARGE_INTEGER StreamBytesTransferred,    // 当前流已拷贝的字节数  _In_     DWORD         dwStreamNumber,    // 当前流序号  _In_     DWORD         dwCallbackReason,    // 回调函数的状态,见定义  _In_     HANDLE        hSourceFile,     // 来源文件句柄  _In_     HANDLE        hDestinationFile,    // 目标文件句柄  _In_opt_ LPVOID        lpData    // CopyFileEx 函数传递过来的参数);

所以下面的程序我们可以这么写:

#include <stdio.h>#include <Windows.h>// 将LARGE_INTTEGER类型转成unsigned long longunsigned long long translate(LARGE_INTEGER num){unsigned long long result = num.HighPart;result <<= 32;result += num.LowPart;return result;}DWORD CALLBACK CopyProgress(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER StreamSize,LARGE_INTEGER StreamBytesTransferred,DWORD dwStreamNumber,DWORD dwCallbackReason,HANDLE hSourceFile,HANDLE hDestionationFile,LPVOID IpData){unsigned long long total = translate(TotalFileSize);unsigned long long copied = translate(TotalBytesTransferred);printf("进度:%I64d/%I64d\n", copied, total);return PROGRESS_CONTINUE;}int main(){const char* source = "resource/demo.avi";const char* destination = "resource/demo_copy.avi";printf("开始复制...\n");bool result = CopyFileEx(source, destination, &CopyProgress, NULL, NULL, 0);getchar();return 0;}


原创粉丝点击