zoukankan      html  css  js  c++  java
  • Cocos2d-X 2.2嵌入MFC的子窗口

    1.在cocos2dx目录下创建基于对话框的MFC工程,对话框中间放一个Picture控件

    2.添加cocos2dx的相关头文件包含路径、库包含路径和依赖项,可以参考其他cocos工程设置

    3.选中Picture控件后右键单击,在弹出菜单中找到“添加变量”。为Picture控件生成一个控件变量。这里命名为m_cocosWin,并点击完成

    4.右击工程添加MFC类,类名里输入“CCocos2dXWin”,并选择基类CWnd。把上面的m_cocosWin变量类型改为CCocoWin 然后点击“完成”并做如下修改。

     4.1头文件添加变量和函数

        //是否已经初始化
        
        BOOL                m_bInitCocos2dX;
        //创建Cocos2dX窗口
        BOOL        CreateCocos2dXWindow();

    4.2 cpp添加COCOS的头文件,并加入一个全局变量

    #include "AppDelegate.h"
    #include "cocos2d.h"
    
    USING_NS_CC;
    
    AppDelegate CocoApp;

    4.3函数实现

    //创建Cocos2dX窗口
    BOOL CCocoWin::CreateCocos2dXWindow()
    {
        //新建一个CRect变量获取窗口的客户区大小
        CRect    tClientRect;
        GetClientRect(&tClientRect);
        //取得使用的OpenGL视窗
        CCEGLView* eglView = CCEGLView::sharedOpenGLView(false,GetSafeHwnd());
        //指定客户区大小。
        eglView->setFrameSize(tClientRect.Width(),tClientRect.Height());
        //调用程序的运行函数,增加参数bool型变量控制是否进行消息循环。因为MFC控件本身有自已的消息响应处理。如果不改动的话,这里就会进入死循环。
        cocos2d::CCApplication::sharedApplication()->run();
        //这里将变量设置为TRUE
        m_bInitCocos2dX = TRUE;
    
        SetTimer(1,15,NULL);
    
        return TRUE;
    }

     4.4在CCocoToolDlg的OnInitDialog()方法中调用 CreateCocos2dXWindow()

    m_cocosWin.CreateCocos2dXWindow();

    5.利用类视图为CCocoWin添加如下方法

    代码实现如下:

    void CCocoWin::OnTimer(UINT_PTR nIDEvent)
    {
        //我们写一个renderWorld函数代表Cocos2d-x的世界渲染  
        cocos2d::CCApplication::sharedApplication()->renderWorld();  
        CWnd::OnTimer(nIDEvent);  
    }
    
    
    void CCocoWin::OnDestroy()
    {
        //在Cocos2d-x的引擎文件CCEGLView_win32.cpp中CCEGLView::release()会再次发送调用DestroyWindow,所以这里用变量m_bInitCocos2dX做下判断,避免二次销毁  
        if(TRUE == m_bInitCocos2dX)  
        {  
            //退出将m_bInitCocos2dX设为FALSE  
            m_bInitCocos2dX = FALSE;  
            //释放定时器资源  
            KillTimer(1);  
            //调用显示设备单件实例对象的end函数  
            CCDirector::sharedDirector()->end();  
            //处理一次下一帧,必须调用.  
            CCDirector::sharedDirector()->mainLoop();  
            CWnd::OnDestroy();  
        }  
    }
    
    
    void CCocoWin::OnSize(UINT nType, int cx, int cy)
    {
        CWnd::OnSize(nType, cx, cy);  
        // TODO: 在此处添加消息处理程序代码  
        if(TRUE == m_bInitCocos2dX)  
        {  
            CRect   tClientRect;  
            GetClientRect(&tClientRect);  
            //重新设置窗口大小及投影矩阵  
            CCEGLView::sharedOpenGLView()->resize(tClientRect.Width(),tClientRect.Height());  
            CCDirector::sharedDirector()->reshapeProjection(CCSizeMake(tClientRect.Width(),tClientRect.Height()));  
    
        }
    }

    6.CCEGLView做如下修改

     头文件

        virtual bool Create(bool bCreateWin=true,HWND hWnd=NULL);
    public:
        bool m_bIsSelfCreWin;//是否cocos自己创建了窗口
    
    static CCEGLView* sharedOpenGLView(bool bCreateWin=true,HWND hWnd=NULL);//bCreateWin是否自己创建窗口,hWnd已有的MFC窗口句柄

    cpp

    void CCEGLView::centerWindow()
    {
        if (! m_hWnd||!m_bIsSelfCreWin)
        {
            return;
        }
    ....
    
    }
    
    
    bool CCEGLView::Create(bool bCreateWin,HWND hWnd)
    {
        bool bRet = false;
        do
        {
            CC_BREAK_IF(m_hWnd);
    
            m_bIsSelfCreWin=bCreateWin;
    
            if (bCreateWin)
            {
    
                HINSTANCE hInstance = GetModuleHandle( NULL );
                WNDCLASS  wc;        // Windows Class Structure
    
                // Redraw On Size, And Own DC For Window.
                wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
                wc.lpfnWndProc    = _WindowProc;                    // WndProc Handles Messages
                wc.cbClsExtra     = 0;                              // No Extra Window Data
                wc.cbWndExtra     = 0;                                // No Extra Window Data
                wc.hInstance      = hInstance;                        // Set The Instance
                wc.hIcon          = LoadIcon( NULL, IDI_WINLOGO );    // Load The Default Icon
                wc.hCursor        = LoadCursor( NULL, IDC_ARROW );    // Load The Arrow Pointer
                wc.hbrBackground  = NULL;                           // No Background Required For GL
                wc.lpszMenuName   = m_menu;                         //
                wc.lpszClassName  = kWindowClassName;               // Set The Class Name
    
                CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());
    
                // center window position
                RECT rcDesktop;
                GetWindowRect(GetDesktopWindow(), &rcDesktop);
    
                WCHAR wszBuf[50] = {0};
                MultiByteToWideChar(CP_UTF8, 0, m_szViewName, -1, wszBuf, sizeof(wszBuf));
    
                // create window
                m_hWnd = CreateWindowEx(
                    WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,    // Extended Style For The Window
                    kWindowClassName,                                    // Class Name
                    wszBuf,                                                // Window Title
                    WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,        // Defined Window Style
                    0, 0,                                                // Window Position
                    //TODO: Initializing width with a large value to avoid getting a wrong client area by 'GetClientRect' function.
                    1000,                                               // Window Width
                    1000,                                               // Window Height
                    NULL,                                                // No Parent Window
                    NULL,                                                // No Menu
                    hInstance,                                            // Instance
                    NULL );
    
                
            }else
            {
                m_hWnd=hWnd;
            }
    
            CC_BREAK_IF(! m_hWnd);
    
            bRet = initGL();
            if(!bRet) destroyGL();
            CC_BREAK_IF(!bRet);
    
            s_pMainWindow = this;
            bRet = true;
        } while (0);
    
    #if(_MSC_VER >= 1600)
        m_bSupportTouch = CheckTouchSupport();
        if(m_bSupportTouch)
        {
            m_bSupportTouch = (s_pfRegisterTouchWindowFunction(m_hWnd, 0) != 0);
        }
    #endif /* #if(_MSC_VER >= 1600) */
    
        return bRet;
    }
    
    
    
    CCEGLView* CCEGLView::sharedOpenGLView(bool bCreateWin,HWND hWnd)
    {
      
        if (s_pEglView == NULL)
        {
            s_pEglView = new CCEGLView();
            if(!s_pEglView->Create(bCreateWin,hWnd))
            {
                delete s_pEglView;
                s_pEglView = NULL;
            }
        }
    
        return s_pEglView;
    }

    7.CCEGLView做如下修改

    头文件添加方法

        //帧循环调用渲染  
        virtual bool renderWorld(); 

    cpp

    bool CCApplication::renderWorld()
    {
        static LARGE_INTEGER nFreq;
        static LARGE_INTEGER nLast;
        static LARGE_INTEGER nNow;
        static bool sbinit=true;
    
        //只执行一次
        if (sbinit)
        {
            QueryPerformanceFrequency(&nFreq);
            QueryPerformanceCounter(&nLast);
            sbinit=false;
        }    
        // Get current time tick.
        QueryPerformanceCounter(&nNow);
    
        // If it's the time to draw next frame, draw it, else sleep a while.
        if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)
        {
            nLast.QuadPart = nNow.QuadPart;
            CCDirector::sharedDirector()->mainLoop();
    
            return true;
        }
    
    
        return false;
        
    }
    int CCApplication::run()
    {
        PVRFrameEnableControlWindow(false);
    
    
        // Main message loop:
        MSG msg;
        LARGE_INTEGER nFreq;
        LARGE_INTEGER nLast;
        LARGE_INTEGER nNow;
    
        QueryPerformanceFrequency(&nFreq);
        QueryPerformanceCounter(&nLast);
    
        // Initialize instance and cocos2d.
        if (!applicationDidFinishLaunching())
        {
            return 0;
        }
    
        CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
        //pMainWnd->centerWindow();
        ShowWindow(pMainWnd->getHWnd(), SW_SHOW);
    
        //cocos自己创建的窗口才要循环处理消息
        bool bloop=CCEGLView::sharedOpenGLView()->m_bIsSelfCreWin;
        if (bloop)
        {
            while (1)
            {
                if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    // Get current time tick.
                    QueryPerformanceCounter(&nNow);
    
                    // If it's the time to draw next frame, draw it, else sleep a while.
                    if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)
                    {
                        nLast.QuadPart = nNow.QuadPart;
                        CCDirector::sharedDirector()->mainLoop();
                    }
                    else
                    {
                        Sleep(0);
                    }
                    continue;
                }
    
                if (WM_QUIT == msg.message)
                {
                    // Quit message loop.
                    break;
                }
    
                // Deal with windows message.
                if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
    
            return (int) msg.wParam;
        }
    
    
        return 0;
    }

    8.新建个Classes文件夹,并把AppDelegate两个文件复制过去,在VS中右击包含到工程里

     9.把工程的工作目录指向Resources文件夹,可以是以前的COCOS工程的Resources目录

    如果出现类似 error LNK2005: "void * __cdecl operator new(unsigned int)的错误,参考

    http://m.blog.csdn.net/blog/dotphoenix/13511863

    运行效果:

    具体修改的思路不做详细说明,具体请参考

    http://blog.csdn.net/honghaier/article/details/8009046

  • 相关阅读:
    多任务并行
    不同方法来移动数据库(更改磁盘时用)(转)
    ASP.NET执行SQL超时的解决方案
    SQL Server 简单模式下,误删除堆表记录如何恢复(绕过页眉校验) (转)
    关于跟踪标记
    .NET分布式事务处理
    安装SQL Server 2005时出现COM+的警告/错误,下面是微软给出的解决方法。
    PHP中如何获取多个checkbox的值
    C# 模拟post数据提交时 出现如下错误: System.Net.WebException: 远程服务器返回错误: (417) Expectation Failed 的解决办法
    winform出现"LC.exe"已退出,代码为1
  • 原文地址:https://www.cnblogs.com/gamesky/p/3668223.html
Copyright © 2011-2022 走看看