Multiple Line Edit Control

I need to implement an edit control that has multiple lines.  What's stopping me from using a CEdit is that the lines may not be of the same width or have the same left margin.  The control needs to have the same functionality as CEdit as far as mouse and keyboard input.

Here's a typical instance ('xxx' is static text, '___' is where the edit control needs to be):

xxxxxxxxxx________
__________________
__________________
LVL 1
AndersonAdrianAsked:
Who is Participating?
 
AndersonAdrianAuthor Commented:
I want to thank everyone that's participated in this discusssion.  Most noticably mikeblas and RONSLOW.  The responses received have been very helpful in exploring the possible solutions for this problem.

Unfortunately, the best answer so far to come from this group is to create a control from scratch.  I've been tempted to accept this answer and give mikeblas the points for so early on providing this answer.

The only thing that's stopping me is that I've implemented a solution with substantially less effort.  I would have shared this with the group earlier, but ExpertsExchange doesn't allow the poster of the question to answer it themselves.

For those interested, the solution I've implemented is to handle it with multiple CEdits.  So given a typical case of:

xxxx 11111
2222222222
2222222222
2222222222
3333 xxxxx

number = edit control
x = static text

Each number is a separate control.  The controls are grouped together.  This is substantially easier than creating a control from scratch.  The only functionalities to worry about are word wrap between controls (override OnChar() and OnKeyDown() and OnKeyUp() ).  There was also a couple of cases where I needed to work with DefWindowProc to make sure the selection wasn't getting mangled by CEdit's default functionality.  
0
 
mikeblasCommented:
As you've found, the Windows edit control doesn't support this sort of layout.

But, what's your specific question?

..B ekiM
0
 
AndersonAdrianAuthor Commented:
Mike,

The question is: 'What do I need to do in order to implement a multi-line edit control with the above mentioned properties?'

I'd rather have not re-write a lot of the functionality already existant in multi-line CEdit controls.
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
mikeblasCommented:
Unfortunately, you'll have to rewrite what's already in the edit control. That's because the Windows controls aren't packaged in a reusable way.

There's no way to tell the control about an offset for painting and hit testing and selection. You can fake the offset by moving around the origin in the device context, but then you'll need to fix word wrapping and selction on the subsequent lines.  And you have _no_ way to address those issues.

Your best bet really is going to be writing this from scratch. Maybe, facing such a large effort, you'll decide to relax this part of your application's requirements and choose a design that's more suitable to what's readily available.

Or, maybe you can find a 3rd-party control that prepackages the functionality you need.

..B ekiM
0
 
AndersonAdrianAuthor Commented:
Mike,

You told me that I do need to reimplement the functionality, not what I need to do in order to accomplish it.

Personally I think that there is a way to accomplish this using a CEdit control.

I cannot relax this requirement.

A 3rd-party control that prepackages the functionality is a possibility, can anyone point one out?
0
 
SamHobbsCommented:
You could process the WM_CHAR message and if the edit control is in the static portion, do not process it further, but if in the editable portion, pass it along to CEdit:OnChar.

Does that sound close?
0
 
RONSLOWCommented:
I'm not exactly sure what the problem with a multi-line CEdit control is.  Notepad uses a simple multi-line edit control (ie a CEditView) and seems to work fine.

Anyway, if you want mor eflexibility, then use a rich edit control instead.

Take a look at the WordPad and SuperPad samples for some ideas.

0
 
mikeblasCommented:
SamHobbs> Does this sound close?

That can come close to working, but it'll be pretty ugly. Most notably, you'll be able to highlight the static portion. You'll also have a bunch of work to do in order to make sure the static portion isn't altered by a clipboard or IME operation.

And you're neglecting the requirement of varying left margin.

 AndersonAdrian> Personally I think that there is a way to accomplish this using a CEdit control.

I've outlined the obstacles you'll face. If you start with a CEdit, you'll end up rewriting so much functionality that you'll realize you should've started with CWnd.

What more do I need to do in order to get the message across?

 RONSLOW> I'm not exactly sure what the problem with a multi-line CEdit control is.

For one, a multiline CEdit doesn't support a ragged left-hand margin. Then, it doesn't support read-only regions.

..B ekiM
0
 
RONSLOWCommented:
OK .. it was this embedded bit of static text that had me confused when I first read your question.

Still rich edit controls offer protected character formatting (which may do what you want).

And later versions provide a heap of extra functionality (if you want it).
0
 
AndersonAdrianAuthor Commented:
Protected character formatting isn't acceptable since the static text cannot be part of the control.
0
 
RONSLOWCommented:
so you want the actual control itself to have a different shape.

How about create a region that corresponds to the shape you want and assign that to the edit control (SetWindowRgn)?
0
 
AndersonAdrianAuthor Commented:
SetWindowRgn is one of the first things I tried.  In the code I looked at it appeared that SetWindowRgn doesn't work the same with CEdits as it does with simple CWnds.  If you'd like to provide a working code sample of how SetWindowRgn would work I'd be glad to accept this as the answer.
0
 
RONSLOWCommented:
I've just been trying that.

It appears the outside of the edit control gets the shape (you can 'see' where the border has taken on the required shape), but the inside remains a rectangle.

It a shame standard controls don't respect the SetWindowRgn.  Wonder if that is documented somewhere?

Damn :-)
0
 
mikeblasCommented:
> but the inside remains a rectangle.

Like I've been saying...

..B ekiM
0
 
RONSLOWCommented:
Mike B: You haven't said that at all yet.  No mention was made of using SetWindowRgn, nor that common controls don't take the region seriously.

One really ugly and kludgy way of doing this might be to place a static text control over a richedit control and 'protect' the text underneath the static.

Another thought is to have two borderless edit controls - one for the first line and another for the remainder.  These would be positioned so that the just touch and look like a single control.  The problem would be to wrap the text between the controls.  And selecting/copy/cut would be awful.

Maybe nicer is a list control in 'report' view mode, with an indent on the first item, and with static ontop of it.  Again, copy/past across multiple lines would be a hassle.

The best solution I can think of is (as MikeB said) to write your own control.  That means not only allowing text entry, but supporting editing including mouse selection and cut/copy/paste.  Possible, but a LOT of work to emulate all the edit control functionality.

0
 
SamHobbsCommented:
This might work; reject if it does not satisfy your requirements. The following is an override for the EN_UPDATE notification message. I have it in a class derived from CEdit, so EN_UPDATE is a reflected message (ClassWizard lists it with a "=" in front of it).

Note that if the edit control is not placed in a dialog as part of the resource (that is, created by a Create function), there is a known bug in Windows NT that might cause this notification to not be processed. If you need more information, say so.

void CLabeledEdit::OnUpdate() {
      CString s, ss="This is the label part: ";
GetWindowText(s);
if (s.Left(ss.GetLength())!=ss)
      Undo();
}

0
 
SamHobbsCommented:
Note that this OnUpdate is not the same as CView::OnUpdate.
0
 
RONSLOWCommented:
He's alrady said that the label cannot be part of the text.

>the static text cannot be part of the control

You probably should withdraw that answer.  Its a lot trickier than that :-)


0
 
mikeblasCommented:
RONSLOW> You haven't said that at all yet.  

On the contrary: see the paragraph that starts out: "There's no way to tell the control about an offset...".  I made that post about 36 hours ago.

 RONSLOW> And selecting/copy/cut would be awful.

Like I said, once you hack around all the things that the edit control doesn't do for you, you're going to wish you started out with CWnd by yourself.

 RONSLOW> Its a lot trickier than that :-)

To say the least!

..B ekiM
0
 
RONSLOWCommented:
MikeB
On the contrary yourself:

You NEVER said ANYTHING about applying a region to the edit control with SetWindwowRegion and that this would not work.  Please read you own posts again before 'On the contrrary'ing me.

What you actually said was:

>There's no way to tell the control
>about an offset for painting and hit
>testing and selection. You can fake
>the offset by moving around the origin
>in the device context, but then you'll
>need to fix word wrapping and selction
>on the subsequent lines.  And you have
>_no_ way to address those issues.

Oh .. I see .. how silly of me to not to know that that meant SetWindowRgn does not work with Edit controls.  Guess I didn't have my special psychic helmet on when reading your earlier message :-)

WOLSONR

0
 
migelCommented:
Hm
not so easy problem with CEdit
you have to override OnChar + OnKeyDown (for edit keys) + clipboard operations
in this method you must check current caret position and reject updates if caret inside non editable area:
{
int nStartChar, nEndChar;
CEdit::GetSel( nStartChar, nEndChar );
int nLine  = CEdit::LineFromChar( -1 );
if (nLine == nonEditLine && nStartSel < nonEditStringLen) /* applay more specific tests here !! it is only for example*/
return;
else // call default implementation
CEdit::...
}
0
 
RONSLOWCommented:
Still does not change the shape of the control nor stops you from copying or pasting over the 'fixed' part.

Seeing edit controls don't repest the SetWindowRegion to change their shape, it looks like a custom-built contorl is required.

It seems a lot of work for a fairly cosmetic feature.  Must be very strict requirements if the shape of the control is so important.

0
 
mikeblasCommented:

 RONSLOW> It seems a lot of work for a fairly cosmetic feature.

Indeed! The only realistic way to get this done is to write a new control. For some reason, AndersonAdrian doesn't want to do that. Aside from dropping the requirements, the only viable alternative is to start searching for 3rd-party controls that provide the functionality.

It would be hard for even non-psyhcic thread participants to deny that I've asserted that answer from the beginning.

..B ekiM
0
 
AndersonAdrianAuthor Commented:
Sam,
Your proposed answer does not solve the problem.

All,
I agree it is very much a 'cosmetic' feature -- one I would rather not support.  The purpose behind the feature is that this application displays contracts and forms and for some reason people like to have contracts with that type of format.

It looks like the only real solution is to write a new control from scratch.  Something I would rather not do, which is why I posted the question.

If someone can find a third party control to solve the problem I'd be glad to award the finder the points.
0
 
RONSLOWCommented:
Mike: I knew you'd say that :-)
0
 
mikeblasCommented:
RONSLOW> Mike: I knew you'd say that :-)

Now I'm confused. Are you psychic, or not?

..B ekiM
0
 
mikeblasCommented:
Well, I'm not into these "find a product for me", so I guess that's the end of my involvement.

..B ekiM
0
 
inprasCommented:
Hi
If U want lines to be of same width just change the font of them to Courrier new like this

      pEditFont = new CFont ;
      pEditFont->CreateFont( -12,0, 0, 0, FW_NORMAL, 0, 0, 0,  
                                     ANSI_CHARSET,OUT_STROKE_PRECIS , CLIP_STROKE_PRECIS,
                                                 PROOF_QUALITY, FF_MODERN, "Courier New");
      m_EditCtrl.SetFont(pEditFont, TRUE);


This will give U a currect solution of UR problem using CEdit

Hope this helps
inpras
0
 
RONSLOWCommented:
This you've misunderstood the problem.

He want the shape of the edit 'box' to not be rectangular .. in particular wants an "indent" at the top.

If it were that easy, I think we'd have gotten an answer for him earlier :-)

0
 
AndersonAdrianAuthor Commented:
inpras,

As RONSLOW stated, it appears that you've misunderstood the question.
0
 
Janusz CzopowikCommented:
I’ve done it by embedding windows in edit control. I have used CStatic derived class, setting font to the control’s font. I have calculated rectangle from a height of the font and setting with that I wanted. I have position of the window in the upper corner of the control.

You have now the general idea. You will have to handle position of the cursor (caret) since mere embedding of another window does not prevent control from positioning caret under it.

I have used padding spaces, and positioning caret outside of the static window if caret changed position that was inside of the static rectangle.

I have handled:
OnSetFocus, OnUpdate and PreTranslateMessage (to catch arrow keys, backspace and any key that may be used to position caret inside static window.
0
 
RONSLOWCommented:
That won't stop you copying/pasting in the hidden area of the control (with the keyboard especially).

I'm pretty sure this was all covered before and that the number of situations you'd need to account for so that the hidden text behind the static control isn't copied/pasted/deleted etc makes this solution impractical.
0
 
AndersonAdrianAuthor Commented:
Sorry JohnCz, RONSLOW is correct.  There's a number of issues your proposed solution doesn't address.
0
 
mikeblasCommented:
Still haven't accepted an answer?

..B ekiM
0
 
RONSLOWCommented:
Mike .. I think you should post your original answer again.  In should be obvious now that what you suggested (rolling your own edit class) is the only way to go on this.  The built-in edit control just doesn't provide the write 'hooks' etc to customise it to this degree.

It may not be what AA wants to hear .. sometimes the correct answer isn't what you'd like .. but that shouldn't mean you don't deserve the points for providing the correct information.
0
 
mikeblasCommented:
If that's what AA has realized, too, then they can accept any one of my comments as the answer.

Letting the question languish after so many people have put effort into it, though, is one of the things that's wrong with ExpertsExchange.

..B ekiM
0
 
RONSLOWCommented:
You may also need to worry about copy/cutting and pasting .. not just keyboard entry.  Handling OnChar and OnKeyDown will probably not be enough.
0
 
AndersonAdrianAuthor Commented:
True, but cut, copy, and paste were quite a bit easier to implement once word wrap was implemented and the caret positioning and selection problems were worked out.
0
 
darinwCommented:
Hello everyone,

I am moving this question to the PAQ.

-- I am accepting AndersonAdrian's comment as an Answer --

darinw
Customer Service
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.