按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
消息循环的秘密:
int CWinThread::Run()
{
。。。
for (;;)
{
while (bIdle &&
!::PeekMessage(&m_msgCur; NULL; NULL; NULL; PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume 〃no idle〃 state
}
。。。 // msg loop
}
}
CThread::OnIdle 做些什么事情呢?CWinApp 改写了OnIdle 函数,CWinApp::OnIdle 又
做些什么事情呢?你可以从THRDCORE。CPP 和APPCORE。CPP 中找到这两个函数的
源代码,源代码可以说明一切。当然基本上我们可以猜测OnIdle 函数中大概是做一些
系统(指的是MFC 本身)的维护工作。这一部份的功能可以说日趋式微,因为低优先
权的执行线程可以替代其角色。
如果你的MFC 程序也想处理idle time,只要改写CWinApp 衍生类别的OnIdle 函数即
可。这个函数的类型如下:
virtual BOOL OnIdle(LONG lCount);
403
…………………………………………………………Page 466……………………………………………………………
第篇 湷觥 FC 程式設計
lCount 是系统传进来的一个值,表示自从上次有消息进来,到现在,OnIdle 已经被调用
了多少次。稍后我将改写Hello 程序,把这个值输出到窗口上,你就可以知道空闲时间
是多么地频繁。lCount 会持续累增,直到CWinThread::Run 的消息循环又获得了一个讯
息,此值才重置为0 。
注意:Jeff Prosise 在他的Programming Windows 95 with MFC 一书第7章谈到OnIdle
函数时,曾经说过有几个消息并不会重置lCount 为0,包括鼠标消息、WM_SYSTIMER 、
WM_PAINT 。不过根据我实测的结果,至少鼠标消息是会的。稍后你可在新版的Hello 程
序移动鼠标,看看lCount 会不会重设为0 。
我如何改写Hello 呢?下面是几个步骤:
1。 在CMyWinApp 中增加OnIdle 函数的声明:
class CMyWinApp : public CWinApp
{
public:
virtual BOOL InitInstance(); // 每一个应用程序都应该改写此函数
virtual BOOL OnIdle(LONG lCount); // OnIdle 用来处理空闲时间(idle time)
};
2。 在CMyFrameWnd 中增加一个IdleTimeHandler 函数声明。这么做是因为我希
望在窗口中显示lCount 值, 所以最好的作法就是在OnIdle 中调用
CMyFrameWnd 成员函数,这样才容易获得绘图所需的DC 。
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd(); // constructor
afx_msg void OnPaint(); // for WM_PAINT
afx_msg void OnAbout(); // for WM_MAND (IDM_ABOUT)
void IdleTimeHandler(LONG lCount); // we want it call by CMyWinApp::OnIdle
。。。
};
3。 在HELLO。CPP 中定义CMyWinApp::OnIdle 函数如下:
404
…………………………………………………………Page 467……………………………………………………………
第6章 MFC 程式的生死因果
BOOL CMyWinApp::OnIdle(LONG lCount)
{
CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd;
pWnd…》IdleTimeHandler(lCount);
return TRUE;
}
4。 在HELLO。CPP 中定义CMyFrameWnd::IdleTimeHandler 函数如下:
void CMyFrameWnd::IdleTimeHandler(LONG lCount)
{
CString str;
CRect rect(10;10;200;30);
CDC* pDC = new CClientDC(this);
str。Format(〃%010d〃; lCount);
pDC…》DrawText(str; ▭ DT_LEFT | DT_TOP);
}
为了输出lCount,我又动用了三个MFC 类别:CString、CRect 和CDC。前两者非常
简单,只是字符串与四方形结构的一层C++ 包装而且,后者是在Windows 系统中绘图所
必须的DC (Device Context )的一个包装。
新版Hello 执行结果如下。左上角的lCount 以飞快的速度更迭。移动鼠标看看,看
lCount 会不会重置为0 。
405
…………………………………………………………Page 468……………………………………………………………
第篇 湷觥 FC 程式設計
Dialog 与 Control
回忆SDK 程序中的对话框作法:RC 文件中要准备一个对话框的Template,C 程序中要
设计一个对话框函数。MFC 提供的CDialog 已经把对话框的窗口函数设计好了,因此
在MFC 程序中使用对话框非常地简单:
WM_MAND
(IDM_ABOUT)
HELLO。CPP
void CMyFrameWnd::OnAbout()
{
CDialog about(〃AboutBox〃; this);
about。DoModal();
}
HELLO。RC
AboutBox DIALOG DISCARDABLE 34; 22; 147; 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION 〃About Hello〃
{
ICON 〃JJHouRIcon〃;IDC_STATIC;11;17;18;20
LTEXT 〃Hello MFC 4。0〃;IDC_STATIC;40;10;52;8
LTEXT 〃Copyright 1996 Top Studio〃;IDC_STATIC;40;25;100;8
LTEXT 〃J。J。Hou〃;IDC_STATIC;40;40;100;8
DE