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

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

当一个程序调用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 long
unsigned 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;
}


©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值