DirectX 之 DirectDraw 窗口模式
来源:互联网 发布:排序算法 java 编辑:程序博客网 时间:2024/05/16 08:37
首先, 窗口模式下创建一个 IDirectDraw 接口对象和全屏模式下是一样的, 不同的是, 在选择协作模式和不能改变屏幕分辨率. (当然你坚决要改变, 一定要有礼貌的改变.)
// 设置协作级别,窗口化下使用 DDSCL_NORMAL 标志.
if (FAILED(m_x2d_lpDDraw->SetCooperativeLevel(m_x2d_hWnd, DDSCL_NORMAL)))
return (E_FAIL);
// 使用 DirectDraw 接口对象创建 DirectDrawSurface 主页面对象.
DDSURFACEDESC2 ddsd;
INIT_DXSTRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (FAILED(m_x2d_lpDDraw->CreateSurface(&ddsd, &m_x2d_lpDDrawPrimarySurface, NULL)))
return (E_FAIL);
// 创建一个离屏页面
INIT_DXSTRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
if (FAILED(m_x2d_lpDDraw->CreateSurface(&ddsd, &m_x2d_lpDDrawBackSurface, NULL)))
return (E_FAIL);
/* 在这里省略掉给这个离屏页面附属上裁剪器,
下面使用到这个离屏页面的是已经附属上裁减器的. */
LPDIRECTDRAWCLIPPER lpDDClipper = NULL;
// 创建裁剪器.
if (FAILED(m_x2d_lpDDraw->CreateClipper(0, &lpDDClipper, NULL)))
return (E_FAIL);
// 与窗口工作区关联.
if (FAILED(lpDDClipper->SetHWnd(0, m_x2d_hWnd)))
{
SAFE_RELEASE(lpDDClipper);
return (E_FAIL);
}
if (FAILED(m_x2d_lpDDrawPrimarySurface->SetClipper(lpDDClipper)))
{
SAFE_RELEASE(lpDDClipper);
return (E_FAIL);
}
SAFE_RELEASE(lpDDClipper);
给主页面设置裁剪器, 是为了窗口在超出(超出屏幕的显示部分)桌面时能正常工作.实际上主页面就是你的桌面.
现在桌面上有许多窗口在运行, 我们不能胡乱的在桌面上乱画, 否则其他的窗口可能抱怨. 我们要知道我们的窗口工作区位置, 然后我们在这个工作区内工作.
GetClientRect(m_x2d_hWnd, &m_x2d_ClientRect);
ClientToScreen(m_x2d_hWnd, (LPPOINT)&m_x2d_ClientRect);
ClientToScreen(m_x2d_hWnd, (LPPOINT)&m_x2d_ClientRect+1);
m_x2d_ClientRect 保存的是我们的窗口工作区(客户区)位置.
然后我们可能这样用:
m_x2d_lpDDrawPrimarySurface->Blt(&m_x2d_ClientRect, m_x2d_lpDDrawBackSurface, NULL, DDBLT_WAIT, NULL));
这个位转换目标位置就是我们的工作区. 因为我们给主页面附属了裁剪器, 所以不能再用BltFast来位转换了.
如果我们像这样用, 可能看到一个杂乱的桌面.
RECT rct = { 0, 0, 300, 123};
m_x2d_lpDDrawPrimarySurface->Blt(&rct, surface, NULL, DDBLT_WAIT, NULL));
这样的后果是:
在桌面的 X = 0, Y = 0 位置, 画上 宽 = 300, 高 = 123 的 surface 图形.
在窗口模式下, 一定要正确获得自己的工作区, 当窗口移动或者改变大小, 我们因该有所行动.
case WM_MOVE:
case WM_SIZE:
GetClientRect(m_x2d_hWnd, &m_x2d_ClientRect);
ClientToScreen(m_x2d_hWnd, (LPPOINT)&m_x2d_ClientRect);
ClientToScreen(m_x2d_hWnd, (LPPOINT)&m_x2d_ClientRect+1);
break;
还有, 当窗口失去焦点(活动), 应该停止在继续向主页面绘画. 否则, 你画的将覆盖掉在窗口上的其他窗口的内容.
case WM_ACTIVATE:
{
switch((LOWORD(wParam)))
{
case WA_ACTIVE:
case WA_CLICKACTIVE:
// 活动, 可以继续向主页面绘画了.
Active(true);
break;
case WA_INACTIVE:
// 不活动, 停止向主页面绘画.
Active(false);
break;
default:
break;
}
- DirectX 之 DirectDraw 窗口模式
- DirectX 之 DirectDraw 窗口模式(转载)
- 窗口模式下使用DirectDraw
- DirectX窗口模式一
- DirectX窗口模式二
- DirectDraw窗口模式下的动画
- directx(directDraw)与GDI
- DirectX简介 第二篇 DirectDraw简介
- DIRECTX中独占模式与窗口模式的切换
- DIRECTX中独占模式与窗口模式的切换(译)
- [DirectDraw]显示模式
- 基于窗口的DirectDraw编程
- 基于窗口的DirectDraw编程
- 基于窗口的DirectDraw编程
- 通向DirectDraw之捷径
- 新手入门之DirectDraw入门
- DirectX Directdraw 用一种 颜色 填充 满屏 画面
- directx 透明窗口
- 什么时候需要用存储过程
- ASP.NET与static
- Java线程同步锁解决共享数据安全
- /etc/fstab文件内容格式分析
- 转:.NET中的安全性之数字签名、数字证书、强签名程序集、反编译
- DirectX 之 DirectDraw 窗口模式
- ARToolKit硬件选型与配置
- blazeds通信相关配置
- Color:颠覆网络社交模式
- 动手写第一个Windows程序
- [ASP.NET]类型初始值设定项引发异常(转)
- oracle public作用
- 希望更多资源共享~~
- 宏定义中使用do{}while(0)的好处