1个回答
展开全部
在窗口模式下使用 DirectDraw , 最大的痛苦是不能使用换页操作(Flip). 但是有许多人还是喜欢在窗口模式下进行游戏.
首先, 窗口模式下创建一个 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;
}
}
首先, 窗口模式下创建一个 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;
}
}
参考资料: http://hi.baidu.com/herocxw2005/blog/item/34a7d36ce5d686f7431694e1.html
威孚半导体技术
2024-08-19 广告
2024-08-19 广告
威孚(苏州)半导体技术有限公司是一家专注生产、研发、销售晶圆传输设备整机模块(EFEM/SORTER)及核心零部件的高科技半导体公司。公司核心团队均拥有多年半导体行业从业经验,其中技术团队成员博士、硕士学历占比80%以上,依托丰富的软件底层...
点击进入详情页
本回答由威孚半导体技术提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询