在C中托管Silverlight

我有点在我头上,想要一些关于如何去做的建议。

基本上我想做的是能够在我的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

有什么想法可能是错的?

编辑4:我退后一步我使用“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); 
    }
}

然后我运行通常的Windows消息处理程序循环与GetMessage,TranslateMessage和DispatchMessage。

然而,我所得到的还是黑色。我究竟做错了什么?

我似乎从“ActivateXcpControl”中的以下调用获取E_FAIL:

hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);
我已经测试了这里的代码项目:http://www.codeproject.com/KB/atl/Host_Silverlight_In_ATL.aspx在Visual Studio 2010.这是需要使其工作:

>在VS 2010下加载它,并将其转换为VS 2010(不关心backupgs日志等)
>删除注册后构建事件(“$(TargetPath)”/ RegServer),它只用于在Projet中注册COM组件。你也可以让这个事件,只要忘记错误,如果你愿意的话。
>我不得不在XcpControlHost.cpp做一个小的改动。

这是变化:

HRESULT CXcpControlHost::CreateXcpControl(HWND hWnd) 
{
    AtlAxWinInit();
    CoInitialize(NULL); // add this line to initialize COM
    ... 
}

它工作(我正在使用Silverlight 4运行Windows 7)。

这是真的要走了。

一个说法:在示例中,作者不使用从这里可用的官方xcpctrl.idl文件:http://msdn.microsoft.com/en-us/library/cc296246(VS.95).aspx。相反,他重新定义了所有接口和GUID,这不是必需的。您可以将xcpctrl.idl添加到Visual Studio 2010并编译,这将触发将创建3个以下文件的MIDL编译器:xcpctrl_h.h,xcpctrl_i.c,xcpctrl_p.c。一旦编译完成,您可以将它们添加到项目中。

http://stackoverflow.com/questions/4768619/hosting-silverlight-in-c

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在C中托管Silverlight