您的当前位置:首页正文

MFC单文档模式下的D3D应用

2024-07-14 来源:步旅网
q。 维普资讯 http://www.cqvip.com

再囊一譬瑟拳鬃 编程语言 PROGRAM l ANGUAG MFC单文档模式下的D3D应用 申 晓 摘要本文介绍在MFC环境下编写D3D程序。 ● 关键词 MFC,DirectX VC中的DirectX向导生成的是Win32应用程序,虽然速 度较快。但是在做一些简单示例或者工具时,如果和界面的交 互操作比较多,就得自己写那些消息映射,很繁琐,不如 辅助工作都已做好,下面该对视图类动点小手术了。首先 在头文件里改成多重继承,就是再添加public CD3DApplication即可。原封不动地复制需要重载的虚函数和 MFC来的方便。通过阅读DX向导生成代码发现,略作修改就 可达到目的。 相关的成员变量。其它虚函数的实现和原来一样,主要是这个 Run方法略有不同,修改它以便支持窗口的任意缩放,关键代 码如下: if10=:g_bContinue) 首先生成一个MFC单文档应用程序,再生成一个D3D应 用程序。把D3D的支持文件都复制过来,一共有16个。相关 的头文件包含在sWafx.h里。然后加入所有文件,编译时选择 自动使用预编译头文件,连接时加入相应的库文件,一共有9 个,可以参考D3D应用的设置。为了保持类的可重用性,在 这里添加两个新的方法,第一个是InitWindow方法,用来设置 初始窗口尺寸。 鬈 磐 罄嚣;》 lA 辔  麓 § ; 毪 I SleepI100): continue; ) else ifI2==g-j)Continue) I PauseI1): SAFERELEASEIm pD3D): _1^ void CD3DApplication::InitWindow(INT Width,INT Height) mm—{ _dwCreationWidth=Width; RECT rect; dwCreationHeight=Height; ・ 《 GetCIientRect I&rect): int width=rect.right—rect.1eft; } 黪々《^ int height=rect.bottom—rect.top; 第二个是InitD3D方法,用来初始化D3D环境。其实它和 eate方法基本相同,只是去掉了创建窗口的语句,简 一 原来的Cr一_ _ 单地复制当前视图类的句柄而已。 一 一 m_dwWindowStyle:O: m_hWndApp=hWnd; InitWindow1 width,height): hr=InitD3DI m-hWnd) g_bContinue=1: continue; 一 } 另外,为了防止在继承时成员变量的冲突,这里把所有的 m_hWnd都改成了m_hWndApp。因为现在的视图类已经是子窗 else ifI 1::g_bContinue) { //和原来一样 } 口,所以原先对窗口属性的设置就不适用了。需要修改的地方 一共有3处,两处在Initialize3DEnvironment方法里,一处在 其中g_bContinue是一个全局变量,初始化为0值。它的 状态为2时,表示有WM_SIZE消息发生。另外拖动边框是会 产生WM_ENTERSIZEMOVE和WM_EXITSIZEMOVE消息,这 ToggleFullscreen方法里。处理过程全一样,重新设置最后一个 参数即可。 SetWindowPos I m_hWndApp,0,0,0, I m_rcWindowBounds.right—m_rcWindowBounds.1eft). I m』cWindowBounds.bottom—m_rcWindowBounds.top), SWP_NOZORDER I SWP_NOMOVE): 些都在WindowProc方法中处理。 .fIWMjJSER+0x8001==message) //WM ENTERSIZEMOVE { 与 l.1雾 鬻黔 。 i誊蔓曩 基il叠囊 “ 嚣 黛_ ;豁 囊 蔓 维普资讯 http://www.cqvip.com

鬟 薹篓 譬。 薹耄薹 《 臻 一露j  f察露● 誓II蠢■ 誊 一 j 。 … 一 =㈠ 编程语 PROGRAM l AN( JAG else if(WM—EXITS亿EMOVE==message) f CZzMFC8View pView=(CZzMFC8View ) GetActiveView(): g_bContinue=O: ) else if(WMjJSER 4-0x8002==message) ,, M.EXlTSIZEMOVE f g_bContinue=2: if(pView)pView一>WindowProc(WM_USER -0x8002.4 WParam.IParam): ) else if(WMIjJSER -0x8003==message)//WM I4ZE ) else if(WM_sIZE==message) f |ff m_bWindowed&&m_hWndApp!=NULL) m_dwWindowStyle=GetWindowLong(m_hWndApp, GWLSTYLE): .f(SIZE_MINIMIZED==WParam) f if f m_bClipCursorWhenFullscreen&&!m_bWindowed) ClipCursor(NULL): ) else if(SIZEJ A×IM亿ED==wParam) f if(m.bMinimized)Pause(faIse): m.j)Minimized=false; m_j)Maximized=true; g_bContinue=2: ) else if(SIZE_RESTORED==wParam) f .f(m_bMaximized) f m_j)Maximized=faIse; g_bContinue=2: ) else.f(m_bMinimized) f Pause(faIse): f/Unpause since we re no longer minimized m_j)Minimized=false; g_bContinue=2: ) ) ) 上面代码中,之所以响应的是自定义的消息,是因为主窗 口尺寸变化的通知是由CMainFrame发出的,那么调用就放在 主窗口的WindowProc方法中,而处理在它的视图类里。 .f(WM—ENTERSIZEMOVE==message) f CZzMFC8View pView=(CZzMFC8View}) GetActiveView(): if(pView)pView一>WindowProc(WM_uSER -40x8001. wParam.1Param): ) f CZzMFC8View pView=(CZzMFC8View ) GetActiveView(): ifIpView)pView一>WindowProcIWM SER 4-0x8003, wParam.IParam) ) 然后在单独的线程里启动D3D应用,就可以看到渲染效 果了。 DWORD WINAPI D3dProc(LPVOID IpParameter) f CZzMFC8View pMainView=(CZzMFC8View ) IpParameter; HWND hWnd=pMainView一>GetSafeHwnd(): RECT rect=f0): pMainView一>GetClientRect(&rect): int width=rect.right—rect.1eft; int height=rect.bottom—rect.top; pMainView一>lnitWindow(width,height) if(FAILED(pMainView一>InitD3D(hWnd)))return (一1): pMainView一>Run(): return(0): ) void CZzMFC8View::OnMenuitem32771() f //开始 //TODO:Add your command handler code here HANDLE hD3dThrd; DWORD ThrdlD; g_bContinue=1: hD3dThrd=CreateThread(0.0.D3dProc.this. CREATE—sUSPENDED.&ThrdlD): ResumeThread f hD3dThrd): ) 现在可以像平常一样映射消息,还能接收键盘和鼠标消 息,操作各种变换,比以前方便多了。最后还要注意一点,就 是加入新的消息映射后再编译,可能会出现3O多个关于申请 内存方面的错误。我推测可能是编译顺序的问题,具体原因不 太清楚。只要选择Build菜单的Clean,再重新编译即可。附 带工程是在VC6.04-Win2000下调试通过,需要安装DX9 SDK开发包。 (收稿日期:2006年2月18日) 

因篇幅问题不能全部显示,请点此查看更多更全内容