王朝百科
分享
 
 
 

随机矩形

王朝百科·作者佚名  2010-01-04  
宽屏版  字体: |||超大  

在图形系统中,有这么一个「永远」有人执行的有趣程式,它简单地使用随机的大小和色彩绘制一系列矩形。您可以在Windows中建立一个这样的程式,但是它并不像乍看起来那样容易编写。我希望您能认识到,您不能简单地在WM_PAINT讯息中使用一个while(TRUE)回圈。当然,它能够执行,但是程式将停止对其他讯息的处理,同时,这个程式不能中止或者最小化。

一种可以接受的方法是设定一个Windows计时器,给视窗程序发送WM_TIMER讯息(我将在第八章中讨论计时器)。对於每条WM_TIMER讯息,您使用GetDC取得一个装置内容,画一个随机的矩形,然後用ReleaseDC释放装置内容。但是这样又降低了程式的趣昧性,因为程式不能尽可能快地画随机矩形,它必须等待WM_TIMER讯息,而这又依赖於系统时钟的解析度。

在Windows中一定有很多「闲置时间」,在这个时间内,所有讯息伫列为空,Windows只停在一个小回圈中等待键盘或者滑鼠输入。我们能否在闲置时间内获得控制,绘制矩形,并且只在有讯息加入程式的讯息伫列之後才释放控制呢?这就是PeekMessage函式的目的之一。下面是PeekMessage呼叫的一个例子:

PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) ;

前面的四个参数(一个指向MSG结构的指标、一个视窗代号、两个值指示讯息范围)与GetMessage的参数相同。将第二、三、四个参数设定为NULL或0时,表明我们想让PeekMessage传回程式中所有视窗的所有讯息。如果要将讯息从讯息伫列中删除,则将PeekMessage的最後一个参数设定为PM_REMOVE。如果您不希望删除讯息,那么您可以将这个参数设定为PM_NOREMOVE。这就是为什么Peek_Message是「偷看」而不是「取得」的原因,它使得程式可以检查程式的伫列中的下一个讯息,而不实际删除它。

GetMessage不将控制传回给程式,直到从程式的讯息伫列中取得讯息,但是PeekMessage总是立刻传回,而不论一个讯息是否出现。当讯息伫列中有一个讯息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理讯息。当伫列中没有讯息时,PeekMessage传回FALSE(0)。

这使得我们可以改写普通的讯息回圈。我们可以将如下所示的回圈:

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

替换为下面的回圈:

while (TRUE)

{

if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

{

if (msg.message == WM_QUIT)

break ;

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

else

{

// 完成某些工作的其他行程式

}

}

return msg.wParam ;

注意,WM_QUIT讯息被另外挑出来检查。在普通的讯息回圈中您不必这么作,因为如果GetMessage接收到一个WM_QUIT讯息,它将传回0,但是PeekMessage用它的传回值来指示是否得到一个讯息,所以需要对WM_QUIT进行检查。

如果PeekMessage的传回值为TRUE,则讯息按通常方式进行处理。如果传回值为FALSE,则在将控制传回给Windows之前,还可以作一点工作(如显示另一个随机矩形)。

(尽管Windows文件上说,您不能用PeekMessage从讯息伫列中删除WM_PAINT讯息,但是这并不是什么大不了的问题。毕竟,GetMessage并不从讯息伫列中删除WM_PAINT讯息。从伫列中删除WM_PAINT讯息的唯一方法是令视窗显示区域的失效区域变得有效,这可以用ValidateRect和ValidateRgn或者BeginPaint和EndPaint对来完成。如果您在使用PeekMessage从伫列中取出WM_PAINT讯息後,同平常一样处理它,那么就不会有问题了。所不能作的是使用如下所示的程式码来清除讯息伫列中的所有讯息:

while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ;

这行叙述从讯息伫列中删除WM_PAINT之外的所有讯息。如果伫列中有一个WM_PAINT讯息,程式就会永远地陷在while回圈中。)

PeekMessage在Windows的早期版本中比在Windows 98中要重要得多。这是因为Windows的16位元版本使用的是非优先权式的多工(我将在第二十章中讨论这一点)。Windows的Terminal程式在从通讯埠接收输入後,使用一个PeekMessage回圈。列印管理器程式使用这个技术来进行列印,其他的Windows列印应用程式通常都会使用一个PeekMessage回圈。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
如何用java替换看不见的字符比如零宽空格​十六进制U+200B
 干货   2023-09-10
网页字号不能单数吗,网页字体大小为什么一般都是偶数
 干货   2023-09-06
java.lang.ArrayIndexOutOfBoundsException: 4096
 干货   2023-09-06
Noto Sans CJK SC字体下载地址
 干货   2023-08-30
window.navigator和navigator的区别是什么?
 干货   2023-08-23
js获取referer、useragent、浏览器语言
 干货   2023-08-23
oscache遇到404时会不会缓存?
 干货   2023-08-23
linux下用rm -rf *删除大量文件太慢怎么解决?
 干货   2023-08-08
刀郎新歌破世界纪录!
 娱乐   2023-08-01
js实现放大缩小页面
 干货   2023-07-31
生成式人工智能服务管理暂行办法
 百态   2023-07-31
英语学习:过去完成时The Past Perfect Tense举例说明
 干货   2023-07-31
Mysql常用sql命令语句整理
 干货   2023-07-30
科学家复活了46000年前的虫子
 探索   2023-07-29
英语学习:过去进行时The Past Continuous Tense举例说明
 干货   2023-07-28
meta name="applicable-device"告知页面适合哪种终端设备:PC端、移动端还是自适应
 干货   2023-07-28
只用css如何实现打字机特效?
 百态   2023-07-15
css怎么实现上下滚动
 干货   2023-06-28
canvas怎么画一个三角形?
 干货   2023-06-28
canvas怎么画一个椭圆形?
 干货   2023-06-28
canvas怎么画一个圆形?
 干货   2023-06-28
canvas怎么画一个正方形?
 干货   2023-06-28
中国河南省郑州市金水区蜘蛛爬虫ip大全
 干货   2023-06-22
javascript简易动态时间代码
 干货   2023-06-20
感谢员工的付出和激励的话怎么说?
 干货   2023-06-18
 
>>返回首页<<
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有