How to set cursor/entry point in an edit box after the last character of text in it.

Hello all,

I have created a multiline edit box using WIN32 APP.

The problem is that, the cursor blinks at the beginning of the edit box.

I want the cursor to blink at the end of the text that is already there...

Please help.

One way to do it is like:
(edit1 is the handle to my edit window)
1
2
3
        
        SendMessage (edit1,EM_SETSEL, 0, -1);
        SendMessage (edit1,EM_SETSEL, -1, -1);
ok thanks for the reply. Can you please tell me where I need to place this SendMessage(). I am placing it in case structure of WM_COMMAND of SEND button. However, its not working. I have checked for the error via GetLastError() and it shows the error as "Invalid window handle".
Please help me.
What handle did you use? If you are inside a dialog, you might have to use GetDlgItem() to retrieve the handle of the edit, or use SendDlgItemMessage() to use the resource id only.
@Ramses12
Please find part of my code. I am using the handle of edit box as shown below.

@Guestgultkan
Please tell me where I should use the SendMessage().



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
		case WM_CREATE:
		{
			// Create an edit box
			hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE,
				"EDIT",
				"",
				WS_CHILD|WS_VISIBLE|
				ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL,
				60,
				50,
				500,
				100,
				hWnd,
				(HMENU)IDC_MAIN_OUTPUT,
				GetModuleHandle(NULL),
				NULL);
                         break;

	case WM_COMMAND:
			switch(LOWORD(wParam))
            {
				case IDC_MAIN_SEND:
				{
					
					
					GetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1,sizeof(buffer1));
					strcat(buffer,"\r\n");
					strcat(buffer,buffer1);
					SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
					SendMessage(hEdit1,EM_SETSEL,0,-1); //I am using hEdit1 as handle of Edit box
					error=GetLastError();
					 SendMessage (hEdit1,EM_SETSEL, -1, -1);
					
					 error=GetLastError();
				//	abc.SetSel(-1,-1,FALSE);
					send(cd,buffer,sizeof(buffer1),0);
					memset(buffer1,0,sizeof(buffer1));
					SetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1);
				}
				break;
Last edited on
The principle is sound maybe the problem you are having is to do with input focus.
If IDC_MAIN_SEND is a button, then that will have the input focus when it is clicked.

When Editboxes do not have the keyboard input focus then they do not show the blinking caret (which you called the cursor).

We will try this (note we can get rid of those GetlastError calls.) and see what happens
1
2
3
4
5
6
7
8
9
10
11
12
13
case IDC_MAIN_SEND:
                {
                    
                    
                    GetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1,sizeof(buffer1));
                    strcat(buffer,"\r\n");
                    strcat(buffer,buffer1);
                    SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
                    SendMessage(hEdit1,EM_SETSEL,0,-1); //I am using hEdit1 as handle of Edit box
                    //error=GetLastError();
                     SendMessage (hEdit1,EM_SETSEL, -1, -1);
                   SetFocus(hEdit1);  //Set the focus back to the edit window
Last edited on
@Guestgulkan

Yes, IDC_MAIN_SEND is a SEND button.
I tried it but didnt work. I didnt understand the working of SetFocus function. I read it on MSDN. If I am understanding it somewhat....it should be used before SendMessage().
Last edited on
Post you full code (on here if possible - or on one of these code pasting sites) and I'll see if
I can finc what the problem is.
This is not the actual code...I am using it for testing. But i have all the fundamental parts of real program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#include  "afxwin.h"
#include "CEdit.h"
#include "CWnd.h"
#include "stdafx.h"
#include "windows.h"
#include "string.h"
#include "winsock2.h" //library for sockets

#define IDC_MAIN_SEND 101			// Button identifier
#define IDC_MAIN_CONNECT 104			// Button identifier
#define IDC_MAIN_DISCONNECT 105
#define IDC_MAIN_INPUT	102			// Edit box identifier
#define IDC_MAIN_OUTPUT	103			// Edit box identifier

HWND hEdit,hEdit1; //Handle for Edit Box
char buffer[512]; //Buffer for putting/getting data
char buffer1[100];
HANDLE ThreadReturn;
void client_program();
DWORD WINAPI Readthread(void *parameter);
//void Writethread(void *parameter);
SOCKET cd,sd;

HWND hWnd;
int error=0;

LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInst,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	//Define a class
 	WNDCLASSEX wClass;

	ZeroMemory(&wClass,sizeof(WNDCLASSEX));
	wClass.cbClsExtra=NULL;
	wClass.cbSize=sizeof(WNDCLASSEX);
	wClass.cbWndExtra=NULL;
	wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
	wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	wClass.hIcon=NULL;
	wClass.hIconSm=NULL;
	wClass.hInstance=hInst;
	wClass.lpfnWndProc=(WNDPROC)WinProc;
	wClass.lpszClassName="Window Class";
	wClass.lpszMenuName=NULL;
	wClass.style=CS_HREDRAW|CS_VREDRAW;


	//Register the class
	if(!RegisterClassEx(&wClass)) 
	{	
		//If class is not registered then get last error via GetLastError()
		int nResult=GetLastError();
		MessageBox(NULL,
			"Window class creation failed\r\n",
			"Window Class Failed",
			MB_ICONERROR);
	}


	//Create Parent window
	 hWnd=CreateWindowEx(NULL,
			"Window Class",
			"Client Side",
			WS_OVERLAPPEDWINDOW,
			200,
			200,
			640,
			480,
			NULL,
			NULL,
			hInst,
			NULL);

	if(!hWnd)
	{
		int nResult=GetLastError();

		MessageBox(NULL,
			"Window creation failed\r\n",
			"Window Creation Failed",
			MB_ICONERROR);
	}

    ShowWindow(hWnd,1);

	MSG msg;
	ZeroMemory(&msg,sizeof(MSG));

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

	return 0;
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
		case WM_CREATE:
		{
			// Create an edit box
			HWND hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE,
				"EDIT",
				"",
				WS_CHILD|WS_VISIBLE|
				ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL,
				60,
				50,
				500,
				100,
				hWnd,
				(HMENU)IDC_MAIN_OUTPUT,
				GetModuleHandle(NULL),
				NULL);


			strcpy(buffer,"Welcome to Chat Program (Client Side)- Created by AbHI\r\n");
			SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);


			hEdit=CreateWindowEx(WS_EX_CLIENTEDGE,
				"EDIT",
				"",
				WS_CHILD|WS_VISIBLE|
				ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL,
				60,
				200,
				500,
				100,
				hWnd,
				(HMENU)IDC_MAIN_INPUT,
				GetModuleHandle(NULL),
				NULL);

			// Create a push button
			HWND hWndButton1=CreateWindowEx(NULL,
				"BUTTON",
				"Send",
				WS_TABSTOP|WS_VISIBLE|
				WS_CHILD|BS_DEFPUSHBUTTON,
				185,
				350,
				100,
				24,
				hWnd,
				(HMENU)IDC_MAIN_SEND,
				GetModuleHandle(NULL),
				NULL);

			// Create a radio button (for connect)
			HWND hWndButton2=CreateWindowEx(NULL,
				"BUTTON",
				"Connect",
				WS_VISIBLE|WS_TABSTOP|
				WS_CHILD|BS_RADIOBUTTON|BS_CHECKBOX,
				315,
				325,
				100,
				24,
				hWnd,
				(HMENU)IDC_MAIN_CONNECT,
				GetModuleHandle(NULL),
				NULL);
				

			// Create a radio button (for disconnect)
			HWND hWndButton3=CreateWindowEx(NULL,
				"BUTTON",
				"Disconnect",
				WS_VISIBLE|
				WS_CHILD|BS_RADIOBUTTON|BS_CHECKBOX,
				315,
				375,
				100,
				24,
				hWnd,
				(HMENU)IDC_MAIN_DISCONNECT,
				GetModuleHandle(NULL),
				NULL);
	}
		break;
	/*	case WM_SETFOCUS:

			SetFocus(hEdit1);
			error=GetLastError();
			CreateCaret(hWnd,NULL,0,0);
			SetCaretPos(200,200);
			ShowCaret(hWnd);
			break;
	*/		

		case WM_COMMAND:
			switch(LOWORD(wParam))
            {
				case IDC_MAIN_SEND:
				{
					
				//	CEdit abc;	
					GetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1,sizeof(buffer1));
					strcat(buffer,"\r\n");
					strcat(buffer,buffer1);
					SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
					int length=GetWindowTextLength(hWnd);
					error=GetLastError();

					SetFocus(hEdit1);
					SendMessage(hEdit1,EM_SETSEL,0,-1);
					error=GetLastError();
					 SendMessage (hEdit1,EM_SETSEL, -1, -1);
					SetFocus(hEdit1);
					 error=GetLastError();
				//	abc.SetSel(-1,-1,FALSE);
					send(cd,buffer,sizeof(buffer1),0);
					memset(buffer1,0,sizeof(buffer1));
					SetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1);
				}
				break;
				case IDC_MAIN_CONNECT:
				{
					client_program();

				}
				break;
				
				case IDC_MAIN_DISCONNECT:
				{
					UINT state=IsDlgButtonChecked(hWnd,IDC_MAIN_CONNECT);
					if(state==BST_CHECKED)
					{
						DWORD s;
						strcpy(buffer,"Closing Connection from Remote Server.....\r\n");
						SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);

						
						int a,error=0;
						a=closesocket(cd);
						if(a==SOCKET_ERROR)//&&(CloseHandle(ThreadReturn)!=0))
						{
						//	Sleep(10000);
						//	strcpy(buffer,"Connection Closed");
						//	SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
							error=WSAGetLastError();
						//	buffer1=(char)error;
							strcpy(buffer,"\r\nError in closing socket");
							MessageBox(hWnd,buffer,"Error",MB_ICONERROR);
						//SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
							strcpy(buffer,"Can not close connection \r\nPlease check the error");
							SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);

							
						}
						WSACleanup();
						GetExitCodeThread(ThreadReturn,&s);
						//ExitThread(s);
						
					}
					else 
					{
						strcpy(buffer,"You are not connected to server");
						SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
					}

				}
				break;

			}
			break;

		case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}
		break;

		case WM_CLOSE:
		if(MessageBox(hWnd,"Really want to quit?","Quit",MB_OKCANCEL)==IDOK)
		{
			DestroyWindow(hWnd);
			break;
		}
		else return 0;
	}

	return DefWindowProc(hWnd,msg,wParam,lParam);
}





void client_program()
{	
does something
}
	
	
Last edited on
Anyone have any idea how to solve the issue.
Please help me. Its urgent.

Thanks in advance
Abhishek
Last edited on
Anyone have any idea how to solve the issue.
Please help me. Its urgent.

Thanks in advance
Abhishek
There is a problem in your code:

Here in your code
1
2
3
4
5
case WM_CREATE:
        {
            // Create an edit box
            HWND hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE,
                "EDIT",

You are creating a local variable called hEdit1
- BUT in the WM_COMMAND code - here

1
2
3
4
5
SetFocus(hEdit1);
                    SendMessage(hEdit1,EM_SETSEL,0,-1);
                    error=GetLastError();
                     SendMessage (hEdit1,EM_SETSEL, -1, -1);
                    SetFocus(hEdit1);

The handle hEdit1 is the GLOBAL variable hEdit1 that you declared on line 15.
This global variable hEdit1 has a value of 0 - so sending any messages to a window handle of 0
will just be silently dumped by windows.

So the WM_CREATE messagecode should be
hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE, and NOT HWND hEdit1=CreateWindowEx(WS_EX_CLIENTEDGE,

Do you see what I mean??
Last edited on
Thanks for the reply. I realize the difference. However, issue remains the same. :(
What?
I took your code which didn't work, made that simple change and it did work..
was the cursor pointing to last character.?

Just put multi lines in the lower edit box and then it will be passed to upper edit box on pressing send button. But the focus was not on last character.
I noticed that the cursor was pointing to last character. But when I put multiple lines....and when the last line sent is out of scope of edit box, it shows from the first character, even though the cursor is on last character. Thus, to see the last line I need to scroll it down.

I want that last line to be seen when SEND button is pressed.

BR//
Abhishek
@guestgulkan

Hey I found the solution. Along with EM_SETSEL we need another message as EM_LINESCROLL which will solv the purpose.

SendMessage (hEdit1,EM_LINESCROLL, wParam, lParam);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GetDlgItemText(hWnd,IDC_MAIN_INPUT,buffer1,sizeof(buffer1));
					strcat(buffer,"\r\n");
					strcat(buffer,buffer1);
					SetDlgItemText(hWnd,IDC_MAIN_OUTPUT,buffer);
				//	int length=GetWindowTextLength(hWnd);
					error=GetLastError();

					HWND a=SetFocus(hEdit1);
					SendMessage(hEdit1,EM_SETSEL,0,-1);
					error=GetLastError();
					 SendMessage (hEdit1,EM_SETSEL, -1, -1);
					SendMessage (hEdit1,EM_LINESCROLL, wParam, lParam);

				//	SetFocus(hEdit1);


Aha,
When I tested it I only tested with 3 or 4 lines so I never needed to scroll it - and it never crossed
my mind.

:)
Topic archived. No new replies allowed.