简易包装windows初始结构类CApp

每次要进行windows编程时都要写结构,虽然可以用windows自己生成,但是实在太乱。只好自己简单的包装一个CApp类。以后需要时,只要继承该类即可。写完后直接如下调用:

#include "stdafx.h"
#include "MyApp.h"

int WINAPI WinMain( HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR     m_lpCmdLine,
       int       m_nCmdShow )
{
 CMyApp app(hInstance,m_lpCmdLine, m_nCmdShow);
 app.Run();

其中CMyApp继承自CApp类。

设计基类时,本来想参考下MFC的设计模式,后来发现MFC实在藏的太深,我还没那个水平完全按照那个结构搞出来。只好自己琢磨一下简易版本的。

基类名我定为R3DApp,首先设计成员变量和成员函数,在头文件中如下描述:

class R3DApp
{

public:
 R3DApp(HINSTANCE hInstance,LPSTR m_lpCmdLine, int m_nCmdShow);
 virtual ~R3DApp(void);
 static void CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 LRESULT InitApp();     //初始化windows基本信息,比如注册类,建立窗口
 void Run();       //开始消息循环  
 virtual void Loop(void){};   // 消息循环中需要的内容
 virtual void InitInstance( void ); // 初始化子类需要的内容
 virtual void GameMsgProcess( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); //处理消息

 protected:

 HWND     m_hWnd;
 HINSTANCE    m_hInstance ;
 LPSTR     m_lpCmdLine  ;
 int      m_nCmdShow  ;

 
 int      m_nPosX;
 int      m_nPosY;
 int      m_nWidth;
 int      m_nHeight;
 HICON     m_hIcon;
 HICON     m_hSmIcon;
 HCURSOR     m_hCursor;
 LPCSTR     m_szWindowsName;
};

        我将windows开始结构的几个部分分开了。讲经常需要添代码的地方设置为虚函数,供继承重写。成员变量主要保存windows的信息,都会先初始话,若子类需要修改某个参数,只要再子类的构造函数中修改参数即可。这里windows参数我只保存常用的,该类仅仅用来测试。

       本来我想将InitApp()函数直接放进基类的构造函数中,不过这样的话,因为基类构造函数先与子类构在函数执行,所以就算再子类的构造函数中修改了成员变量中的windows参数,也无法对InitApp产生影响。只好让子类再修改数值后再调用该函数。其中的WinProc一定要申明为static因为它是CALLBACK函数。至于什么叫callback函数,以及为什么callback函数作为类成员必须是static类型的,在候俊杰的深入浅出第二版的298页有详细解释。

       接下来写具体代码。其实需要写的也就三个函数 InitApp,Run,以及winProc函数。实现如下:       

static  R3DApp *g_pMe;

 void R3DApp::Run()
{
 MSG        uMsg;
 ZeroMemory( &uMsg, sizeof(MSG));

 while( uMsg.message != WM_QUIT )
 { 

  if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  {
   TranslateMessage( &uMsg );
   DispatchMessage( &uMsg );

  }
  else
  {
   Loop();
  }

 }

}

LRESULT R3DApp::InitApp()
{
 WNDCLASSEX winClass;

 winClass.lpszClassName = "MY_WINDOWS_CLASS";
 winClass.cbSize        = sizeof(WNDCLASSEX);
 winClass.style         = CS_HREDRAW | CS_VREDRAW;
 winClass.lpfnWndProc   = (WNDPROC)WindowProc;
 winClass.hInstance     = m_hInstance;
 winClass.hIcon        = m_hIcon;
 winClass.hIconSm    = m_hSmIcon;
 winClass.hCursor       = m_hCursor;
 winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
 winClass.lpszMenuName  = NULL;
 winClass.cbClsExtra    = 0;
 winClass.cbWndExtra    = 0;

 if (!RegisterClassEx(&winClass) )
 {
  return E_FAIL;
 }

 m_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS",
  m_szWindowsName,
  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
  m_nPosX, m_nPosY, m_nWidth, m_nHeight, NULL, NULL, m_hInstance, NULL );

 if( m_hWnd == NULL )
 {
  return E_FAIL;
 }
 InitInstance();

 ShowWindow( m_hWnd, m_nCmdShow );
 UpdateWindow( m_hWnd );
 return S_OK;
}

 void  CALLBACK R3DApp::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
 g_pMe->GameMsgProcess(hWnd, msg, wParam, lParam); //GameMsgProcess(hWnd, msg, wParam, lParam);
 switch( msg )
 { 
 case WM_KEYDOWN:
  {
   switch( wParam )
   {
   case VK_ESCAPE:
    PostQuitMessage(0);
    break;

   } 
  }
  break;

 case WM_DESTROY:
  {
   PostQuitMessage(0);
  }
  break;

 default:
  {
   DefWindowProc( hWnd, msg, wParam, lParam );
  }
  break;
 }
}

         其中虚函数的调用已经用蓝字标出。我用红字标出的地方卡了我2天没有解决,后来最后还是在csdn论坛问人才解决的。这个地方的难点是因为winproc是static的,而GameMsgProcess是虚函数,无法申明为static。想解决这个问题,只能进行间接调用。首先要在全局变量声名static  R3DApp *g_pMe,然后在基类构造函数中初始化为this指针,这样就可以在winproc中调用GameMsgProcess了。

        到这里类已经设计完了。子类继承后在3个虚函数中添入所需代码,然后直接实例化后,run就可以了。

ps:由于作者水平有限,只写了个小框架,可能有些地方还有问题。也没有做什么错误处理,该类仅用来学习。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值