好的,这是一段针对你提供的易语言代码的描述,适合用于论坛发帖,并明确指出了代码存在的问题和无法运行的状态:
帖子标题: 【求助/讨论】尝试将 DirectComposition C++ ApplyEffects 示例翻译为易语言 (代码无法运行)
帖子内容:
大家好,
我正在尝试学习和使用 Windows 的 DirectComposition API,并将微软官方的 C++ 示例 ApplyEffects
翻译成易语言。
这个示例的预期功能是:
OPAQUE
)。TRANSPARENT
)。我根据 C++ 示例的逻辑,编写了以下的易语言代码。代码结构大致如下:
DemoApp
类: 封装了应用程序的主要逻辑,包括窗口句柄、Direct3D/DirectComposition 设备指针、Visual 指针等。Initialize
, InitializeDirectCompositionDevice
, CreateResources
): 创建 D3D11 设备、DXGI 设备、DirectComposition 设备和窗口目标,并加载 GDI 位图资源。RunMessageLoop
): 标准的 Windows 消息处理循环。WndProc
: 窗口过程函数,处理 WM_PAINT
, WM_MOUSEMOVE
, WM_LBUTTONDOWN
, WM_DESTROY
等消息。OnPaint
: 在 WM_PAINT
中创建 IDCompositionVisual
,调用 MyCreateGDIRenderedDCompSurface
将 GDI 位图绘制到 Surface 上,设置 Visual 的内容、位置和初始透明度,并提交显示。OnMouseMove
: 根据鼠标坐标判断是否在图片区域内,调用 SetVisualOpacity
改变透明度。OnClientClick
: 判断点击位置,如果在图片内则调用 RotateVisual
。SetVisualOpacity
: 使用 IDCompositionEffectGroup
来设置 IDCompositionVisual
的透明度属性。RotateVisual
: 使用 IDCompositionRotateTransform3D
和 IDCompositionAnimation
来实现 Visual 的 3D 旋转动画。MyCreateGDIRenderedDCompSurface
: (问题所在) 尝试创建一个 DirectComposition Surface,获取其 DC,然后使用 GDI 的 BitBlt
将加载的 HBITMAP 绘制上去。LoadResourceGDIBitmap
: 从资源加载 HBITMAP。SafeRelease
: 用于安全释放 COM 接口的辅助函数。.版本 2
.支持库 spec
.支持库 shellEx ' 可能需要数学函数和 GuidFromString
' --- 常量定义 ---
#常量 OFFSET_X, 整数型, 20
#常量 OFFSET_Y, 整数型, 20
#常量 TRANSPARENT, 小数型, 0.5 ' C++ 是 float,易语言用小数型
#常量 OPAQUE, 小数型, 1.0
#常量 IDB_PENGUINS, 整数型, 101 ' 假设资源 ID
' --- 全局子程序:安全释放 COM 对象 ---
.子程序 SafeRelease, , , 安全释放 COM 接口指针
.参数 pInterface, 整数型, 参考, COM 接口指针变量
.如果真 (pInterface ≠ 0)
IUnknown_Release (pInterface) ' 依赖 IUnknown_Release 包装器
pInterface = 0
.如果真结束
' --- 主程序类 ---
.程序集 DemoApp_ApplyEffects
.程序集变量 m_hwnd, 整数型
.程序集变量 m_hBitmap, 整数型
.程序集变量 m_pD3D11Device, 整数型
.程序集变量 m_pDevice, 整数型 ' DComp Device
.程序集变量 m_pCompTarget, 整数型
.程序集变量 m_pVisual, 整数型
.程序集变量 m_bitmapWidth, 整数型
.程序集变量 m_bitmapHeight, 整数型
.程序集变量 m_fOverImage, 逻辑型 ' 鼠标悬停标志
' (此处省略 _初始化, _销毁, Initialize, InitializeDirectCompositionDevice, CreateResources, DiscardResources, RunMessageLoop 的详细代码 - 与帖子中提供的代码一致)
' ...
.子程序 OnPaint, 整数型, 公开
.局部变量 hr, 整数型
.局部变量 pSurface, 整数型
' (此处省略 OnPaint 的详细代码 - 与帖子中提供的代码一致)
' ...
返回 (hr)
.子程序 OnClientClick, 整数型, 公开, 处理 WM_LBUTTONDOWN 消息
.参数 xPos, 整数型, , 鼠标 X 坐标
.参数 yPos, 整数型, , 鼠标 Y 坐标
.局部变量 hr, 整数型
' (此处省略 OnClientClick 的详细代码 - 与帖子中提供的代码一致)
' ...
返回 (hr)
.子程序 OnMouseMove, 整数型, 公开, 处理 WM_MOUSEMOVE 消息
.参数 xPos, 整数型, , 鼠标 X 坐标
.参数 yPos, 整数型, , 鼠标 Y 坐标
.局部变量 hr, 整数型
.局部变量 isOver, 逻辑型
' (此处省略 OnMouseMove 的详细代码 - 与帖子中提供的代码一致)
' ...
返回 (hr)
.子程序 RotateVisual, 整数型, 公开, 应用 3D 旋转动画到 Visual
.参数 pVisual, 整数型, , 要旋转的 Visual 指针
.参数 degrees, 小数型, , 旋转角度 ' C++ 是 float
.局部变量 hr, 整数型
.局部变量 pAnimation, 整数型
.局部变量 pRotate3D, 整数型
.局部变量 pEffectGroup, 整数型
' (此处省略 RotateVisual 的详细代码 - 与帖子中提供的代码一致)
' ...
返回 (hr)
.子程序 SetVisualOpacity, 整数型, 公开
.参数 pVisual, 整数型
.参数 opacity, 小数型 ' C++ 是 float
.局部变量 pEffectGroup, 整数型
.局部变量 hr, 整数型
' (此处省略 SetVisualOpacity 的详细代码 - 与帖子中提供的代码一致)
' ...
返回 (hr)
.子程序 MyCreateGDIRenderedDCompSurface, 整数型, 公开
.参数 hBitmap, 整数型
.参数 ppSurface, 整数型, 参考
.局部变量 hr
.局部变量 bmpSize
.局部变量 hBitmapOld
.局部变量 hSurfaceDC
.局部变量 hBitmapDC
.局部变量 pDXGISurface
.局部变量 pDCSurface
.局部变量 pointOffset, POINTAPI
.局部变量 bmp, BITMAP
.局部变量 _uuidOf, 字节集
' (此处省略 MyCreateGDIRenderedDCompSurface 的详细代码 - 与帖子中提供的代码一致)
' --- 问题点在这里 ---
.如果真 (SUCCEEDED (hr))
' !!! 此调用失败,返回 E_INVALIDARG (0x80070057) !!!
hr = IDXGISurface1_GetDC (pDXGISurface, 0, hSurfaceDC)
.如果真结束
' ... 后续 GDI 操作也因此无法执行 ...
返回 (hr)
.子程序 LoadResourceGDIBitmap, 整数型, 公开
.参数 resourceID, 整数型 ' 修改为接受整数 ID
.参数 hbmp, 整数型, 参考
.局部变量 hInst, 整数型
hInst = GetModuleHandleW(0)
hbmp = LoadImageW (hInst, resourceID, #IMAGE_BITMAP, 0, 0, #LR_DEFAULTCOLOR)
返回 (选择 (hbmp ≠ 0, #S_OK, #E_FAIL))
' --- 窗口过程 和 主程序入口 ---
' (此处省略 WndProc 和 __启动窗口_创建完毕 的详细代码 - 使用全局变量 g_pCurrentDemoApp 的版本)
' ...
!!! 重要警告:此代码目前无法正常运行 !!!
主要问题在于 MyCreateGDIRenderedDCompSurface
子程序。 在尝试将 GDI 位图绘制到 DirectComposition Surface 时,调用 IDXGISurface1_GetDC
这一步会失败,返回错误码 0x80070057 (E_INVALIDARG)
。
根据之前的讨论和分析,这极有可能是因为通过 IDCompositionDevice::CreateSurface
创建的 Surface 默认不支持 GDI 设备上下文 (DC) 的获取。DirectComposition 的 Surface 主要设计用于 Direct2D 或 Direct3D 渲染。直接在其上使用 GetDC
并进行 GDI 操作(如 BitBlt
)是不被支持的。
其他潜在问题:
IDComposition*
, IDXGI*
, ID3D11*
等接口方法都有对应的、功能正确的易语言包装子程序。如果这些包装器有误,代码也会失败。RotateVisual
中调用 IDCompositionAnimation_AddCubic
和 End
的参数是基于对 C++ 示例的理解,可能与实际易语言包装器的参数不完全匹配,需要核对。g_pCurrentDemoApp
来在 WndProc
中访问类实例,这是一个可行的变通方法,但在更复杂的应用中可能不是最佳实践。发帖目的:
我将这段(有问题的)代码发出来,主要是希望:
IDCompositionSurface
上?(正确的方法很可能是使用 Direct2D 进行绘制,而不是 GetDC/BitBlt)。如果大家对如何修复 MyCreateGDIRenderedDCompSurface
中的 GetDC
问题(或者更好的替代方案,如 Direct2D)有任何建议或经验,恳请不吝赐教!感谢!
使用说明:
#IDB_PENGUINS
为你实际使用的位图资源 ID。IUnknown_Release
, IDCompositionDevice_CreateVisual
等)是你项目中实际使用的名称。欢迎光临 精易论坛 (https://125.confly.eu.org/) | Powered by Discuz! X3.4 |