打乒乓程序的PeekMessage版本
2006-06-04 23:26
190 查看
今天看到Programming Windows多任务及多线程那章,提到了PeekMessage( )函数,那这个不是正好可以用在打乒乓程序中吗,就不用定时器了,应用PeekMessage( )函数的版本如下:
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void DrawRect(HWND);
static int cxClient,cyClient,cxStart, cyStart,xStart,yStart;
static int i,j,delay,direction=1;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Bounce_PeekMessageEditon") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
int delay;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON)) ;
wndclass.hCursor = LoadCursor (hInstance, MAKEINTRESOURCE(IDC_CURSOR)) ;
wndclass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(208,221,238));
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Bounce_PeekMessageEdition"),
WS_OVERLAPPED | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
{
delay=1000000;
while(delay)
{
delay--;
}
DrawRect(hwnd) ;
}
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
switch (message)
{
case WM_SIZE:
cxClient=LOWORD (lParam);
cyClient=HIWORD (lParam);
cxStart =LOWORD (lParam)/2-5;
cyStart =HIWORD (lParam)-10-10;
xStart =cxClient/2-30;
yStart =cyClient-10;
cyClient-=11;
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
for(i=0;i<10;i++)
{
for(j=0;j<60;j++)
{
SetPixel(hdc,xStart+j,yStart+i,RGB(0,128,0));
}
}
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
SetPixel(hdc,cxStart+i,cyStart+j,RGB(255,128,0));
}
}
EndPaint(hwnd,&ps);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(xStart>=0)
{
xStart-=5;
}
break;
case VK_RIGHT:
if(xStart<=cxClient-60)
{
xStart+=5;
}
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
void DrawRect(HWND hwnd)
{
HDC hdc;
hdc=GetDC(hwnd);
switch(direction)
{
case 1:
if(cxStart>0 && cyStart>=0)
{
cxStart-=1;
cyStart-=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cxStart<=0)
{
direction=2;
}
if(cyStart<=0)
{
direction=4;
}
break;
case 2:
if(cyStart>0 && cxStart<cxClient-10)
{
cxStart+=1;
cyStart-=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart<=0)
{
direction=3;
}
if(cxStart>=cxClient-10)
{
direction=1;
}
break;
case 3:
if(cxStart<cxClient-10 && cyStart<cyClient-10)
{
cxStart+=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart>=cyClient-10)
{
if(cxStart+10<xStart+60 && cxStart>=xStart)
{
direction=2;
}
else
{
cxStart+=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
if(cyStart>cyClient+10)
{
MessageBox(hwnd,"AWOH,You lost!","Fail !",MB_OK);
SendMessage(hwnd,WM_DESTROY,0,0);
}
}
}
if(cxStart>=cxClient-10)
{
direction=4;
}
break;
case 4:
if(cyStart<cyClient-10 && cxStart>0)
{
cxStart-=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart>=cyClient-10)
{
if(cxStart+10<xStart+60 && cxStart>=xStart)
{
direction=1;
}
else
{
cxStart-=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
if(cyStart>cyClient+10)
{
MessageBox(hwnd,"AWOH,You fail!","Fail !",MB_OK);
SendMessage(hwnd,WM_DESTROY,0,0);
}
}
}
if(cxStart<=0)
{
direction=3;
}
break;
}
}
没错,这样程序确实可以实现既画运动的小球,又监视板的移动,但是我发现了一个问题栏 就是当我将指针放在标题栏上,按下指针时(我本意是想试试拖动窗口),小球停止了运动,好像WINDOWS产生了什么特殊的消息,可这时究竟发生了什么事情呢,我不知道,然后我把前一个,就是用TIMER的那个版本运行了一下,情况是当我按下时,小球停顿了一下,然后接着开始运动,然后我就可以开始拖动窗口了,拖的时候小球仍然在动。那么当我在标题栏上按下鼠标时,WINDOWS内部倒底发生了什么事情呢?谁肯指教我一下啊!!!!!!!
我想用多线程的方法实现时它应该不会有这个问题,明天把它写出来试试。
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void DrawRect(HWND);
static int cxClient,cyClient,cxStart, cyStart,xStart,yStart;
static int i,j,delay,direction=1;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Bounce_PeekMessageEditon") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
int delay;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON)) ;
wndclass.hCursor = LoadCursor (hInstance, MAKEINTRESOURCE(IDC_CURSOR)) ;
wndclass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(208,221,238));
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Bounce_PeekMessageEdition"),
WS_OVERLAPPED | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
{
delay=1000000;
while(delay)
{
delay--;
}
DrawRect(hwnd) ;
}
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
switch (message)
{
case WM_SIZE:
cxClient=LOWORD (lParam);
cyClient=HIWORD (lParam);
cxStart =LOWORD (lParam)/2-5;
cyStart =HIWORD (lParam)-10-10;
xStart =cxClient/2-30;
yStart =cyClient-10;
cyClient-=11;
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
for(i=0;i<10;i++)
{
for(j=0;j<60;j++)
{
SetPixel(hdc,xStart+j,yStart+i,RGB(0,128,0));
}
}
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
SetPixel(hdc,cxStart+i,cyStart+j,RGB(255,128,0));
}
}
EndPaint(hwnd,&ps);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(xStart>=0)
{
xStart-=5;
}
break;
case VK_RIGHT:
if(xStart<=cxClient-60)
{
xStart+=5;
}
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
void DrawRect(HWND hwnd)
{
HDC hdc;
hdc=GetDC(hwnd);
switch(direction)
{
case 1:
if(cxStart>0 && cyStart>=0)
{
cxStart-=1;
cyStart-=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cxStart<=0)
{
direction=2;
}
if(cyStart<=0)
{
direction=4;
}
break;
case 2:
if(cyStart>0 && cxStart<cxClient-10)
{
cxStart+=1;
cyStart-=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart<=0)
{
direction=3;
}
if(cxStart>=cxClient-10)
{
direction=1;
}
break;
case 3:
if(cxStart<cxClient-10 && cyStart<cyClient-10)
{
cxStart+=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart>=cyClient-10)
{
if(cxStart+10<xStart+60 && cxStart>=xStart)
{
direction=2;
}
else
{
cxStart+=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
if(cyStart>cyClient+10)
{
MessageBox(hwnd,"AWOH,You lost!","Fail !",MB_OK);
SendMessage(hwnd,WM_DESTROY,0,0);
}
}
}
if(cxStart>=cxClient-10)
{
direction=4;
}
break;
case 4:
if(cyStart<cyClient-10 && cxStart>0)
{
cxStart-=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
}
if(cyStart>=cyClient-10)
{
if(cxStart+10<xStart+60 && cxStart>=xStart)
{
direction=1;
}
else
{
cxStart-=1;
cyStart+=1;
InvalidateRect(hwnd,NULL,TRUE);
if(cyStart>cyClient+10)
{
MessageBox(hwnd,"AWOH,You fail!","Fail !",MB_OK);
SendMessage(hwnd,WM_DESTROY,0,0);
}
}
}
if(cxStart<=0)
{
direction=3;
}
break;
}
}
没错,这样程序确实可以实现既画运动的小球,又监视板的移动,但是我发现了一个问题栏 就是当我将指针放在标题栏上,按下指针时(我本意是想试试拖动窗口),小球停止了运动,好像WINDOWS产生了什么特殊的消息,可这时究竟发生了什么事情呢,我不知道,然后我把前一个,就是用TIMER的那个版本运行了一下,情况是当我按下时,小球停顿了一下,然后接着开始运动,然后我就可以开始拖动窗口了,拖的时候小球仍然在动。那么当我在标题栏上按下鼠标时,WINDOWS内部倒底发生了什么事情呢?谁肯指教我一下啊!!!!!!!
我想用多线程的方法实现时它应该不会有这个问题,明天把它写出来试试。
相关文章推荐
- VS2008/VS2005/VC6.0调试Release版本程序
- ICTCLAS2016 linux C++版本 使用教程 Eclipse下开发C/C++程序之头文件,库文件引用
- VS2012 MFC程序生成Release版本在其他机器上运行
- VS2008编写的程序使用更低版本VS打开
- 关于DYNPRO程序的系统迁移与版本不匹配问题之一
- asp防SQL注入程序优化版本
- OpenGL编程指南第版本学习笔记 --- OpenGL程序实现过程(win32 + OpenGL)
- 无法通过windows installer服务安装此安装程序包。您必须安装带有更新版本windows Installer服务的Windows
- .Net Framework 数据提供程序要求 Microsoft Data Access Components(MDAC).请安装 Microsoft Data Access Components(MDAC) 2.6 或更高版本。
- 装64为office Access驱动的时候,无法安装64位版本的Office,因为在您的PC上找到了以下32位程序
- 这样提供程序的版本信息
- [VS2008] Debug版本程序发布后 由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题 解决方法
- 2530程序用IAR新版本编译旧版本程序可能遇到的一个问题
- flash 拼音发音标准小程序(未完善版本)
- 微信小程序 122100版本更新问题解决方案
- OpenCV杂记11---升级opencv版本打开原来的程序
- C模拟SVN命令行执行本地版本管理程序
- C++ builder XE2 版本编译独立运行程序
- 在IIS中改变ASP.NET程序版本的实现方法附批处理代码
- 解决xp下无法通过windows installer服务安装此安装程序包。您必须安装带有更新版本Windows Installer服务的Windows Service Pack