windows游戏编程封装窗口类
本系列文章由jadeshu编写,转载请注明出处。http://blog.csdn.net/jadeshu/article/details/22451353
作者:jadeshu 邮箱: jadeshu@qq.com 欢迎邮件交流
1.由于除了少数固定窗口的游戏可以不考虑分辨率的处理,大部分游戏都要考虑不同分辨率的情况,所以需要具备这么能处理分辨率!因此我们将显示模式添加窗口类中,如下,可以简单处理
2.就是一些WIN32创建窗口的方面问题
3.
#ifndef _JSWND_H_
#define _JSWND_H_
#include <windows.h>
#include <typeinfo.h>
#include <time.h>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
#include <gdiplus.h>
#pragma comment(lib,"Msimg32.lib")
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
static const LPCTSTR G_WIN_CLASS = TEXT("JS"); //默认注册的窗口类名
static const LPCTSTR G_WIN_TITLE = TEXT("JSWnd Ver 1.0"); //默认窗口标题
static const int G_WIN_WIDTH = 1024; //默认游戏窗口宽
static const int G_WIN_HEIGHT = 768; //默认游戏窗口高
//游戏状态枚举常量定义
enum GAME_STATE
{
GAME_START, //开始
GAME_RUN, //运行
GAME_PAUSE, //暂停
GAME_UPGRADE, //升级
GAME_WIN, //通关
GAME_OVER, //结束
GAME_HELP, //帮助状态
GAME_ABOUT, //关于状态
GAME_SETTING //设置状态
};
//按键行为常量
enum KM_ACTION
{
KEY_SYS_NONE, //非系统按键处理
KEY_UP, //释放按键
KEY_DOWN, //按下键
MOUSE_MOVE, //鼠标移动
MOUSE_LCLICK, //鼠标左键点击
MOUSE_RCLICK //鼠标右键点击
};
class CJSWnd
{
public:
CJSWnd(HINSTANCE hInstance, LPCTSTR szWindowClass = G_WIN_CLASS,
LPCTSTR szTitle = G_WIN_TITLE,
WORD Icon = NULL, WORD SmIcon = NULL,
int iWidth = G_WIN_WIDTH, int iHeight = G_WIN_HEIGHT);
virtual ~CJSWnd();
inline int GetInterval() { return _IntervalTime; } //获取游戏帧刷新间隔时间
inline void SetFrame(int iTime) { _IntervalTime = 1000 / iTime; } //设置游戏帧刷新间隔时间
inline BOOL GetSleep() { return _bIsAsleep; } //获取窗口是否为焦点状态
inline void SetSleep(BOOL asleep) { _bIsAsleep = asleep; } //设置窗口是否为焦点状态
inline void SetFullScreen(BOOL isFull){ _bFullScreen = isFull; } //设置窗口是否全屏显示
inline bool CheckKey(WPARAM wParam){ return _bKeys[wParam]; } //获取当前的按键状态
BOOL WndInit(); //注册 创建 显示 更新窗口
static LONG CALLBACK DefProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); //静态回调函数
LONG WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); //消息处理函数,将被回调函数调用
void Run(); //启动游戏引擎
virtual void GameInit()=0; //游戏初始化
virtual void GameLogic()=0; //游戏逻辑处理
virtual void GameEnd()=0; //游戏结束处理
virtual void GamePaint(HDC hdc)=0; //根据GAME_STATE值显示游戏界面
virtual void GameKeyAction(KM_ACTION ActionType=KEY_SYS_NONE)=0; //处理按键行为
virtual void GameMouseAction(int x, int y, KM_ACTION ActionType)=0; //处理鼠标行为
void SaveMode(); //存储现在的显示模式
void ResetMode(); //还原之前的存储的显示模式
bool ChangeMode(int ChangeWidth, int ChangeHeight); //更改显示模式
static CJSWnd* m_pWnd; //窗口接口指针
//CJSWnd *GetPwnd(){ return m_pWnd;}
private:
void SubKeyAction(WPARAM wParam); //附加按键行为处理
protected:
HWND _hWnd; //窗口句柄
HINSTANCE _hInstance; //实例句柄
LPCTSTR _wndClass; //窗口类名
LPCTSTR _wndTitle; //窗口标题
int _wndWidth, _wndHeight; //窗口高度和宽度
int _scrnWidth, _scrnHeight; //屏幕分辨率宽和高
WORD _wIcon, _wSmIcon; //程序大图标和小图标
BOOL _bFullScreen; //全屏标志
int _IntervalTime; //游戏帧刷新间隔时间
BOOL _bIsAsleep; //窗口是否处于非焦点状态
GAME_STATE _GameState; //游戏状态(为GAME_STATE常量值)
bool _bKeys[256]; //记录键盘状态的数组(是否按下标志)
RECT _rcOldRect; //当前窗口尺寸
LONG _style; //窗口基本风格
LONG _ex_style; //窗口扩展风格
HBITMAP _hBufferBitmap; //内存缓冲位图
HDC _hBufferDC; //内存缓冲DC
private:
ULONG_PTR __ptrGdiplusToken; //对GDI+的引用
HBITMAP __oldHbitmap; //旧的内存位图
DEVMODE __devmodeSaved;
bool __modeChanged;
};
#endif
#include "JSWnd.h"
CJSWnd *CJSWnd::m_pWnd = NULL; //引擎类指针
CJSWnd::CJSWnd(HINSTANCE hInstance, LPCTSTR szWindowClass,
LPCTSTR szTitle, WORD Icon /* = NULL */, WORD SmIcon /* = NULL */,
int iWidth /* = G_WIN_WIDTH */, int iHeight /* = G_WIN_HEIGHT */):_hInstance(hInstance),_wndClass(szWindowClass),
_wndTitle(szTitle),_wndWidth(iWidth),_wndHeight(iHeight),_wIcon(Icon),_wSmIcon(SmIcon),_bFullScreen(FALSE),
_IntervalTime(40),_bIsAsleep(FALSE),/*_GameState(GAME_START),*/__modeChanged(false)
{
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&__ptrGdiplusToken,&gdiplusStartupInput,NULL);
m_pWnd = this;
for (int i=0;i<256;i++)
{
_bKeys[i] = false;
}
SaveMode();
}
CJSWnd::~CJSWnd()
{
if (__oldHbitmap)
{
::SelectObject(_hBufferDC,__oldHbitmap);
}
if (_hBufferBitmap)
{
::DeleteObject(_hBufferBitmap);
_hBufferBitmap = NULL;
}
if (_hBufferDC)
{
::DeleteDC(_hBufferDC);
}
::DeleteObject(__oldHbitmap);
__oldHbitmap = NULL;
ResetMode();
Gdiplus::GdiplusShutdown(__ptrGdiplusToken); //关闭GDI+
}
//注册 创建 显示 更新窗口
BOOL CJSWnd::WndInit()
{
WNDCLASSEX wndClassex;
wndClassex.cbSize = sizeof(WNDCLASSEX);
wndClassex.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
wndClassex.lpfnWndProc = DefProc;
wndClassex.cbClsExtra = wndClassex.cbWndExtra = 0;
wndClassex.hInstance = _hInstance;
wndClassex.hIcon = ::LoadIcon(_hInstance,MAKEINTRESOURCE(_wIcon));
wndClassex.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wndClassex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClassex.lpszMenuName = NULL;
wndClassex.lpszClassName = _wndClass;
wndClassex.hIconSm = ::LoadIcon(_hInstance,MAKEINTRESOURCE(_wSmIcon));
if (!::RegisterClassEx(&wndClassex))
{
return FALSE;
}
//使窗口居中,获取客户区全屏幕宽高(去掉任务栏高度)
//如果要获取完全全屏幕宽高,包括任务栏高度,使用SM_CXSCREEN和SM_CYSCREEN
_scrnWidth = ::GetSystemMetrics(SM_CXFULLSCREEN); //屏幕宽度
_scrnHeight = ::GetSystemMetrics(SM_CYFULLSCREEN); //屏幕高度
int x = (_scrnWidth - _wndWidth)/2;
int y = (_scrnHeight - _wndHeight)/2;
//获取窗口边框和标题栏大小
int iXFrameSize = ::GetSystemMetrics(SM_CXBORDER);
int iYFrameSize = ::GetSystemMetrics(SM_CYBORDER);
int iCaptionSize = ::GetSystemMetrics(SM_CYCAPTION);
_hWnd = ::CreateWindow(_wndClass,_wndTitle,
WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, //禁止调整大小
x,y,_wndWidth+2*iXFrameSize,_wndHeight+iCaptionSize+2*iYFrameSize, //加上窗口边框和标题栏占用
NULL,NULL,_hInstance,NULL);
if (!_hWnd)
{
return FALSE;
}
//如果是全屏的话,改为全屏模式
if (_bFullScreen == TRUE)
{
::GetWindowRect(_hWnd,&_rcOldRect);
_style = ::GetWindowLong(_hWnd,GWL_STYLE);
_ex_style = ::GetWindowLong(_hWnd,GWL_EXSTYLE);
SaveMode();
HWND hDesktop;
hDesktop = ::GetDesktopWindow(); //获取桌面窗口的句柄
RECT rc;
::GetWindowRect(hDesktop,&rc);
ChangeMode(_wndWidth,_wndHeight);
//设置为WS_DLGFRAME.WS_BORDER或WS_EX_CLIENTEDGE都可以去掉标题栏
//设置扩展风格为WS_EX_WINDOWEDGE,去掉窗口边框
::SetWindowLong(_hWnd,GWL_EXSTYLE,WS_EX_WINDOWEDGE);
::SetWindowLong(_hWnd,GWL_STYLE,WS_BORDER);
::SetWindowPos(_hWnd,HWND_TOP,-1,-1,rc.right,rc.bottom,SWP_SHOWWINDOW);
}
HDC _hdc = ::GetDC(_hWnd);
_hBufferDC = ::CreateCompatibleDC(_hdc);
_hBufferBitmap = ::CreateCompatibleBitmap(_hdc,_wndWidth,_wndHeight);
__oldHbitmap = (HBITMAP)::SelectObject(_hBufferDC,_hBufferBitmap);
::ReleaseDC(_hWnd,_hdc);
::ShowWindow(_hWnd,SW_NORMAL);
::UpdateWindow(_hWnd);
return TRUE;
}
//附加按键行为处理(此处处理Esc键)
void CJSWnd::SubKeyAction(WPARAM wParam)
{
int x,y;
if (wParam == VK_ESCAPE) //按下ESC键
{
_bFullScreen = !_bFullScreen; //设置全屏显示标志
if (!_bFullScreen) //恢复窗口模式
{
ResetMode();
::SetWindowLong(_hWnd,GWL_STYLE,_style);
::SetWindowLong(_hWnd,GWL_EXSTYLE,_ex_style);
int oldWidth = _rcOldRect.right - _rcOldRect.left;
int oldHeight = _rcOldRect.bottom - _rcOldRect.top;
x = _rcOldRect.left;
y = _rcOldRect.top;
::SetWindowPos(_hWnd,HWND_NOTOPMOST,x,y,oldWidth,oldHeight,SWP_SHOWWINDOW);
}
else //显示退出程序对话框
{
::ShowCursor(true); //显示光标
if (IDOK == ::MessageBox(NULL,L"你确定要退出吗?",_wndTitle,MB_OKCANCEL|MB_ICONQUESTION))
{
::DestroyWindow(_hWnd);
}
}
}
}
LONG CALLBACK CJSWnd::DefProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
return m_pWnd->WindowProc(hWnd,msg,wParam,lParam); //调用类中的消息处理函数
}
LONG CJSWnd::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SETFOCUS:
{
SetSleep(FALSE);
return 0;
}
case WM_KILLFOCUS:
{
SetSleep(TRUE);
return 0;
}
case WM_CREATE:
{
GameInit();
return 0;
}
case WM_LBUTTONDOWN: //鼠标左键按下的处理
{
GameMouseAction(LOWORD(lParam),HIWORD(lParam),MOUSE_LCLICK);
return 0;
}
case WM_RBUTTONDOWN: //鼠标右键按下的处理
{
GameMouseAction(LOWORD(lParam),HIWORD(lParam),MOUSE_RCLICK);
return 0;
}
case WM_MOUSEMOVE: //鼠标移动处理
{
GameMouseAction(LOWORD(lParam),HIWORD(lParam),MOUSE_MOVE);
return 0;
}
case WM_KEYDOWN: //键被按下的处理
{
_bKeys[wParam] = true; //记录对应的按键状态
GameKeyAction(KEY_DOWN); //执行游戏按键行为
SubKeyAction(wParam); //附加按键行为处理
return 0;
}
case WM_KEYUP: //释放按键处理
{
_bKeys[wParam] = false;
GameKeyAction(KEY_UP);
return 0;
}
case WM_NCLBUTTONDBLCLK: //禁止双击窗口标题栏最大化窗口
{
if (HTCAPTION == wParam) return 0;
}
case WM_SYSCOMMAND:
{
if (wParam == SC_MAXIMIZE)
{
_bFullScreen = !_bFullScreen; //设置全屏显示标志
if (_bFullScreen) //全屏幕显示
{
::GetWindowRect(_hWnd,&_rcOldRect); //记住当前窗口的尺寸
_style = ::GetWindowLong(_hWnd,GWL_STYLE);
_ex_style = ::GetWindowLong(_hWnd,GWL_EXSTYLE);
SaveMode();
HWND hDesktop;
hDesktop = ::GetDesktopWindow(); //获取桌面窗口的句柄
RECT rc;
::GetWindowRect(hDesktop,&rc); //获取桌面窗口的矩形
ChangeMode(_wndWidth,_wndHeight);
//设置为WS_DLGFRAME.WS_BORDER或WS_EX_CLIENTEDGE都可以去掉标题栏
//设置扩展风格为WS_EX_WINDOWEDGE,去掉窗口边框
::SetWindowLong(_hWnd,GWL_EXSTYLE,WS_EX_WINDOWEDGE);
::SetWindowLong(_hWnd,GWL_STYLE,WS_BORDER);
::SetWindowPos(_hWnd,HWND_TOP,-1,-1,rc.right,rc.bottom,SWP_SHOWWINDOW);
}
}
else if (wParam == SC_CLOSE)
{
if (IDOK == ::MessageBox(NULL,L"你确定要退出吗?",_wndTitle,MB_OKCANCEL|MB_ICONQUESTION))
{
::DestroyWindow(_hWnd);
}
}
else
{
//由于WM_SYSCOMMAND消息不是由程序控制的,
//所以必须将该消息传给DefWindowProc,否则会造成其他消息无法处理
return ::DefWindowProc(hWnd,WM_SYSCOMMAND,wParam,lParam);
}
return 0;
}
case WM_CLOSE:
{
::DestroyWindow(hWnd);
return 0;
}
case WM_PAINT: //窗口绘制
{
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hWnd,&ps);
GamePaint(hdc);
::EndPaint(hWnd,&ps);
return 0;
}
case WM_DESTROY: //程序销毁
{
::PostQuitMessage(0);
return 0;
}
}
return ::DefWindowProc(hWnd,msg,wParam,lParam);
}
void CJSWnd::Run()
{
MSG msg;
WndInit(); //初始化窗口
::srand((unsigned)time(NULL)); //初始化随机数
static int TickElapsed = 0;
int nowTick;
while (TRUE)
{
if (::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
if (!_bIsAsleep) //确保游戏没有进入睡眠状态
{
nowTick = ::GetTickCount();
if (nowTick > TickElapsed) //判断游戏循环的时间
{
TickElapsed = nowTick + _IntervalTime;
GameLogic(); //处理游戏逻辑
GamePaint(_hBufferDC); //在内存中绘制内容
HDC hDc = ::GetDC(_hWnd); //获取游戏窗口句柄及绘图设备
::BitBlt(hDc,0,0,_wndWidth,_wndHeight,_hBufferDC,0,0,SRCCOPY); //将内存设备中绘制的内容绘制到屏幕上
::ReleaseDC(_hWnd,hDc); //释放设备
}
}
}
}
m_pWnd->GameEnd(); //游戏结束处理
}
void CJSWnd::SaveMode()
{
HDC dc = ::GetDC(0);
__devmodeSaved.dmSize = sizeof(DEVMODE);
__devmodeSaved.dmDriverExtra = 0;
__devmodeSaved.dmPelsWidth = ::GetDeviceCaps(dc,HORZRES);
__devmodeSaved.dmPelsHeight = ::GetDeviceCaps(dc,VERTRES);
__devmodeSaved.dmBitsPerPel = ::GetDeviceCaps(dc,BITSPIXEL);
__devmodeSaved.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
//判断windows版本是否为windows NT/2000
if (::GetVersion() & 0x80000000 == 0)
{
__devmodeSaved.dmFields |= DM_DISPLAYFREQUENCY;
__devmodeSaved.dmDisplayFrequency = GetDeviceCaps(dc,VREFRESH);
}
::ReleaseDC(0,dc);
}
void CJSWnd::ResetMode()
{
if (__modeChanged)
{
::ChangeDisplaySettings(&__devmodeSaved,0);
__modeChanged = false;
}
}
bool CJSWnd::ChangeMode(int ChangeWidth, int ChangeHeight)
{
DEVMODE devmode;
devmode = __devmodeSaved;
devmode.dmPelsWidth = ChangeWidth;
devmode.dmPelsHeight = ChangeHeight;
devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
if (::ChangeDisplaySettings(&devmode,CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
{
__modeChanged = true;
return true;
}
return false;
}
例子1.进行测试一个简单窗口程序 HELLO WORLD!
首先从上个窗口类派生一个自己的游戏窗口类
#pragma once
#include "JSWnd.h"
class CTestWnd :public CJSWnd
{
public:
CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon = NULL, WORD SmIcon = NULL,
int iWidth = G_WIN_WIDTH, int iHeight = G_WIN_HEIGHT);
virtual ~CTestWnd();
public:
virtual void GameInit(){}; //游戏初始化
virtual void GameLogic(){}; //游戏逻辑处理
virtual void GameEnd(){}; //游戏结束处理
virtual void GamePaint(HDC hdc); //根据GAME_STATE值显示游戏界面
virtual void GameKeyAction(KM_ACTION ActionType=KEY_SYS_NONE){}; //处理按键行为
virtual void GameMouseAction(int x, int y, KM_ACTION ActionType){}; //处理鼠标行为
};
#include "TestWnd.h"
CTestWnd::CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon /*= NULL*/, WORD SmIcon /*= NULL*/,
int iWidth /*= WIN_WIDTH*/, int iHeight/* = WIN_HEIGHT*/):CJSWnd(hInstance,szWindowClass,szTitle,Icon,SmIcon,iWidth,iHeight)
{
}
CTestWnd::~CTestWnd()
{
}
void CTestWnd::GamePaint(HDC hdc)
{
HGDIOBJ mbrush,oldbrush;
HGDIOBJ mpen,oldpen;
RECT mrect;
int cell_width = _wndWidth/20;
int cell_height = _wndHeight/20;
for (int r=0;r<20;r++)
{
for (int c=0;c<20;c++)
{
mpen = ::CreatePen(PS_SOLID,0,RGB(240,240,240));
oldpen = ::SelectObject(hdc,mpen);
mbrush = ::CreateSolidBrush(RGB(rand()%255,rand()%255,rand()%255));
oldbrush = ::SelectObject(hdc,mbrush);
mrect.left = c*cell_width;
mrect.right = mrect.left + cell_width;
mrect.top = r*cell_height;
mrect.bottom = mrect.top + cell_height;
::FillRect(hdc,&mrect,(HBRUSH)mbrush);
::Rectangle(hdc,mrect.left,mrect.top,mrect.right,mrect.bottom);
::SelectObject(hdc,oldbrush);
::DeleteObject(mbrush);
::SelectObject(hdc,oldpen);
::DeleteObject(mpen);
}
}
}
主程序
#include "TestWnd.h"
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
CJSWnd *ptest = new CTestWnd(hInstance,G_WIN_CLASS,L"HELLO WORLD",NULL,NULL,800,600);
ptest->SetFrame(20);
ptest->Run();
delete ptest;
return 0;
}
运行结果:
例子2.根据鼠标移动,窗口显示鼠标的坐标
首先从上个窗口类派生一个自己的游戏窗口类
#pragma once
#include "JSWnd.h"
class CTestWnd :public CJSWnd
{
public:
CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon = NULL, WORD SmIcon = NULL,
int iWidth = G_WIN_WIDTH, int iHeight = G_WIN_HEIGHT);
virtual ~CTestWnd();
public:
virtual void GameInit(){}; //游戏初始化
virtual void GameLogic(){}; //游戏逻辑处理
virtual void GameEnd(){}; //游戏结束处理
virtual void GamePaint(HDC hdc){}; //根据GAME_STATE值显示游戏界面
virtual void GameKeyAction(KM_ACTION ActionType=KEY_SYS_NONE){}; //处理按键行为
virtual void GameMouseAction(int x, int y, KM_ACTION ActionType); //处理鼠标行为
};
#include "TestWnd.h"
#include <tchar.h>
CTestWnd::CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon /*= NULL*/, WORD SmIcon /*= NULL*/,
int iWidth /*= G_WIN_WIDTH*/, int iHeight/* = G_WIN_HEIGHT*/):CJSWnd(hInstance,szWindowClass,szTitle,Icon,SmIcon,iWidth,iHeight)
{
}
CTestWnd::~CTestWnd()
{
}
void CTestWnd::GameMouseAction(int x, int y, KM_ACTION ActionType)
{
if (ActionType == MOUSE_MOVE)
{
TCHAR str[20] = _T("");
TextOut(_hBufferDC,10,10,_T("鼠标坐标是:"),_tcslen(_T("鼠标坐标是:")));
_stprintf_s(str,sizeof(_T("鼠标坐标x是:%d")),_T("鼠标坐标x是:%d"),x);
TextOut(_hBufferDC,20,40,str,_tcslen(str));
_stprintf_s(str,sizeof(_T("鼠标坐标Y是:%d")),_T("鼠标坐标x是:%d"),y);
TextOut(_hBufferDC,20,60,str,_tcslen(str));
}
}
运行结果
例子3.窗口显示一副图片
首先从上个窗口类派生一个自己的游戏窗口类
#pragma once
#include "JSWnd.h"
class CTestWnd :public CJSWnd
{
public:
CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon = NULL, WORD SmIcon = NULL,
int iWidth = G_WIN_WIDTH, int iHeight = G_WIN_HEIGHT);
virtual ~CTestWnd();
HBITMAP hBKBmp;
public:
virtual void GameInit(); //游戏初始化
virtual void GameLogic(){}; //游戏逻辑处理
virtual void GameEnd(){}; //游戏结束处理
virtual void GamePaint(HDC hdc); //根据GAME_STATE值显示游戏界面
virtual void GameKeyAction(KM_ACTION ActionType=KEY_SYS_NONE){}; //处理按键行为
virtual void GameMouseAction(int x, int y, KM_ACTION ActionType){}; //处理鼠标行为
};
#include "TestWnd.h"
#include <tchar.h>
CTestWnd::CTestWnd(HINSTANCE hInstance, LPCTSTR szWindowClass, LPCTSTR szTitle,
WORD Icon /*= NULL*/, WORD SmIcon /*= NULL*/,
int iWidth /*= G_WIN_WIDTH*/, int iHeight/* = G_WIN_HEIGHT*/):CJSWnd(hInstance,szWindowClass,szTitle,Icon,SmIcon,iWidth,iHeight)
{
}
CTestWnd::~CTestWnd()
{
if(hBKBmp)
{
//删除位图对象
::DeleteObject(hBKBmp);
}
}
void CTestWnd::GamePaint(HDC hdc)
{
//创建缓冲的内存设备
HDC memDC = ::CreateCompatibleDC(hdc);
//将图选进内存设备HBITMAP
oldFrameBmp = (HBITMAP)::SelectObject(memDC,hBKBmp);
//设置指定设备环境中的位图拉伸模式
//COLORONCOLOR:删除像素。该模式删除所有消除的像素行,不保留其信息。
::SetStretchBltMode(hdc,COLORONCOLOR);
::StretchBlt(hdc,0,0,800,600,memDC,0,0,600,450,SRCCOPY);
//还原内存设备环境中的原来的位图对象
::SelectObject(memDC,oldFrameBmp);
//删除内存设备
::DeleteDC(memDC);
//删除位图对象
::DeleteObject(oldFrameBmp);
oldFrameBmp = NULL;
}
void CTestWnd::GameInit()
{
hBKBmp = (HBITMAP)::LoadImage(_hInstance,_T("bg.bmp"),IMAGE_BITMAP,600,450,LR_LOADFROMFILE);
}
运行结果: