Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Need some help with Editbox

Posted on 2009-12-16
34
Medium Priority
?
860 Views
Last Modified: 2013-11-20
Hello,
I have a large Editbox with multiline function.
How can I change the Editbox that after
54 chars added  a return to the new line will be set.
--------------------------------------------------------------------
A-3456789-123456789-123456789-123456789-1234<---- after I have entered 54 chars it should start at the beginning with a new line at pos A

Please help.
500 points.
Best regards,
Thomas


0
Comment
Question by:tsp2002
  • 18
  • 8
  • 7
  • +1
34 Comments
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26062478
You need to insert space after 54 character: A-3456789-123456789-123456789-123456789-1234<-space and then the rest.
I think, you are talking about the standard CEdit from MFC.
I think, that you need to modify the text before sending to the editbox.
If you draw the text in this editbox, you can modify the text before the drawing.
 
0
 
LVL 16

Expert Comment

by:Bryan Butler
ID: 26062498
You can use the ON_EN_MAXTTEXT event and when the max number of characters is reached (54) you would automatically add a CR/LF and increase the max number to 108. (ie increase by 54 each time)
0
 

Author Comment

by:tsp2002
ID: 26062763
You can use the ON_EN_MAXTTEXT....how can I do this?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26062866
EN_MAXTEXT is a notification that will be sent when the number of characters in the editbox will rich a predefined maximal number (also if the editbox does not have a scroll bar).
You editbox has many lines and each line you need to see 54 characters.
If I understand you correctly.
 
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26062924
If you want to try, you can handle this notification in the OnCommand of the parent window. You will receive EN_MAXTEXT there
if (LOWORD(wParam)==ID_MY_EDIT && HIWORD(wParam)==EN_MAXTEXT)
 
0
 

Author Comment

by:tsp2002
ID: 26062929
my editbox has a scrollbar and each line should only be 54 char.
How can I sent the EN_MAXTEXT notification to the editbox...can you provide some code, thanks
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26062971
The editbox sends this notification to the parent window.
You can send everything you want but it will not help.
m_Editbox->SendMessage(WM_COMMAND, EN_MAXTEXT, 0);
But it is absolutely wrong.
0
 

Author Comment

by:tsp2002
ID: 26063017
<<<<
The editbox sends this notification to the parent window.
You can send everything you want but it will not help.
m_Editbox->SendMessage(WM_COMMAND, EN_MAXTEXT, 0);
But it is absolutely wrong. >>>>
what did you mean....? will not work this ? or what do you mean
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26063150
That's my question. :)
What do you mean?
Shortly, comment 26062498 will not work for you now.
The answer is format the text before you send it to the editbox.
You asked about DrawText in your previous thread, so you can format the text before drawing.
For example, make a function MyFormat that will receive the text in CString object and this function will modify this object.
 
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26064921
Why do you want only 54 chars a line?

Note, an editbox normally has proportional font. Hence 54 iiiiiiiiiiii... is much less then 54 WWWWWW... beside ou change the font to monospace font (what normally doesn't look good).  If you need those fixed lines because of printing, the issue is the same. The printer also would use a proprotional font and though it might be a little different from that of the dialog font (you can try to use the same font family where the differences by scaling are minimal) it is much less a difference than with using 54 characters each line.

If you would call myEdit.FmtLines() the edit text retrieved would have a \r\r\n for each softbreak because of word wrapping and a \r\n for each user break (where the user typed ENTER). Maybe that helps you for your problem?

If you still want to have a wrapping before the 55th character you can get the EN_UPDATE notification (right-click at the edit control in resource editor and choose 'add event handler ... '). That way you will be notified for each character the user is to put to the edit control *BEFORE* it is displayed at screen. By calling LineIndex and LineLength you can retrieve the number of chars prior to the new char entered. If it is 54 you could iterate left until to next space and insert a \n there by calling the ReplaceSel member function. Don't forget to add also the new char passed by the current EN_UPDATE notification. If you call FmtLines you also could try to insert a "\r\r\n" sequence to indicate a soft break, but actually I don't know whether that works. To get the correct positions for inserting you would need to iterate all lines before the current line and call LineLength for that line.
0
 

Author Comment

by:tsp2002
ID: 26070462
Hello itsmeandnobodyelse's ,
please take a look at my code.
After I have added 54 chars it will start at the beginning of that line...but not at a new line.
Please help,
thanks.
Best regards,
Thomas
 

void CGeschaeftsadressen::OnEnChangeEditBemerkung_Anzahl_Zeichen_left()
{
	 //zeigt Anwender wieviele Zeichen man noch eingeben kann (4000 max. Zeichen)
	CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BEMERKUNG);
	pEdit->FmtLines(54);

        CString strTxt;
        GetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
        CString strMsg;
        strMsg.Format( "noch %d Zeichen", 1204 - strTxt.GetLength() );
        GetDlgItem(IDC_STATIC_BEMERKUNG)->SetWindowText( strMsg );

		m_BemerkungEingabeChar54=m_BemerkungEingabeChar54+1;
		if(m_BemerkungEingabeChar54==54)
		{
			strTxt.Insert(54,"\r\n");
	
			m_BemerkungEingabeChar54=0;
			SetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
		}

Open in new window

0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26070614
SetDlgItemText - because you replace the entire text in the editbox.
 
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26070633
You know that you can use GetDlgItemText function to take the text from the edit box, then add new line and then call SetDlgItemText.
There are other message you can send to the edit box in order to append the text. For example, EM_SETSEL and all around. But, I think, the way I explained is the simplest to understand.
0
 

Author Comment

by:tsp2002
ID: 26071025

You know that you can use GetDlgItemText function to take the text from the edit box, then add new line and then call SetDlgItemText.
How can I add a new line..it is to difficult to provide me with some code....?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26071170
>>>> pEdit->FmtLines(54);

The FmtLines is to let the CEdit add soft line-break characters \r\r\n for all automatical wrappings.  The argument is a BOOL where you can switch it on/off. For your first approach of OnEnChangeEditBemerkung_Anzahl_Zeichen_left() I would NOT work with formatted lines (later if it works without soft line-breaks you may switch the FmtLines on in the OnInitDialog). So comment the FmtLines for now:

    // pEdit->FmtLines(TRUE);


>>>>                m_BemerkungEingabeChar54=m_BemerkungEingabeChar54+1;
>>>>                if(m_BemerkungEingabeChar54==54)

No. You need to find out the current line where the caret (text cursor) is and get the number of characters of that line.

   int curline = pEdit->LineFromChar();
   int nchars = pEdit->LineLength(curline);
   if (nchars >= 54)
   {
         // check at which char index the current line is beginning
         int idxline = pEdit->LineIndex(curline);
         // check whether there is a space in that line where we could wrap
         int spaceidx = idxline + 54;
         while (spaceidx > idxline)
         {
               if (isspace(strTxt[--spaceidx]) == TRUE)
                   break;
         }
         if (spaceidx > idxline)
         {
               pEdit->SetSel(spaceidx, spaceIdx);  // should set the caret to the space char and select
               pEdit->ReplaceSel("\n");  // should add a new line
         }
   }

Had no time to test to above. Probably you have to *play* with the SetSel parameters and or  ReplaceSel.  

I am offline now because of a "Weihnachtsfeier".

Regards, Alex

   




0
 

Author Comment

by:tsp2002
ID: 26071302
Hi Alex....have a nice Weihnachtsfeier....but your code will not work.
Best regards,
Thomas
0
 

Author Comment

by:tsp2002
ID: 26078419
Hello Alex,
can you help me with your code?
What is spaceIdx..... ?

void CGeschaeftsadressen::OnEnChangeEditBemerkung_Anzahl_Zeichen_left()
{
	 //zeigt Anwender wieviele Zeichen man noch eingeben kann (4000 max. Zeichen)
	CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BEMERKUNG);
	
        CString strTxt;
		CString strHelp="        ";
        GetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
        CString strMsg;
        strMsg.Format( "noch %d Zeichen", 1204 - strTxt.GetLength() );
        GetDlgItem(IDC_STATIC_BEMERKUNG)->SetWindowText( strMsg );


       int curline = pEdit->LineFromChar();
       int nchars = pEdit->LineLength(curline);

	    if (nchars >= 54)
        {
         // check at which char index the current line is beginning
         int idxline = pEdit->LineIndex(curline);
         // check whether there is a space in that line where we could wrap
         int spaceidx = idxline + 54;
         while (spaceidx > idxline)
         {
               if (isspace(strTxt[--spaceidx]) == TRUE)
                   break;
         }
         if (spaceidx > idxline)
         {
               pEdit->SetSel(spaceidx, spaceIdx);  // should set the caret to the space char and select
               pEdit->ReplaceSel("\n");  // should add a new line
         }
   } 

        

Open in new window

aaa.BMP
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26078506
What is spaceIdx..... ?

spaceIdx is the index in the text where you may add a line-break because there is a space char.
0
 

Author Comment

by:tsp2002
ID: 26078536
spaceIdx is the index in the text where you may add a line-break because there is a space char.
where I have to set or declare that?
even if I had some value for that....your code will not work
pEdit->SetSel(spaceidx, 10);  
0
 

Author Comment

by:tsp2002
ID: 26078544
have you tried your code on a sample project at your studio?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26078599
>>>> pEdit->SetSel(spaceidx, spaceIdx);  

It was only a typo. Do

    pEdit->SetSel(spaceidx, spaceidx);  


That would select the space character at position spaceidx in text.

Next ReplaceSel would replace it by a line break.

>>>> have you tried your code on a sample project at your studio?
No, unfortunately I am on a hurry this morning and have only little time.
0
 

Author Comment

by:tsp2002
ID: 26078842
Hi Alex,
I changed your code....will not work. Perhaps
you can help me on Monday and can test your code .
Have a great weekend.
Best regards,
Thomas
 
0
 

Author Comment

by:tsp2002
ID: 26095451
Hi,
I created my own code...and it works....the only thing I miss is that when I reach the end of the entry....f.e      
...............this is the end    
  will cut in .........this is the e
nd
So when I reach the end....I have to find out if it is a " " then I can break the line....or if there is a char/word....then not.
 
 

void CGeschaeftsadressen::OnEnChangeEditBemerkung_Anzahl_Zeichen_left()
{
	 //zeigt Anwender wieviele Zeichen man noch eingeben kann (4000 max. Zeichen)
	CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BEMERKUNG);
	
        CString strTxt;
		CString strHelp;
        GetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
        CString strMsg;
     
		
	

	int L=strTxt.GetLength();
    strHelp=strTxt.Mid(L-1,L);

 
	if (strHelp!="\n")	m_BemerkungEingabeChar54=m_BemerkungEingabeChar54+1;
	strMsg.Format( "noch %d Zeichen", m_BemerkungEingabeChar54 );
    GetDlgItem(IDC_STATIC_BEMERKUNG)->SetWindowText( strMsg );
		 
   if (m_BemerkungEingabeChar54 >= 54)
   {
	  strTxt=strTxt+"\r\n"+"";
	 int Laenge=strTxt.GetLength();
		
	 CEdit *pEdit=(CEdit*) GetDlgItem(IDC_EDIT_BEMERKUNG);
	 SetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
			 
	 ASSERT(pEdit);
     int nPos=1;
	 pEdit->SetSel(Laenge,Laenge+1);
        
	  m_BemerkungEingabeChar54=0;

			 
}

Open in new window

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26097749
>>>> I created my own code...and it works....

???? it works for 2 lines only and if the arrows were used or you didn't count the characters inserted you would get garbage like in the ".........this is the e\nnd";

The only way to make it work properly is to using LineFromChar, LineLength, SetSel and ReplaceSel.
0
 

Author Comment

by:tsp2002
ID: 26098765
The only way to make it work properly is to using LineFromChar, LineLength, SetSel and ReplaceSel.
okay...have you tested your code? The code you posted will not work
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26100412
>>>> The code you posted will not work
Note, the code I posted was from my memories. My second MFC project in 1994 exactly provides a dynamic Editbox within a grid-like Scrollview. Later I made only a few improvements on edit boxes but enough to be able to assist you with any issue you have when trying to implement an owner-driven word-wrapping in a CEdit field.

But you might need to tell what does not work, cause unfortunately I neither have a crystal ball to look in what happens on your system nor the time to make a new test project to post you the full working code here.
0
 

Author Comment

by:tsp2002
ID: 26103053
your code> when I reach the end (54 chars) there is no new line...also when I use return I got this error message wrong parameter.
 

aaa.BMP
0
 

Author Comment

by:tsp2002
ID: 26103056
your code
void CGeschaeftsadressen::OnEnChangeEditBemerkung_Anzahl_Zeichen_left()
{
	 //zeigt Anwender wieviele Zeichen man noch eingeben kann (4000 max. Zeichen)
	CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BEMERKUNG);
	
        CString strTxt;
		CString strHelp;
        GetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
        CString strMsg;
     
		int curline = pEdit->LineFromChar();
        int nchars = pEdit->LineLength(curline);
   if (nchars >= 54)
   {
         // check at which char index the current line is beginning
         int idxline = pEdit->LineIndex(curline);
         // check whether there is a space in that line where we could wrap
         int spaceidx = idxline + 54;
         while (spaceidx > idxline)
         {
               if (isspace(strTxt[--spaceidx]) == TRUE)
                   break;
         }
         if (spaceidx > idxline)
         {
              pEdit->SetSel(spaceidx, spaceidx);  // should set the caret to the space char and select
               pEdit->ReplaceSel("\n");  // should add a new line
         }
   } 

Open in new window

0
 

Author Comment

by:tsp2002
ID: 26103558
so all you experts out there :-)    ....I find the solution....very simple
just disable ES_AUTOHSCROLL in your rescoure editor and the editbox and it handles the word wrap by itself.
I found the solution on experts-exchange question:  "Word wrap in a CEdit control"
Merry Christmas to all
 
 
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 2000 total points
ID: 26103916
>>>> just disable ES_AUTOHSCROLL in your rescoure editor
yeah, we should have asked for your resource file. ES_AUTOHSCROLL actually isn't an option which makes sense for a multi-line edit control (I never use it for single-edit controls either).

If you read my first comment you'll see that I told you of a 'soft break' you can get indicated by '\r\r\n'. Those soft-breaks only occur if automatic word-wrapping was active what isn't the case if the ES_AUTOHSCROLL is switched on.

Note, automatic word wrapping isn't a solution to your original question as it would wrap on text size (pixels) rather than on number of characters.

Merry Christmas to you
0
 

Author Comment

by:tsp2002
ID: 26104017
Note, automatic word wrapping isn't a solution to your original question as it would wrap on text size (pixels) rather than on number of characters.

okay...that was a mistake in my question....I did not now the english word....now I know word wrapping.
I just used the number....so you can count easy to 54
       
A-3456789-123456789-123456789-123456789-123456789-1234
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 26104018
>>>> when I reach the end (54 chars) there is no new line...also when I use return I got this error message wrong parameter.
A multi-line editbox may or may not accept <ENTER> for a new line. That is another option you can switch on/off in the resource editor called 'Want Return' (Return möglich). If switched off, you need CTRL+ENTER to get a new line.

When using the ReplaceSel you might have to use "\r\n" for replacing the space char in order to get a proper new line.

The message box "Falscher Parameter" you get if you have the 'Want Return' switched off and the OK button is the Default push button. Then, any ENTER strike would invoke the OK button and the OnOK handler function which probably issues the message box. As I normally don't want the dialog to be closed after ENTER my OnOK has the following code at begin:

    if (GetFocus() != GetDlgItem(IDOK))
    {
         NextDlgCtrl();
         return;
    }

So, if the OK button doesn't has the focus, it would move to next control in tab order in case of ENTER.
0
 

Author Comment

by:tsp2002
ID: 26104074
the only thing I now miss is:
when I count the chars ... I show the user how many chars the user can enter...and has left.
When I use the back-arrow (German keyboard under F11 and F12) it should add per click on char to the left-chars...because I erase the entry.
if(strTxt=="\b") .....then will not work....any suggestion???

// CEdit *pEdit=(CEdit*)GetDlgItem(IDC_EDIT_BEMERKUNG);

CString strTxt;
CString strHelp;
GetDlgItemText(IDC_EDIT_BEMERKUNG,strTxt);
CString strMsg;

strMsg.Format( "noch %d Zeichen", 1204 - strTxt.GetLength() );
GetDlgItem(IDC_STATIC_BEMERKUNG)->SetWindowText( strMsg );
 
0
 

Author Comment

by:tsp2002
ID: 26104129
sorry forgot my last statement....it works...I did a mistake
Merry Christmas
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

581 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question