快速拖动窗口有残影.如何解决

mylzy159 2011-03-14 10:05:57
我快速拖动标题栏就会出先画面重绘.

#include <windows.h>
#include "resource.h"
#include <stdio.h>

#define UP 0
#define LEFT 1
#define DOWN 2
#define RIGHT 3

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

void GameMessage (HWND hwnd, int time ,int point)//结束时的对话框设置
{
TCHAR szBuffer[1024] ;

KillTimer (hwnd, 1) ;
sprintf(szBuffer,"所用时间: %d\n你的得分: %d ", time, point) ;
MessageBox (hwnd,szBuffer, TEXT ("GameOver"), 0) ;
}

BOOL CheckSnake ( HWND hwnd, RECT *Snake, RECT *TwoRect, int *Array)//检查是否蛇撞到自身和蛇头出界
{ //返回TRUE表示得到目标,FALSE表示还要爬行
RECT StRect[60] ;
int i ,Number ;

Number = Array[2] + 4 ;
switch (Array[0])
{
case UP :

if( TwoRect[1].right == Snake[Number].right && TwoRect[1].bottom == Snake[Number].top)
return TRUE ;

for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;

for (i = Number - 2 ; i >= 0 ; i--)

if(Snake[Number].top <= TwoRect[0].top ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))
{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}

Snake[Number].top -= 15 ;
Snake[Number].bottom -= 15 ;

break ;

case DOWN :

if (TwoRect[1].right == Snake[Number].right && TwoRect[1].top == Snake[Number].bottom)

return TRUE ;

for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;

Snake[Number].bottom += 15 ;
Snake[Number].top += 15 ;

for (i = Number - 2 ; i >= 0 ; i--)

if(Snake[Number].bottom >= TwoRect[0].bottom ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))

{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}

break ;

case LEFT :

if(TwoRect[1].right == Snake[Number].left && TwoRect[1].bottom == Snake[Number].bottom)

return TRUE ;

for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;

for (i = Number - 2 ; i >= 0 ; i--)

if(Snake[Number].left <= TwoRect[0].left ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))

{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}

Snake[Number].right -= 15 ;
Snake[Number].left -= 15 ;

break ;

case RIGHT :

if(TwoRect[1].left == Snake[Number].right && TwoRect[1].top == Snake[Number].top)

return TRUE ;

for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;

Snake[Number].left += 15 ;
Snake[Number].right += 15 ;

for (i = Number - 2 ; i >= 0 ; i--)

if(Snake[Number].right >= TwoRect[0].right ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))

{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}

break ;
}
return FALSE ;
}

POINT GetRect (HWND hwnd, RECT MainRect, RECT *Snake, int Number) //得到目标黑色矩形
{
int i, xSize, ySize ;
BOOL In ;
POINT lPoint, rPoint ;

xSize = (MainRect.right - MainRect.left) / 15 ; //给窗口按比例缩放
ySize = (MainRect.bottom - MainRect.top) / 15 ;
In = FALSE ;

while(1) //让目标在主框内,并且不会和蛇碰到
{

lPoint.x = MainRect.left + (rand() % (xSize + 1)) * 15 ;
lPoint.y = MainRect.top + (rand() % (ySize + 1)) * 15 ;
rPoint.x = lPoint.x + 15 ;
rPoint.y = lPoint.y + 15 ;

if (PtInRect (&MainRect, lPoint) && PtInRect (&MainRect, rPoint))
{
for ( i =0 ; i <= Number ; i ++)
{

if (PtInRect (&Snake[i], lPoint) && PtInRect (&Snake[i], rPoint))
In = TRUE ;
}

if(In == FALSE)
break ;
}
}
return lPoint ;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)

{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
HACCEL hAccel ;

static TCHAR szAppName [] = TEXT ("Snake");

wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;

RegisterClass (&wndclass) ;

hwnd = CreateWindow (szAppName, TEXT ("Snake"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

hAccel = LoadAccelerators (hInstance, szAppName) ;

while (GetMessage (&msg, NULL, 0, 0))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}

return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps;
static int cxClient, cyClient, time, drection, point, i, Array[3];
static TCHAR szGetPoint[] = TEXT ("得分 : "),
szTime[] = TEXT ("时间 : "),
szBuffer[10] ;
static RECT MainRect, SnakeRect[60], DstRect, TwoRect[2] ;
HBRUSH Hbrush ;
static BOOL ChangeRect, Stop ;
static POINT RectPoint ;
HMENU hMenu ;

switch(message)
{

case WM_CREATE:

hdc = GetDC (hwnd) ;

time = 0 ;
drection = 3 ;
point = 0 ;
Stop = ChangeRect = TRUE ;

ReleaseDC (hwnd ,hdc) ;

return 0;

case WM_SIZE :

cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;

MainRect.left = cxClient / 12 ;
MainRect.top = cyClient / 12 ;
MainRect.right = 10 * MainRect.left ;
MainRect.bottom = 10 * MainRect.top ;

SetRect (&SnakeRect[0], MainRect.left + 45 , MainRect.top + 45, MainRect.left + 60, MainRect.top + 60) ;//设置5个蛇部分

for (i = 1 ; i < 5 ; i ++)
SetRect (&SnakeRect[i], SnakeRect[i-1].left + 15, SnakeRect[i-1].top, SnakeRect[i-1].right + 15, SnakeRect[i-1].bottom);

return 0;

case WM_TIMER:

time++;
InvalidateRect (hwnd ,NULL, TRUE) ;

return 0;

case WM_KEYDOWN:

switch (wParam)
{

case VK_UP :
if(drection == DOWN )
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over!"), TEXT (" Game Message "), 0) ;
}
else
drection = UP ;
break ;

case VK_DOWN :

if(drection == UP)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over!"), TEXT (" Game Message "), 0) ;
}
else
drection = DOWN ;
break ;

case VK_LEFT :

if(drection == RIGHT)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over "), TEXT (" Game Message "), 0) ;
}
else
drection = LEFT ;
break ;

case VK_RIGHT :

if(drection == LEFT)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over "), TEXT (" Game Message "), 0) ;
}
else
drection = RIGHT ;
break ;

case VK_SPACE :
if(Stop)
{
KillTimer (hwnd, 1) ;
Stop = FALSE ;
}
else
{
SetTimer (hwnd, 1, 100, NULL) ;
Stop = TRUE ;
}
}

return 0 ;

case WM_COMMAND:

hMenu = GetMenu (hwnd) ;

switch (LOWORD (wParam))
{

case IDA_F2:
case IDM_START : //重新开始

drection = 3 ;
SetRect (&SnakeRect[0], MainRect.left + 45 , MainRect.top + 45, MainRect.left + 60, MainRect.top + 60) ;

for (i = 1 ; i < 5 ; i ++)
SetRect (&SnakeRect[i], SnakeRect[i-1].left + 15, SnakeRect[i-1].top, SnakeRect[i-1].right + 15, SnakeRect[i-1].bottom);

SetTimer (hwnd, 1, 100, NULL) ;
InvalidateRect (hwnd ,NULL, TRUE) ;

break;

case IDM_HELP :

KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT ("空格暂停"), TEXT("about"), 0) ;
break;
}
return 0;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

Hbrush = GetStockObject (BLACK_BRUSH) ;
Rectangle (hdc, MainRect.left , MainRect.top, MainRect.right, MainRect.bottom ) ;
TextOut (hdc, MainRect.right + 40, 2 * MainRect.top, szTime, strlen (szTime)) ;
TextOut (hdc, MainRect.right + 40, 3 * MainRect.top, szGetPoint, strlen (szGetPoint)) ;
TextOut (hdc, MainRect.right + 80, 2 * MainRect.top, szBuffer, wsprintf( szBuffer, TEXT(" %d"), time / 10));
TextOut (hdc, MainRect.right + 80, 3 * MainRect.top, szBuffer, wsprintf( szBuffer, TEXT(" %d"), point));

if(ChangeRect)
{
RectPoint = GetRect (hwnd, MainRect, SnakeRect, 4 + point) ;
ChangeRect= FALSE ;
}

for(i = 4 + point ; i >= 0 ; i --)
Rectangle (hdc,SnakeRect[i].left, SnakeRect[i].top, SnakeRect[i].right, SnakeRect[i].bottom) ;
FillRect (hdc, &SnakeRect[4+point], Hbrush) ;

SetRect (&DstRect, RectPoint.x, RectPoint.y, RectPoint.x + 15, RectPoint.y + 15) ;
FillRect (hdc, &DstRect, Hbrush) ; //给蛇头涂黑

TwoRect[0] = MainRect ; //做这些是为了在CheckSnake中少放点参数进去
TwoRect[1] = DstRect ;
Array[0] = drection ;
Array[1] = time / 10;
Array[2] = point ;

if(ChangeRect = CheckSnake (hwnd, SnakeRect, TwoRect, Array))
{
point ++ ;
SnakeRect[4+point] = DstRect ;
}

EndPaint (hwnd, &ps) ;

return 0;

case WM_DESTROY:

KillTimer (hwnd,1) ;
PostQuitMessage (0) ;
return 0;

}
return DefWindowProc (hwnd ,message, wParam, lParam) ;
}


...全文
179 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
babala2009 2011-03-15
  • 打赏
  • 举报
回复
处理一下WM_ERASEBKGND

同时使用双缓冲技术
向立天 2011-03-14
  • 打赏
  • 举报
回复
两个一样的帖子?

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧