DLL bleibt nicht in Nachrichtenschleife hängen
-
Sowas programmiert man doch nicht direkt in die DllMain rein.

-
@Ringding hast recht, habe mir vorhin mal den Petzold organisiert und da stehts bei den DLLs auch dabei, man braucht in der DLL das HINSTANCE des Hauptprozesses, da die Nachrichten weiterhin über den laufen.
Kann ich mit ner Winapi Funktion das HINSTANCE meines Programmes ermitteln?
Wäre schöner, als ne Funktion zu exportieren und im Hauptprogramm aufzurufen.
-
HINSTANCE von EXE => GetModuleHandle(NULL);
-
Danke, er kann das Handle zwar auslesen, aber die Message-Loop wird weiterhin sofort beendet

-
Ich werd jetzt einfach in DLL_PROCESS_ATTACH nen Thread starten, dann hab ich ne eigene MessageLoop und die Probleme dürften erledigt sein. Damit die Fenster, aber meinem Thread gehören bzw. dessen MessageLoop muss ich ja beim erstellen das HINSTANCE Handle angeben, aber wie bekomm ich das von meinem Thread?
Geht das mit GetModuleHandle (NULL)? Oder gibts dafür ne andere Variante?
-
hast du schonmal versucht das Fenster und die Message Loop ausserhalb der DllMain zu tun? also in einer seperaten Funktion
-
man19 schrieb:
hast du schonmal versucht das Fenster und die Message Loop ausserhalb der DllMain zu tun? also in einer seperaten Funktion
Das Fenster und die Funktion sind ja seperat und ob DllMain jetzt noch ne funktion start() aufruft die genau den gleichen Code hat ändert ja nix daran, dass GetMessage in Frame::run() nicht funktioniert (PeekMessage geht, dann hab ich aber immer die Sanduhr)
-
Also mit nem Thread funktioniert es, allerdings bekommt mein Programm ständig WM_PAINT Nachrichten was dazu führt, dass ständig die Sanduhr un der normale Mauszeiger wechselt und erst, wenn ich das Fenster schließe sehe ich die MSG-Boxen die aus WM_PAINT kommen.
Könnt ihr euch das mal ansehen, woran es liegen könnt (bin aber immerhin auf dem richtigen weg, da es jetzt in der MSG Loop bleibt)?
#include <windows.h> #include <process.h> LRESULT CALLBACK WProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { case WM_CREATE: MessageBox (0,"WM_Create", "msg", MB_OK); return 0; case WM_PAINT: MessageBox (0,"WM_Paint", "msg", MB_OK); return 0; case WM_DESTROY: MessageBox (0,"WM_Destroy", "msg", MB_OK); PostQuitMessage (0); return 0; } return DefWindowProc (hwnd, msg, wparam, lparam); } void Thread (PVOID pvoid) { static TCHAR szAppName[] = TEXT ("DLL"); MSG msg; HWND hWnd; WNDCLASSEX wndclassex = {0}; wndclassex.cbSize = sizeof(WNDCLASSEX); wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WProc; wndclassex.cbClsExtra = 0; wndclassex.cbWndExtra = 0; wndclassex.hInstance = (HINSTANCE)pvoid; wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW); wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclassex.lpszMenuName = NULL; wndclassex.lpszClassName = szAppName; wndclassex.hIconSm = wndclassex.hIcon; if (!RegisterClassEx (&wndclassex)) { MessageBox (NULL, TEXT ("DLL RegisterClassEx fehlgeschlagen!"), szAppName, MB_ICONERROR); return; } hWnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, // erweiterter Fensterstil szAppName, // Name der Fensterklasse szAppName, // Fenstertitel WS_OVERLAPPEDWINDOW, // Fensterstil 350, // X-Position des Fensters .... CW_USEDEFAULT für Default 300, // Y-Position des Fensters 180, // Fensterbreite 120, // Fensterhöhe NULL, // übergeordnetes Fenster NULL, // Menü (HINSTANCE)pvoid, // Programm-Kopiezähler (Programm-ID) NULL); // zusätzliche Parameter if (!hWnd) { MessageBox (0, "CreateWindow in DLL fehlgeschlagen", "info", MB_OK); return; } ShowWindow (hWnd, SW_SHOW); UpdateWindow (hWnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } } int APIENTRY DllMain (HINSTANCE hinst, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: _beginthread (Thread, 0, hinst); break; case DLL_PROCESS_DETACH: _endthread (); break; } return TRUE; }
-
Zur Message-Loop in DllMain:
The entry-point function should perform only simple initialization or termination tasks.
Aber warum du mit PeekMessage Nachrichten bekommst und mit GetMessage nicht, ist auch seltsam

-
Das Beispiel aus meinem letzten Posting geht ja soweit, nur bekomm ich eben ununterbrochen WM_PAINT nachrichten, welche aber erst nach beenden des Fensters angezeigt werden. Aber das WM_DESTROY bekommt er nicht mit, da es anscheinend ab dem ersten WM_PAINT hängt.
Die exe und die dll sind beide als multithreaded Programme kompiliert, also daran kann es nicht liegen.
-
Du hast wohl BeginPaint und EndPaint vergessen, oder lass DefWindowProc das Regeln. :p
-
int APIENTRY DllMain (HINSTANCE hinst, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: _beginthread (Thread, 0, hinst); break; case DLL_PROCESS_DETACH: _endthread (); break; } return TRUE; }Bad idea. You should have a dedicated initialization function in the DLL
that creates the thread and the dialog. You should only perform simple
initializations in DllMain, read the documentation on DllMain.
-
painter schrieb:
Du hast wohl BeginPaint und EndPaint vergessen, oder lass DefWindowProc das Regeln. :p
Wow das klappt ja damit wirklich

hab nicht gewusst, dass man in WM_PAINT "zwangsweise" beginpaint und endpaint benutzen mussDanke

-
Windowsprogger schrieb:
int APIENTRY DllMain (HINSTANCE hinst, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: _beginthread (Thread, 0, hinst); break; case DLL_PROCESS_DETACH: _endthread (); break; } return TRUE; }Bad idea. You should have a dedicated initialization function in the DLL
that creates the thread and the dialog. You should only perform simple
initializations in DllMain, read the documentation on DllMain.Where else should I create the thread when I don't want to export a function for creating the thread und dialog.
The only thing would be an asynchronous function which creates them else it would be the same thing only that DllMain
calls another function which takes the same amount of time to initialize them.
-
Where else should I create the thread when I don't want to export a function for creating the thread und dialog.
Ok, if you don't want to export a seperate function, live with your dirty design.

-
Windowsprogger schrieb:
Where else should I create the thread when I don't want to export a function for creating the thread und dialog.
Ok, if you don't want to export a seperate function, live with your dirty design.

It seems that I dont have the choide cause I've just discovered, that directly after the DLL_PROCESS_ATTACH call I get a DLL_PROCESS_DETACH call which destroys the thread and causes some trouble in my program (I get new DLL_PROCESS_ATTACH calls, but normally there should be only one).
-
Vielleicht hängt es damit zusammen:
When a DLL is unloaded from a process as a result of an unsuccessful load of the DLL, termination of the process, or a call to FreeLibrary, the system does not call the DLL's entry-point function with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only sent a DLL_PROCESS_DETACH notification.
-
Gut möglich, aber durch die exportierte Funktion welche jetzt den Thread erzeugt läuft es super

Wieso kann ich eine exportierte Funktion die so aussieht EXPORT bool CALLBACK initialize (); nicht mit bool (CALLBACK *init_ptr)() laden?
Bekomme, dann immer nen NULL Handle von GetProcAdress, wenn ich statt __stdcall __cdecl, also einfach nix dazu schreibe, benutze geht es