Tôi hơi ngó qua đầu của tôi ở đây và muốn một số lời khuyên về cách thực hiện.Hosting Silverlight trong C++
Cơ bản những gì tôi muốn làm là có thể hiển thị và điều khiển Silverlight bên trong ứng dụng C++ của tôi. Tôi muốn một cái gì đó như:
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
};
Nói dễ hơn làm. Tôi đã tìm thấy các bài viết sau đây Host Silverlight Contorl in C++ và Communication between C++ Silverlight Host and Silverlight Application. Vấn đề của tôi với những điều này là mã được cung cấp dường như không hoạt động khi được biên dịch trong VS2010 và chúng tạo ra một cửa sổ thực tế thay vì một điều khiển không cửa sổ. Ngoài ra những gì xảy ra không được giải thích rất rõ và tôi hơi thiếu kiến thức về COM và ATL.
Tôi cũng đã tìm thấy this dường như có cách đơn giản hơn để triển khai xcpcontrolhost hơn các bài viết ở trên.
Tôi đã tìm thấy một số thông tin tham chiếu trên msdn. Trường hợp ISilverlightViewer có vẻ khá thú vị cho nhu cầu của tôi. Để cho phép một điều khiển không cửa sổ tôi tin rằng tôi có thể phải thực hiện một cái gì đó như IOleInPlaceSiteWindowless?
Tuy nhiên, tôi khá hơn một chút so với đầu của tôi ở đây và tôi không chắc chắn nên bắt đầu từ đâu. Tôi muốn hỏi một số lời khuyên về nơi tôi nên bắt đầu và nếu bạn có bất kỳ lời khuyên chung hoặc kinh nghiệm với một cái gì đó như thế này?
CHỈNH SỬA: Một cái gì đó cũng sẽ thú vị, mặc dù khá phụ, sẽ là nếu việc triển khai như vậy có thể được làm nền tảng độc lập không?
EDIT2: Tôi đã sửa đổi mã trong "TestProject" từ một trong các bài viết ở trên. Tôi đã cố gắng để loại bỏ mã dự phòng và cố định nó để nó chạy trên VS2010 (theo câu trả lời dưới đây). Bạn có thể tìm thấy nó here.
EDIT3:
Tôi đã cố gắng thực hiện một lớp XcpControlHost cửa sổ. Tôi đã nhìn vào mã trong CAxHostWindow và cố gắng tái tạo nó. Lý do tôi không sử dụng CAxHostWindow để tạo ra một điều khiển không cửa sổ là nó không hỗ trợ alpha.
Dường như biên dịch tốt, tuy nhiên khi tôi gọi DrawControl tôi chỉ lấy lại một khung màu đen.
XcpContorlHost.h XcpControlHost.cpp
Bất kỳ ý tưởng về những gì có thể là sai?
EDIT4: Tôi đang tiến hành một bước trở lại. Tôi sử dụng mã từ "TestProject" Tôi muốn sửa đổi CreateXcpControl (HWND hWnd) để có thể lấy hWnd == nullptr (không cửa sổ) và sử dụng OleDraw để vẽ điều khiển vào bộ nhớ.
Soo những gì tôi đã cố gắng làm là chỉ cần bỏ qua cuộc gọi đến "AttachControl" và gọi trực tiếp "ActivateXcpControl". Và tôi đã thay thế GetClientRect bằng các giá trị mã hóa cứng.
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
}
tôi tạo XcpControlHost bên a thread với 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);
}
}
Và sau đó tôi chạy các cửa sổ nhắn handler vòng lặp thông thường với GetMessage, TranslateMessage và DispatchMessage.
Tuy nhiên, tôi vẫn nhận được màu đen. Tôi đang làm gì sai?
tôi dường như để có được E_FAIL từ cuộc gọi sau đây trong "ActivateXcpControl":
hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos);
+1 cho chủ đề hay này. Tôi cũng cần phải biết về điều này .. tôi đã cố gắng để làm những việc này: http://stackoverflow.com/questions/4744522/handle-to-silverlight-usercontrol ... và http://stackoverflow.com/questions/4758568/deploying-xbap-with-win32-dll – Nawaz
Phiên bản Silverlight nào? –
Tốt nhất có thể. – ronag