Windows TextArea.Drawinto does not work with styled text

OS: Windows 8

Xojo: Xojo 2015r1

Steps: Run the attached project. The box on the right is a canvas into which TextArea1 GotFocus event draws into the canvas backdrop picture.

As you will see, the text is not styled, when in fact the TextArea does show styled text.

The same project on Mac shows the control as it appears with styled text, as expected.

It very much looks like a bug that needs to be fixed.

Expected Result:
TextArea draws into with all its attributes

Actual Result:
Only plain text is copied

Workarounds:
Grab a screen shot. Cumbersome…

<https://xojo.com/issue/38485>

This is the same issue or closely related to <https://xojo.com/issue/23288> that I posted a couple of years ago. Status: Verified.

It would be very helpful to see this one fixed.

[quote=172920:@Richard Corlett]This is the same issue or closely related to <https://xojo.com/issue/23288> that I posted a couple of years ago. Status: Verified.

It would be very helpful to see this one fixed.[/quote]

That is indeed the same issue. Feedback did not find your case.

It is not encouraging to see that nothing has been done since 2012 :frowning:

I don’t remember the exact issue, but I did find a declare based workaround a while back… seems like Xojo isn’t setting the correct flags. I think it was the nonclient flag that needed to be added… hmm anyway, here’s the function

Sub mDrawInto(extends r As RectControl, g as graphics,x As integer, y as integer)
  #if TargetWin32
    Soft Declare Function SendMessage Lib "user32" Alias "SendMessageW" ( hwnd As int32,  wMsg As int32, ByVal wParam As uint32, lParam As int32) As  integer
    const WM_PRINT = &h317
    const PRF_NONCLIENT = 2
    const PRF_CLIENT = 4
    const PRF_CHILDREN = &h10
    
    
    dim p As new Picture(max(1,r.Width),max(1,r.Height),32)
    call sendmessage(r.handle,WM_PRINT,p.Graphics.Handle(Graphics.HandleTypeHDC),PRF_NONCLIENT+PRF_CLIENT+PRF_CHILDREN)
    g.DrawPicture p,x,y
    
  #endif
End Sub

Thanks Jim for that suggestion, I’ll give it a try!

[quote=173081:@jim mckay]I don’t remember the exact issue, but I did find a declare based workaround a while back… seems like Xojo isn’t setting the correct flags. I think it was the nonclient flag that needed to be added… hmm anyway, here’s the function

Sub mDrawInto(extends r As RectControl, g as graphics,x As integer, y as integer)
  #if TargetWin32
    Soft Declare Function SendMessage Lib "user32" Alias "SendMessageW" ( hwnd As int32,  wMsg As int32, ByVal wParam As uint32, lParam As int32) As  integer
    const WM_PRINT = &h317
    const PRF_NONCLIENT = 2
    const PRF_CLIENT = 4
    const PRF_CHILDREN = &h10
    
    
    dim p As new Picture(max(1,r.Width),max(1,r.Height),32)
    call sendmessage(r.handle,WM_PRINT,p.Graphics.Handle(Graphics.HandleTypeHDC),PRF_NONCLIENT+PRF_CLIENT+PRF_CHILDREN)
    g.DrawPicture p,x,y
    
  #endif
End Sub

[/quote]

Jim, once again, you shine. This is absolutely perfect.

I have completed the bug report and suggested to simply implement your solution.

Well, I have been testing this function with Windows 7 and I get very inconsistent results, and I have no idea why. I am calling it from a print method in a very simple test project.

A few times it has worked as expected, whereas numerous times the output sent to the printer is a blank text area having a border but no content.

Does anyone have any ideas why it might not work consistently?

[quote=174665:@Richard Corlett]Well, I have been testing this function with Windows 7 and I get very inconsistent results, and I have no idea why. I am calling it from a print method in a very simple test project.

A few times it has worked as expected, whereas numerous times the output sent to the printer is a blank text area having a border but no content.

Does anyone have any ideas why it might not work consistently?[/quote]

I have implemented it to catch the content of a textArea, turn the white transparent, and show the resulting image in a canvas. Works perfectly and reliably under Windows 8.1 and Windows 10.

But I wonder : do you first create the picture as in Jim’s code then print that picture, or are you trying to directly address the printer’s graphics object ?

I need to address the printer’s graphics object, in the same way that I can with the built-in DrawInto method.

I have one particular TextArea that has a coloured background and may or may not contain styled text, depending on what it receives from the database, and all appears correctly on screen.

For printing the page, in Carbon, DrawInto used to work fine, but in Cocoa this gives very blurred results (see <https://xojo.com/issue/23239>). In Cocoa I can draw a coloured rectangle and use DrawBlock to put the styled text on top of it, which gives nice clear results, but this does not work in Windows because DrawBlock leaves the text with an opaque white background. And as we know, DrawInto in Windows causes the styled text formats to be lost.

Jim’s method has worked a couple of times for me, but more often I have been getting this blank output as described in my post above. I have no idea why it should work some times and not others.

You can address the printer’s graphic object directly, or create a picture and drawpicture it into the graphics object. A simple intermediary method would do.

If you have modified extensively Jim’s code and do not use a picture as it does, this may explain the problem.

I haven’t modified Jim’s method.

In a small project I have a TextArea with a coloured background and some styled text. In the Action event of a button I have the code:

[code]Sub Action()
Dim myPage as Graphics=openPrinterDialog()

If myPage<>Nil Then
#if TargetWin32
TextArea1.mDrawInto(myPage, 40, 20)
#elseif TargetMacOS
TextArea1.DrawInto(myPage, 40, 20)
#endif
End If
End Sub[/code]

I don’t see a reason why this wouldn’t work, and in fact it did work on a couple of rare occasions in debug but not at all in a built application. This is what is puzzling me.

I just tested under Windows 7 and Windows XP. In 7 it seems only the control but not its content is copied, and in XP nothing copies.

For me that will be a big issue, as I need the program to work from XP up to Win 10.

I will have to go back to what I was doing before Jim posted his code : ScreenShotRectMBS where I simply grab the TextArea screen content.

I suppose the BitBlt method in WFS would do too.

Reading Jim’s code, it uses SendMessage, which may not work quite the same in 7 and XP.

Your tests would seem to bear out my own results in Windows 7. I also need a solution that will work through Windows versions from XP SP3 to Windows 8.

So back to the drawing-board!

The solution just hit me. I now use StyledTextPrinter.DrawBlock on a picture Graphics object. I do not have the frame of the TextArea, but precisely I had to remove it with DrawInto for my project purpose.

http://documentation.xojo.com/index.php/StyledTextPrinter

[quote=174881:@Michel Bujardet]The solution just hit me. I now use StyledTextPrinter.DrawBlock on a picture Graphics object. I do not have the frame of the TextArea, but precisely I had to remove it with DrawInto for my project purpose.

http://documentation.xojo.com/index.php/StyledTextPrinter[/quote]

“StyledTextPrinter no longer works on Windows starting with 2016r4.”

And the Feedback cases are still not fixed.

Are there any new solution? Or is the bug fixed and the cases just have not been updated? Asking for a friend :wink: