WM_CLOSE hinauszögern



  • Deswegen hab ich ja zur Sicherheit nochmal gefragt.
    Kannst du eventuell einen ganzen Quellcode posten damit man damit rumprobieren kann?



  • PauleW schrieb:

    Wo liegt der (logische) Fehler?

    welcher fehler? welche WinProc ist das in deinem code?

    PauleW schrieb:

    Wird an das Editfenster auch eine WM_CLOSE-Nachricht geschickt, oder muss ich das selbst machen?

    nein, denn PostQuitMessage schickt eine WM_QUIT-nachricht und beendet damit die gesamte nachrichtenschleife



  • Ich habe mir den Quellcode jetzt auch nachgebaut und bekomme das selbe Problem. Ich habe es so gemacht das bei WM_CLOSE einfach nur der Text gesetzt wird und die Applikation nicht beendet wird. Das funktioniert. Aber setze ich nach dem SetWindowText ein Sleep wird der Text nicht geändert. Ich werde noch weiter rumprobieren.



  • Das Problem scheint zu sein das der Text sich nicht neu zeichnet! Wenn ich das Fenster aus dem Desktop schiebe und wieder zurückhole um ein Neuzeichnen zu veranlassen steht der richtige Text drin.



  • Hab aber alles unwichtige rausgenommen, sonst wirds zuviel 🙂 ...
    (auch nur die WndProc und die Log-Funktion)

    #include <windows.h>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
    void Log( char * str,... );
    
    const TCHAR szAppName[] = TEXT( "TestProg" );
    HINSTANCE Instanz;
    HWND hedit;
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow )
    {
      WNDCLASSEX wndclass;
      MSG msg;
      HWND hwnd;
      char temp[128];
      Instanz = hInstance;
    
      wndclass.cbSize = sizeof( WNDCLASSEX );
      wndclass.style = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc = WndProc;
      wndclass.cbClsExtra = 0;
      wndclass.cbWndExtra = 0;
      wndclass.hInstance = hInstance;
      wndclass.hIcon = LoadIcon( hInstance, szAppName );
      wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
      wndclass.hbrBackground = CreateSolidBrush( RGB(192, 192, 192) );
      wndclass.lpszMenuName = NULL;
      wndclass.lpszClassName = szAppName;
      wndclass.hIconSm = NULL;
    
      if ( !RegisterClassEx( & wndclass ) )
      {
        sprintf( temp, "Fehlermeldung : %d", GetLastError() );
        MessageBox( NULL, temp, "Error...!", MB_ICONERROR );
        return 0;
      }
    
      hwnd = CreateWindow( szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 617, 340, NULL,
            NULL, hInstance, NULL );
    
      ShowWindow( hwnd, SW_SHOW );
      UpdateWindow( hwnd );
    
      while ( GetMessage( & msg, NULL, 0, 0 ) )
      {
        TranslateMessage( & msg );
        DispatchMessage( & msg );
      }
    
      return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
      static LOGFONT logFont;
      static HFONT hFont;
    
      switch ( message )
      {
        case WM_CREATE:
          hedit = CreateWindow( "EDIT", "",
                WS_BORDER | WS_VSCROLL | WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY | ES_WANTRETURN, 5, 5,
                600, 300, hwnd, NULL, Instanz, NULL );
    
          //Font erstellen und an das Log-Fenster schicken
          logFont.lfHeight = 0;
          logFont.lfWidth = 0;
          logFont.lfEscapement = 0;
          logFont.lfOrientation = 0;
          logFont.lfWeight = FW_DONTCARE;
          logFont.lfItalic = 0;
          logFont.lfUnderline = 0;
          logFont.lfStrikeOut = 0;
          logFont.lfCharSet = ANSI_CHARSET;
          logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
          logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
          logFont.lfQuality = ANTIALIASED_QUALITY;
          logFont.lfPitchAndFamily = DEFAULT_PITCH;
          strcpy( logFont.lfFaceName, "Verdana" );
    
          hFont = CreateFontIndirect( & logFont );
    
          SendMessage( hedit, WM_SETFONT, ( WPARAM )hFont, ( LPARAM )FALSE );
    
          Log("Fenster erfolgreich erstellt!");
    
          return 0;
    
        case WM_CLOSE:
        case WM_DESTROY:
          Log("beende");
          Sleep(2000);
          DeleteObject(hFont);
          PostQuitMessage( 0 );
          return 0;
      }
      return DefWindowProc( hwnd, message, wParam, lParam );
    }
    
    void Log( char * str,... )
    {
      unsigned int length;
      char * buf;
      char szBuffer[2048];
      va_list valist;
    
      va_start( valist, str );
      vsprintf( szBuffer, str, valist );
      va_end( valist );
    
      if ( hedit != NULL )
      {
        length = SendMessage( hedit, WM_GETTEXTLENGTH, 0, 0 );
        length += strlen( szBuffer ) + 2;
    
        buf = new char[length];
    
        SendMessage( hedit, WM_GETTEXT, ( WPARAM )length, ( LPARAM )buf );
    
        strcat( buf, szBuffer );
        strcat( buf, "\r\n" );
    
        SendMessage( hedit, WM_SETTEXT, ( WPARAM )0, ( LPARAM )buf );
    
        delete buf;
      }
    
      return;
    }
    

    Der Code ist eben schnell entstanden, habs aber eben getestet und Effekt ist immernoch da (beende wird am Ende nicht angezeigt)



  • hmm... mir scheint übrigens auch, dass der allokierte Buffer (buf bei Log() )zu klein ist (müsste doch +3 sein wegen dem Nullzeichen)



  • Dein Programm ist fehlerhaft. Stürzt bei mir ab.

    Aber egal. Mein Programm funktioniert jetzt durch ein UpdateWindow.

    /*-----------------------------------------------------------------------
      Muster Window.cpp 
    
      www.winapi.net
      -----------------------------------------------------------------------*/
    
    #include <windows.h>
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
       static TCHAR szAppName[] = TEXT ("Klassenname");
       HWND         hwnd;
       MSG          msg;
       WNDCLASSEX   wndclassex = {0};
    
       wndclassex.cbSize        = sizeof(WNDCLASSEX);
       wndclassex.style         = CS_HREDRAW | CS_VREDRAW;
       wndclassex.lpfnWndProc   = WndProc;
       wndclassex.cbClsExtra    = 0;
       wndclassex.cbWndExtra    = 0;
       wndclassex.hInstance     = hInstance;
       wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
       wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW);
       wndclassex.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
       wndclassex.lpszMenuName  = NULL;
       wndclassex.lpszClassName = szAppName;
       wndclassex.hIconSm       = wndclassex.hIcon;
    
       if (!RegisterClassEx (&wndclassex))
       {
          MessageBox (NULL, TEXT ("RegisterClassEx fehlgeschlagen!"),
                      szAppName, MB_ICONERROR);
          return 0;
       }
    
       hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, // erweiterter Fensterstil
                      szAppName, // Name der Fensterklasse
                      TEXT ("Fenstertitel"), // Fenstertitel
                      WS_OVERLAPPEDWINDOW, // Fensterstil
                      CW_USEDEFAULT, // X-Position des Fensters                      
                      CW_USEDEFAULT, // Y-Position des Fensters       
                      CW_USEDEFAULT, // Fensterbreite                 
                      CW_USEDEFAULT, // Fensterhöhe                
                      NULL, // übergeordnetes Fenster
                      NULL, // Menü           
                      hInstance, // Programm-Kopiezähler (Programm-ID)            
                      NULL); // zusätzliche Parameter
    
       ShowWindow (hwnd, iCmdShow);
       UpdateWindow (hwnd);
    
       while (GetMessage (&msg, NULL, 0, 0))
       {
          TranslateMessage (&msg);
          DispatchMessage (&msg);
       }
       return msg.wParam;
    }
    
    // Die Hauptnachrichtenschleife
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
       static HWND hEdit;
    
       switch (message)
       {
       case WM_CREATE:
    	   hEdit = CreateWindowEx(0, TEXT("Edit"), TEXT(""), WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hwnd, 0, GetModuleHandle(NULL), NULL);
    	   break;
       case WM_CLOSE:
    	   SetWindowText(hEdit, TEXT("Ende!"));
    	   UpdateWindow(hEdit); 
    	   Sleep(5000);
    	   break;
       case WM_DESTROY:
          PostQuitMessage (0);
          return (0);
       }
    
       return DefWindowProc (hwnd, message, wParam, lParam);
    }
    


  • Hmm... bei mir läufts einwandfrei... (benutze C++BuilderX von Borland, also bcc32)
    So wie es da steht... Der Fehler wird sich früher oder später zeigen...
    Das mit UpdateWindow funzt super, danke vielmals 🙂



  • Du hast ja selbst gesagt das da was mit dem Buffer wäre.

    Wenn ich + 3 in dieser Zeile mache stürzt es nicht mehr ab.

    length += strlen( szBuffer ) + 3;



  • Wäre es nicht besser wenn deine Log Funktion an das Edit-Feld etwas anhängt anstatt immer alles auslesen, Text dranhängen und dann wieder Text setzen?

    Auf www.winapi.net findest du ein Code zum Dranhängen.



  • Das tut es doch, es liest zuerst den Text ein, hängt was dran, und setzt den Text wieder... oder hab ich das umständlich gemacht?!?
    Ja, ich habs umständlich gemacht... kann ja nicht jeder auf so eine schöne Lösung wie bei winapi.net kommen 🙂

    Danke 😃


Anmelden zum Antworten