好的,现在我想创建一个COM接口来表示我的自定义表控件将采用的数据模型,而不是使用在表及其父窗口之间传递的消息。该表当前显示文本,图像和复选框。实现该接口的对象应该存在于单线程公寓中。
我知道我可以将BSTR
用于字符串,并使用一些整数类型作为复选框布尔值,并且已经建立了所有权转让的约定,我可以遵循这些约定。但我不确定位图。
我想要做的是调用模型对象的GetCellData()
方法,该方法将行,列和指针指向模型将放置单元格的VARIANT
&#39} ; s数据。我只需要在处理它之前绘制一次位图。 Since bitmaps can only be selected into one DC at a time,我需要成为位图的独家所有者,但只是暂时的。
我试图寻找微软的类似COM接口已经做到了这一点,但没有找到任何东西(或者没有使用正确的术语)。
所以我的问题是:
如何将HBITMAP
传递给VARIANT
?我最好的猜测是将其存储在byref
字段中。
我应该如何协商HBITMAP
的所有权?我看到两种可能性:a)要求每次都要发送HBITMAP
的副本,表格控件本身调用DeleteObject()
,或b)借用HBITMAP
(使用它)然后有另一个模型方法FinishedWithBitmap()
,完成时将调用它。这些规则中的任何一个都比其他规则更适合COM的规则吗?或者我完全有错误的想法? STGMEDIUM
会合适吗?
我应该指出HBITMAP
被视为32位ARGB(也就是说,它们被AlphaBlend()
绘制)。我发现IPicture
但这似乎不适合这种格式。
感谢。
更新
好的,这是一般的想法。让我们说model
是表模型,它是服务器。表本身就是客户端。在客户端中绘制位图单元格的代码如下所示:
HBITMAP bitmap;
ITableModel_GetCellData(model, row, column, &bitmap);
// draw the bitmap (CreateCompatibleDC(), SelectObject(), AlphaBlend())
此时客户端不再需要bitmap
。我问COM是否有规范的方法来定义HBITMAP
对客户端绘图代码的所有权,所以作为客户作者我会知道我是否应该写
// the client owns the bitmap
DeleteObject(bitmap);
或
// the model still owns bitmap
// we need to explicitly give it back because only one DC can have a bitmap selected at one time
// since each client has the DCs, the server needs to know when it's safe to give the same HBITMAP to another client
ITableModel_ReturnBitmap(model, bitmap);
(IDataObject以STGMEDIUM.pUnkForRelease
的形式提供了解决此问题的方法。)
答案 0 :(得分:1)
最后我决定采用不同的方法:而不是返回HBITMAP进行绘制,我提供了一个采用HDC并让模型进行绘制的方法。 (DLL将为编写自定义模型的人提供帮助器实现。)其他COM接口(如IImageList)已经这样做了,为什么不这样做:/
我不确定我是否会保留GetCellData()
方法,或者将其拆分为每种数据类型的一个函数。我刚才意识到我需要的另一个列类型是COLORREF
(用于自定义单元格背景颜色;模型列和视图列不等效)。我也不确定我会以同样的方式对SetCellData()
方法做些什么;当用户决定在UI中更改某些内容时(例如,通过选中复选框),它只会被Table视图本身使用,我认为我不会提供直接从表中更改图像的方法,所以...为每种不同的数据类型添加单独的模型函数显然是一个糟糕的想法(特别是如果接口必须在最终确定后保持不变),但VARIANT
看起来越来越不理想。
答案 1 :(得分:0)
这当然是一种方式。实现IDataObject的美妙之处在于对象的使用者可以决定他需要什么格式 - 当然你必须说明你将提供什么。但是,使用延迟渲染,您可以等到他们提供数据之前实际请求数据。