EditField line spacing

| | Comments (3)

Have you ever wanted to set the line spacing on an EditField so that you can double space a line?

I haven't. However, someone asked me (over the x-mas break) how to do it, and so I found some declares that do the trick well enough.

You see, on Windows, everything happens based off the current selection. Which is very, very annoying. That means you need to select whatever it is that you want to modify. But then you end up with a ton of flickering from it. So not only do you have to do the selection, but you have to hide it when you do so. Then, to make matters worse, you have to properly restore the user's previous selection information. It sucks -- I personally hate the RighEdit APIs. I think it's hacked together, and it's a PITA to work with.

So, without further ado, here's the code I added to the WFS to do line spacing:
[rbcode]
Sub LineSpacing(extends EditField1 as EditField, spacing as Double)
Dim EM_SETPARAFORMAT as Integer = &h400 + 71
Dim EM_HIDESELECTION as Integer = &h400 + 63

Dim paraFormat2 as new MemoryBlock( 188 )

paraFormat2.Long( 0 ) = paraFormat2.Size

Const PFM_LINESPACING = &h100
Const PFM_SPACEAFTER = &h80
paraFormat2.Long( 4 ) = PFM_LINESPACING

dim spacingRule as Integer
select case spacing
case 1
spacingRule = 0
case 1.5
spacingRule = 1
case 2
spacingRule = 2
end select

paraFormat2.Byte( 170 ) = spacingRule

Declare Sub SendMessageA Lib "User32" ( hwnd as Integer, msg as Integer, wParam as Integer, lParam as Ptr )

// If the user has something selected, then we
// want to apply to just that paragraph. However,
// if they don't have anything selected, then we
// want to apply to the whole field.
dim restoreSelectionPoint as Integer = -1
if EditField1.SelLength > 0 then
// Just use what the user has
else
// Hide the selection
SendMessageA( EditField1.Handle, EM_HIDESELECTION, 1, nil )

restoreSelectionPoint = EditField1.SelStart
EditField1.SelStart = 0
EditField1.SelLength = -1

end if

// Set the format
SendMessageA( EditField1.Handle, EM_SETPARAFORMAT, 0, paraFormat2 )

if restoreSelectionPoint >= 0 then
// Restore the selection
EditField1.SelStart = restoreSelectionPoint
EditField1.SelLength = 0

// Show the selection
SendMessageA( EditField1.Handle, EM_HIDESELECTION, 0, nil )
end if
End Sub
[/rbcode]
Using this, you can have single, double and even 1.5 spaced lines in your EditFields. There are other neat things you can do with the PARAFORMAT2 structure, so I may add some of those if I feel bored later on.

Enjoy!

3 Comments

Pretty easy. How about superscript/subscript--that's character formatting?

It would be really, really nice if the RB EditField and StyledText supported Superscript and Subscript. The report ID is fpjthavy; it hasn't even been reviewed since 2000, when it was first requested. Windows support would be trivial, and Mac/Linux support couldn't be too hard.

And by "pretty easy", I mean it's a neat little bit of code to do something that seems impossible--not that it's so easy anyone could do it in a day. It would have taken me a little while to figure that out, what with Win32's wacky SendMessage system and all!

What about a way to do this for the Mac? Why is line spacing so difficult? I rolled my own for a statictext, but I would love proper line spacing control in an Editfield.


Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.