ReportPro - Tabs
If you print a memo-field with the following content (chr(9) between the blocks):
1234 5678 abcde 1234 5678 abcde
RP prints 5678 abcde too high:
This happens with normal text and with RTF-text and worked fine in the VO-Version.
This bug is caused by the function rpTabbedTextOut in Drawtext.prg
Please replace the line
MoveToEx(sDrawText:hDC,nX,sDrawText:nY-sDrawText:nDescent,NULL_PTR)
with
MoveToEx(sDrawText:hDC,nX,sDrawText:nY,NULL_PTR)
This fixes the behaviour.
A second problem concerns only RTF-text. If the text after the first tab is marked as bold, RP goes completely nuts:
I did not find a solution for this yet, this didn’t work in VO either. If you find a solution please let me know. I will also try to figure it out when I find some time.
This should fix both problems:
STATIC FUNCTION rpTabbedTextOut(sDrawText AS rpDrawTextStruct,nLineStart AS LONGINT,nLineStop AS LONGINT) AS VOID
// this is a simple replacement for the API Tabbedtextout() since it doesn't work correctly...
// (there is a bug with mapping modes and tabs)
// this replacement doesn't do everything the API function does but, does solve our problems
// sDrawText - DrawText structure
// nLineStart - the starting character of this line (in the buffer)
// nLineStop - the ending character of this line (in the buffer)
LOCAL nDefTabSize,nPrintChars,nX,nTab,nTabStop AS LONGINT
LOCAL ptrText,ptrStart AS BYTE PTR
LOCAL nTextExt AS DWORD
IF sDrawText:sParaProp:nTabs > 0 // default size is the width of the first tab
nDefTabSize := sDrawText:aTabs[1] // if tabs are sent in...
ELSE
nDefTabSize := sDrawText:nAvgCharWid*8 // initialize the avg tab width
ENDIF
IF nDefTabSize = 0 // make sure we have a def size
nDefTabSize := 48
ENDIF
ptrText := sDrawText:ptrText+nLineStart-1
ptrStart := ptrText
nPrintChars := 1
nX := sDrawText:nX
DO WHILE nLineStart <= nLineStop // skip through the buffer
IF DWORD(BYTE(ptrText)) = 9 // if this is a tab character
IF nPrintChars > 1
IF sDrawText:lClipText
ExtTextOut(sDrawText:hDC,0,0,ETO_CLIPPED,(PTR)@sDrawText:nLeft,PSZ(_CAST,ptrStart),nPrintChars-1,NULL_PTR)
ELSE
ExtTextOut(sDrawText:hDC,0,0,0,NULL_PTR,PSZ(_CAST,ptrStart),nPrintChars-1,NULL_PTR)
ENDIF
ENDIF
nTextExt := GetTabbedTextExtent(sDrawText:hPrinterDC,PSZ(_CAST,ptrStart),nPrintChars-1,0,NULL_PTR)
nX += LONGINT(LoWord(nTextExt))
ptrStart := ptrText+1 // setup pointers to the next char
nPrintChars := 0
IF sDrawText:sParaProp:nTabs < 2 // use the default tab size
nTabStop := sDrawText:nLeft+nDefTabSize
DO WHILE nTabStop <= nX
nTabStop += nDefTabSize
ENDDO
nX := nTabStop
ELSE // variable position tabs
FOR nTab := 1 UPTO sDrawText:sParaProp:nTabs
nTabStop := sDrawText:aTabs[nTab]+sDrawText:nLeft
IF nTabStop > nX
nX := nTabStop
EXIT
ENDIF
NEXT
ENDIF
// [KW---]
// MoveToEx(sDrawText:hDC,nX,sDrawText:nY-sDrawText:nDescent,NULL_PTR)
MoveToEx(sDrawText:hDC,nX,sDrawText:nY,NULL_PTR)
// [---KW]
ENDIF
++ptrText // setup pointers to the next char
nPrintChars +=1
nLineStart +=1
ENDDO
IF nPrintChars>1
IF sDrawText:lClipText
ExtTextOut(sDrawText:hDC,0,0,ETO_CLIPPED,(PTR)@sDrawText:nLeft,PSZ(_CAST,ptrStart),nPrintChars-1,NULL_PTR)
ELSE
ExtTextOut(sDrawText:hDC,0,0,0,NULL_PTR,PSZ(_CAST,ptrStart),nPrintChars-1,NULL_PTR)
ENDIF
ENDIF
// [KW---]
sDrawText:NX := nX
// [---KW]
RETURN