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(,,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();
//调用显示设备单件实例对象的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 = ; // No Extra Window Data
wc.cbWndExtra = ; // 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) && != GetLastError()); // center window position
RECT rcDesktop;
GetWindowRect(GetDesktopWindow(), &rcDesktop); WCHAR wszBuf[] = {};
MultiByteToWideChar(CP_UTF8, , m_szViewName, -, 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
, , // Window Position
//TODO: Initializing width with a large value to avoid getting a wrong client area by 'GetClientRect' function.
, // Window Width
, // 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 (); #if(_MSC_VER >= 1600)
m_bSupportTouch = CheckTouchSupport();
if(m_bSupportTouch)
{
m_bSupportTouch = (s_pfRegisterTouchWindowFunction(m_hWnd, ) != );
}
#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 ;
} CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
//pMainWnd->centerWindow();
ShowWindow(pMainWnd->getHWnd(), SW_SHOW); //cocos自己创建的窗口才要循环处理消息
bool bloop=CCEGLView::sharedOpenGLView()->m_bIsSelfCreWin;
if (bloop)
{
while ()
{
if (! PeekMessage(&msg, NULL, , , 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();
}
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 ;
}
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
Cocos2d-X 2.2嵌入MFC的子窗口的更多相关文章
- MFC关闭子窗口 如何把父窗口也一起关闭
在子窗口OnClose() 消息里添加: GetParent()->DestroyWindow();//子窗口关闭 父窗口也同样关闭
- MFC子窗口和父窗口
转载声明: 本文转载自:http://www.cnblogs.com/BeyondTechnology/archive/2011/03/25/1995934.html 感谢BeyondTechnolo ...
- MFC子窗口和父窗口(SetParent,SetOwner)
一.概念和区别 在windows系统中,每个窗口对象都对应有一个数据结构,形成一个list链表.系统的窗口管理器通过这个list来获取窗口信息和管理每个窗口.这个数据结构中有四个数据用来构建list, ...
- VTK嵌入MFC同步显示
使用VTK嵌入MFC,实现四视图更新,机制和细节参考原文. 原文链接:http://blog.csdn.net/www_doling_net/article/details/8939115 原文代码: ...
- MFC多文档程序启动无子窗口的实现
刚学MFC的我们,肯定会从一个基本MFC程序开始. 而VC++6.0的MFC基础类提供了三种创建方式:单文档.多文档.对话框. 当我们创建多文档应用程序的时候,会自动启动一个子窗口. 在我们平时使用软 ...
- windows窗口分析,父窗口,子窗口,所有者窗口
(本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++.Windows编程及MFC经验,还得有一定动手能力.文中可能出现一些术语不统一的现象 ...
- 转载VC6.0 子窗口和父窗口
这个是我周一在一家公司做的上机题中的一道,当场没做出来.我当时只跟考官说了设计思路,是带回来查了几本资料书之后才完成的.因为有半个学期没用VC开发了……,最近一直都在实践ASP.NET相关的…… 建立 ...
- FineUI小技巧(5)向子窗口传值,向父窗口传值
前言 FineUI中经常会用到启用IFrame的Window控件,这样有助于从物理上进行代码解耦和.IFrame的引入就会涉及传值问题,如何在父窗口和子窗口之间相互传值呢? 向子窗口传值 向子窗口传值 ...
- 第十三篇:在SOUI中使用有窗口句柄的子窗口
前言: 无论一个DirectUI系统提供的DUI控件多么丰富,总会有些情况下用户需要在DUI窗口上放置有窗口句柄的子窗口. 为了和无窗口句柄的子窗口相区别,这里将有窗口句柄的子窗口称之为真窗口. 每一 ...
随机推荐
- DHCPv6 server port and DHCPv6 client port
The DHCPv6 draft says that, the port numbers for client and agents are given as 546 & 547 在wires ...
- jAVA HDU1001题
import java.util.Scanner;public class Main { public static void main(String args[]) { Scanner cin=ne ...
- Nginx/LVS/HAProxy负载均衡软件的优缺点详解(转)
PS:Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,参考了一些资料,结合自己的一些使用经验,总结一下. 一般对负载均衡的使用是随着网站规模的提升根据不 ...
- java class 文件解析
参考下面两个文章对一个class文件进行解析: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.6 htt ...
- Java实现堆排序
import java.util.Scanner; /*堆是一种数据结构,类似于一棵完整的二叉树. * 思想:堆的根节点值最大(最小),将无序序列调整成一个堆,就能找出这个序列的最大值(最小值),将找 ...
- Android开发--UI之Bundle的使用
Android开发–UI之Bundle的使用 最近,把之前学过的东西大体的整理了以下,并且想把学过的心得分享给大家.我自己做了一个小小的demo,以便说明具体的应用. 这里的两个界面是通过第一个界面输 ...
- mysql脚本mysql_safe解释、mysql.sock文件、mysql_install_db
1.首先解释下,启动mysql时为何会调用mysql_safe脚本来启动mysql [root@localhost ~]# /etc/init.d/mysqld start 正在启动 mysqld: ...
- fedora 23 安装genymotion解决方案
由于学习android开发,都说genymotion模拟器给力,我就尝试了下,安装过程参考 :但出现这种错误:缺少库 libjpeg.so.8 ,我就各种goole和百度找到库(链接地址),解压之后放 ...
- C语言-求1-20的阶乘的和(函数的递归)
// // main.c // C语言 // // Created by wanghy on 15/9/5. // Copyright (c) 2015年 wanghy. All rights ...
- [转]:移动端H5页面高清多屏适配方案
原文链接:http://www.tuicool.com/articles/YJviea 背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们 ...