Wie kann ich ein Edit Control mit einem void* füllen?



  • Hallo,

    Weiß jemand wie ich ein Edit Conrol mit dem Wert einer Pointer Variable füllen kann? Ich wollte ein Dialog programmieren mit dem ich Daten über die serielle Schnittstelle senden und empfangen kann. Dazu wollte ich mir die empfangenen Daten in einem Edit Control anzeigen lassen. Ich arbeite mit den WinAPI-Funktionen CreateFile, WriteFile, ReadFile, CloseFile. Das senden funktioniert auch schon so weit ganz gut, nur habe ich mit dem empfangen so meine Probleme. Das liegt allerdings nicht an den API-Funktionen sondern daran, dass ich meine empfangenen Daten nicht in einem Edit Control darstellen kann. Ich weiß nicht wie ich mit dem 2.Parameter von ReadFile (void* ...) umgehen soll das mir die Daten in meinem Edit Control dargestellt werden.

    Vielleicht weiß ja jemand bescheid und kann mir mit meinem Problem weiterhelfen.

    Ach ja meinem Edit Control habe ich eine CString Variable hinterlegt.

    Oder wie stelle ich sonst meine mit der seriellen Schnittstelle erfassten Daten dar?

    Oliver



  • Weiß denn keiner einer Antwort?


  • Mod

    void* ist ein nicht spezifizierter Zeiger. In was hast Du denn nun die Daten gespeichert? In einem char Array?
    Wenn die Daten nun in einem char-Array sind, und Du Deinem Edit Control eine CString Variable zugeordnet hast, dann kannst Du die Daten aus dem char-Array einfach der CString Variable zuweisen und UpdateData aufrufen. Dann werden die Daten dargestellt.



  • Also ich zeig mal einen Ausschnitt meines Programmcodes:

    Im Header:

    public:
        char* testChar;
    

    Im Programmcode:

    void CSerial_006Dlg::OnBnClickedButtonEmpfangen()
    {
        ReadData(&testChar,1);
        //UpdateData(TRUE);
        SetDlgItemText(IDC_EDIT_EMPFANGEN,(LPCTSTR)testChar);
        //UpdateData(FALSE);
    }
    
    int CSerial_006Dlg::ReadData(void* buffer, int length)
    {
        DWORD receive = 0;
        if(hPort != 0 && length > 0){
            ReadFile(hPort,buffer,length,&receive,NULL);
        }
        if(receive != 0){
            return receive;
        }
        else{
            return 0;
        }
    }
    

    Wenn ich mich im Debug-Modus befinde, dann hat "testChar", nachdem Daten von der seriellen Schnittstelle eingelesen wurden den Inhalt 0xcccccc67 wenn ich ein 'g' über die serielle Schnittstelle mit einem anderen PC sende. Das ist laut ASCII-Tabelle ja richtig.



  • Dein Fehler ist erstens, daß du den Umgang mit Pointern nicht richtig verstanden hast - du füllst die char*-Variable testChar mit einem beliebigen Zahlenwert, der von SetItemDlgText() als Adresse eines char-Arrays verwendet wird, und zweitens die fehlende Null-Terminierung deiner Ausgaben.

    //Ctor und Dtor für die Speicherverwaltung
    CSerial_006Dlg::CSerial_006Dlg() : testChar(new char[buflen+1] {}
    CSerial_006Dlg::~CSerial_006Dlg() {delete[] testChar;}
    /*
    alternativ könntest du statt des char* auch ein 'char testChar[buflen+1]' verwenden,
    dann erübrigen sich die beiden Funktionen
    */
    
    void CSerial_006Dlg::OnBnClickedButtonEmpfangen()
    {
        int rlen=ReadData(testChar,buflen);
        testChar[rlen]='\0';//Abschlußzeichen anhängen
        //UpdateData(TRUE);
        SetDlgItemText(IDC_EDIT_EMPFANGEN,(LPCTSTR)testChar);
        //UpdateData(FALSE);
    }
    
    int CSerial_006Dlg::ReadData(void* buffer, int length)
    {
        DWORD receive = 0;
        if(hPort != 0 && length > 0){
            ReadFile(hPort,buffer,length,&receive,NULL);
        }
        if(receive != 0){
            return receive;
        }
        else{
            return 0;
        }
    }
    


  • Ich habe versucht den Code entsprechend zu ändern. Wenn ich das Programm dann laufen lasse bekomme ich allerdings eine unbehandelte Ausnahme an der Stelle:

    testChar[rlen] = '\0';
    

    Ich muss allerdings dazusagen, dass ich nicht genau weiß an welcher Stelle ich den Speicher für mein char-Array wieder freigeben soll, auch wenn das wahrscheinlich jetzt nichts mit der unbehandelten Ausnahme zu tun hat. OK, Normalerweise gibt man den reservierten Speicher im Deskruktor wieder frei, nur wo ist der Destruktor in der Dialogklasse?

    Den Speicher für das Array habe ich hier untergebracht:

    CSerial_006Dlg::CSerial_006Dlg(CWnd* pParent /*=NULL*/)
        : CDialog(CSerial_006Dlg::IDD, pParent)
        , m_strSenden(_T(""))
        , m_strEmpfangen(_T(""))
        , testChar(new char[20+1])
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_EMS);
    }
    

    Statt

    testChar(new char[buflen+1])
    

    habe ich:

    testChar(new char[20+1])
    

    Da ich nicht weiß, wo ich die Variable "buflen" anlegen soll. Bitte jetzt nicht steinigen, denn ich bin was die Programmierung angeht noch ziehmlicher Anfänger.

    Oliver



  • Das Freigeben des Speichers erledigst du am einfachsten im Destruktor der Klasse.

    Und eine konstante Angabe von "20+1" kannst du natürlich auch nehmen - allerdings solltest du dann aufpassen, daß du maximal 20 Zeichen von der ReadDate()-Methode anfordern darfst, sonst hat das abschließende '\0' keinen Platz mehr im reservierten Speicherblock (und das benötigst du, wenn du die Daten als C-String weiterverarbeiten willst).



  • Hallo,

    also erstmal vielen Dank für deine Hilfe

    ich habe eben noch einen Fehler behoben. Somit bekomme ich jetzt auch keine unbehandelte Ausnahme mehr.

    Und zwar hatte ich noch den alten Code drin:

    int rlen = ReadData(&testChar,20);
    

    statt Deinen neuen Code zu nehmen, ohne &:

    int rlen = ReadData(testChar,20);
    

    Jetzt bekomme ich auch Zeichen allerdings nicht die Zeichen, die ich gesendet habe.
    Sondern:

    lauter Vierecke 😕

    Vielleicht sollte ich noch dazu sagen, das ich auf der Senden-Seite also mit dem anderen PC das Programm "Hyperterminal" verwende. Das Betriebssystem ist auf beiden Rechnern XP.

    Oliver


Anmelden zum Antworten