Win32 API und WPF
-
Jau
und auch das habe ich probiert:
CoInitializeEx ( NULL, COINIT_APARTMENTTHREADED );
Vlt sollte ich einfach mal meinen Testcode reinstellen:
#pragma managed using namespace System; using namespace System::Windows; using namespace System::Windows::Controls; using namespace System::Windows::Forms; using namespace System::Windows::Interop; HwndSource^ TestFkt ( HWND hWnd, int x, int y, int width, int heigt ); void InitWPF ( RECT rc ); void InitWPF ( RECT rc ) { HWND hWndParent; if (( hWndParent = GetParent ( g_hWnd )) == NULL ) hWndParent = GetActiveWindow ( ); MapWindowPoints ( 0, hWndParent, ( POINT* ) &rc, sizeof ( RECT ) / sizeof ( POINT )); HwndSource^ srcWpfView = TestFkt ( hWndParent, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top ); ShowWindow (( HWND ) srcWpfView->Handle.ToPointer ( ), SW_SHOW ); } HwndSource^ TestFkt ( HWND hWnd, int x, int y, int width, int height ) { Button^ bWpfButton = gcnew Button ( ); // hier krachts! bWpfButton->Content = "Testbutton"; bWpfButton->Opacity = 0.8f; bWpfButton->Width = 120; bWpfButton->Height = 30; HwndSourceParameters params; params.ParentWindow = IntPtr ( hWnd ); params.WindowStyle = WS_CHILD | WS_VISIBLE; params.PositionX = x; params.PositionY = y; params.Width = width; params.Height = height; HwndSource^ src = gcnew HwndSource ( params ); src->RootVisual = bWpfButton; return ( src ); } #pragma unmanaged LRESULT CALLBACK WndProc ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch ( message ) { case WM_CREATE: RECT rc; GetWindowRect ( g_hWnd, &rc ); InitWPF ( rc ); return ( 0 ); ... int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { ::MSG msg; WNDCLASSEX wndclass; int cx, cy; g_hInst = hInstance; CoInitializeEx ( NULL, COINIT_APARTMENTTHREADED ); ZeroMemory ( &wndclass, sizeof ( WNDCLASSEX )); ...
Irgendwo ein Fehler? Sollte ich irgendwas anders machen?
-
Was ist eigentlich schlussendlich das Ziel?
Mir schein WinAPI mit WPF zu verwenden ein ziemlicher "Murks".Was natürlich nicht dein Problem erklärt oder löst.
Simon
-
Ich wollte es eigentlich nur probieren und u.U. ein Frontend mit WPF bauen und den Rest DX überlassen (C++). Aber wahrscheinlich werde ich nun doch alles in C/C++ machen.
Die Frage ist durchaus berechtigt!
-
Die Frage ist eher: Warum machst Du es nicht in C#?
PS: Ich sehe hier nirgens, dass Du ein
System::Thread::Thread::CurrentThread->SetApartmentState(ApartmentState.STA);
machst...
-
Ich habe jetzt versucht den Code
System::Threading::Thread::CurrentThread->SetApartmentState ( System::Threading::ApartmentState::STA );
in void InitWPF ( ... ) reinzunehmen, die Anwendung schmiert nun mit folgender Meldung ab:
Eine nicht behandelte Ausnahme des Typs "System.InvalidOperationException" ist in mscorlib.dll aufgetreten.
Zusätzliche Informationen: Der angegebene COM-Apartmentzustand konnte nicht festgelegt werden.
Viele Grüße und sorry fürs Nerven
-
Dann lass mal alle anderen Aufrufe von "CoI*" einfach weg! Du hast den Thread schon anders initialisiert!
-
Habe ich bereits versucht, funktioniert trotzdem nicht, schmiert mit der COM-Apartmentzustands-Meldung ab. Ich gebs auf, danke an alle!
-
Folgendes Projekt geht bei mir wunderbar:
[System::STAThreadAttribute] int main(array<System::String ^> ^args) { System::Windows::Controls::Button ^btn = gcnew System::Windows::Controls::Button(); }
-
Also, nochmals etwas ausführlicher:
Wenn Du eine bestehende Win32-Anwendung hast, dann musst Du folgendes tun:Ersetze den Code:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
durch
#pragma managed(push, off) EXTERN_C IMAGE_DOS_HEADER __ImageBase; HINSTANCE GetHInstance() { HINSTANCE hInstance = (HINSTANCE) &__ImageBase; return hInstance; } #pragma managed(pop) #pragma comment(linker, "/entry:main") [System::STAThreadAttribute] int main(array<System::String ^> ^args) { //UNREFERENCED_PARAMETER(hPrevInstance); //UNREFERENCED_PARAMETER(lpCmdLine); HINSTANCE hInstance = GetHInstance(); STARTUPINFO si; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); int nCmdShow = SW_SHOW; if (si.dwFlags & STARTF_USESHOWWINDOW) int nCmdShow = si.wShowWindow;
Dann geht es
-
Das probier ich nochmal! Danke!