表5-3配置消息列表
名称 消息源 过滤器 目标文件
正确配置文件 用户输入正确的配置文件路径
系统自带程序搜索路径 程序自动过滤系统捕捉路径是否合法是否可用
程序自身check自己是否正确是否无崩溃 保存到 LightsOff.Ini
发送到通知监视机制
错误配置文件 用户输入错误信息 程序自检测系统 无
图5-3 更改配置文件LightsOff.Ini场景的系统顺序图
6 设计的实现
6.1 KMainFrame模块的实现
鼠标按下时的消息处理,主要调用kGameControler的ChangeLight,GetCurrLevel函数实现灯盘的转换效果。
LRESULT KMainFrame::OnLButtonDown(WPARAM wParam, LPARAM lParam)
{
int nXPos = LOWORD(lParam);
int nYPos = HIWORD(lParam);
if (0 < nXPos && 0 < nYPos && 5 * LIGHT_WIDTH > nXPos && 5 * LIGHT_HEIGHT > nYPos)
{
if(3 == ::g_kGameControler.ChangeLight(this, nXPos, nYPos))
{
::PostQuitMessage(0);
//如果用户全部通过,并选择不再继续, 则退出程序
return FALSE;
}
SetWndTitle(szTitle); //设置窗口标题
return TRUE;
}
int nCurr = g_kGameControler.GetCurrLevel(); //获取当前等级
int bChangeResult = 0;
POINT point = {nXPos, nYPos};
if(::PtInRect(&m_kLPointRect, point) && 0 < nCurr)
//判断一个点是否在一个矩阵区内
{
::SetCursor(::LoadCursor(NULL, IDC_HAND)); //载入手形鼠标
bChangeResult = g_kGameControler.SetLevel(nCurr - 1);
//移动到上一个等级
}
else if(::PtInRect(&m_kRPointRect, point))
{
::SetCursor(::LoadCursor(NULL, IDC_HAND)); //载入手形鼠标
bChangeResult = g_kGameControler.SetLevel(nCurr + 1);
//移动到下一个等级
}
else if(::PtInRect(&m_kResetRect, point))
{
::SetCursor(::LoadCursor(NULL, IDC_HAND)); //载入手形鼠标
bChangeResult = g_kGameControler.GameRestart(); //重置游戏
}
if (bChangeResult)
//如果bChangeResult值为,代表执行成功,成功后执行下面的语句,重绘窗口
{
InvalidateSpace(); //把窗户区变为无效区, 以便重绘
SetWndTitle(szTitle); //设置窗口标题
}
return TRUE;
}
画灯部分主要调用LoadBitmap函数加载位图然后复制一个DC句柄,从新的DC句柄中选择位图并付给hBitmap指针实现其功能。
BOOL KMainFrame::DrawLights(HDC hDc)
{
int nColor = 0;
int nXPos = LIGHT_WIDTH;
int nYPos = LIGHT_HEIGHT;
HBITMAP hBitmap = ::LoadBitmap(hInst, MAKEINTRESOURCE(m_nImgID));
//加载位图
if(!hBitmap)
{
return FALSE; //加载失败返回FALSE
}
HDC hMemDc = ::CreateCompatibleDC(hDc); //复制一个DC句柄
if (!hMemDc)
{
return FALSE; //创建DC句柄失败返回FALSE
}
hBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap);
//从新的DC句柄中选择位图,并赋给hBitmap指针
for (int i = 0; i < MATRIX_HEIGHT; i++)
{
for (int j = 0; j < MATRIX_WIDTH; j++)
{
POINT ptPoint = {j, i};
if(g_kGameControler.IsLightOn(ptPoint)) //判断是否为变灯
{
nColor = 0; //改变读取Bitmap的起始纵坐标
}
else
{
nColor = LIGHT_HEIGHT;
}
::BitBlt(hDc, nXPos * j, nYPos * i, LIGHT_WIDTH, LIGHT_HEIGHT, hMemDc, 0, nColor, SRCCOPY);
//利用BitBlt,把图形绘制到主窗口中
}
} //跟据矩阵,画出图形
hBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDc);
return TRUE;
}
画箭头部分主要是用到两个系统API:SelectObject和BitBlt。
BOOL KMainFrame::DrawPointer(HDC hDc, RECT& rtlPointer, int nCopyYPos)
{
int nStartXPos = rtlPointer.left;
int nStartYPos = rtlPointer.Top;
HDC hMemDc = ::CreateCompatibleDC(hDc);
HBITMAP hBitmap = ::LoadBitmap(::hInst, MAKEINTRESOURCE(IDB_CONTROL_POINT));
::SelectObject(hMemDc, hBitmap);
::BitBlt(hDc, nStartXPos, nStartYPos, 25, 22, hMemDc, 0, nCopyYPos, SRCCOPY); //25 这图片宽, 22为图片高, 0, nCopyYPos分别为图片中的起始X, Y
hBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDc);
return TRUE;
}
画游戏等级部分主要调用的是kGameControler的GetCurrLevel函数来实现。
BOOL KMainFrame::DrawLevel(HDC hDc, RECT& rtLevel)
{
char chLevel[NUM_LEN];
COLORREF wWhite = RGB(255, 255, 255); //三个代表白色
COLORREF wBlack = RGB(0, 0, 0); //三个代表黑色
int nLevel = ::g_kGameControler.GetCurrLevel();
::itoa(nLevel, chLevel, 10); //10代表是一个十进制数
::SetTextColor(hDc, wWhite);
::SetBkColor(hDc, wBlack);
::DrawText(hDc,chLevel, strlen(chLevel), &rtLevel, DT_CENTER);
return TRUE;
}
画重置按钮
BOOL KMainFrame::DrawResetBtn(HDC hDc, RECT& rtResetBtn)
{
HDC hMemDc = ::CreateCompatibleDC(hDc);
HBITMAP hBitmap = ::LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RESETBTN));
::SelectObject(hMemDc, hBitmap);
::BitBlt(hDc, rtResetBtn.left, rtResetBtn.top, 50, 45, hMemDc, 0, 0, SRCCOPY); //50 这图片宽, 45为图片高, 0, 0分别为图片中的起始X, Y
hBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDc);
return TRUE;
}
画控制台背景
BOOL KMainFrame::DrawBackGround(HDC hDc, COLORREF wColor, RECT& rtConsole)
{
HBRUSH hBrush = ::CreateSolidBrush(wColor);
::SelectObject(hDc, hBrush);
::FillRect(hDc, &rtConsole, hBrush);
hBrush = (HBRUSH)::SelectObject(hDc, hBrush);
::DeleteObject(hBrush);
return TRUE;
}
6.2 KSwitchFrame模块的实现
显示灯局主要是从新的DC句柄中选择位图,并赋值给hBitmap指针之后利用BitBlt把图形绘制到主窗口的正中间。
BOOL KSwitchFrame::DisplayLights(HDC hDc)
{
int nImageBaseID = BASE_IMAGE;
HDC hMemDc = ::CreateCompatibleDC(hDc);
int j = 0;
for (int i = 0; i < LIGHTS_KIND; i++)
{
HBITMAP hBitmap = ::LoadBitmap(hInst, MAKEINTRESOURCE(nImageBaseID + i));
SelectObject(hMemDc, hBitmap);
//从新的DC句柄中选择位图,并赋给hBitmap指针
if(0 == i % ROW_SIZE && 0 != i)
{
j++;
}
::BitBlt(hDc,
LIGHT_WIDTH * (i % ROW_SIZE),
LIGHT_HEIGHT * j,
LIGHT_WIDTH,
LIGHT_HEIGHT,
hMemDc,
0,
0,
SRCCOPY
);
//利用BitBlt,把图形绘制到主窗口中
hBitmap = (HBITMAP)::SelectObject(hMemDc, hBitmap);
::DeleteObject(hBitmap);
}
::DeleteDC(hMemDc);
return TRUE;
}
画焦点首先要将坐标转换为逻辑坐标,之后在制定的区域画一个矩形框。
BOOL KSwitchFrame::DrawFocus(RECT& rtOld, RECT& rect, HDC hDc)
{
int nOldX = rtOld.left / LIGHT_WIDTH; //把坐标转为逻辑坐标
int nOldY = rtOld.top / LIGHT_HEIGHT;
int nXPos = rect.left / LIGHT_WIDTH;
int nYPos = rect.top / LIGHT_HEIGHT;
if(nOldY ==nYPos &&nOldX == nXPos &&nOldX > 0 && nOldY > 0)
return FALSE;
HBRUSH hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
HPEN hPen = ::CreatePen(PS_SOLID, 5, FRAME_COLOR);
//创建画笔与画刷, 画笔宽为
::SelectObject(hDc, hPen);
::SelectObject(hDc, hBrush); //给DC对象选择画笔与画刷
::Rectangle(hDc,
rect.left + 3, //减的原因在于画矩形的时候,是以该位置为中心的,所以要先减去画笔的宽度一半
rect.top + 3,
rect.right - 3,
rect.bottom - 3
); //在指定区域画一个矩形框
hBrush = (HBRUSH)::SelectObject(hDc, hBrush);
hPen = (HPEN)::SelectObject(hDc, hPen);
::DeleteObject(hBrush);
::DeleteObject(hPen);
return TRUE;
}
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] 下一页