Text in die nächste Zeile einer EditBox hinzufügen.



  • Letzte Position mit EM_SETSEL auswhälen und mit EM_REPLACESEL ersetzen.

    HWND hEdit = GetDlgItem (hDlg, ID_EDIT);
    int ndx = GetWindowTextLength (hEdit);
    SetFocus (hEdit);
    SendMessage (hEdit, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);
    SendMessage (hEdit, EM_REPLACESEL, 0, (LPARAM) ((LPSTR) szBuffer));
    


  • hi okay... jetzt bricht aber mein Programm immer ab, an dem Punkt wo der string eingefügt werden soll. Gerade sieht es so aus:

    SendMessage(hWndEditRecv, EM_SETSEL, -1, 0);
    SendMessage(hWndEditRecv, EM_REPLACESEL, 0, (LPARAM) wBuf);



  • HighLigerBiMBam schrieb:

    Letzte Position mit EM_SETSEL auswhälen und mit EM_REPLACESEL ersetzen.

    HWND hEdit = GetDlgItem (hDlg, ID_EDIT);
    int ndx = GetWindowTextLength (hEdit);
    SetFocus (hEdit);
    SendMessage (hEdit, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);
    SendMessage (hEdit, EM_REPLACESEL, 0, (LPARAM) ((LPSTR) szBuffer));
    

    hier stürzt das programm leider auch ab...

    HWND hEdit = GetDlgItem (hDlg, ID_EDIT);
    

    und das^^ hab ich weggelassen da die box nicht in einem Dialog ist sondern im hWnd

    habe mal einfach SetWindowText benutze und damit einen text reingeschrieben
    und da stürzt das programm nicht ab.

    ich glaube es liegt an dieser funktion:

    SendMessage (hEdit, EM_REPLACESEL, 0, (LPARAM) ((LPSTR) szBuffer));
    


  • Warum denn SetFocus? Hatte irgendwann mal sowas geschrieben..

    // -> First kill window focus
      SendMessage(hwnd_edit, WM_KILLFOCUS, 0, 0);
      // -> Set carret at the end
      SendMessage(hwnd_edit, EM_SETSEL, textlen, textlen);
      // -> Replace selection (carret is at the end) so -> adding text
      SendMessage(hwnd_edit, EM_REPLACESEL, 1, (LPARAM)text);
      // -> Reset window focus
      SendMessage(hwnd_edit, WM_SETFOCUS, 0, 0);
    

  • Mod

    SendMessage(..., WM_SETFOCUS,...);
    Verbietet sich in jeder Art und Weise.

    Das ist die Notification, die von Windows gesendet wird und nicht ein Ersatz für die Funktion SetFocus!
    http://blog.m-ri.de/index.php/2007/12/24/die-unsitte-windows-interne-nachrichten-zu-versenden/

    Siehe auch:
    http://blog.m-ri.de/index.php/2007/08/24/setfocus-versus-wm_nextdlgctl/



  • Steht so bei Microsoft... Copy Paste ^^



  • @ Herr Richter 🙂
    Also - wenn Du das sagst wird es wohl stimmen. Ich habe nicht wirklich viel Ahnung von der WinAPI, also habe ich einfach mal "was gebastelt".
    Verhindern soll das ganze natürlich dass man den "caret" während des schreibens verschiebt. Das schöne an WM_SETFOCUS ist dass es eben nicht(!) den Focus auf das Fenster setzt, sondern ihn nur wieder zurück gibt falls das Fenster den Focus vorher hatte.
    SetFocus ist hier irgendwie kein wirklich passender Ersatz und mir fällt auch nichts anderes ein..



  • und wie muss ich es jetzt machen?

    hat keine ne antwort? hier mal mein ganzer code bis jetzt, vllt findet ja einer den fehler. isn bisschen viel 😃

    #include "stdafx.h"
    #include "ServerSocket.h"
    #include "WinSock2.h"
    
    #pragma comment(lib, "Ws2_32.lib")
    
    #define MAX_LOADSTRING 100
    
    // Globale Variablen:
    static SOCKET acceptSocket;
    static SOCKET connectedSocket;
    static TCHAR wBuf[400];
    static int in;
    static long rc;
    HINSTANCE hInst;
    TCHAR szTitle[MAX_LOADSTRING];					// Titelleistentext
    TCHAR szWindowClass[MAX_LOADSTRING];			// Klassenname des Hauptfensters
    
    // Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    DWORD	WINAPI		Listen(LPVOID);
    DWORD	WINAPI		Empfangen(LPVOID);
    INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int startWinsock(void);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
     	// TODO: Hier Code einfügen.
    	MSG msg;
    	HACCEL hAccelTable;
    
    	// Globale Zeichenfolgen initialisieren
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_SERVERSOCKET, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Anwendungsinitialisierung ausführen:
    	if (!InitInstance (hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	CreateThread(NULL,0,Listen,(LPVOID)0,0,0);
    	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SERVERSOCKET));
    
    	// Hauptnachrichtenschleife:
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SERVERSOCKET));
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH) CreateSolidBrush(RGB(220,220,220));
    	wcex.lpszMenuName	= 0;
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
    	return RegisterClassEx(&wcex);
    }
    
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
    
       hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hEditRecv, hEditSend, hBtnSend;
    	static RECT rcClient;
    	TCHAR SendBuf[100];
    	char buf2[100];
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    	case WM_CREATE:
    		GetClientRect(hWnd, &rcClient);
    
    		hEditRecv = CreateWindow(_T("edit"), NULL,
    									WS_VISIBLE | WS_CHILD | WS_BORDER | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL,
    									10, 10, rcClient.right-20, rcClient.bottom-50,
    									hWnd, (HMENU) 1, hInst, NULL);
    
    		hEditSend = CreateWindow(_T("edit"), NULL,
    									WS_VISIBLE | WS_CHILD | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL,
    									10, rcClient.bottom-35, rcClient.right-100, rcClient.bottom-rcClient.bottom+25,
    									hWnd, (HMENU) 2, hInst, NULL);
    
    		hBtnSend = CreateWindow(_T("button"), _T("Send"),
    									WS_VISIBLE | WS_CHILD | WS_BORDER,
    									rcClient.right - 80, rcClient.bottom - 35, 
    									rcClient.right - rcClient.right + 70, rcClient.bottom-rcClient.bottom + 25,
    									hWnd, (HMENU) 3, hInst, NULL);
    		break;
    
    	case WM_COMMAND:
    		if(in==1)
    		{
                            ///// Hier soll der Empfangen Text in Die EditBox geschrieben werden
    			int ndx = GetWindowTextLength (hEditRecv);
    			SetFocus (hEditRecv);
    			SendMessage (hEditRecv, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);
    			SendMessage (hEditRecv, EM_REPLACESEL, 0, (LPARAM) ((LPSTR) wBuf));
    		}
    
    		switch(LOWORD(wParam))
    		{
    		case 3:
    			GetWindowText(hEditSend, SendBuf, 100); 
    			WideCharToMultiByte(CP_ACP, NULL, SendBuf, sizeof(SendBuf), buf2, sizeof(buf2), 0, 0);
    			rc=send(connectedSocket,buf2,strlen(buf2),0); 
    			SetWindowText(hEditSend, _T(""));
    			break;
    		}
    
    		break;
    
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    
    		EndPaint(hWnd, &ps);
    		break;
    
    	case WM_SIZE:
    		switch(LOWORD(wParam))
    		{
    		case SIZE_RESTORED:
    			GetClientRect(hWnd, &rcClient);
    			MoveWindow(hEditRecv, 10, 10, rcClient.right-20, rcClient.bottom-50, 0);
    			MoveWindow(hEditSend, 10, rcClient.bottom-35, rcClient.right-100, rcClient.bottom-rcClient.bottom+25, 0);
    			MoveWindow(hBtnSend, rcClient.right - 80, rcClient.bottom - 35, 
    								 rcClient.right - rcClient.right + 70, rcClient.bottom-rcClient.bottom + 25, 0);
    			break;
    
    		case SIZE_MAXIMIZED:
    			GetClientRect(hWnd, &rcClient);
    			MoveWindow(hEditRecv, 10, 10, rcClient.right-20, rcClient.bottom-50, 0);
    			MoveWindow(hEditSend, 10, rcClient.bottom-35, rcClient.right-100, rcClient.bottom-rcClient.bottom+25, 0);
    			MoveWindow(hBtnSend, rcClient.right - 80, rcClient.bottom - 35, 
    					   rcClient.right - rcClient.right + 70, rcClient.bottom-rcClient.bottom + 25, 0);
    			break;
    		}
    		break;
    
    	case WM_DESTROY:
    		closesocket(acceptSocket);
    		closesocket(connectedSocket);
    		WSACleanup();
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    DWORD WINAPI Listen(LPVOID)
    {
    SOCKADDR_IN addr;
    
    		///// WinSock Starten
    		rc=startWinsock();
    		if(rc!=0)
    		{
    		MessageBoxA(NULL, "Fehler: startWinsock, fehler !", "Fehler", MB_OK);
    		return 1;
    		}
    
    		///// Socket erstellen
    		acceptSocket=socket(AF_INET,SOCK_STREAM,0);
    		if(acceptSocket==INVALID_SOCKET)
    		{
    		MessageBoxA(NULL, "Fehler: Der Socket konnte nicht erstellt Werden !", "Fehler", MB_OK);
    		return 1;
    		}
    
    		///// Socket binden
    		memset(&addr,0,sizeof(SOCKADDR_IN));
    		addr.sin_family=AF_INET;
    		addr.sin_port=htons(12345);
    		addr.sin_addr.s_addr=ADDR_ANY;
    		rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    		if(rc==SOCKET_ERROR)
    		{
    		MessageBoxA(NULL, " Bind Fehler! ", "Socket", MB_OK);
    		return 1;
    		}
    
    		///// In den listen Modus
    		rc=listen(acceptSocket,10);
    		if(rc==SOCKET_ERROR)
    		{
    		MessageBoxA(NULL, " Listen Fehler! ", "Socket", MB_OK);
    		return 1;
    		}
    		else
    		{
    		MessageBox(NULL, _T("acceptSocket ist im listen Modus...."), _T("Info"), MB_OK );
    		}
    
    		///// Verbindung Akzeptieren
    		connectedSocket=accept(acceptSocket,NULL,NULL);
    		if(connectedSocket==INVALID_SOCKET)
    		{
    			MessageBox(NULL, _T("Fehler: accept, fehler code: %d\n"), _T("Error"), MB_OK);
    			return 1;
    		}
    		else
    		{
    			MessageBox(NULL, _T("Neue Verbindung Akzeptiert!"), _T("Info"), MB_OK);
    		}
    
    		CreateThread(NULL, 0, Empfangen, (LPVOID)0, 0, 0);
    
    		return 0;
    }
    
    DWORD WINAPI Empfangen(LPVOID) 
    {
    char buf[258];
    
    	while(rc!=SOCKET_ERROR)
    	{
    		rc=recv(connectedSocket,buf,256,0);
    		if(rc==0)
    		{
    			MessageBoxA(NULL, "Server hat die Verbindung getrennt..", "Info", MB_OK);
    			break;
    		}
    		if(rc==SOCKET_ERROR)
    		{
    			MessageBoxA(NULL, "Fehler: recv", "Error", MB_OK);
    			break;
    		}
    		buf[rc]='\0';
    
                    ///// Der Text Der Empfangen wird
    		MultiByteToWideChar(CP_ACP, NULL, buf, sizeof(buf), wBuf, sizeof(wBuf));
    		in=1;
    	}
    
    	closesocket(acceptSocket);
    	closesocket(connectedSocket);
    	WSACleanup();
    
    	return 0;
    }
    
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    
    	case WM_COMMAND:
    
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }
    
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    

  • Mod

    cooky451 schrieb:

    @ Herr Richter 🙂
    Also - wenn Du das sagst wird es wohl stimmen. Ich habe nicht wirklich viel Ahnung von der WinAPI, also habe ich einfach mal "was gebastelt".
    Verhindern soll das ganze natürlich dass man den "caret" während des schreibens verschiebt. Das schöne an WM_SETFOCUS ist dass es eben nicht(!) den Focus auf das Fenster setzt, sondern ihn nur wieder zurück gibt falls das Fenster den Focus vorher hatte.
    SetFocus ist hier irgendwie kein wirklich passender Ersatz und mir fällt auch nichts anderes ein..

    Und was soll das verhindern?
    Du setzt doch die Position des Cursors explizit mit EM_SETSEL. Was soll also KillFocus und SetFocus verhindern?

    Lass es einfach weg.[s]



  • Probier das mal ohne KILLFOCUS usw, gib vielleicht alle 50ms eine neue Zeile aus und makiere den Text dann dauernd neu. Irgendwann wird dann der Text falsch makiert und überschrieben. (Sollte sich sehr schnell bemerkbar machen.)
    Ich weiß auch nicht genau woran das liegt - die Nachrichten sollten ja eigentlich direkt hintereinander geschickt werden. Aber KILLFOCUS und SETFOCUS verhindern das..


  • Mod

    cooky451 schrieb:

    Probier das mal ohne KILLFOCUS usw, gib vielleicht alle 50ms eine neue Zeile aus und makiere den Text dann dauernd neu. Irgendwann wird dann der Text falsch makiert und überschrieben. (Sollte sich sehr schnell bemerkbar machen.)
    Ich weiß auch nicht genau woran das liegt - die Nachrichten sollten ja eigentlich direkt hintereinander geschickt werden. Aber KILLFOCUS und SETFOCUS verhindern das..

    Unfug.
    1. Wenn Du nicht neue Nachrichten abholst kann keine Eingabe zwischen EM_SETSEL und EM_REPLACESEL
    2. Man muss nur sicher gehen und das Ende des Buffers ermitteln. Denn die Länge könnte sich ja durch Benutzereingaben verändern.
    3. Es ist falsch, falsch, falsch, WM_SETFOCUS oder WM_KILLFOCUS an ein Editcontrol zu senden! Das darf nur die Funktion SetFocus selbst.

    Nochmal: Zwischen 2 SendMessage (SetSel,ReplaceSel) Aufrufen die direkt aufeinander folgen gibt es keine Möglichkeit, dass Windows den Inhalt der Fenster oder dessen Position verändert.

    EOD



  • hmm....

    hat denn noch niemand von euch einen chat gebastelt oder so? da muss es doch eine lösung geben.



  • es funktioniert jetzt mit den funktionen nur geht der text nicht in die nächste zeile.

    doch jetz gehts

    danke euch allen....


Anmelden zum Antworten