Strange behaviour with TextHeight function [resolved]
I have created a user control which simulates a textbox control, but instead of having the text contained within the control flush with the top, it is flush with the bottom. If anyone knows another way of achieving this please let me know and I can ditch my user control solution.
Anyway more on the problem, the project I will be implementing the user control in will have a feature to change the text size displayed but with the user control I get some strange results when changing the size to 12 and 24. The textheight function which basically controls the resizing of the textbox seems to be giving out incorrect results thus sizing the textbox too large.
It's hard to explain what the control actually and does and what's wrong with it so you are best of having a look at my mockup test project to see what's going on. Any help highly appreciated.
I've looked at your code and everything looks good. I think there must be a bug inside of the TextHeight function or the textbox isn't spacing correctly. In either case there isn't anything you can do about it that I know of. I tried replacing the TextHeight function with the DrawText API and had the same results. Therefor I would guess that the textbox isn't displaying the text height correctly (or TextHeight calls DrawText). It doesn't make any sense, though.
It seems to be a rounding error. I say this because the more lines of text in the box, the greater the gap. It's possible that if you did enough tests you could find out what the true font size to text height ratio is. I tried doing this, but I gave up because the ratio of the TextHeight function and font size is very different at different sizes.
Also if you replace the textbox with a rich textbox then you will get somewhat different results. If that's not confusing...
This is a very interesting problem and I hope that someone with more knowledge than me replies soon, otherwise I would look for a better way of achieving this if I were you.
Cheers for the reply. I made another mock up achieving sort of the same effect with just a textbox, no user control involved or anything and it works perfect, the height is correct.
I know the placement of the textbox on the control is good because as you can I made the backcolour to your selection colour, probably blue so I can tell the actual height of the control and as you said it all boils down to the incorrect height of it.
I also tried another method using the SendMessageAPI and EM_GETLINECOUNT then multiplying that value by the height of a single line, but again I was left with the same distorted result only on those certain heights.
Just made another discovery, I ran some simple code through VB and found that some of the sizes I'm specifying are being coerced into a decimal.
As you can see the sizes I am running into trouble with are all of the whole numbers, although I have not noticed any problems with 36 anymore whereas I did at one time which in itself is quite strange.
I tried changing all of the whole numbered sizes I am using to a size returning a decimal and the problem still arises BUT and that was a very big but, I have just discovered that the text size specified in the PictureBox on my control is different to that specified for the TextBox mostly by .75 and only on the number I'm having trouble with. It's now looking more like a bug in VB not the TextHeight function.
By adding a debug.print line on the TextSize function of the usercontrol and outputting the height specified and the height of the PictureBox against the height of the TextBox the immediate window shows:
Originally posted by adzzzz
I have just discovered that the text size specified in the PictureBox on my control is different to that specified for the TextBox mostly by .75 and only on the number I'm having trouble with.
You found the solution. The font you have picked for your picBorder (MS Sans Serif) isn't the same font you have in your textbox (Tahoma). If you make the fonts the same then your control works.
I guess different fonts resize differently. Still confusing, but it works.
If you're interested, I have made a WordWrap code which will wrap the text just like it would be wrapped in a textbox. The problem is... well, it should be called each time the textbox changes and if the content is long, it is slow to execute... making updating slow. Of course if the linecounting works, there shouldn't be too big problems.
If the text is going for a chat application, it needs wordwrap (since there will be no horizontal scrolling).
Edit
Also, there might come problems with the size of the textbox. I mean... a control can't be sized for thousands and thousands lines of text. So you're running to problems with the current technique you're using. Not having the textbox in the way it is now gets you back to the base error: textbox text not in the bottom. But know what? I think I have a solution for this: just have the textbox a little bit bigger than the picturebox it is in. How to count this?
- get the height of a font
- see how big the visible text area is
- use visible area Mod height of the font to get the remaining size
Now make the textbox the size of the text area plus the remaining size. You should have it: a textbox which text is in the bottom instead of floating in the air.
Now, if you try to go on with your control... it is hard. Easier would be to resize a textbox to use these certain sizes only.
Here is a sample project. The text stays in the bottom no matter what is the font. The only thing that needs fixing is the scrollbar. But that's a different story.
Edit Made a cheatty scrollbar. To make it better, it should use line numbers instead. There were just too many things I don't know (how to get the current line the cursor is in, how to get the start position of each line...) so I didn't make it any better.
Nice solution Merri. Another problem with the original solution is awkwardness in selecting text (dragging to select) and not being able to use the up key to scroll up. Your solution fixes all this.