请问这段windows api 代码哪里错了?我为什么得不到预期的结果?

yuh0001 2012-10-24 11:46:34
我在写一段关于扫雷的程序,现在写到这里错误连连,晕死了。。。
可以运行,有窗口,有最初的绘画,但是当我点击了鼠标的左键后,屏幕上“最初的图案”消失了,本应该改变成“点击图案”的啊!!!!!

//*****************************************************************//

#include"stdafx.h"
#include <windows.h>
#include <stdio.h>
#include"mineswepper.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
struct Block
{
bool ifOpened; //if the block has been clicked
bool ifMined; //if the block contains a mine
bool ifFlaged; //if user has flgged the block as a mine
int minesAround;
};
static Block blocks[20][20];

static bool startFlag=false;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

TCHAR szAppName[]=TEXT("Minesweeper");
TCHAR szClassName[]=TEXT("MinesweeperClassName");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
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 =NULL;
wndclass.lpszClassName =szClassName;
RegisterClass(&wndclass);
hwnd=CreateWindow(szClassName,TEXT("Mineswepper"), WS_OVERLAPPEDWINDOW &~ WS_SIZEBOX,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam ;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{

PAINTSTRUCT ps;
RECT rect;
HDC hdc , hdcMem;
static HBITMAP hBitmap;
BITMAP bm;
static int bmX = 0;
static int bmY = 0;
static int mouseX;
static int mouseY;
static int row = 20;
static int coloum = 20;


switch (message)
{

case WM_CREATE:
{
for(int i=0;i<row;++i)
{
for(int l=0;l<coloum;++l)
{
blocks[i][l].ifMined=false;
blocks[i][l].ifFlaged=false;
blocks[i][l].ifOpened=false;
}
}
hBitmap=(HBITMAP)LoadImage(NULL,TEXT("Blocks.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
GetObject(hBitmap,sizeof(BITMAP),&bm);
bmX=bm.bmWidth;
bmY=bm.bmHeight;
return 0;
}



case WM_PAINT:
{
if(!startFlag)
{
hdc=BeginPaint(hwnd,&ps);
hdcMem=CreateCompatibleDC(hdc);
SelectObject(hdcMem,hBitmap);

for(int i=0;i<coloum;++i)
{
for(int l=0;l<row;++l)
{
BitBlt(hdc,(i*bmX),(l*bmY),bmX,bmY,hdcMem,0,0,SRCCOPY);
}
}
EndPaint(hwnd,&ps);
startFlag=true;
return 0;
}

for(int i=0;i<coloum;++i)
{
for(int l=0;l<row;++l)
{
if(blocks[i][l].ifOpened)
{
hdc=BeginPaint(hwnd,&ps);
hdcMem=CreateCompatibleDC(hdc);
SelectObject(hdcMem,hBitmap);
hBitmap=(HBITMAP)LoadImage(NULL,TEXT("mineKEYDOWN.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
GetObject(hBitmap,sizeof(BITMAP),&bm);
bmX=bm.bmWidth;
bmY=bm.bmHeight;
BitBlt(hdc,(i*bmX),(l*bmY),bmX,bmY,hdcMem,0,0,SRCCOPY);
EndPaint(hwnd,&ps);
}
}

}
return 0;
}



case WM_LBUTTONDOWN:
{
mouseX=LOWORD(lParam);
mouseY=HIWORD(lParam);
if( (mouseX<(coloum*bmX)) && (mouseY<(row*bmY)) )
{
int box_X = (mouseX/bmX)*bmX;
int box_Y = (mouseY/bmY)*bmY;
blocks[box_Y][box_X].ifOpened=true;
InvalidateRect(hwnd,NULL,true);
}
return 0;
}


case WM_DESTROY:
{
DeleteObject(hBitmap);
PostQuitMessage(0);
return 0;
}

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


请问哪位能帮我看一下啊。。。。。实在是非常感谢。。。。。。

...全文
150 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuh0001 2012-10-24
  • 打赏
  • 举报
回复
我实在不知道该怎么写了……既然“当点击格子”的时候重绘,我的那个startFlag变量该怎么办?撤销吗?如果撤销了的话我又该怎么开始呢?请指点一下我吧……谢谢您了……
I_ask_who 2012-10-24
  • 打赏
  • 举报
回复
你可以算出要点击的矩形,然后只invalidate这个矩形,并且重绘,可能效果还要好一点,不会闪。
yuh0001 2012-10-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

InvalidateRect(hwnd,NULL,true);
是全画面清除
if(blocks[i][l].ifOpened){...}只画一格我没猜错的话

InvalidateRect的param2应该考虑用一下
[/Quote]
忽然纠结了。。。。。我把startFlag在Paint消息后设为false了。。。。。。。唉...所以不能重绘了。。谢谢您!
I_ask_who 2012-10-24
  • 打赏
  • 举报
回复
InvalidateRect(hwnd,NULL,true);
是全画面清除
if(blocks[i][l].ifOpened){...}只画一格我没猜错的话

InvalidateRect的param2应该考虑用一下
yuh0001 2012-10-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

点击后,你好像擦掉整幅画面,再重新只重绘了一小块
[/Quote]
在我这里运行后,程序在开始时画出了一幅“扫雷格子图”,当我点击后,图消失了。。。。。。
I_ask_who 2012-10-24
  • 打赏
  • 举报
回复
点击后,你好像擦掉整幅画面,再重新只重绘了一小块
I_ask_who 2012-10-24
  • 打赏
  • 举报
回复
监听WM_SIZE,发生后全部m_bRedraw=true
Eleven 2012-10-24
  • 打赏
  • 举报
回复
WM_PAINT:
BeginPaint();
... // 绘图
EndPaint();
break;
yuh0001 2012-10-24
  • 打赏
  • 举报
回复
可如果我最小化窗口,再打开,不就显示不完整了吗?
I_ask_who 2012-10-24
  • 打赏
  • 举报
回复
每个格子加一个m_bRedraw变量,初始=true
点击后相应格子m_bRedraw=true,并且Invalidate相应格子
WM_PAINT判断m_bRedraw是否重绘,==true的重绘,重绘后=false。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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