Skocz do zawartości

[RichEdit]Wstawianie do nowej lini


Brzdyl

Recommended Posts

Pewnie że się da ;)

Najpierw musisz przesunąć kursor do nowej linii:

int line_index = SendMessage(hEdit, EM_LINEFROMCHAR, (WPARAM) -1, 0) ;

line_index++ ;

int pos = SendMessage(hEdit, EM_LINEINDEX, line_index, 0) ;
SendMessage(hEdit, EM_SETSEL, pos, pos) ;

Komunikat EM_LINEFROMCHAR (zapomnialem go opisać w arcie..echh) zwraca na podstawie pozycji znaku numer linii w kontrolce richedit...jeśli podamy -1 wtedy zwróci nam bieżącą linię...następnie zwiększamy o jeden (możesz sprawdzać czy jest to ostania linia [EM_GETLINECOUNT i wtedy przejść do poprzedniej(--) lub pierwszej(0)). Mamy już właściwą linie...teraz wysyłamy EM_LINEINDEX i otrzymujemy nową pozycję znaku...potem tylko ustwiamy wiadomością EM_SETSEL pozycję kursora...

No i wypadałoby wstawić tekst...

EM_REPLACESEL
fCanUndo = (BOOL) wParam ;
lpszReplace = (LPCTSTR) lParam ;

fCanUndo określasz czy operacja wstawiania może być cofnięta..no a lpszReplace tekst do (w naszym przypadku nie mamy zaznaczonego przedziału) wstawienia...

to tyle, jeśli masz jakieś pytania to wal śmiało...coś na pewno znajdziesz w ostatnim arcie..który postaram się uzupełnić o pominięte przeze mnie infromacje...hehe wybaczcie... :$

pozdrawiam

Link do komentarza
Udostępnij na innych stronach

Jeśli richedit i wogle edit ma ustawione enabled na true to jest wszystko w porządku...nie rozumiem...znaczy, że jest aktywny, jakby miał enabled false to wtedy byłby nieaktywny...czy kod wtedy zadziała...myśle, że powinien zadziałać...ale nie jestem pewnien na 100% - sprawdź...hehe...jeśli nie chcesz żeby można było kliknąc i nic zmieniać w richedicie to ustaw flage EM_READONLY...a właściwie to nie mieszam już bo do końca nie wiem do czego ci to potrzebne i jaki chcesz osiągnąć efekt..hehe...możesz potraktować to jako pytanie..ale nie musisz... ;)

pozdrawiam

Link do komentarza
Udostępnij na innych stronach

  • 2 weeks later...

Witam

Nie wiem czy dobrze zrozumiałem ale jeżeli chodzi o procedurę wstawiającą tekst jako dowolną nową linię w RichEdit (w Edit też prawdopodobnie działa) to zobacz coś takiego (kod w MASM :D ):

InsertText proc uses esi hEdit:HWND, LineIndex: DWORD, lpText: LPSTR
LOCAL SelStart, LineLen: DWORD 
;Rozmiar bufora rowny maksymalemu długości linji + 2
LOCAL Buf[1024]: BYTE  
LOCAL lpNewLine[3]: BYTE 

    lea esi, lpNewLine          
    mov dword ptr [esi], 0A0Dh  ;Znaki nowej linii do buforka #13#10
    .if LineIndex > 0
        invoke SendMessage, hEdit, EM_LINEINDEX, LineIndex, 0
        mov SelStart, eax
        .if eax >= 0
            ;Kopiujemy wstawiany Tekst do buforka 
            invoke lstrcpy, addr Buf, lpText
            ;Dołanczamy znaki nowej linii #13#10 do buforka
            invoke lstrcat, addr Buf, addr lpNewLine
        .else
            invoke SendMessage, hEdit, EM_LINEINDEX, LineIndex - 1, 0
            mov SelStart, eax
            .if eax < 0
                ret
            .endif
            invoke SendMessage, hEdit, EM_LINELENGTH, eax, 0
            mov LineLen, eax
            .if eax < 0
                ret
            .endif 
            add SelStart, eax ;SelStart = SelStart + LineLen
            ;Kopiujemy znaki nowej linii #13#10 do buforka
            invoke lstrcpy, addr Buf, addr lpNewLine
            ;Dołanczamy wstawiany Tekst do buforka 
            invoke lstrcat, addr Buf, lpText                  
        .endif  
        invoke SendMessage, hEdit, EM_SETSEL, SelStart, SelStart
        invoke SendMessage, hEdit, EM_REPLACESEL, 0, addr Buf             
    .endif  
        ret
                
InsertText endp

Parametry:
hEdit:HWND - Uchwyt RichEdit
LineIndex: DWORD - Nr. linii do ktorej ma być wstaiony tekst
lpText: LPSTR - Adres buforka z tekstem który ma być wstawiony

Jeżeli chcesz dodać nową linię na końcu tekstu to wcześniej wysyłasz komunikat EM_GETLINECOUNT który zwraca ilosć linii w RichEdit-a więc to podstawiasz jako LineIndex

A jeżeli chcesz aby RightEdit zachowywał sie jak Static (Nie można edytować, brak migającego kursora, nie można zaznaczać tekstu) to kiedyś wymyśliłem 9_9 takie rozwiązanie (choć nie wiem czy najlepsze). Ustawiasz mu styl ES_READONLY i pomocą SubClassingu podmieniasz procedurę obsługi RichEdit na coś takiego:

RichEditProc proc hRichEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

     .if (uMsg==WM_CHAR) || (uMsg == WM_LBUTTONDOWN) 
        ;Wywołaj starą procedurę obsługi okna
        invoke CallWindowProc,lpRichEdit,hRichEdit,uMsg,wParam,lParam
        invoke HideCaret, hRichEdit ;Ukryj kursor
        sub eax, eax ;Zwroc 0
        ret
     .elseif (uMsg == WM_SETFOCUS) || (uMsg == WM_SETCURSOR)  
        sub eax, eax ;Zwroc 0
        ret                     
     .endif
     ;Wywołaj starą procedurę obsługi okna
     invoke CallWindowProc,lpRichEdit,hRichEdit,uMsg,wParam,lParam
     ret

RichEditProc endp

Celowo nie robiłem nic przez EnableWindow ponieważ jak próbowałem ustawić na FALSE to nie mogłem zmienić koloru tła tekstu.

Jeżeli jednak nie o to chodziło :$ to sorry
Pozdro

Link do komentarza
Udostępnij na innych stronach

Witam

No to nie rozumiem w czym problem przecież napisalem jak wstawić tekst do nowej linii a z resztą chyba niema problemu :/

;Pobierz tekst z RighEdit
invoke GetWindowText, hRichEditMaly, addr szBufText, 1024
;Sprawdź do której linii wstawić
invoke SendMessage, hRichEditDuzy, EM_GETLINECOUNT, 0, 0
;Kod funkcji InsertText masz w moim poprzednim poście
;w eax jest numer linii d o której wstawiamy tekst 
;(w tym wypadku na koniec) 
invoke InsertText, hRichEditDuzy, eax, addr szBufText
;Wyczyść tekst
invoke SetWindowText, hRichEditMaly, NULL

PS: Moja funkcja InsertText ma pewną wadę: Jeżeli w RichEdit znajduje sie już tekst wstawiony np. przez SetWindowText to na jego końcu nie ma znaków końca linii #13#10 więc przed wstawieniem tekstu trzeba wstaić te znaki na początku wstawianego tekstu. Jeżeli natomiast użyjesz InsertText na wyczyszczonym RichEdit to i czały czas za pomocą tej funkcji dokładasz nowy tekst to niema problemu :)
PS2: Jeżeli cos nie działa albo nie umiesz przetłymaczyć tego na C++ to napisz spróbuję wyjaśnić o co chodzi. Bo ten kod działa sprawdziłem (przynajmniej w tekscie bez obrazków) :D

Pozdro

Link do komentarza
Udostępnij na innych stronach

Witam ponownie

Rzeczywiście ten mój pierwszy sposób jest baaardzo zły...jednak żeby wyjść z tego wszystkiego z honorem ;) zmarax masz tutaj funckje:

bool WstawNowaLinia(char * tekst, HWND hEdit)
{
    char nowalinia[255] ;
    int line, line_count, line_len, start ;
    
    if((tekst[0] != (char) NULL) && (hEdit))
    {
        line_count = SendMessage(hEdit, EM_GETLINECOUNT, (WPARAM) 0, (LPARAM) 0) ;
        line       = SendMessage(hEdit, EM_LINEINDEX, (WPARAM) (line_count - 1), (LPARAM) 0) ;
        line_len   = SendMessage(hEdit, EM_LINELENGTH, (WPARAM) line, (LPARAM) 0) ;
        
        start = line + line_len ;
                
        SendMessage(hEdit, EM_SETSEL, start, start) ;                
                
        if(line)
        wsprintf(nowalinia, "\n%s", tekst) ;
        else
        wsprintf(nowalinia, tekst) ;
        
        SendMessage(hEdit, EM_REPLACESEL, (WPARAM) 1, (LPARAM) nowalinia) ;
        return true ;
    }    
    return false ;
}    

Wyjaśnienie:

Jeśli wszystko zostało prawidłowo przekazane to najpierw pobieramy sobie ilość lini, a potem (ideks jest liczony od zera ilość linie nie) za pomocą EM_LINEINDEX otrzymujemy odpowiednie współrzędne lini. Pobieramy długość tej linii i (w start) otrzymujemy pozycję ostatniego znaku w tekście..ostaniego znaku(!!!!!!!!!!)....kurde..a nie lepiej zrobić tak:

bool WstawNowaLinia(char * tekst, HWND hEdit)
{
    char nowalinia[255] ;
    int start ;
    
    if((tekst[0] != (char) NULL) && (hEdit))
    {
        start = (GetWindowTextLength(hEdit) -1) ;
                
        SendMessage(hEdit, EM_SETSEL, start, start) ;                
                
        if(start != -1)
        wsprintf(nowalinia, "\n%s", tekst) ;
        else
        wsprintf(nowalinia, tekst) ;
        
        SendMessage(hEdit, EM_REPLACESEL, (WPARAM) 1, (LPARAM) nowalinia) ;
        return true ;
    }    
    return false ;
}    

Pobieramy ilość tekstu i odejmuje jeden (w końcu ma być to index, liczony od 0). No a potem to już wszystko jasne...

Jeśli chcesz zrobić tak jak w gg...to nie ma problemu. Ustawiasz sobie flage ES_READONLY (w gg można zaznaczać). Potem jakiś przycisk, który będzie dodawał nowe linie. Oto przykładowa obsługa zdarzenia dla takiego przycisku:

char pomoc[255] ;
//----
case WM_COMMAND:
    if(wParam == 100) //załużmy, że id tego przycisku to 100
    {
        GetWindowText(hZdanie, pomoc, 255) ; //pobieramy sobie tekst do dodania
        WstawNowaLinie(pomoc, hDialog) ; //wstawiamy go do okna dialogu (tak jak w gg ;))
        SetWindowText(hZdanie, "") ; //czyścimy pole do wprowadzania tekstu
    }    
    break ;
//----
break ;

I nie wciskać kitu, że nie działa bo sprawdzałem...hehe
I to tyle. Pozdrawiam ;)

Link do komentarza
Udostępnij na innych stronach

Witam
Tworzysz sobie zmienne globalne i deklarujesz.

#include <windows.h>
// -= tu deklaracje pozostałych modółów =-
// -= tu ewentualne nagłówki procedur =-
// -= a tutaj deklaracje zmiennych globalnych np.: =>
HWND hDialog;
HWND hZdanie;
// -= no i dopiero dalej właśiwy kod programu =-

Mam nadzieję, że teraz już wszystko jest jasne :D
Podro

Link do komentarza
Udostępnij na innych stronach

#include <winsock2.h>
#include <windows.h>
static TCHAR nazwa[]=TEXT("okno");
char wyslij[1000];
int ID, kom;
SOCKET klient;
HWND hDialog, hZdanie;
bool WstawNowaLinia(char * tekst, HWND hEdit)
{
   
    int line, line_count, line_len, start ;
   
    if((tekst[0] != (char) NULL) && (hEdit))
    {
        line_count = SendMessage(hEdit, EM_GETLINECOUNT, (WPARAM) 0, (LPARAM) 0) ;
        line       = SendMessage(hEdit, EM_LINEINDEX, (WPARAM) (line_count - 1), (LPARAM) 0) ;
        line_len   = SendMessage(hEdit, EM_LINELENGTH, (WPARAM) line, (LPARAM) 0) ;
       
        start = line + line_len ;
               
        SendMessage(hEdit, EM_SETSEL, start, start) ;               
               
        if(line)
        wsprintf(wyslij     , "\n%s", tekst) ;
        else
        wsprintf(wyslij, tekst) ;
       
        SendMessage(hEdit, EM_REPLACESEL, (WPARAM) 1, (LPARAM) wyslij) ;
        return true ;
    }   
    return false ;
}       

LRESULT CALLBACK ProcOkna(HWND uchwyt,UINT komunikat,WPARAM wParam,LPARAM lParam)
{
  switch (komunikat)
  {
        case WM_CREATE:
        //
        break;
        case WM_COMMAND:
        ID = LOWORD(wParam);
                kom = HIWORD(wParam);
                if((kom == BN_CLICKED)&&(ID=2)) {
                         ;


                        GetDlgItemText(uchwyt, 3, wyslij, 999);
                        GetWindowText(hZdanie, wyslij, 999);
                        send(klient, wyslij, sizeof(wyslij), 0);
                        WstawNowaLinia(wyslij, hDialog);
                    SetDlgItemText(uchwyt, 3, "");
        }
                break;
                case WM_DESTROY:
        PostQuitMessage(0);
        break;

        case WM_KEYDOWN:
            switch (wParam)
            {
            case VK_ESCAPE:
            PostQuitMessage(0);
            break;
            }
        break;

default:
return (DefWindowProc(uchwyt,komunikat,wParam,lParam));
}
return(0L);
} 

Nie wiem dalej nie działa... ;(
Jeszcze raz dzięki tym którzy mi odpowiadają :D

Link do komentarza
Udostępnij na innych stronach

Może spróbuj tak


#include <windows.h>

char wyslij[1000];
int ID,kom;
HWND hDialog,hZdanie;

LRESULT CALLBACK ProcOkna(HWND uchwyt,UINT komunikat,WPARAM wParam,LPARAM lParam)
{
   switch(komunikat)
   {
        case WM_CREATE:
        //
        break;
        
        case WM_COMMAND:
           ID=LOWORD(wParam);
           kom=HIWORD(wParam);
           if((kom==BN_CLICKED)&&(ID=2))
      {
                   GetWindowText(hZdanie,wyslij,999);
                   int start=GetWindowTextLength(hDialog);
                   SendMessage(hDialog,EM_SETSEL,start,start);
         SendMessage(hDialog,EM_REPLACESEL,0,(long)wyslij);
                   SendMessage(hDialog,EM_REPLACESEL,0,(long)"\n");
                   SetWindowText(hZdanie,"");
           }
        break;

        // itd. .......
        // ............
    }
}
Link do komentarza
Udostępnij na innych stronach

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gość
Odpowiedz...

×   Wkleiłeś zawartość bez formatowania.   Usuń formatowanie

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Utwórz nowe...