定时器的使用;回调函数的使用;目录遍历算法;硬盘信息获取;

 1.
回调函数的定义与使用
回调函数的定义:
回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回
调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发
现函数指针的声明与函数声明非常类似。
1)函数指针的声明方法如下:
void (*) ();
让我们来分析一下,左边圆括弧中的星号是函数指针声明的关键。另外两个元素是函数的返回类型(void)
和由边圆括弧中的入口参数(本例中参数是空)。
2)为函数指针声明类型定义:
typedef void (*pfv) ();
pfv是一个函数指针,它指向的函数没有输入参数,返回类行为void。使用这个类型定义名可以隐藏复杂的
函数指针语法。
typedef void (*DiskAlarm)(int alarm); // in my application
DiskAlarm是一个函数指针类型,这个函数输入参数是一个整型的alarm
注释:回调函数要使用静态函数或成员函数,这里我们使用了静态函数,在定时器回调函数
中我们使用全局函数;
具体实例
在被调用处:
1)头文件:
typedef void (*DiskAlarm)(int alarm); (类外面定义)
void SetCallback(DiskAlarm callback, void* inst) { Callback = callback; Inst = inst;}
public:
void* Inst;
DiskAlarm Callback; //实例化一个函数指针,注意Callback
是一个指针;
2)源文件:
if(host1->m_nFreeSpace>host1->m_nDiskAlarmValue)
{
if(host1->Callback) //因为之前实例化了这个指针,所以就不为空;
host1->Callback(1);
}
杭州普诺科技有限公司Copyright:王学智
www.punuo.net 3
回调函数处:
1)头文件:
static void DiskAlarm(int Type); //回调函数要设置为静态函数,但是在源文件中就不要
写了
2)源文件:
类构造的时候:
m_pCRecordDisk->SetCallback(DiskAlarm,this);
void CTestDlg::DiskAlarm(int Type)
{
switch(Type)
{
case 1:
AfxMessageBox("硬盘容量不足");
break;
case 2:
AfxMessageBox("文件夹容量不足");
break;
default:
AfxMessageBox("DiskAlarm");
}
return;
}
回调函数流程图:
m_pCRecordDisk->SetCallback(DiskAlarm,this)
首先在初始化类的时候将回调函数的地址赋给
调用处。
void SetCallback(DiskAlarm callback, void* inst)
{ Callback = callback; Inst = inst;}
接着在调用处就接收到回调函数的信息,将回
调函数的指针给了Callback,将回调函数所在的
类指针给了Inst.
杭州普诺科技有限公司Copyright:王学智
www.punuo.net 4
2.
时间定时器的写法
这个时间定时器不是用在对话框中的那种时间定时器,而是在一个类中开一个线程执行的这
么一个定时器;
1)首先定义一个时间定时器的ID;
protected:
MMRESULT watch_thread; #include "Mmsystem.h" 头文件可以在MSDN 中查;
2)接着在咱们这个类构造的时候开启这个时间计时器;
watch_thread = timeSetEvent(4000, 1000, WorkProc_60s, (DWORD)this, TIME_PERIODIC);
参数1:这个参数是定时的时间,即延时多少时间发送信号;
参数2:分辨率1000 表示1 秒;
参数3:回调函数;
参数4:给回调函数的数据,this 表示是将咱们自己这个类的指针给那个回调函数;
参数5:TIME_PERIODIC,表示每次延时后都触发;
3)然后再看看回调函数
回调函数是一个全局函数或是一个静态函数,这里我使用全局函数;
void CALLBACK WorkProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1,
DWORD dw2)
{
CClientViewer* host = (CClientViewer *)dwUser;
EnterCriticalSection(&host->critical);
LeaveCriticalSection(&host->critical);
}
注意:我把(DWORD)this 这个参数传递给DWORD dwUser;
3.
临界区的使用
临界区(criticalSection)
又称阻塞,它能够使一段代码只由一个线程来执行,其它线程被挡在这段代码之外,直到第
一个线程执行完代码。
因为之前已经定义了Calllback,类型就是我们定
义的DiskAlarm,所以这时Callback 已经有了回
调函数的地址了,这样的话就可以调用了。
host1->Callback(1) 最后直接调用那个地址调
用回调函数。
杭州普诺科技有限公司Copyright:王学智
www.punuo.net 5
1)首先定义临界区结构体
public:
CRITICAL_SECTION critical;
2)接着初始化临界区
InitializeCriticalSection(&critical);
3)然后是进入临界区
EnterCriticalSection(&host1->critical);
4) 随后出临界区
LeaveCriticalSection(&host1->critical);
5)最后释放临界区
DeleteCriticalSection(&critical);
4.
目录的遍历算法
用这么一个通用的文件(*.*)搜索,调用函数findfile来搜索,搜索(*.*)这个文件,
bool CRecordDisk::GetFolderInfo(CString nRecPath,int *pFileNum,ULONGLONG *pFileSpace)
{
CFileFind file;
CString FileName,name;
*pFileNum=0;
*pFileSpace=0;
/*****************************************************************************/
FileName=nRecPath+_T("//*.*");
if(bWorking=file.FindFile(FileName))
{
while(bWorking)
{
bWorking=file.FindNextFile();
这里的算法特别注意!为什么要多此一举!
因为它检测到最后一个FindNextFile 返回0,所以这个直接执行一个死循环。遍历完为止。
/*****************************************************************************/
if(!file.IsDots()&&!file.IsDirectory())
{
i++;
*pFileNum=i;
杭州普诺科技有限公司Copyright:王学智
www.punuo.net 6
*pFileSpace+=file.GetLength();
}
}
}
5.
硬盘盘符容量函数使用
ULONGLONG CRecordDisk::GetPathFreeSpace(const char *szPath)
{
ASSERT(szPath != NULL);
nLen = strlen(szPath);
if (nLen == 0)
{
return 0;
}
ULARGE_INTEGER nFreeBytesAvailable;
ULARGE_INTEGER nTotalNumberOfBytes;
ULARGE_INTEGER nTotalNumberOfFreeBytes;
if(GetDiskFreeSpaceEx(szPath,&nFreeBytesAvailable,&nTotalNumberOfBytes,&nTotalNu
mberOfFreeBytes))
{
result = nFreeBytesAvailable.QuadPart;
}
else
{
AfxMessageBox("check the path for record!");
}
return result;
}
输入的值可以是任何一个路径,它自己会自动得到盘符的容量信息;
杭州普诺科技有限公司Copyright:王学智
www.punuo.net 7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值