There are two ways to do this, one is simple, another is complicated but more powerful.
Method A:
::SetWindowsHookEx(WH_FOREGROUNDIDLE, YourIdleProc, AfxGetInstanceHandle(), GetCurrentThreadId());
Method B (my way):
1 static HHOOK s_hGetMsgHook = NULL;
2
3 LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
4 {
5 AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
6
7 LPMSG lpMsg = (LPMSG) lParam;
8 if( (nCode >= 0) && PM_REMOVE == wParam)
9 {
10 //your code here. maybe to deal with hot-keys, accelerators ...
11 //see http://support.microsoft.com/kb/187988
12
13 //my code to simulate OnIdle
14 static BOOL bIdle = FALSE;
15 CWinApp* pApp = AfxGetApp();
16 if(!bIdle && pApp->IsIdleMessage(lpMsg))
17 bIdle = TRUE;
18
19 if(bIdle)
20 {
21 MSG msgPeek = {0};
22 if(!::PeekMessage(&msgPeek, NULL, NULL, NULL, PM_NOREMOVE))
23 {
24 VERIFY(PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_USER+0x12, 0x34, 0x56));
25 }
26 }
27
28 if(lpMsg->hwnd == AfxGetMainWnd()->GetSafeHwnd() &&
29 lpMsg->message == WM_USER+0x12 && lpMsg->wParam == 0x34 && lpMsg->lParam == 0x56)
30 {
31 lpMsg->message = WM_NULL;
32 lpMsg->lParam = 0L;
33 lpMsg->wParam = 0L;
34
35 pApp->OnIdle(0);
36 bIdle = FALSE;
37 }
38 }
39
40 return ::CallNextHookEx(s_hGetMsgHook, nCode, wParam, lParam);
41 }
42
43 int CYourOleControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
44 {
45 //...
46
47 if(NULL == s_hGetMsgHook)
48 s_hGetMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, AfxGetInstanceHandle(), GetCurrentThreadId());
49 }
50
51 void CYourOleControl::OnDestroy()
52 {
53 //...
54
55 ::UnhookWindowsHookEx(s_hGetMsgHook);
56 s_hGetMsgHook = NULL;
57
58 COleControl::OnDestroy();
59 }
Method A is far more simple, but with Method B:
1) You can override CWinApp::IsIdleMessage to filter some special messages, such as a frequent timer which will not affect what you want to do in CWinApp::OnIdle. Because timer will affect message queue and if you don't filter it, OnIdle will be called every time after the timer is invoked.
2) Sometimes your action in OnIdle will affect message queue inevitably, thus you will get a infinite loop: OnIdle->the special messages in message queue->OnIdle->... But with Method B, with SPY++ you can find the special messages, and filter them in IsIdleMessage.