VC6下建立一个“A Simple Win32 Application ”工程,命名为PeekMsgDemo
将第4章的CMyWnd加入工程,并从CMyWnd派生一个新类,命名为CMsgWnd
// MsgWnd.h: interface for the CMsgWnd class.
//
//
#if !defined(AFX_MSGWND_H__4276D849_7881_4206_BC7E_2CDFB5A9459E__INCLUDED_)
#define AFX_MSGWND_H__4276D849_7881_4206_BC7E_2CDFB5A9459E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyWnd.h"
class CMsgWnd : public CMyWnd
{
public:
CMsgWnd();
virtual ~CMsgWnd();
BOOL OnIdle();
protected:
///保护函数成员
BOOL OnDestroy();
BOOL PreProcessMsg(HWND hWnd, UINT nMsg , WPARAM wp , LPARAM lp ,LRESULT *pResult);
protected:
///保护数据成员
DWORD m_dwTick;
};
#endif // !defined(AFX_MSGWND_H__4276D849_7881_4206_BC7E_2CDFB5A9459E__INCLUDED_)
// MsgWnd.cpp: implementation of the CMsgWnd class.
//
//
#include "stdafx.h"
#include "MsgWnd.h"
//
// Construction/Destruction
//
CMsgWnd::CMsgWnd()
{
///初始化成员变量
m_dwTick = GetTickCount();
}
CMsgWnd::~CMsgWnd()
{
}
CMsgWnd::OnIdle()
{
///程序空闲处理
if(GetTickCount() - m_dwTick >= 1000 )
{
///如果空闲了1秒,则不再接收空闲通知
SetWindowText(m_hWnd , _T("程序空闲了1秒..."));
return false;
}
else
return true;
}
BOOL CMsgWnd::OnDestroy()
{
//退出消息循环
PostQuitMessage(0);
return false;
}
BOOL CMsgWnd::PreProcessMsg(HWND hWnd, UINT nMsg , WPARAM wp , LPARAM lp ,LRESULT *pResult)
{
///处理了消息,重新计算空闲时间
m_dwTick = GetTickCount();
///在界面上显示键盘或鼠标消息
if(nMsg >= WM_KEYFIRST && nMsg <= WM_KEYLAST)
SetWindowText(m_hWnd , _T("收到了键盘盘消息..."));
else if(nMsg >= WM_MOUSEFIRST && nMsg <= WM_MOUSELAST)
SetWindowText(m_hWnd , _T("收到了鼠标消息..."));
return true;
}
// PeekMsgDemo.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "MsgWnd.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
///建立主窗口
CMsgWnd wnd;
wnd.CreateEx(WS_OVERLAPPEDWINDOW , 300 ,300 , 300 ,200 ,NULL);
if(wnd.GetHwnd() == NULL)
{
MessageBox(NULL ,_T("主窗体创建失败...") , _T("") , MB_OK);
return 0;
}
wnd.Show(SW_SHOW);
///进入消息循环
MSG msg;
BOOL bProcessIdle;
while(true)
{
if(PeekMessage(&msg , NULL ,0 , 0 ,PM_REMOVE) )
{
///检查是否需要退出循环
if(msg.message == WM_QUIT)
break;
bProcessIdle = true;
///转换消息
TranslateMessage(&msg);
///分派消息
DispatchMessage(&msg);
}
else
{
///应用程序空闲了
if(bProcessIdle)
//处理空闲时做的工作
bProcessIdle = wnd.OnIdle();
else
///释放CPU时间片
Sleep(1);
}
}
return 0;
}
说明:
1、由于Peekmessage会立即返回,所以应用程序能得知应用程序何时空闲。如果用GetMessage,没有消息时,主线程
被阻塞,一旦函数返回,就说明有消息到达,所以空闲通知没有机会发出。
2、在Peekmessage没有收到消息时,用Sleep(1)函数来释放CPU资源。
3、代码中用到的“WM_KEYFIRST”、“WM_KEYLAST”等常量,并非是消息ID,而是系统为区分消息类别所定义的常量。