在我們編寫MFC程序的過程中,難免會用到c(SDK)函數,雖然MFC對大部分win32 API進行了封裝,但是很多的時候,使用SDK函數更加易於我們使用,有很強的靈活性。如果是標準的SDK函數一般沒有什麼問題,但是有的SDK函數,需要你提供一個回調函數,那麼這個回掉函數是不能是MFC對象的成員函數。就需要我們在cpp文件中自定義一個C回調函數。既然是回調函數,當然是希望我們在這個回調函數中做一些事情,然而在MFC中,我們的方法都是MFC類的對象來操作方法的。但是在這個我們自定義的回調函數中,我們不能使用MFC對象。這樣不就矛盾了。下面,我通過的一個實例來描述這個問題。
在我編寫的一個播放器程序中,需要一個定時器來定時調用回調函數,來更新播放時間
hTimerQueue = CreateTimerQueue();
CreateTimerQueueTimer( &hTimer, hTimerQueue,
(WAITORTIMERCALLBACK)TimerProc, 0 , 1000, 1000, WT_EXECUTEINPERSISTENTTHREAD);
由上面可以看見,需要一個TimerProc的回調函數,當然名字是可以取別的,我這裏取的這個名字。於是,我聲明並定義了一個這樣的回調函數
VOID CALLBACK TimerProc(PVOID lpParameter,BOOLEAN TimerOrWaitFired);///源文件開頭聲明函數
.............................
VOID CALLBACK TimerProc(PVOID lpParameter,BOOLEAN TimerOrWaitFired)////在源文件中實現它
{
this->.....
}
在回調函數中,我定期的調用mfc類的方法來進行時間更新,然而,在這個我定義的回調函數中,是一個c函數,不能使用對象的方法,直接錯誤提示:“未定義的標示符”;那麼應該如何做呢,如下:
VOID CALLBACK TimerProc(PVOID lpParameter,BOOLEAN TimerOrWaitFired)
{
::SendMessage(hcwnd,WM_TIMEPROC,0,0);
}
先在全局聲明一個窗口句柄來保存這個窗口類的窗口句柄。然後在這個回調函數中是用發送消息給窗口的形式,那麼在消息的處理中,我們就可以調用這個類的方法了,當然這裏的消息是自定義消息(WM_TIMEPROC)。這時候也許有人會問,爲什麼在一個線程中使用SendMessage沒有出現程序死鎖呢,這是因爲這個回到函數的調用者不是本線程的,而是在thread pool中,所以沒有出現程序死鎖。
下面是重新虛函數WindowProc中處理虛函數,當然,你可以用mfc的標準私有消息處理辦法,使用宏ON_MESSAGE來處理私有消息:
case WM_TIMEPROC:
{
this->TimeStart();
}
break;
上面說的這個情況呢,是我們無法避免的,我們必須要一個回調函數,其他情況應該儘量避免這樣的使用。如果一個我們自定義的c函數,在MFC類的成員函數中調用並不存在這個情況,可以任意調用我們自定義的c函數,但是反過來就不行。