我在這裏有點頭痛,想要提供一些關於如何去做的建議。在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
}
我創建XcpControlHost一個線程中使用的CoInitialize:
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通常窗口消息處理循環。
但是,我仍然得到的是黑暗。我究竟做錯了什麼?
我似乎從「ActivateXcpControl」下面的調用獲取E_FAIL:
hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);
+1這個好主題。我也需要知道這個..因爲我試圖做這些事情:http://stackoverflow.com/questions/4744522/handle-to-silverlight-usercontrol ...和http://stackoverflow.com/questions/4758568 /部署-xbap -with-win32-dll – Nawaz 2011-01-22 15:20:41
哪個版本的Silverlight? – 2011-01-22 17:02:33