Richtext printing

Richtext printing

Postby reinaldocrespo » Tue Feb 07, 2006 8:36 pm

Hi.

To print richt text with tprinter class, I've decided to implement an algorithm where I parse the richtext detecting rtf tokens and printing every time a font change happens. To this end, when achange is detected I do a "selection" of the text and then with REGetCharFormat I get the font and color.

But ortf:SetSel() does not seem to work properly. ReGetCharFormat always return the last font and color of text in the rtf control.

Here is a piece of the code showing at least part of the logic:

Code: Select all  Expand view
local cRtf      := RESaveAsRTF( ::ortf:hWnd, SF_RTF )
...
   While nStart < len( cRtf )
      nLast := FindEndOfText( cRtf, nStart )
      ::oRtf:SetSel( nStart, nLast )
      cLine := SubStr( cRtf, nStart, nLast - nStart )

      nStart := nLast + 1
      nStart := FindEndOfTokens( cRtf, nStart )

      aFont := REGetCharFormat( ::ortf:hWnd, @nColor )
      nPad := ::oRtf:GetAlign()
      oRtfFont := tFont():New( aFont[ LF_FACENAME ], ;
                  aFont[ LF_WIDTH ], ;
                  aFont[ LF_HEIGHT ], .f.,;
                  aFont[ LF_WEIGHT ] == FW_BOLD,,,;
                  aFont[ LF_WEIGHT ],;
                  aFont[ LF_ITALIC ],;
                  aFont[ LF_UNDERLINE ],,,,,, ::oPrn, aFont[ LF_PITCHANDFAMILY ] )

      nChrsPerLine:= Int( ( ::oPrn:nHorzRes() - ( ::oPrn:nHorzRes() / 8.5 ) ) / max( oRtfFont:nWidth, 10 )  )
      cLine := StrTran( cLine, "\par", "" )
      nTotLns   := MlCount( cLine, nchrsPerLine, 5, .t. )

      For i:= 1 to nTotLns
         ::oprn:InchSay( nLine, nLeftMargin, MemoLine( cLine, nChrsPerLine, i, 5, .t. ), ;
               oRtfFont,, nColor,, iif( nPad == 3, 2, 0 ) )

         nLine += 0.16
...


It prints the text just fine. But it prints all text using the last font and color on the rtf control. I'm quite sure I'm doing something wrong with SetSel() or it is just not the function I need.

I still need to implement justification (npad above) and how to continue printing at the exact position that the last char was printed, but I'll get to that later. Right now, I only need to solve the setsel() problem.

Please help.




Reinaldo.
User avatar
reinaldocrespo
 
Posts: 973
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby reinaldocrespo » Wed Feb 08, 2006 2:04 pm

This silence only tells me that, perhaps, my note is not clear enough. So let me update the situation.

I've found that with this small change it almost works.
Code: Select all  Expand view
   While nStart < len( cRtf )
      nLast := FindEndOfText( cRtf, nStart )
      cLine := SubStr( cRtf, nStart, nLast - nStart )
      ::oRtf:SetSel( nMax := at( cLine, cText ), Len( cLine ) )


Which means that ::setsel() takes a parameter the point where to start and end using as reference the actual text with out the rtf code. And this is why setsel() was not working for me.

Reinaldo.

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 973
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Enrico Maria Giordano » Wed Feb 08, 2006 2:07 pm

reinaldocrespo wrote:This silence only tells me that, perhaps, my note is not clear enough.


No, this silence loudly tells you that without a reduced and self-contained sample it is often practically impossible to help you. :-)

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8410
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby reinaldocrespo » Wed Feb 08, 2006 2:52 pm

Enrico;

Good to see your answer.
Ok. I take your point.

Let's just rephrase the question. First let's laid a couple of assumptions:
With:

Code: Select all  Expand view
local cRtf   := RESaveAsRTF( ::ortf:hWnd, SF_RTF )
local cText  := ortf:GetText()


I have in cRtf all text together with all rtf tokens embedded. And cText contains only the text.

Now I want to select a piece of text that starts at nMin and ends at nMax in cRtf and the only way I know how is using ::setsel( nMin, nMax). But the parameters expected by setsel() are in reference to cText not in cRtf. Thus if use:
Code: Select all  Expand view
::oRtf:SetSel( nMin, nMax )


I'd get the wrong text selected and that is because nMin and nMax are points in cRtf not in cText.

So my question is: given start and end points in cRtf how can I select that piece? (I intend to use ReGetCharFormat afterwards). I'm thinking that perhaps there is another way to select() using points that reference cRtf.

After reading this and what I wrote before, I have to say; I made a mess the first time. I appologize. If you'd still need a self contained sample, I'll gladly work it up and upload it.

Thank you,

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 973
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Enrico Maria Giordano » Wed Feb 08, 2006 3:08 pm

Try with EM_EXSETSEL message instead of EM_SETSEL. From the MSDN:

EM_EXSETSEL
The EM_EXSETSEL message selects a range of characters and/or COM objects in a rich edit control.

To send this message, call the SendMessage function with the following parameters.

SendMessage(
(HWND) hWnd, // handle to destination window
EM_EXSETSEL, // message to send
(WPARAM) wParam, // not used; must be zero
(LPARAM) lParam // selection range (CHARRANGE *)
);
Parameters
wParam
This parameter is not used; it must be zero.
lParam
Pointer to a CHARRANGE structure that specifies the selection range.
Return Values
The return value is the selection that is actually set.

Requirements
Windows NT/2000/XP: Included in Windows NT 4.0 and later.
Windows 95/98/Me: Included in Windows 95 and later.
Header: Declared in Richedit.h.

See Also
Rich Edit Controls Overview, Rich Edit Messages


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8410
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby reinaldocrespo » Wed Feb 08, 2006 5:23 pm

Enrico;

My rtf file is 676 bytes long. The text obtain by ortf:gettext() is 202 bytes long.

when I issue a EM_EXSETSEL message with cpmin set at any nuber above 202 it set is to 202.

Example:

Code: Select all  Expand view
      RESetSelection( ::ortf:hWnd, nmin, len( cLine ) )

Where nmin is 300,
Code: Select all  Expand view
      REGetSelection( ::oRtf:hwnd, @nMin, @nMax )

will set nmin to 202.
Below my ReGet and ReSel funcs.
Code: Select all  Expand view
//------------------------------------------------------------------------------------------------------------------------------
HB_FUNC( REGETSELECTION )
{
   CHARRANGE cr;

   SendMessage( ( HWND ) hb_parnl( 1 ), EM_EXGETSEL, 0, ( LPARAM ) &cr );

   if( hb_pcount() > 1 )
      hb_stornl( cr.cpMin, 2 );

   if( hb_pcount() == 3 )
      hb_stornl( cr.cpMax, 3 );
}

//------------------------------------------------------------------------------------------------------------------------------
HB_FUNC( RESETSELECTION )
{
   CHARRANGE cr;

   cr.cpMin = hb_parnl( 2 );
   cr.cpMax = hb_parnl( 3 );

   SendMessage( ( HWND ) hb_parnl( 1 ), EM_EXSETSEL, 0, ( LPARAM ) &cr );

   hb_retni( SendMessage( ( HWND ) hb_parnl( 1 ), EM_SCROLLCARET, 0, 0L ) );
}


so obviously EM_EXSETSEL is working on plain text not on the actual rtf command embedded text.

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 973
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Enrico Maria Giordano » Wed Feb 08, 2006 5:32 pm

Sorry, I ran out of ideas... :-(

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8410
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby Antonio Linares » Wed Feb 08, 2006 9:33 pm

Reinaldo,

We plan to publish richedit printing in next March build.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41462
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby reinaldocrespo » Wed Feb 08, 2006 9:51 pm

Antonio;

Hi.

Glad to hear the news. I'll be waiting in line to place the order for March build. :-)


BTW -- with it, I'll be able to print rtf data to a region of an already opened tprinter object. Right?


Reinaldo.
User avatar
reinaldocrespo
 
Posts: 973
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Postby Antonio Linares » Wed Feb 08, 2006 11:30 pm

Reinaldo,

Yes
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41462
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Thu Feb 09, 2006 7:34 am

Reinaldo,

Yes,
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41462
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Silvio » Thu Feb 09, 2006 9:09 am

Dear Antonio,
I have richpad ( do you remember ?) But there are many func REXXXXXXXX , I not have this source file where i can found it ?
I used it for a program at school office
silvio
User avatar
Silvio
 
Posts: 3107
Joined: Fri Oct 07, 2005 6:28 pm
Location: Teramo,Italy


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 151 guests