是否有从STA COM对象接收HBITMAP并将其返回的约定?

时间:2015-03-06 03:17:18

标签: winapi com

好的,现在我想创建一个COM接口来表示我的自定义表控件将采用的数据模型,而不是使用在表及其父窗口之间传递的消息。该表当前显示文本,图像和复选框。实现该接口的对象应该存在于单线程公寓中。

我知道我可以将BSTR用于字符串,并使用一些整数类型作为复选框布尔值,并且已经建立了所有权转让的约定,我可以遵循这些约定。但我不确定位图。

我想要做的是调用模型对象的GetCellData()方法,该方法将行,列和指针指向模型将放置单元格的VARIANT&#39} ; s数据。我只需要在处理它之前绘制一次位图。 Since bitmaps can only be selected into one DC at a time,我需要成为位图的独家所有者,但只是暂时的。

我试图寻找微软的类似COM接口已经做到了这一点,但没有找到任何东西(或者没有使用正确的术语)。

所以我的问题是:

  1. 如何将HBITMAP传递给VARIANT?我最好的猜测是将其存储在byref字段中。

  2. 我应该如何协商HBITMAP的所有权?我看到两种可能性:a)要求每次都要发送HBITMAP的副本,表格控件本身调用DeleteObject(),或b)借用HBITMAP(使用它)然后有另一个模型方法FinishedWithBitmap(),完成时将调用它。这些规则中的任何一个都比其他规则更适合COM的规则吗?或者我完全有错误的想法? STGMEDIUM会合适吗?

  3. 我应该指出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的形式提供了解决此问题的方法。)

2 个答案:

答案 0 :(得分:1)

最后我决定采用不同的方法:而不是返回HBITMAP进行绘制,我提供了一个采用HDC并让模型进行绘制的方法。 (DLL将为编写自定义模型的人提供帮助器实现。)其他COM接口(如IImageList)已经这样做了,为什么不这样做:/

我不确定我是否会保留GetCellData()方法,或者将其拆分为每种数据类型的一个函数。我刚才意识到我需要的另一个列类型是COLORREF(用于自定义单元格背景颜色;模型列和视图列不等效)。我也不确定我会以同样的方式对SetCellData()方法做些什么;当用户决定在UI中更改某些内容时(例如,通过选中复选框),它只会被Table视图本身使用,我认为我不会提供直接从表中更改图像的方法,所以...为每种不同的数据类型添加单独的模型函数显然是一个糟糕的想法(特别是如果接口必须在最终确定后保持不变),但VARIANT看起来越来越不理想。

答案 1 :(得分:0)

这当然是一种方式。实现IDataObject的美妙之处在于对象的使用者可以决定他需要什么格式 - 当然你必须说明你将提供什么。但是,使用延迟渲染,您可以等到他们提供数据之前实际请求数据。