WNDCLASS in einer DLL registrieren?



  • Nein, die Instanz der DLL ist schon richtig:

    Platform SDK schrieb:

    Handle to the instance that contains the window procedure for the class.

    ...und die Instanz die die Fensterprozedur enthält ist ja die der dll und nicht die der Anwendung.
    Wenn er sein RegisterClass also in eine InitMeineControls()-Funktion auslagern will, müsste er sich die Instanz in der DllMain schonmal irgendwie als globale Variable oder so sichern.
    ( GetModuleHandle(NULL) kann man nämlich vergessen, da das den instanz-handle der anwendung, welche die dll verwendet, zurückliefert... )



  • Die Richedit-DLL macht das auch in der DllMain. (ein einfaches laden reicht) Also wird das wohl in Ordnung sein!



  • Da hält sich Microsoft wohl an ihre eigenen Regeln nicht 😉
    ...aber ich würd eh ersma einfach Rückgabewerte prüfen - der wird wohl den Grund nennen warum es nicht klappt oder ob die DllMain überhaupt betreten wird (dann läge der Fehler wohl außerhalb der dll...)



  • Und wo steht die Regel? Die einzige Regel ist das man LoadLibrary nicht in der DllMain aufrufen soll.

    So funktioniert es:

    #include <windows.h>
    
    LRESULT CALLBACK ControlWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    	if(fdwReason == DLL_PROCESS_ATTACH)
    	{
    		WNDCLASSEX WindowClass;
    		WindowClass.cbSize = sizeof(WindowClass);
    		WindowClass.lpszClassName = TEXT("Control");
    		WindowClass.lpfnWndProc = ControlWindowProc;
    		WindowClass.cbClsExtra = 0;
    		WindowClass.cbWndExtra = 0;
    		WindowClass.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
    		WindowClass.style = 0;
    		WindowClass.lpszMenuName = NULL;
    		WindowClass.hInstance = hinstDLL;
    		WindowClass.hIcon = NULL;
    		WindowClass.hIconSm = NULL;
    		WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    
    		return RegisterClassEx(&WindowClass) != 0;
    
    	}
    
    	return TRUE;
    }
    


  • Sorry. Das CS_GLOBALCLASS war im vorherigen Code nicht eingebaut.

    #include <windows.h>
    
    LRESULT CALLBACK ControlWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
    	if(fdwReason == DLL_PROCESS_ATTACH)
    	{
    		WNDCLASSEX WindowClass;
    		WindowClass.cbSize = sizeof(WindowClass);
    		WindowClass.lpszClassName = TEXT("Control");
    		WindowClass.lpfnWndProc = ControlWindowProc;
    		WindowClass.cbClsExtra = 0;
    		WindowClass.cbWndExtra = 0;
    		WindowClass.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
    		WindowClass.style = CS_GLOBALCLASS;
    		WindowClass.lpszMenuName = NULL;
    		WindowClass.hInstance = hinstDLL;
    		WindowClass.hIcon = NULL;
    		WindowClass.hIconSm = NULL;
    		WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    
    		return RegisterClassEx(&WindowClass) != 0;
    
    	}
    
    	return TRUE;
    }
    


  • Jetzt fällt mir gerade auf das plusman gar nicht cbSize gefüllt hat.



  • Ah könnte schon sein das mit der kernel32.dll Der Aufruf einer Funktion aus einer anderen DLL (hier user32.dll) lädt die DLL ja auch implizit.



  • !!!!!!!!!!!! schrieb:

    Jetzt fällt mir gerade auf das plusman gar nicht cbSize gefüllt hat.

    Er nimmt auch noch die alte WNDCLASS, nicht WNDCLASSEX - bei der WNDCLASS gibt es gar kein cbSize...



  • Also, ich habe jetzt mal das Registrieren der WNDCLASSEX nu in einer eigenen Funktion. So weit, so gut. Nur schien das immer noch nicht zu klappen. Also habe ich geprüft, was GetLastError mir dazu sagen vermochte, die Funktion spuckt den Fehler 87 aus, d.h. "The parameter is incorrect." Aber welcher Parameter ist gemeint?
    Ich habe die Funktion jetzt auf WNDCLASSEX angepasst und auch RegisterClassEx verwendet. Nichts!



  • Habe nen bisschen rumprobiert und mit deinem code dasselbe festgestellt.
    Nachdem ich noch
    wc.hbrBackground=NULL;
    ergänzt hatte funktionierte es dann 😉

    Das ganze lässt sich übrigens noch etwas kürzer schreiben:

    int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
    {
        WNDCLASS        wc;
    
        ZeroMemory(&wc,sizeof(WNDCLASS)); // In der WNDCLASS-Struktur alles auf NULL setzen
        wc.lpszClassName= TEXT ("statusleiste");
        wc.lpfnWndProc    = WndProc_LoadingString;
        wc.hInstance    = hInstance;
    
        RegisterClass(&wc); // Fallunterscheidung zu Unicode sollte schon in der windows.h (bzw. winuser.h) drin sein ;D
        return TRUE;
    }
    

Anmelden zum Antworten