Increase size/limit of TRichEdit? - delphi

I am having some issues with the TRichEdit.
The first issue is if I try to paste a lot of text from the clipboard into a empty TRichEdit, it truncates the bottom of the text.
The second issue, which I guess ties into the first issue, is that I seem to be limited to how many characters the TRichEdit can display, hence pasting from the clipboard is losing some of the data.
If I paste into a TJvRichEdit (Jedi), that works fine, obviously because that is a completely different component.
At this moment in time I would like a solution for the TRichEdit because I am using a lot of procedures/functions etc, if I change to a different Rich Edit class then I will have to edit a lot of my code to work.
So basically what I am asking is:
Is there a limit in the TRichEdit? which I am sure there is.
How can I increase the limit of the TRichEdit to accept more characters and lines etc.
Please provide advice/solution for TRichEdit only.
EDIT
never mind found the answer using:
RichEdit11.MaxLength := $7FFFFFF0;

Quoting an answer given by David Pate from the newsgroups:
The following remarks apply to the versions of Delphi that use the Windows Richedit version 1 control. I understand that this includes all Delphi versions prior to version 7. (I do not know what the situation is when you run programs compiled in these versions on the various NT/2000 versions of Windows although Windows XP behaves as described.)
Q. What is the limit to the amount of text that a Richedit can hold? A. The help files (Delphi help and Win32 SDK) are confusing, contradictory and incorrect on this point. There are 5 limits to be considered
The Maximum Capacity: the "hard-wired" limit, i.e the maximum size of the RichEdit's text buffer. It is 2 bytes less than 2 Gb. Note that this is the theoretical limit; in practice the limit will be determined by your computer's memory.
The Capacity: the actual size of the current buffer. By default, it is 64Kb but can be resized by several means.
The "Keyboard limit": the limit beyond which characters cannot be added by typing from the keyboard. It is often different from the Capacity but, like the Capacity, it is by default, 64Kb and can be resized by several means.
The MaxLength property of the tRichEdit object. The default of 0 sets both the Capacity and "Keyboard limit" to 64Kb.
The line-number limit: theoretically this is around 134 million, but in practice, you can expect to get much less than this. The maximum number of lines seems to depend on several factors including the amount of memory available and the average length of the lines. I find that I can get around 150 thousand to 200 thousand lines. Note also that it has been reported that some releases of the Windows 95 Richedit control sometimes throw an exception when more than a few hundred lines are added. This appears to be due to a bug in the control and to have been corrected in later releases..
Q. How can I increase the amount of text that a tRichEdit can hold?
A. When you add text programmatically, both the Capacity and the "Keyboard limit" are resized to accommodate the text being added. By adding text programmatically, I mean using any of the Add, Append, AddStrings or Assign methods of the tRichEdit.Lines property or the LoadFromFile, LoadFromStream or SetTextBuf methods of tRichEdit. Note that adding text in this way does not update the MaxLength property.
B. By using the MaxLength property. This sets the "Keyboard limit" to the value passed to MaxLength. It also increases the Capacity to match the "Keyboard limit" if the existing Capacity is less than MaxLength. Note that you cannot use MaxLength to reduce the Capacity and that changing MaxLength has no effect if the value passed is less than the length of the text currently in the control. To increase the Capacity and the "Keyboard limit" to the same value, set the tRichEdit.MaxLength to the desired value. To set the maximum size in the Object Inspector, use the value 2147483645 ($7FFFFFFD). To set it programmatically it is simpler to use .MaxLength := System.MaxInt-2;. The EM_LIMITTEXT and EM_EXLIMITTEXT messages may also be used to change the "Keyboard limit" and Capacity but I'd not normally recommend using them since, if you do, you will not be updating the MaxLength property.

Related

Aebacus Controls Negative Number Issue

I am working to flush out some defects from an older program and I'm running into an issue with negative numbers in aebacus textboxes.
Basically, whenever a negative number (i.e. -1) is entered into a textbox, on focus lost the textbox shows the number with a trailing negative (i.e. 1-). On focus again, the number is displayed correctly as -1.
I have seen this in excel and maybe it is a formatting setting, or possibly just a limitation of vb6?
Apparently using a different font can fix it, in our case we made a custom font to alleviate the issue.

How to adjust Font Size according text viewable in a TButton.Text using Firemonkey?

I am using buttons to display product names in a matrix using TGridLayout.
The problem is that commonly Items contains 3 or 4 words and in my language (Portuguese) some words tend to be long.
I would like that somehow I could calculate the size of the font, decreasing it, in order to make all the text show up automatically (of course there is also a decrease limit, anything below 9 or 8 point for the font turn to be difficult to read).
The wordwrap property is turned on to have many lines, and use the most possible space for the text.
I don't know if you're programming for an Android/iOS app, but you can't change the fontsize of a button. I've had the same problem, my solution was to make an abbreviation of the words. And then i put labels above it to explain the abbreviations.
Of course you can adjust the font size of a button:
TButton.TextSettings.Font.Size

Efficiently Computing Text Widths

I need to compute the width of a column with many rows (column AutoSize feature). Using Canvas.TextWidth is far too slow.
Current solution: My current solution uses a text measurer class that builds a lookup table for a fixed alphabet once and then computes the width of a given string very fast by adding up character widths retrieved from the lookup table. For characters not contained in the lookup table, the average character width is used (also computed once).
Problem: This works well for European languages but not for Asian languages.
Question: What's the best way to tackle this problem? How can such an AutoSize feature be realized without the relatively slow Canvas functions and without depending on a specific alphabet?
Thanks for any help.
You said you want to get the maximum text width for a column. Can't you, say, take only the 4 or 5 longest strings and get their widths? That way you won't have to find the width for all items and can save quite some time.
Or you use your cache to find the rough length of the strings and then refine that by getting the actual width for the top 4 or 5 items you found.
I don't think it matters a lot whether you use Canvas.TextWidth or GetTextExtentPoint32. Just use one of these to get the exact widths, after you used one of the methods above to guesstimate the longest/widest strings.
To those who think this doesn't work
If the poster of the original question thinks it could work, I have no reason to think it won't. He knows best what kind of strings can be in the columns he has.
But that is not my main argument. He already wrote that he does a preliminary textwidth by adding the predetermined individual widths of the characters. That does not take into account any kerning. Well, kerning can only make a string narrower, so it still makes sense to check only the top 4 or 5 items for the exact width. The biggest problem that can occur is that the column could be a few pixels too wide, no more. But it will be a lot faster than using TextWidth or GetTextExtentPoint32 or similar functions on each entry (assuming more than 5 entries), and that is what the original poster wanted. I suggest that those who don't believe me simply try it out.
As for using the pure string length: even that is probably good enough. Yes, 'WWW' is probably wider than '!!!!!', but the original poster will probably know best wat kind of string material he has, and if it is feasible. '!!!!!' or 'WWW' are not the usual entries one expects. Especially if you consider that not only one single string is checked, but the longest 4 or 5 strings (or whatever number turns out to be optimal). It is very unlikely that the widest string is not among them. But the original poster can tell if that is possible or feasible. He seems to think it is.
So stop the downvoting and try it out for yourself.
I'm afraid you have to use Canvas.TextWidth, or your implementation will be imprecise. The width of text depends on the font kerning, where different character sequences may have different widths (not just the total of individual character widths).
Me, I cut out the middle-man and use the Windows API directly. Specifically, I use GetTextExtentPoint32 with the .Handle of the Canvas. There's nothing you can do to be faster, other than caching results in some way, and frankly you'll just add overhead.

Delphi IDE Line Length

In Delphi 7 IDE, do the lines need to be a given length? I see a gray line in some Delphi code I'm working with, and it looks like ever line ends right before it.
It's called the right margin. It is intended as a guide to help you avoid writing lines that are too long and exceed your coding standards. You can switch it off from the Editor Options, as I have done here:
It's just a guide to line length. Some people don't like long lines because they can be hard to read on different resolutions or when doing comparisons.
That gray line is called the margin.
You can set its visibility and position in the Editor Properties at the Display tab in the Margin and gutter groupbox.
The margin is a visual assistent. The standard position is 80 characters, which defaults to the maximum unscrolled size of many source formatting output media, such as the one used here at Stack Overflow. Originally, it had something to do with the paper width on (matrix) printers. Maybe it still does.

How to fully justify texts programmatically (Delphi)?

How can I fully justify a block of text (like MS Word does, not only on the right and not only on the left but on both sides)?
I want to justify some texts (mainly arabic text) adjusted to certain screen size (some handheld device screen actually, and its text viewer doesn't have this function) and save this text as justified. So I can reload and reuse it again elsewhere.
(The problem with MS word is, that if you copy the justified text from MS Word and paste it to another editor it'll copy it un-justified).
Update : for now I'm thinking of doing it like this:
get-a-word
get-word-width
add-word-to-total-Word and add-Word-width-to-total-word-width
check if total-Word-width = myscreen-width then continue
else if total-Word-width is between myscree-wdith and (myscreen-width -3) then
add-spaces-To-total-word until it = myscreen-width
This is what I'm thinking now, but I put this question up and hope to see if there is a better solution, or somebody else already implemented it.
PS: I hope I have made my question clear and I'm sorry for bad expression if there is.
edit1 : changed the title to make it more clear.
If you want to justify plain text, you can only add extra spaces to the lines to get them align on the left and right. Unfortunately the character widths differ in fonts; so doing it this way will only work for a certain font, unless you limit yourself to monospaced fonts where all characters have the same size.
If you want a result like in Word, adding spaces won't cut it. Word will not add spaces, but stretch and shrink the existing spaces. This information is lost when you copy and paste it into another app.
Either way, justifying is an optimization problem. If you are interested in a good solution and its implementation: have a look a TeX. For an implementation that works on plain text with monospaced fonts have a look at par
There are some API calls that may help:
ExtTextOut and GetCharacterPlacement
Look at the GCP_JUSTIFY flag for GetCharacterPlacement
ExtTextOut is used by Canvas.TextRect
The problem you are going to face is always going to be differences in the rendering of the font. Word handles full justification by adjusting kerning as well as adjusting the number of pixels between words by a few (either way). The end result is lined up both margins. This pixel adjustment is done BOTH ways, and as evenly as possible.
To properly handle this in your portable device you will have to also perform the same algorithm for the display of the text there.
If this is not possible, then the ONLY way you can even get somewhat close would be to add whitespace between words.
As has been pointed out in other answers Word does full justification by stretching the existing spaces often by very small amounts. This is only possible if you have full control over how your text is drawn on the screen (which word - or any other windows program has).
You only real option in this regard would be to implement your own text viewer on the platform you are targeting. Eg you would need to draw the text on the screen yourself (any platform that allows games should allow you to draw on the screen). However this seems like an awful lot of trouble to get justified text.
Sorry couldn't be of more help.

Resources