[gelöst] private methode wird nicht aufgerufen



  • Hallo,
    ich versuche mich gerade als Übung an der Kapselung der winapi.

    ich habe da eine private methode (BuildMainMenu) meiner Fensterklasse (CWindow), die aus unerfindlichen Gründen nicht aufgerufen wird. keinerlei compiler-warnungen/fehler. wenn ich den aufruf ändere, kommen erwartungsgemäß Fehler...

    ich zeige vor dem Aufruf eine Messagebox an und in der Methode. die davor kommt (Message WM_Create), die in der Methode nicht.

    ich habe schon die optimierung (-O0) ausgeschaltet und alle warnungen eingeschaltet (-Wall)

    http://dl.dropbox.com/u/3228629/winclass.zip

    Compiler G++ (MingW)

    ich hoffe, irgendjemand hat eine Idee...

    Gruß Frank



  • Poste am besten mal etwas Code (deine zip-Files wird hier kaum jemand entpacken).
    Außerdem solltest du mal mit dem Debugger Breakpoints in die Methode und vor den Methodenaufruf setzen und schauen was genau passiert.



  • hab die dateien nochmal separat hochgeladen, wenn ihr zip nicht mögt...und die entsprechenden Ausschnitte.

    mit der 2. privaten Methode (Menucommand) fuktioniert es komischerweise.

    da ich nur mingw und keine richtige IDE habe, habe ich noch keine richtige Ahnung vom Debuggen mit gdb...habs mir zwar schonmal grob angeschauen, bin aber noch nicht so ganz fit drin.

    Header-Datei:
    http://dl.dropbox.com/u/3228629/WinTut.h

    class CWindow
    
    {
    
    	private:
    
    	  HWND hWnd;
    
    	  void BuildMainMenu();
    
        void MenuCommand(int ID);
    

    CPP-Datei:
    http://dl.dropbox.com/u/3228629/WinTut.cpp

    void CWindow::BuildMainMenu()
    
    {
    
      MessageBox(hWnd,"(BuildMainMenu)","Info",0);
     //wird nicht aufgerufen
    }
    
    void CWindow::MenuCommand(int ID)
    
    {
    
      switch(ID)
    
      {
    
        case ID_FILE_EXIT:
    
          PostMessage(hWnd, WM_CLOSE, 0, 0);
    
        break;
    
        case ID_MENU_HELP:
    
          MessageBox(hWnd,"Help (MenuCommand)","Info",0);
    
        break;
    
      }
    
    }
    
    ...
        case WM_CREATE:
    
          MessageBox(hWnd,"Call BuildMainMenu","Info",0);
     //wird aufgerufen
          BuildMainMenu();
    
        break;
    
        case WM_COMMAND:
    
          MenuCommand(LOWORD(wParam));
    
        break;
    

    Gruß Frank



  • Hallo,

    sehr unwahrscheinlich, dass das in deinem Programm wirklich so aussieht.
    Das einzige, was in diesem Codeauszug zu einem Fehler führen kann, ist das in '...' nochmal hwnd lokal definiert wird
    und daher einen anderen Wert hat, als das Member-Hwnd und daher die Memberfunktion nicht richtig funktioniert (wohl aber aufgerufen wird).



  • Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Dein Construktor ruft CreateWindowEx auf, der schon WM_CREATE verschickt bevor das Ergebnis in der Membervariable hWnd gespeichert wird.

    LRESULT CALLBACK CWindow::stWinProc benutzt hwnd, den es als Parameter bekommen hat. BuildMainMenu benutzt aber die Membervariable hWnd, die noch nicht inistialisiert ist.

    Es sollte also funktionieren, wenn Du die Variable vor dem Aufruf von BuildMainWindow initialisierst.

    mfg Martin



  • ich habe die Sache mit dem Hwnd bereinigt und jetzt funktioniert es,
    trotzdem ist der Fehler an sich nicht so recht nachvollziehbar, da die andere Methode aufgerufen wurde...

    @pumuckl: ich habe es wegen o.g. Fehlerbild (innerhalb meiner Klassendefinition) für ein C++-Problem gehalten und nicht für win32...den Win32-code habe ich nur gepostet, damit es für euch erkennbar wird, was ich erreichen will/was nicht funktioniert.
    Wenn ich den code zum erstellen des Menüs direkt vor den BuildMainMenu()-Aufruf gepackt habe, wurde das Menü erstellt, in BuildMainMenu() nicht mehr, genauso wie die Messagebox nicht angezeigt wurde. wurde das menü erstellt ging davon aber auch der MenuCommand.
    der code wurde auch 1:1 aus meinem Programm kopiert, die eizige erklärung wäre wirklich, dass irgendwo das Hwnd verbogen/undefiniert war, da es in den Message-Handlern und als privates Feld der klasse existierte.

    Gruß Frank



  • frank schrieb:

    ich habe die Sache mit dem Hwnd bereinigt und jetzt funktioniert es,
    trotzdem ist der Fehler an sich nicht so recht nachvollziehbar, da die andere Methode aufgerufen wurde...

    die eizige erklärung wäre wirklich, dass irgendwo das Hwnd verbogen/undefiniert war, da es in den Message-Handlern und als privates Feld der klasse existierte.

    Gruß Frank

    Hast Du meine Antwort nicht verstanden?

    Dein Construktor ruft die Funktion CreateWindow auf und diese verschickt sofort die WM_CREATE-Message an Dein Fenster noch BEVOR der Konstruktor Deine Membervariable versorgen kann, weil CreateWindow noch nicht zurückgekehrt ist.

    mfg Martin



  • das habe ich schon verstanden...wird aber hiermit umgangen:

    //erstellen des fensters aus Klassenmethode (Constructor)
    hMainform = CreateWindowEx(WS_EX_APPWINDOW, "CWindowClass", "WinTut!", WS_OVERLAPPEDWINDOW, 10, 10, 300, 400, NULL, NULL, hInst, this);
    
    //und die callback
    LRESULT CALLBACK CWindow::stWinProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
    {
      if (uMsg == WM_NCCREATE)
      {
        // Set the pointer
        SetWindowLong(hWnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
      }
      CWindow* pWnd;
      // Get the pointer
      pWnd = (CWindow *)GetWindowLong(hWnd, GWL_USERDATA);
      if (pWnd)
      {
        return pWnd->WinProc(hWnd, uMsg, wParam, lParam);
      }
      else
      {
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
      }
    }
    

    Gruß Frank



  • frank schrieb:

    das habe ich schon verstanden...wird aber hiermit umgangen:

    Gruß Frank

    Und wo setzt Du hier die Membervariable hWnd? Das bewirkt nur, daß Deine Callbackfunktion das richtige C++-Objekt findet. Die hWnd Membervariable des C++-Objektes wird hier aber nirgends gesetzt.

    mfg Martin



  • da hast recht, in der alten version wird das wirklich nicht gesetzt...
    hab das bei meinem Umbau wohl behoben...

    die Membervariable heist jetzt hMainform (vorher das hWnd hat verwirrt, weil man nie wusste, ob die Member oder die lokale aufgerufen wurde)

    LRESULT CALLBACK CWindow::WinProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      switch(uMsg)
      {
        case WM_CREATE:
          hMainform=hWnd; //hMainform ist die umbenannte Membervariable
    

    Danke für deine Hilfe

    Gruß Frank


Log in to reply