OK, here's what I need to know. If I have a label (for example and it's alignment is vbLeft) I want to center text in the label using spaces instead of the alignment property. How do I figure out the number of spaces I need to center the text
Label1.Caption = Space(??) & Text
I have the width of the Text and I have the width of the label
I know it doesn't make sense to anyone who doesn't have any idea of the whole picture which is a little difficult to explain but disregarding what my reasons are just take it for face value. In simple terms I need to know how many spaces it takes to center the text and I am just using the label because it is the simplest control for a printing canvas but later the centered text will be applied to other things
If you are NOT using a fixed-width font, then the calculation is much harder. Spaces take up a lot less space than most other characters, plus each character takes up a different amount of space. You would need a way to add up the width values for each character to get the amount of space that they are using, then you could subtract that from the available space and divide by 2, then figure out how many spaces you need to fill that distance.
If you are NOT using a fixed-width font, then the calculation is much harder. Spaces take up a lot less space than most other characters, plus each character takes up a different amount of space. You would need a way to add up the width values for each character to get the amount of space that they are using, then you could subtract that from the available space and divide by 2, then figure out how many spaces you need to fill that distance.
Is that not what I am doing in Post #5
You would need a way to add up the width values for each character to get the amount of space that they are using:
Value in TextLength
then you could subtract that from the available space and divide by 2:
(Label2.Width / 2) - (TextLength / 2)
then figure out how many spaces you need to fill that distance.
From the sound of it, it seems like it would be measured in characters, i.e. "This is a test" is 14 (I use that a lot so know it is 14 characters off the top of my head).
The Label2.Width is in some other units, usually Twips if you haven't changed the scale of the container.
So, while the length of any letter would be 1, measured in Characters, the Width of the letter "T" could be over 100 twips easily.
Also, the width of the letter "i", could be much less, perhaps 80 twips.
So, if you're going to compare the Width of the Label in Twips against the total Width of the characters in your string, you need to use the same Units, e.g. Twips.
So, again, how is TextLength calculated?
Assuming that the font in your label and the font of your form are the same, you could use the TextWidth function of the form to approximate the values.
Or you could use a hidden picturebox set to the same font as the lable, to do the same.
Or you try using API calls to measure a text string as well, although I'm not going to bother looking up the API calls needed.
An example using the Form's Font and methods.
Code:
Private Sub Command1_Click()
Dim s As String
s = "This is a test"
Dim tl As Single
tl = Me.TextWidth(s)
Dim spaceW As Single
spaceW = Me.TextWidth(" ")
Dim numSpaces As Integer
numSpaces = (((Label1.Width - t1) / 2) / spaceW) \ 2
Label1.Caption = Space(numSpaces) & s
End Sub
Last edited by passel; May 21st, 2019 at 09:07 PM.
From the sound of it, it seems like it would be measured in characters, i.e. "This is a test" is 14 (I use that a lot so know it is 14 characters off the top of my head).
The Label2.Width is in some other units, usually Twips if you haven't changed the scale of the container.
So, while the length of any letter would be 1, measured in Characters, the Width of the letter "T" could be over 100 twips easily.
Also, the width of the letter "i", could be much less, perhaps 80 twips.
So, if you're going to compare the Width of the Label in Twips against the total Width of the characters in your string, you need to use the same Units, e.g. Twips.
So, again, how is TextLength calculated?
Assuming that the font in your label and the font of your form are the same, you could use the TextWidth function of the form to approximate the values.
Or you could use a hidden picturebox set to the same font as the lable, to do the same.
Or you try using API calls to measure a text string as well, although I'm not going to bother looking up the API calls needed.
An example using the Form's Font and methods.
Code:
Private Sub Command1_Click()
Dim s As String
s = "This is a test"
Dim tl As Single
tl = Me.TextWidth(s)
Dim spaceW As Single
spaceW = Me.TextWidth(" ")
Dim numSpaces As Integer
numSpaces = (((Label1.Width - t1) / 2) / spaceW) \ 2
Label1.Caption = Space(numSpaces) & s
End Sub
Post the values you are getting for your TextLength and that amount of space you want to center it in, with a screen capture of what it actually looks like.
You didn't take out the final divide by 2, like I said.
Also, the variable tl is T and the letter L, but in the line where it is used it is t1 "T one", not "T L".
If you look closely you can see the slight swoop of the serif at the top for the number 1, compared to the straight serif for the letter l.
If you had Option Explicit turned on, which I do, then the IDE would have informed you that t1 was undefined.
I didn't test the code in the IDE when I first posted, just typed it in the post, so it was my fault for the typo, but as soon as I copied it in the project, the IDE let me know it was undefined, since I turned on the option (menu Tools =>Options) "Require Variable Declaration" so any project I create gets the Option Explicit defined at the top of the file automatically.
I also turn the option "Auto Syntax Check" off, since I don't like a dialog box always popping up when I try to navigate from a partially completed line to look at something.
Even with that option off, the line will still turn red if there is a syntax error, so it still checks and lets you know, it just doesn't popup an annoying message box for each occurrence.
Lets change the variable name to make it clearer and so that the lower case L is not confused with the number 1 or the letter I depending on the font used.
Code:
Private Sub Command1_Click()
Dim s As String
s = Text1.Text
Dim tLen As Single
tLen = Me.TextWidth(s)
Dim spaceW As Single
spaceW = Me.TextWidth(" ")
Dim numSpaces As Integer
numSpaces = (((Label1.Width - tLen) / 2) / spaceW)
Label1.Caption = Space(numSpaces) & s
End Sub
If you step through the code you'll see that spaceW is equal to 3, which is what you used. That is the width of the space character, which is much narrower than a letter like "M".
The text center will hardly ever be exactly center since the characters may have different kerning depending on the adjacent letters, and there is no kerning after the last letter, which will bias the letters one way or the other. Of course it also depends on whether you have an odd or even number of letters or not.
Since you are doing an Integer divide at the end, there will be some cases where you will truncate toward the left pixel, where mine will round to the right pixel. In that case you will be slightly more off center to the left direction and I will be slightly less off center to the right.
Try the string "A+A" for instance to see the difference between your result, and my result (assuming you change mine to the code in this post).
Last edited by passel; May 23rd, 2019 at 11:04 AM.
As you already know I copied your code as you posted it. I'm not using Option Explicit because I add variables on the fly while I'm testing. I didn't noticed the typo of t1 instead of tl so when I ran your example I did remove the \2 at the end but that threw the text way off of centering it so then I put it back and then the text got closer to being centered so I just left it.
I corrected your code and now it centers correctly or as close as you're going to get.
I didn't use the /3 because it is the width of a space I just added it because it worked and I had no idea at the time it was the width of a space.
I tested the "A+A" and I see what you are talking about.
OK, all is well now. Thank's for your help
NOTE: I wish I knew how the code under the label does it because it centers perfectly
Last edited by Code Dummy; May 23rd, 2019 at 12:37 PM.
You should always use option explicit ALWAYS! No exceptions, turn it on in the IDE so it is automatically added to every code module you create.
Having to go back after the fact and dim your variables is a major pain and not doing so is very poor practice not to mention results in slow sloppy code that is prone to unexpected results.
Wasn't going to butt in again, as OP definitely seems to like to do things his/her own way....but, as DM pointed out....ALWAYS use Option Explicit On. I didn't use it for years when I first started with VB6,,,what a mistake. On the many projects I had created, and then wanting to update any, it was a PITA figuring out irregularities with different variables (some declared, some not). USING OEON could have prevented me HOURS of code reviews tracking down issues. Okay, butting back out.
.... I'm not using Option Explicit because I add variables on the fly while I'm testing.
......
NOTE: I wish I knew how the code under the label does it because it centers perfectly
I add variables on the fly as well. You can put a "Dim variable As Type" anywhere in the code as you're writing it, so if I'm introducing a new variable as I write, I'll just put the Dim line there so I don't have to go back up to the top of the procedure to add it. Later, if the variable stays, I may move the declaration to the top, but VB6 doesn't require that, and I may not if it is throw away code that others aren't going to have to look at.
The label can center the text exactly because it can start the text on a pixel boundary, not a character boundary. If you wrote the text your self, i.e. using a Print Statement in a user control or a picturebox that you are using to replace a label control, then you can start the text on any pixel you want a well. You could even print each character you wanted at a specific pixel to customize spacing, or slightly raise or lower characters if you wanted.
I totally understand about dim'ing variables on the fly but still it's an extra step and I have found for me that it is much easier to just comment out the Option Explicit statement and not have to fiddle around with all this extra dim'ing especially since I'm going to discard 90% of them anyway. Very seldom do I forget to go back and uncomment the Option Explicit statement and run a final test. Apparently I didn't do it this time
Not using "Option Explicit" usually bites when using extra API constants that you haven't declared, so they default to 0, and you get unexpected behavior.