RichEdit will nicht



  • Moin Mr Evil 😉 ,

    Mr Evil schrieb:

    aber er findet nie was, das verwirrt mich

    Hm was sagt denn GetLastError() ?

    Mr Evil schrieb:

    long CRichedit::FindString(DString strName, unsigned int uiAt) const{
        CHARRANGE Search;
        Search.cpMin = uiAt;
        Search.cpMax = -1;
    
        CHARRANGE Found;
        Found.cpMin = 0;
        Found.cpMax = -1;
    	
        FINDTEXTEX text;
        text.chrg = Search;
        text.lpstrText = const_cast<LPTSTR>(strName.c_str());
        text.chrgText = Found;
    
        ::SendMessage(m_Handle, EM_FINDTEXTEX, 0, reinterpret_cast<LPARAM>(&text));
        return text.chrgText.cpMin;
        // text.chrgText.cpMin sowie cpMax sind nach SendMessage immer -1
    }
    long pos = m_Element.FindString(_T("Text"), 0); // immer -1
    

    Lass da mal den const_cast weg, sowas gehört sich nicht 😉 . Man castet das const von c_str() nicht einfach so weg (und hier ist es auch nicht nötig).
    Siehe

    [...]LP[b]C[/b]TSTR lpstrText;[...]
    

    . Das C impliziert hier const 😉 .

    Du brauchst hier übrigens die beiden Variablen 'Search' und 'Found' nicht 💡 , da Du ja auch direkt über die Struktur FINDTEXTEX darauf zugreifen kannst.

    Mr Evil schrieb:

    zudem ist "FR_DOWN" oder "FR_MATCHCASE" immer unbekannt, hab ich auch nicht in intellisense
    jemand n plan ?

    Jo da brauchst Du noch den Header: commdlg.h

    Mr Evil schrieb:

    wenn ich erst alles hole und dann den string durchsuche funktioniert logischerweise alles - aber ich find das ein bloeden workaround - ich moechte nicht jedesmal das gesammte edit auslesen muessen

    Jo das ist echt hässlich^^, und dauert bei längeren Texten ja auch wesentlich länger... 🤡

    PS: Wenn es Dir nichts ausmacht, kannst Du mir die Klassen mal per Mail schicken ? - würde mich echt interessieren 😋 ! ➡ sieht nämlich ganz ordentlich aus 👍 .

    PPS: Das Flag FR_DOWN bringt Dir in Deiner derzeitigen Version (wie ich vermute, da Du warscheinlich RichEdits der Version 1 erstellst) nichts, siehe:

    MSDN zu EM_FINDTEXTEX Message schrieb:

    Rich Edit 1.0: The FR_DOWN flag is ignored. The search is always from the end of the current selection to the end of the document.

    Quelle: http://msdn2.microsoft.com/en-us/library/ms651982.aspx



  • CodeFinder schrieb:

    Hm was sagt denn GetLastError() ?

    das hab ich bisher nicht geschaut #gg

    CodeFinder schrieb:

    Lass da mal den const_cast weg, sowas gehört sich nicht 😉 . Man castet das const von c_str() nicht einfach so weg (und hier ist es auch nicht nötig).
    Siehe

    [...]LP[b]C[/b]TSTR lpstrText;[...]
    

    . Das C impliziert hier const 😉 .

    wenn ich da nicht caste bekomm ich nur bloede error im form von "kann x nicht nach LPTSTR schieben"

    CodeFinder schrieb:

    Du brauchst hier übrigens die beiden Variablen 'Search' und 'Found' nicht 💡 , da Du ja auch direkt über die Struktur FINDTEXTEX darauf zugreifen kannst.

    ich dacht ich muss die vorher angeben, da in der MSDN zu FINDTEXTEX steht das ich was angeben muss

    CodeFinder schrieb:

    Jo da brauchst Du noch den Header: commdlg.h

    ok, danke

    CodeFinder schrieb:

    Jo das ist echt hässlich^^, und dauert bei längeren Texten ja auch wesentlich länger... 🤡

    darum will ich es ja vermeiden

    CodeFinder schrieb:

    PS: Wenn es Dir nichts ausmacht, kannst Du mir die Klassen mal per Mail schicken ? - würde mich echt interessieren 😋 ! ➡ sieht nämlich ganz ordentlich aus 👍 .

    #gg danke, ich kapsel, wie ich hier irgendwo schonmal erwaehnte, die WinAPI in klassen welche mich die zugriffe erleichtern - aehnlich wie die MFC usw - diese elemente habe ich schon "fertig" {erweiterbar ist es ja immer}:
    Button:
    Checkbox:
    Edit:
    Listbox:
    Listbox Control:
    Progress Bar:
    Status Bar:
    Textbox:
    Groupbox:
    Radiobox:
    Combobox:
    Slider:
    Scrollbar:
    Treeview:
    meine aufrufe sehen immer so aus
    in der main klasse fuer das hauptfenster einfach eine instanz meiner klasse

    CElement m_Element;
    

    und dann

    //CElement::Create(DString strName, ELEMPOS pos, HWND *MainHandle, unsigned int uiId)
    m_Element.Create(_T("Titel"), ELEMPOS(10, 10, 70, 20), &hWnd, IDC_ELEMENT);
    

    bei einer scrollbar oder sowas hab ich das wieder anders

    //CElement::Create(bool Vertical, ELEMPOS pos, HWND *MainHandle, unsigned int ID)
    m_Element.Create(false, ELEMPOS(10, 10, 70, 20), &hWnd, IDC_ELEMENT);
    

    halt je nach bedarf
    die einzelnen funktionen auch immer so gekapselt das ich nur minimalistisches aufrufen muss - und auch diverse hilffunktionen die einen den umgang erleichtern zb fuer OnSize ein

    m_Element.SetPos(&ELEMPOS(10, 10, 70, 20));
    

    dann brauch ich mich nicht um die ganzen windows messages zu kuemmern
    ich denk mir halt vorher immer alles moegliche aus was man brauchen koennte und das wird dann eingebunden

    ps. DString ist einfach ein define fuer std::string oder std::wstring und ELEMPOS ist eine kleine hilfsklasse aehnlich wie rect nur das diese left, top, wide, height beinhaltet

    alle klassen sind un unicode sowie multibyte compilierbar

    was ich noch einbinden will ist das ich die messages fuer die elemente auch nur global an die klasse weitergebe und diese dann selber raussucht und verwaltet

    was ich auch noch habe ist das direkt nach der _tmain nur drei zeilen sind und das hauptfenster und deren messages bereits in der hauptklasse sind - das moechte ich aber noch verbessern

    CodeFinder schrieb:

    PPS: Das Flag FR_DOWN bringt Dir in Deiner derzeitigen Version (wie ich vermute, da Du warscheinlich RichEdits der Version 1 erstellst) nichts, siehe:

    jo das kenn ich, aber ich bin verwirrt was ich ueberhaupt habe, und zwar hab ich diese Riched32.dll includiert und RICHEDIT_CLASS beim create



  • Button:
    Checkbox:
    Edit:
    Listbox:
    Listbox Control:
    Progress Bar:
    Status Bar:
    Textbox:
    Groupbox:
    Radiobox:
    Combobox:
    Slider:
    Scrollbar:
    Treeview:
    [...]

    Hey das hört sich echt gut an...war das jetzt ein ja ? 😋 ^^

    Bezüglich:

    wenn ich da nicht caste bekomm ich nur bloede error im form von "kann x nicht nach LPTSTR schieben"

    Dann solltest Du eine Kopie erstellen (C-String) und die Kopie übergeben, da const_cast's auf C++ Strings böse enden können.

    ich dacht ich muss die vorher angeben, da in der MSDN zu FINDTEXTEX steht das ich was angeben muss

    Ähm also ich meine das so:

    //  CHARRANGE Search;
    //  Search.cpMin = uiAt;
    //  Search.cpMax = -1;
    
        FINDTEXTEX text;
    //  text.chrg = Search;
        text.chrg.cpMin = uiAt;
        text.chrg.cpMax = -1;
        // ...
    


  • CodeFinder schrieb:

    Hey das hört sich echt gut an...war das jetzt ein ja ? 😋 ^^

    #gg
    solange keiner lacht weil er meint es besser zu koennen {und was auch gut moeglich ist}

    CodeFinder schrieb:

    Dann solltest Du eine Kopie erstellen (C-String) und die Kopie übergeben, da const_cast's auf C++ Strings böse enden können.

    hei gute idee - werd ich gleich morgen versuchen #gg

    CodeFinder schrieb:

    //  CHARRANGE Search;
    //  Search.cpMin = uiAt;
    //  Search.cpMax = -1;
       
        FINDTEXTEX text;
    //  text.chrg = Search;
        text.chrg.cpMin = uiAt;
        text.chrg.cpMax = -1;
        // ...
    

    aaaaaaaaaaah, so ist das gemeint, die anderen structs sind da schon bei {=

    hier mal die beispielklasse zu checkboxes:

    *wegedit*

    hat wie man erwarten kann hier und da seine eigenarten - zb das die Font einfach nur ueber ein unsigned int laeuft - und sonst welche sachen die ich so implementiert habe da ich es so immer benutz
    List Control und Treeview usw ist natuerlich laenger - klar

    nu aber nicht haun #gg



  • nu aber nicht haun #gg

    Ach quatsch wieso denn 😉 . Ich könnte Dir jetzt ne Liste mit Fehlern machen^^ (die zum Teil auch gravierend sind^^) aber ich will Dich ja nicht demotivieren 😉 .

    Jo also wenn ok, dann: cpp [minus] coding [at] arcor [punkt] de 😉



  • schreib mir ruhig deine meinung an mr.evil.evl@gmx.net - hab nichts dagegen diverse sachen auszubessern {= danke {=



  • ich hab dir ne mail geschrieben - waere schoen wenn wir uns darueber dann austauschen

    zurueck zu dem anderen problem wegen den suchen

    ich habs das jetzt so:

    long CRichedit::FindString(DString strName, unsigned int uiAt) const{
        FINDTEXTEX text;
        text.lpstrText = const_cast<LPTSTR>(strName.c_str());
        text.chrg.cpMin = uiAt;
        text.chrg.cpMax = -1;
    
        ::SendMessage(m_Handle, EM_FINDTEXTEX, 0, reinterpret_cast<LPARAM>(&text));
        return text.chrgText.cpMin;
    }
    

    cpMin ist immer -1
    GetLastError gibt hier "5" zurueck - wahrscheinlich da dieses EM_FINDTEXTEX kein GetLastError unterstuetzt, zumindest steht nichts in der MSDN
    dort steht aber:

    If there are no more matches, the return value is –1.
    

    und ich bekomm ja immer -1

    dazuedit: nachdem ich die "commdlg.h" eingebunden habe und FR_DOWN verwende funktioniert es !! {=

    long CRichedit::FindString(DString strName, unsigned int uiAt) const{
        FINDTEXTEX text;
        text.lpstrText = &strName[0];
        text.chrg.cpMin = uiAt;
        text.chrg.cpMax = -1;
    
        ::SendMessage(m_Handle, EM_FINDTEXTEX, FR_DOWN, reinterpret_cast<LPARAM>(&text));
        return text.chrgText.cpMin;
    }
    


  • was anderes:

    warum funktioniert das nicht, ich bekomm nie etwas zurueck:

    DString CRichedit::GetActLine() const{
    	unsigned int pos = (GetActLinePos()-1);
    	long leng = (GetLineLenght(pos)+1);
    	TCHAR *line = new TCHAR[leng];
    	::SecureZeroMemory(line, leng);
    	::SendMessage(m_Handle, EM_GETLINE, pos, reinterpret_cast<LPARAM>(line));
    	delete [] line;
    	return _T("");
    }
    

    get last error sagt gar nichts
    wenn ich
    TCHAR[200] mache holt er die zeile aber ohne abschliessendes \0 - ist dann "das ist die zeileXXXXXXXXXXXXXXX"
    wenn ich TCHAR[200] mit \0 deklariere schreibt er nichts hinein

    wenn ich "SecureZeroMemory" weg lasse, sind hinter der zeile IMMER noch andere ungewollte zeichen , und dann knallts bei delete
    mit SecureZeroMemory knallts nirgends aber ich erhalte auch kein string }=

    //dazuedit:

    bei dieser variante knallts anders:

    DString CRichedit::GetActLine() const{
    	unsigned int pos = (GetActLinePos()-1);
    	long leng = (GetLineLenght(pos)+(sizeof(TCHAR)*2));
    	TCHAR *line = new TCHAR[leng];
    	::SendMessage(m_Handle, EM_GETLINE, pos, reinterpret_cast<LPARAM>(line));
    	line[leng] = _T('\0');
    	delete [] line;
    	return _T("");
    }
    

    "wrote to memory after heap"
    im debugger sieht alles genau richtig aus


  • Mod

    Sag mal: Hast Du es schon mal mit lesen probiert? 👎

    1. Aus der EM_GETLINE Doku:
    Pointer to the buffer that receives a copy of the line. Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer. For ANSI text, this is the number of bytes; for Unicode text, this is the number of characters. The size in the first word is overwritten by the copied line.

    Ist doch logisch, dass Dir das Ding nicht initialisiert um die Ohren fliegt bzw. bei 0 nichts liefert!

    TCHAR *line = new TCHAR[leng];
    *reinterpret_cast<WORD*>(line) = leng;
    

    2. Es steht nichts in der Doku, dass der String 0 terminert wäre.
    Du erhälst die Länge als return Ergebnis:

    leng = ::SendMessage(m_Handle, EM_GETLINE, pos, reinterpret_cast<LPARAM>(line));
    line[leng] = _T('\0');
    


  • *reinterpret_cast<WORD*>(line) = leng;
    

    das hab ich ja noch nie gesehen, hatte das zwar gelesen in der MSDN aber nicht kapiert

    DString CRichedit::GetActLine() const{
    	unsigned int pos = (GetActLinePos()-1);
    	long leng = (GetLineLenght(pos)+(sizeof(TCHAR)*2));
    	TCHAR *line = new TCHAR[leng];
    	SecureZeroMemory(line, leng);
    	*reinterpret_cast<WORD*>(line) = static_cast<WORD>(leng);
    	leng = ::SendMessage(m_Handle, EM_GETLINE, pos, reinterpret_cast<LPARAM>(line));
    	line[leng] = _T('\0');
    	delete [] line;
    	return _T("");
    }
    

    knallt trotzdem bei delete mit der meldung "wrote to memory after heap"
    die laenge ist aber definitiv korrekt, das zweite leng braeuchte ich gar nicht holen da es oben bei "GetLineLenght" direkt schon geholt wird, also ist die ganze zeit ein unveraenderter wert

    bei
    long leng = (GetLineLenght(pos)+(sizeof(TCHAR)*2));
    knallts und bei
    long leng = (GetLineLenght(pos)+(sizeof(TCHAR)*3));
    nicht, versteh ich nicht, denn an der letzten stelle wird doch nie was geschrieben



  • Martin Richter schrieb:

    line[leng] = _T('\0');
    

    Sollte da nicht einfach = 0 reichen ? 0 ist doch 0 😉 .
    @Mr Evil:
    Dann siehts so aus, als würde etwas mit 'GetLineLenght' nicht stimmen.

    PS: Jo danke hab Deine Mail bekommen. Werd mich noch zurückmelden!



  • CodeFinder schrieb:

    line[leng] = _T('\0');
    Sollte da nicht einfach = 0 reichen ? 0 ist doch 0 😉 .

    ich mach auch immer \0 - das hatte ich damals so gelernt - war allerdings bei C, das \0 bedeutete immer null-terminierung

    CodeFinder schrieb:

    @Mr Evil:
    Dann siehts so aus, als würde etwas mit 'GetLineLenght' nicht stimmen.

    tatsaechlich, ich hab das mal mit diversen zeilen durchdebuggt, es lag daran das er "anscheinend" immer von der select position aus ging, ich hab das so gemacht das ich zu begin der funktion die alte selection merke, alles deselektiere, die laenge hole und dann wieder die alte selection drueber - hab ich eigentlich immer gemacht wenn ich es fuer eine funktion die selektierungen aendern muss



  • Mr Evil schrieb:

    CodeFinder schrieb:

    line[leng] = _T('\0');
    Sollte da nicht einfach = 0 reichen ? 0 ist doch 0 😉 .

    ich mach auch immer \0 - das hatte ich damals so gelernt - war allerdings bei C, das \0 bedeutete immer null-terminierung

    Jo ist ja auch nicht falsch, nur überflüssig 😉 .

    PS: <<Sie haben Post 😃 >>.


  • Mod

    Ich bin ein Fan von Code bei dem man erkennt, dass wir es hier mit Zeichen und strings zu tun haben.
    Deshalb finde ich es sogar lesbarer:

    line[leng] = _T('\0');
    


  • Martin Richter schrieb:

    Deshalb finde ich es sogar lesbarer:

    Ok ok, akzeptiert^^.


Anmelden zum Antworten