DLL-Fenster erzeugen, dann vom Hauptprogramm weitere Funktionen aufrufen
-
Hallo,
folgende Problem: Mein Hauptprogramm ruft eine DLL auf, die wiederum ein Fenster erzeugt. Soweit sogut. Jetzt würde ich gerne aus dem Hauptprogramm (z.B: Excel) eine weitere Funktion der DLL aufrufen, die im Fenster z.B: was zeichnet (die Funktion gibt es schon). Mein Problem ist nur, dass wenn ich die DLL initialisiere (das Fenster erzeuge) ich keine Möglichkeit mehr habe von meinem Hauptprogramm aus Funktionen aufzurufen, da das Fenster ja in einer "Schleife" ist. Ich bekomme erst wieder die Kontrolle wenn das Fenster geschlossen ist.
Wie kann man so ein Problem lösen???
-
ein eigener thread für die fensterfunktion z.b.?
-
Hab ich auch schon probiert, aber dann geht das Fenster (das die DLL erzeugt) gleich wieder zu....
-
du brauchst doch in der DLL eigentlich nicht nochmal eine MessageLoop, oder doch?
-
Was meinst Du damit? Vielleich mal noch ein bisschen Code:
void FensterThread(void*) { MSG msg; // Globale Zeichenfolgen initialisieren LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_TRISOFTPDLL, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Anwendungsinitialisierung ausführen: if (!InitInstance (hInstance, 1)) { return ;//FALSE; } // Hauptmeldungsschleife: while (GetMessage(&msg, NULL, 0, 0)) { //if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) //{ TranslateMessage(&msg); DispatchMessage(&msg); //} } return;// (int) msg.wParam; } int ShowPwindow()//Wird vom Hauptprogramm aufgerufen { _beginthread(FensterThread,0,0); return 0; }
Irgendwie wird der Thread also das Fenster sofort wieder beendet...
-
also der code scheint mir soweit in ordnung zu sein
schau doch mal was GetMessage, RegisterClass(Ex) und CreateWindow() zurückliefern, vielleicht liegt der fehler auch daran, dass er die WndProc nicht findet
kannst mir den code der dll evtl. mal schicken?
hab irgendwie nix zu tun heut ausser in allen möglichen foren rumzuhängen...
-
Ich sehe nirgends etwas vom Erzeugen eines Fensters
Imho brauchst du aber in der DLL keine zusätzliche Message-Loop und folglich keinen extra Thread
-
Also hier noch den Rest des Codes:
Den MessageLoop brauche ich, um das Menu und einen Button für Abbrechen zu steuern...
ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW | WS_EX_TOOLWINDOW ; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MYPROG); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); wcex.lpszMenuName = (LPCTSTR)IDC_MYPROG; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 280,150, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); g_hWnd = hWnd; //Global Var für restliche DLL return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: ShowProgressBar(hWnd,1000); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Menüauswahl bearbeiten: switch (wmId) { // case IDM_\1: // DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); // break; case IDM_EXIT: DestroyWindow(hWnd); break; case IDM_SHOWPROGRESS: ShowProgressBar(hWnd,100); break; case IDM_COUNTUP: SendMessage(hwndPB, PBM_STEPIT, 0, 0); break; case IDM_UPTHREAD: //Dieser Thread soll auch per Function (aus Hauptprogramm) aufgerufen werden _beginthread(TransferThread,NULL,NULL); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Fügen Sie hier den Zeichnungscode hinzu... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
-
Werden die Messages nicht schon vor der Main-Message-Loop in WinMain an die WndProc in der DLL verteilt
-
Mag sein, aber ich will eigentlich Excel als Hauptprogramm verwenden, und da hab ich nunmal keine Möglichkeit auf irgendwelche Messages zu reagieren...
-
Ich bin mir zwar nicht sicher, ob das mit Excel nicht auch ohne eigene Message-Loop klappt (Excel muss ja auch eine haben)
Woher kommt eigentlich hInstance in FensterThread? ist das eine globale Variable?
-
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hInstance = (HINSTANCE) hModule;//hIstance ist Global break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: PostQuitMessage(0); break; } return TRUE; }
-
Bist du dem Hinweis von BlueScreen32.dll auch mal nachgegangen und hast die Rückgabewerte überprüft - und evtl. noch GetLastError befragt
-
ja, aber ich hab in der zwischenzeit was anderes entdeckt. Wenn ich in der DLLMain das PostQuitMessage() auskommentiere bleibt der Dialog offen. Dabei dachte ich immer DLL_PROCESS_DETACH wird erst aufgerufen (Statisch gelinkt) wenn das Hauptprogramm geschlossen wird...
Vielleicht kann mich mal jemand "aufklären"....
DANKE an alle die mir geholfen haben
!!!
-
Du musst nach jedem case ein break haben! Du rufst PostQuitMessage() bei DLL_THREAD_ATTACH, DLL_THREAD_DETACH und DLL_PROCESS_DETACH auf
Hätte mir eigentlich auch auffallen können
-
Mensch jetzt wo Du es sagst, vielen Dank für die Lösung. Ist wohl doch nicht mehr so weit her am abend...
Eine Frage habe ich noch an den Profi...
...da jetzt mit ShowWindow einen Process starte, bekomme ich ja keinen Rückgabewert wenn der Process beendet ist (wenn ich es richtig weiss müssen Processfunction immer mit void deklariert sein). Wie bekomme ich es hin, das eine Funktion erst wieder nach Excel zurückkehrt wenn der von Ihr gestartete Process beendet ist. Muss ich da in eine Schleife und auf eine Nachricht warten? (ich denke da z.B. an eine FTP Thread, bzw. eine Thread der Dateien ändert) Wohlgemerkt das Ursprüngliche Fenster (ShowWindow) soll immer dargestellt werden, es soll z.B. nur eine andere Datei (wird aus Excel übergeben) bearbeitet werden.
Nochmal vielen vielen Dank. Die Nacht kann kommen....
-
Also ich bin mitnichten ein Profi
1.) Du startest einen Thread keinen Process
2.) mit ShowPwindow und nicht mit ShowWindow
3.) wenn die Funktion nicht assynchron laufen soll, warum packst du sie dann überhaupt in einen eigenen Thread?Du kannst aber auch CreateEvent ein event Objekt erstellen und mit WaitForSingleObject darauf warten, dass es signalisiert wird (SetEvent)