CreateWindow in DLL
-
Das hInstance der DLL gilt allein für die DLL, das von WinMain allein für die EXE. Man kann die gegenseitig mitteilen, doch besser nur für Informationszwecke und Abfragefunktionen der WinApi. Betrachte DLL und EXE als quasi getrennte Prozesse. Es sind nur die Datenbereiche miteinander verknüpft. Verteile die Aufgaben der DLL eindeutig auf diese und regel alles weitere über DLL-Funktionen. Dann gibt es keine Komplikationen!
-
Danke erst einmal für die Hinweise. Leider bin ich damit immer noch nicht weiter.
Mir ist allerdings aufgefallen, dass der Wert des handles für die DLL mit dem Handle der EXE übereinstimmt. AuchEXTERN_C IMAGE_DOS_HEADER __ImageBase; #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)liefert mir diesen Wert.
Den Wert des Handles der EXE bekomme ich, wie gesagt, über die WinMain Methode. Etwas ratlos
Dirk
-
Kann das nicht nachvollziehen, wie du das machst.
Vorschlag: Richte für die EXE und die DLL jeweils eine Protokolldatei EXE.TXT und DLL.TXT ein und schreibe die hInstance-Handles hinein. Du wirst sehen, sie sind verschieden, weil quasi getrennte Prozesse. Wie man das mit solchen Protokolldateien machen kann, findest du auf meiner Homepage http://berniebutt.npage.de auf der Seite Protokolldatei. Solche Protokolldateien sind auch sonst nützlich.
-
Nach den handles habe ich schlichtweg im Debugger nach dem Wert geschaut.
-
Habe dann doch noch mal die Wert in eine Logdatei geschrieben. Die Werte sind unterschiedlich, werden vom Fuschel Studio Debugger aber als gleich angegeben.
Bleibt dennoch das Problem, dass das WindowHandle NULL ist.
Dirk
-
MrMagoo schrieb:
Habe dann doch noch mal die Wert in eine Logdatei geschrieben. Die Werte sind unterschiedlich, werden vom Fuschel Studio Debugger aber als gleich angegeben.
Bleibt dennoch das Problem, dass das WindowHandle NULL ist.
DirkBist du dir sicher, dass hwnd NULL ist oder vertraust du da dem Debugger? Debugger können nicht alles und haben für das gemeinsame Debuggen von EXE und DLLs schon mal Schwierigkeiten oder erfordern besondere Massnahmen. Dies ist der Grund, warum ich lieber eigene Protokolldateien einsetze und den Debugger nur für Notfälle nehme. Wenn die Fensterklasse korrekt registriert ist, liefert ein CreateWindow auch ein gültiges hwnd-Handle zürück. Mache alles in der DLL und kontrolliere, was diese macht.
-
Die NULL stammt jetzt aus dem Protokoll.
-
Wenn ein Windows Handle NULL ist nach CreateWindow, dann hat GetLastError einen Wert für die Fehlerursache...
@berniebutt: Eine DLL in einem Prozess als eigenen Prozess zu beschreiben ist falsch. Einer DLL gehören keine Handles, kein dyamischer Speicher!
Eine DLL ist nichts anderes als zusätzlicher Code und Daten, die man sich in den Speicher lädt.
-
Martin Richter schrieb:
Eine DLL in einem Prozess als eigenen Prozess zu beschreiben ist falsch. Einer DLL gehören keine Handles, kein dyamischer Speicher!
Eine DLL ist nichts anderes als zusätzlicher Code und Daten, die man sich in den Speicher lädt.
--> Eine DLL wird nur tätig, wenn ein Prozess eine Funktion daraus aufruft, das ist unbestritten.
--> Jede Instanz einer DLL besitzt sehr wohl eigene Handles, z.B. ihren InstanzHandle hInstance
--> Jede Instanz einer DLL kann auch dynamischen Speicher anfordern und diesen wieder freigeben.
--> Eine DLL kann unter Windows verschiebbar sein.
--> Eine DLL ist mehr als nur die Bereitstellung von zusätzlichem Code und Daten.
--> So betrachtet darf man jede DLL-Instanz schon als quasi eigenständigen Prozess ansehen.Aber das führt hier nicht viel weiter. Der Fragesteller erhält mit seinem CreateWindow ein hwnd = NULL und weiss nicht warum. Nur darum geht es!
-
Habe noch ein wenig weiter gebastelt, aber noch immer kein HWND erhalten. Mein aktuller Code sieht so aus:
Instance handle erhalten über:
EXTERN_C IMAGE_DOS_HEADER __ImageBase; #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)Versuchen, ein Window Handle zu erhalten mit:
TCHAR *szWindowClass=L"TestSapiTtsWindowClass"; TCHAR *szTitle=L"Test SAPITTS"; LogWrite(LOG_I, "hinstance: %ld", HINST_THISCOMPONENT); WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC) MyWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = HINST_THISCOMPONENT; wndclass.hIcon = NULL;// LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); wndclass.hCursor = 0; wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szWindowClass; ATOM atom = RegisterClass(&wndclass); if (atom == NULL) { LogWrite(LOG_E, "unable to register TTS window. Last Error: %ld", GetLastError()); } HWND hWnd = CreateWindow( szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, NULL, HINST_THISCOMPONENT, NULL); if (hWnd==0) { LogWrite(LOG_E, "unable to create TTS window. Last Error: %ld", GetLastError()); }Die Logausgabe ist folgende:
`077367 I(sapitts.cpp:35) hinstance: 1433141248
079286 E(sapitts.cpp:68) unable to create TTS window. Last Error: 0
`
Ein ATOM kann ich also erzeugen, ein Window nicht. GetLastError hilft mir hier leider auch nicht weiter.
Ich verwende Windows 7, falls das weiter hilft.
Dirk
-
Habe mal einen Breakpoint in meinen EventHandler gesetzt. Der wird tatsächlich mehrmals aufgerufen.
Mein Handler sieht so aus:
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CLOSE: DestroyWindow(hWnd); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, message, lParam, wParam); }Messages sind 36, 129, 130
Dirk
-
Das war wohl der Schlüssel dazu. Nach Änderung meines Codes zu:
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NCCREATE: return 1; case WM_CLOSE: DestroyWindow(hWnd); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, message, lParam, wParam); }Geht es weiter und ich bekomme tatsächlich ein Window Handle. Ich hoffe nur, dass diese Abwandlung so korrekt ist.
Dirk