【发布时间】:2011-06-13 16:59:25
【问题描述】:
我有点不知所措,想要一些关于如何去做的建议。
基本上,我想做的是能够在我的 C++ 应用程序中渲染和控制 Silverlight。我想要一些东西:
class silverlight_host
{
public:
// Prio 1
silverlight_host(const std::string& filename); // Load a xap file
void draw(void* dest); // Draw with alpha to dest
std::pair<size_t, size_t> get_size(); // Need to know required size of dest
// Prio 2
bool is_dirty() const; // Check for dirty rect since last call to draw
void send_param(const std::string& param); // Send data to silverlight control or call functions. Alternative name maybe, call_function
void set_size(size_t width, size_t height); // Set the size of drawing.
// Prio 3
// Some more nice to have functions, although not as important as those above
double get_desired_frame_rate(); // The desired frame rate which is specified in xap
std::pair<size_t, size_t> get_desired_size(); // The desired size which is specified in xap
void tick(); // Tick a synchronous timeline, disable internal asynchronous timer
void set_param_callback(const std::function<void(const std::string&)>& callback); // Let the xap file call the application
};
说起来容易做起来难。我找到了以下文章Host Silverlight Contorl in C++ 和Communication between C++ Silverlight Host and Silverlight Application。我的问题是,提供的代码在 VS2010 中编译时似乎不起作用,它们创建了一个实际的窗口而不是无窗口控件。发生的事情也没有得到很好的解释,而且我在 COM 和 ATL 知识方面有些缺乏。
我还发现this 似乎比上面的文章有更简单的方法来实现 xcpcontrolhost。
我在msdn 上找到了一些参考信息。 ISilverlightViewer 对我的需求来说似乎很有趣。为了允许无窗口控件,我相信我可能必须实现类似IOleInPlaceSiteWindowless? 的东西。
但是,我在这里有点不知所措,甚至不确定从哪里开始。我想问一些关于我应该从哪里开始的建议,您是否有任何一般性的建议或经验?
编辑:如果可以使这样的实现独立于平台,也会很有趣,虽然相当次要?
EDIT2:我已经从上面的一篇文章中修改了“TestProject”中的代码。我试图删除冗余代码并修复它,以便它在 VS2010 上运行(根据下面的回答)。你可以找到它here。
EDIT3:
我试图实现一个无窗口的 XcpControlHost 类。我查看了 CAxHostWindow 中的代码并尝试重新创建它。我不使用 CAxHostWindow 创建无窗口控件的原因是它不支持 alpha。
它似乎编译得很好,但是当我调用 DrawControl 时,我只得到一个黑框。
XcpContorlHost.h XcpControlHost.cpp
关于可能出现什么问题的任何想法?
EDIT4:我要后退一步。我使用“TestProject”中的代码我想修改 CreateXcpControl(HWND hWnd) 以便能够采用 hWnd == nullptr(无窗口)并使用 OleDraw 将控件绘制到内存。
我试图做的是简单地绕过对“AttachControl”的调用并直接调用“ActivateXcpControl”。我已经用硬编码值替换了 GetClientRect。
STDMETHODIMP XcpControlHost::AttachControl(IUnknown* pUnKnown, HWND hWnd)
{
assert(hWnd == nullptr);
ReleaseAll();
// Removed all hWnd related code
return ActivateXcpControl(pUnKnown);
}
HRESULT XcpControlHost::ActivateXcpControl(IUnknown* pUnKnown)
{
// Lots of code
// GetClientRect(&m_rcPos); // Remove this
m_rcPos.top = 0;
m_rcPos.left = 0;
m_rcPos.right = 720;
m_rcPos.bottom = 576;
// Lots of code
}
我使用 CoInitialize 在线程内创建 XcpControlHost:
void run()
{
struct co_init
{
co_init(){CoInitialize(nullptr);}
~co_init(){CoUninitialize();}
} co;
if(FAILED(CComObject<XcpControlHost>::CreateInstance(&host_)))
throw std::exception("Failed to create XcpControlHost");
if(FAILED(host_->CreateXcpControl()))
throw std::exception("Failed to create XcpControl");
while(GetMessage(&msg, 0, 0, 0))
{
if(!is_running_)
PostQuitMessage(0);
if(msg.message == WM_USER + 1) // Sent from app
OleDraw(host_->m_pUnKnown, DVASPECT_CONTENT, targetDC, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
然后我使用 GetMessage、TranslateMessage 和 DispatchMessage 运行通常的 Windows 消息处理程序循环。
但是,我得到的仍然是黑暗。我做错了什么?
我似乎从“ActivateXcpControl”中的以下调用中得到 E_FAIL:
hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);
【问题讨论】:
-
为这个好话题+1。我还需要知道这一点..因为我试图做这些事情:stackoverflow.com/questions/4744522/… ...和stackoverflow.com/questions/4758568/…
-
Silverlight 的哪个版本?
-
最好是最新的。
标签: c++ silverlight com atl