WM_PRINT problem with RichTextBox

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello..

..Net RichTextBox (and so Win32 Rich Edit control) does not responds to
WM_PRINT message. MSDN provides an article for printing the content of the
RichTextBox by using the EM_FORMATRANGE message. So it looks like only the
content of the control can be copied, but not the screen shot of the control(
Especially when the content is scrolled). EM_FORMATRANGE cannot be used in
this case. So any body have solution for this..?
 
Mahantesh,

I must agree that RichEdit behaves rather strange.
Actually RichEdit would process the message if it received it. If you try
Spy++ on such a control you'll see that WM_PRINT never make it to the
control. Weird, isn't it?

As a workaround put a RichTextBox control in a panel and send the message to
the panel. This way the WM_PRINT will go to the control as part of printing
the children of the panel.
 
Thanks a lot for your reply.
I just tried again placing the rich text control in a panel and passing
WM_PRINT message, still the behaviour is the same. I tried with spy++ where I
am seeing the message reaching the control. It is processing the non client
area but it is not processing the client area. I am using Visual Studio 2003.
--
Thanks and regards
Mahantesh


Stoitcho Goutsev (100) said:
Mahantesh,

I must agree that RichEdit behaves rather strange.
Actually RichEdit would process the message if it received it. If you try
Spy++ on such a control you'll see that WM_PRINT never make it to the
control. Weird, isn't it?

As a workaround put a RichTextBox control in a panel and send the message to
the panel. This way the WM_PRINT will go to the control as part of printing
the children of the panel.
 
Mahantesh,

This is strange, because I tested it and it works. Send the message to the
panel not the rich text. Also I found that PrintWindow API method works
better than sending the WM_PRINT message even though they are supposed to do
the same. My test was with PrintWindow API.



--

Stoitcho Goutsev (100)

Mahantesh said:
Thanks a lot for your reply.
I just tried again placing the rich text control in a panel and passing
WM_PRINT message, still the behaviour is the same. I tried with spy++
where I
am seeing the message reaching the control. It is processing the non
client
area but it is not processing the client area. I am using Visual Studio
2003.
 
Hello Stoitcho,

One important difference I observed between WM_PRINT and PrintWindow is
PrintWindow does not capture snapshot of the invisible windows, where as
WM_PRINT message can handle even when invisible, So I am not in a position to
use the PrintWindow API. And also the PrintWindow API depends on the WM_PAINT
message for its capturing not WM_PRINT. So PrintWindow API invocation will
send WM_PAINT message instead of WM_PRINT message to the window, so it works
in case of RichTextBox, only when it is visible.
 
Mahantesh,

I suggest to read carefully MSDN regarding this method. It is based on
sending WM_PRINT not WM_PAINT (that's where the name comes from -
PrintWindow) It does take a snapshot of obscured windows. I've tested it
before I made my post.
If you want to give it a shot otherwise there is no other solution to your
problem that I'm aware of.

BTW netither WM_PRINT nor PrintWindow will take a snapshot of minimized
windows though. The snapshot that they take is the button on the taskbar
 
Hello Stoitcho,

First thanking you for showing keen interest in my problem.
I am still little unclear about the following issues:
Msdn documentation says PrintWindow API is similar to WM_PRINT. But I think
it is different than WM_PRINT, I failed to observe PrintWindow sending
WM_PRINT message to a control when it is invoked, for e.g. When I invoked
PrintWindow on a form with a text box on it and spyed on text box control
message, Spy++ logged me following messages
<00002> 000A1022 S WM_NCPAINT hrgn:00000001
<00003> 000A1022 R WM_NCPAINT
<00004> 000A1022 S WM_ERASEBKGND hdc:A901133B
<00005> 000A1022 R WM_ERASEBKGND fErased:True
<00006> 000A1022 R WM_PAINT
<00007> 000A1022 S WM_NCPAINT hrgn:A2040F72
<00008> 000A1022 R WM_NCPAINT
<00009> 000A1022 S WM_ERASEBKGND hdc:57011773
<00010> 000A1022 R WM_ERASEBKGND fErased:True
<00011> 000A1022 P WM_PAINT hdc:00000000

This made me believe that PrintWindow is depending on the WM_PAINT message.
And the major difference is unlike PrintWindow API WM_PRINT can take
invisible windows. This is evident from the AnimateWindow API relies on the
WM_PRINT message. I observed calling AnimateWindow API sends the WM_PRINT
message to the window passed as parameter. So It is evident that WM_PRINT can
take invisible windows.. but same is not possible with the PrintWindow.
PrintWindow is even not able to take the obscured windows too.

Microsoft's inconsistancy in handling the WM_PRINT message for different
control is causing me major trouble. Just hoping for the best to happen soon.

Thanking you.
 
Mahantesh,

Actually you are right. It doesn't send WM_PRINT to the window, but it doesn
capture obscured windows.
It look slike you have tried it and it also looks like it doesn't work for
you. Is that right?
My next question is what do you mean by "invisible" window?
Is it window that is (1)covered by other windows, (2)half out of the desktop
screen, (3)minimized or (4)completely hidden by removing its style
WS_VISIBLE (the same setting richtextbox Visible property to true)?

PrintWindow will work on cases 1 and 2, but won't work on (3) and (4). I
don't think WM_PRINT will work either on 3 and 4, but I might be wrong.

I run more tests. In my tests I have one capture application and one
application that is a simple form with RichTextBox on it. So far I run my
tests against the whole test application. Now I decided to try testing
against the richtext only like the control covered by other controls on the
form, control partially outside its container, control hidden via Visible
property, etc. What I found is that this method doesn't work in cases where
the control is hidden via Visible property (this one I expected) and it also
doesn't work when the control is partially outside its container (this one I
didn't expect).
The method works if the control is covered, by other controls in the form,
thougth.

Again this is the only solution that can come with. Did you try to put the
richtext on a panel and send WM_PRINT to the panel, specifying to draw the
children also?
 
Hi Stoitcho,

What I mean invisible is when the Control.Visible = false (your case 4). At
this stage the control is not visible on the screen neither minimized nor
obscured by other windows. It is possible to take the snap of a invisible
window using WM_PRINT. This should be possible with every microsoft's window,
because the AnimateWindow API is completely relying on this mechanism. It
just take the snap of the window passed as parameter by sending the WM_PRINT
message to the control to take the snap in a device context (or bitmap ) and
animates the bitmap till it shows the entire window and then finally in the
last animation stepchanges the visibility of the window to show. This is how
I would like to use in my custom animation api, I am developing.
I saw almost all controls process the WM_PRINT message even in invisible
mode too, and can be captured in a bitmap except RichTextBox. I even tried
placing RTB in a panel and passing message to the panel.
--
Thanks and regards
Mahantesh


Stoitcho Goutsev (100) said:
Mahantesh,

Actually you are right. It doesn't send WM_PRINT to the window, but it doesn
capture obscured windows.
It look slike you have tried it and it also looks like it doesn't work for
you. Is that right?
My next question is what do you mean by "invisible" window?
Is it window that is (1)covered by other windows, (2)half out of the desktop
screen, (3)minimized or (4)completely hidden by removing its style
WS_VISIBLE (the same setting richtextbox Visible property to true)?

PrintWindow will work on cases 1 and 2, but won't work on (3) and (4). I
don't think WM_PRINT will work either on 3 and 4, but I might be wrong.

I run more tests. In my tests I have one capture application and one
application that is a simple form with RichTextBox on it. So far I run my
tests against the whole test application. Now I decided to try testing
against the richtext only like the control covered by other controls on the
form, control partially outside its container, control hidden via Visible
property, etc. What I found is that this method doesn't work in cases where
the control is hidden via Visible property (this one I expected) and it also
doesn't work when the control is partially outside its container (this one I
didn't expect).
The method works if the control is covered, by other controls in the form,
thougth.

Again this is the only solution that can come with. Did you try to put the
richtext on a panel and send WM_PRINT to the panel, specifying to draw the
children also?
 
Mahantesh,

Now everything's clear. Sorry for my unhelpful posts :).
Yes, you are right; RichText box don't respond to WM_PRINT. Actually nothing
in the docs says that this message has to be processed. I noticed that
usually this message is processed by MS controls, but not from thinrd party
controls. With RichText box it might be a bug or might have some security
considerations. Either ways I can't think of any workaround.
 
Back
Top