"Edit"-Window Kann man den Inhalt UPDATEN anstatt ihn zu überschreiben ?


  • Mod

    Wenn Du nur scrollst bleibt das letzte Item aktiv. Bewegt nun der Benutzer die Cursor-Taste springt die Anzeige auf das zuletzt markierte Item zurück.

    Durch LB_SETCURSEL wird die Selektion versetzt.



  • Achso okay, das wusste ich nicht . Vielen Dank 🙂

    Habe noch eine weitere Frage : Wie machen Programme wie ICQ/MSN das, dass sie 2 Fenster auf einmal haben ? Ich denke mal, dass das Hauptfenster das mit den Kontakten ist. Wenn man dann ein Kontak doppel-klickt bekommt wird ja ein neues Fenster ( eben zum chatten mit diesem Kontakt ) geöffnet. Und dieses Fenster ist wohl definitiv kein Child-Window sondern ein eigenes Fenster. Da aber doch jedes Fenster eine eigene, unendliche Message-Schleife hat, müsste man das ganze wohl Mutlithreaden ?



  • Oh moment, ich bin wohl doch fündig geworden :

    http://stackoverflow.com schrieb:

    Your message loop fetches, and dispatches, messages for all windows created on the current thread.

    A simple message loop like this will suffice.

    MSG msg;
    while(GetMessage(&msg,0,0,0,0)>0)
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

    Otherwise, to create windows on the thread, you simply call CreateWindow(...) as often as you want/need to build your UI.

    Warning: A common pattern seen in many simple programs is to handle WM_DESTROY in a WindowProc to call PostQuitMessage(). PostQuitMessage() posts a message to the thread, telling the message loop to exit. This will terminate the app, destroying all the windows on the thread. If you have a main application window that, if closed, should exit the app, only that window should call PostQuitMessage. If you have two (or more) windows that can be closed in any sequence, then you need to maintain a count of open windows and call PostQuitMessage only when the last window is closed by the user.

    Really, any sample program that demonstrates a dialog box is ALSO demonstrating how to create many windows on a thread, as every control on a dialog box IS also a window with a windowproc.

    Many new Windows developers fall into a trap of trying to filter messages for a specific window:

    while(GetMessage(&msg,hwnd,0,0,0)...

    This is wrong as it prevents any child windows getting their messages. Lots of utilitie libraries will create hidden windows on a thread and use them to receive messages from other processes / threads - filtering only messages for the app window like that will cause the message queue to grow, and other things to fail in strange an unusual ways. Pass NULL for the hwnd until you understand exactly why you might want to filter messages for a specific window for a while.

    Auf English googlen hilft wohl 😛



  • WinApi-Noob schrieb:

    Wenn man dann ein Kontak doppel-klickt bekommt wird ja ein neues Fenster ( eben zum chatten mit diesem Kontakt ) geöffnet. Und dieses Fenster ist wohl definitiv kein Child-Window sondern ein eigenes Fenster.

    Ich hoffe ich habe dich nicht falsch verstanden, aber das Erstellen eines Child-Window und das Erstellen eines neuen Fensters schließen sich ja nicht gegenseitig aus. Das zweite ist einfach ein modeless child window (kA wie's auch Deutsch richtig heißt).



  • Hmm, ich dachte ein Child-Window liegt bedingt innerhalb des Parent-Windows ? Bei den Chat-Programmen ist das ja eher nicht der Fall.



  • Sorry, dass ich schon wieder nerve aber ich bekomme hier was nicht hin :

    Ich habe eine Funktion, die in einer Endlosschleife auf Daten warten soll ( recv() von den WinSockets ) .
    Mein Problem : Wo soll die laufen ? Denn das Programm hat ja eig. schon eine Endlosschleife, die ausgeführt werden muss : Die Message-Schleife.

    Hatte mir überlegt, die funktion ( receive() ) in ein Thread zu packen und vor der Message-Schleife aufzuführen, in der Hoffnung, dass die sich wechselseitig CPU-Zeit geben 😛

    LPDWORD dwThreadId;
    HANDLE hTread = CreateThread( NULL , 0 , reinterpret_cast<LPTHREAD_START_ROUTINE>( receiveData ) , NULL , 0 , dwThreadId);            
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    

    Naja, scheint nicht so zu klappen. Mein Programm hängt sich auf.

    Villeicht denke ich auch zu kompliziert, kann ich die Funktion evtl auch einfach in der Message-Schleife ausführen lassen ? Etwa hier oder so :

    while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
            // --> Hier
        }
    

    Und dann eben die Endlosschleife aus der Funktion an sich raushausen ?

    Mal meine receiveData() an sich :

    [cpp]
    void receiveData() {
    int rec = 0;
    char buffer[1024];
    while(1) {
    rec = recv(s,buffer,1024,0);
    //If recv returns 0 or SOCKET_ERROR the server closed the connection.
    if(rec == 0 || rec == SOCKET_ERROR ) {
    Data.push_back( "Server closed the Connection ..." );
    SendMessage(GetDlgItem(hwnd, ListBoxId), LB_ADDSTRING, 0,0);
    SizeListItems(GetDlgItem(hwnd, ListBoxId), Data);
    closesocket(s);
    WSACleanup();
    exit(1);
    }
    else {
    buffer[rec] = '\0';
    SendMessage(GetDlgItem(hwnd, ListBoxId), LB_ADDSTRING, 0,0);
    SizeListItems(GetDlgItem(hwnd, ListBoxId), Data);
    Data.push_back(buffer);
    }

    }

    }[cpp]



  • Umpf ... nochmal die Funktion :

    void receiveData() {
         int rec = 0;
         char buffer[1024];
         while(1) {
              rec = recv(s,buffer,1024,0);
              //If recv returns 0 or SOCKET_ERROR the server closed the connection.
              if(rec == 0 || rec == SOCKET_ERROR ) {
                 Data.push_back( "Server closed the Connection ..." );
                 SendMessage(GetDlgItem(hwnd, ListBoxId), LB_ADDSTRING, 0,0);
                 SizeListItems(GetDlgItem(hwnd, ListBoxId), Data);
                 closesocket(s);
                 WSACleanup();
                 exit(1);
              }
    
              else {
                buffer[rec] = '\0';
                SendMessage(GetDlgItem(hwnd, ListBoxId), LB_ADDSTRING, 0,0);
                SizeListItems(GetDlgItem(hwnd, ListBoxId), Data);
                Data.push_back(buffer);
              }
    
         }
    
    }
    

  • Mod

    Bau einen eigenen Thread dafür.
    Der neue Thread benötigt keine Messageloop!
    Du kannst enfach dort auf die Daten oder das Programmende warten.



  • Hmm, du meinst so wie im 1. Code den ich geposted habe :

    LPDWORD dwThreadId;
        HANDLE hTread = CreateThread( NULL , 0 , reinterpret_cast<LPTHREAD_START_ROUTINE>( receiveData ) , NULL , 0 , dwThreadId);            
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    

    Mir wurde gesagt, dass hier 1. der reinterpret_cast keinen Sinn macht ( wollte eig. auch static cast verwenden ) und 2. garkeiner gebraucht ist wenn man die Funktion richtig deklariert, und zwar sollte sie so aussehen :

    DWORD WINAPI receiveData(LPVOID)
    

    Warum man diese calling convention ( WINAPI alias __stdcall ) angeben muss is mir aber irgendwie schleiferhaft 😛

    Aber auch so funktioniert das nicht, ich weiss halt nicht wo ich den Thread starten soll.



  • Soooo, ich bins wieder mit neuen Probleme 😛

    Und zwar habe ich in meinem Main-Fenster ein Edit-Control zur Eingabe. Wenn der User Enter drückt, soll der Content davon abgeschickt werden. Das Problem : Das Edit-Control gibt mir keinerlei Infos darüber, was gerade eingegeben wurde. Da gibt es leider nur ES_UPDATE, dass mir zwar sagt, dass der Text gleich erweitert wird, aber nicht um welches Zeichen -.-

    Also musste meiner Meinung nach GetAsyncKeyState her :

    while (GetMessage (&messages, NULL, 0, 0))
        {
            if( GetAsyncKeyState( VK_RETURN ) & 0x8000 ) { 
               char temp_buf[1024];
               Edit_GetText( hInput, temp_buf , sizeof(temp_buf) );
               if ( strcmp( temp_buf, "" ) != 0 ) {
                   Data.push_back(temp_buf);
                   SendMessage(GetDlgItem(hwnd, ListBoxId), LB_ADDSTRING, 0,0);
                   SizeListItems(GetDlgItem(hwnd, ListBoxId ), Data);
                   SendMessage(GetDlgItem(hwnd, ListBoxId) , WM_VSCROLL, SB_BOTTOM, 0);
                   Edit_SetText ( hInput , "" );
               }
            } 
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    

    Problem : Da wird lauter Schmarrn ausgegeben ;P Das was ich eingebe, dann irgendwie noch 3 Leerzeilen. Verstehe ich also nicht, denn eigentlich dürfte GetAsyncKeyState ja nur anschlagen, wenn Enter down ist.

    Ein weiter Lösungvorschlag, der mir gemacht wurde : Im Hauptwindow Key-Events abfangen. Ja, das ist natürlich gut möglich, aber wie soll ich prüfen, ob der Key in der Edit-Box eingegeben wurde ? Da wurde dann Subclassing erwähnt, aber konkret habe ich keine Ahnung wie mir jetzt ne Klasse weiterhelfen soll ;P



  • EINE Zeile wird ausgegeben ( hab einfach mal der leere Zeugs angeklickt, und scheint ein Eintrag in der Listbox zu sein )


Anmelden zum Antworten