SetWindowLong / GetWindowLong Problem



  • Hallo,
    Versuche mich auch mal mit der WinAPI. Habe mir eine Klasse
    geschrieben, um ein Window zu erzeugen. Da ich später (in der WNDPROC)
    noch auf einige Methoden dieser Klasse zugreifen möchte, habe ich
    mir rausgetüftelt, daß ich den Zeiger auf meine Klasse mit
    SetWindowLong in das Window speichern kann...

    Ich mache das so:

    SetWindowLong(hwnd,GWL_USERDATA,(long)this);
    

    Alles schön und gut. Das schluckt VC++.

    Jetzt möchte ich aber in der WNDPROC drauf zugreifen, dann mach ich das
    so:

    Win32Form * main = (Win32Form *) GetWindowLong(hwnd,GWL_USERDATA);
    // Da scheint noch kein Prob zu sein
    // wenn ich jetzt aber auf eine Methode zugreifen will zB:
    main->GetWindowRect();
    // Dann kommt eine Zugriffsverletzung  :(
    

    Was mache ich falsch?

    Das komische ist, bei einem anderen Fenster scheint es zu funzen...
    Ich blick da echt nicht mehr durch.

    Wäre nett, wenn einer mir einen Tip geben könnte 😋

    Also danke!
    Auf bald,
    Stefan



  • Dein Win32Form-Objekt muß (z. B. mittels new) auf dem Heap abgelegt sein -- oder auf dem Stack der WinMain()-Funktion. Ist es stattdessen sonstwo auf dem Stack abgelegt, so wurde es zwischenzeitlich destruiert und damit ungültig.



  • Hey danke für deine schnelle Antwort 🙂
    Habe jetzt in der WinMain das Objekt so erzeugt:

    Win32Form * App = new Win32Form(MainWndProc, hInstance);
    App->Create();
    //In der Create Methode habe ich SetWindowLong...
    

    Aber das Problem ist leider damit noch nicht behoben,
    wenn ich in MainWndProc auf den Zeiger wie oben
    beschrieben zugreife 😞



  • Der Pointer liefer NULL zurück



  • Wo rufst du denn genau SetWindowLong auf? Ich denke mal das du GetWindowLong aufrufst, bevor du mit SetWindowLong überhaupt einen Wert gesetzt hast.



  • Also, meine Create-Methode sieht so aus:

    HWND Win32Form::Create(HWND hParent)
    {
    //if (hParent) WndStyle= WndStyle | WS_CHILD;
    
    	WNDCLASSEX wcx;
    	wcx.cbSize           = sizeof(WNDCLASSEX);
    	wcx.style            = WndClassStyle;
    	wcx.lpfnWndProc      = (WNDPROC)WndProc;
    	wcx.cbClsExtra       = 0;
    	wcx.cbWndExtra       = 0;
    	wcx.hInstance        = hInst;
    	wcx.hIcon            = LoadIcon(NULL,IDI_APPLICATION);
    	wcx.hCursor          = LoadCursor(NULL,IDC_ARROW);
    	wcx.hbrBackground    = (HBRUSH)(COLOR_BTNFACE+1);
    	wcx.lpszMenuName     = NULL;
    	wcx.lpszClassName    = GetWndClassName();
    	wcx.hIconSm          = NULL;
    
    	if (!RegisterClassEx(&wcx))
    		{		
    			MessageBox( NULL,TEXT("Failed to register wnd class"),TEXT("ERROR"),MB_OK|MB_ICONERROR);
    			return NULL;
    		}
    
    	hwnd=Win32Std::Create(hParent); // Hier wird dann der HWND erstellt.. also nichts besonderes
    
    	if (!hwnd)
    		{		
    			MessageBox( NULL,TEXT("Failed to create Wnd"),TEXT("ERROR"),MB_OK|MB_ICONERROR);
    			return NULL;
    		}
    
    	GetWindowRect(hwnd,&WindowRect);
    	GetClientRect(hwnd,&ClientRect);
    
             //!!	
             SetWindowLong(hwnd,GWL_USERDATA,(long)this);
             //!!
    	ShowWindow(hwnd,SW_SHOW); 
    	UpdateWindow(hwnd);
    	return hwnd;
    }
    

    Diese Create-Anweisung rufe in der WinMain ganz am Anfang auf.
    die GetWindowLong rufe ich in meiner WNDPROC in WM_CREATE auf...

    Wenn ich direkt in der Create-Methode auch testweise gleich
    GetWindowLong aufrufe, gibt er mir auch den richtigen Pointer
    zurück... Deswegen kann es gut sein, daß Du Recht hast...
    Nur, wo ist der richtige Ort, um an den Zeiger ran zu kommen 😉

    Gruss & Vielen Dank!



  • GetWindowLong rufe ich in meiner WNDPROC in WM_CREATE auf...

    Da ist es ja wohl zu früh. WM_CREATE wird von der Funktion CreateWindowEx aufgerufen. Und du setzt den Wert erst dannach.

    Normalerweise kenne ich das so, das man den this-Pointer schon bei CreateWindowEx angibt (lpParam).



  • Ich glaube dieser Link sollte dir helfen: http://www.codeproject.com/win32/win32windowwrapperclass.asp



  • Hey SUPI 😃

    Der Tip mit WM_NCCREATE wars 🙂

    Ich dank Dir, jetzt kann ich wieder ruhiger
    schlafen 😉

    Danke für alle Hilfe!


Anmelden zum Antworten