关闭

打乒乓程序的PeekMessage版本

标签: nulldelaywindowscallback多线程winapi
1053人阅读 评论(0) 收藏 举报
分类:

今天看到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内部倒底发生了什么事情呢?谁肯指教我一下啊!!!!!!!

我想用多线程的方法实现时它应该不会有这个问题,明天把它写出来试试。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:279432次
    • 积分:4191
    • 等级:
    • 排名:第7315名
    • 原创:117篇
    • 转载:4篇
    • 译文:1篇
    • 评论:279条
    文章分类
    最新评论