Printing RTF using CreateTextServices()

Printing RTF using CreateTextServices()

Postby Antonio Linares » Fri Feb 04, 2022 7:43 pm

to test it, from FWH\samples do:

buildh32.bat tim

tim.prg
Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   local oWnd

   DEFINE WINDOW oWnd

   ACTIVATE WINDOW oWnd ;
      ON PAINT PrnSayRTF( hDC )

return nil

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>
#include <Richedit.h>
#include <TextServ.h>
#include <memory>

EXTERN_C const IID IID_ITextHost = {
    0xc5bdd8d0,
    0xd26e,
    0x11ce,
    { 0xa8, 0x9e, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5 }
};

EXTERN_C const IID IID_ITextServices = {
    0x8d33f740,
    0xcf58,
    0x11ce,
    { 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5 }
};

typedef HRESULT ( _stdcall * PCREATETEXTSERVICES ) ( IUnknown *, ITextHost *, IUnknown ** );

class TextHost : public ITextHost {
public:
    HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override {

        if (ppvObject == nullptr) {
            return E_POINTER;
        }

        if ((riid == IID_IUnknown) || (riid == IID_ITextHost)) {
            *ppvObject = this;
            return S_OK;
        }

        *ppvObject = nullptr;
        return E_NOINTERFACE;
    }

    ULONG __stdcall AddRef(void) override {
        return 0;
    }

    ULONG __stdcall Release(void) override {
        return 0;
    }

    HDC TxGetDC() override {
        return nullptr;
    }

    INT TxReleaseDC(HDC hdc) override {
        return 0;
    }

    BOOL TxShowScrollBar(INT fnBar, BOOL fShow) override {
        return FALSE;
    }

    BOOL TxEnableScrollBar(INT fuSBFlags, INT fuArrowflags) override {
        return FALSE;
    }

    BOOL TxSetScrollRange(INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw) override {
        return FALSE;
    }

    BOOL TxSetScrollPos(INT fnBar, INT nPos, BOOL fRedraw) override {
        return FALSE;
    }

    void TxInvalidateRect(LPCRECT prc, BOOL fMode) override {

    }

    void TxViewChange(BOOL fUpdate) override {

    }

    BOOL TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight) override {
        return FALSE;
    }

    BOOL TxShowCaret(BOOL fShow) override {
        return FALSE;
    }

    BOOL TxSetCaretPos(INT x, INT y) override {
        return FALSE;
    }

    BOOL TxSetTimer(UINT idTimer, UINT uTimeout) override {
        return FALSE;
    }

    void TxKillTimer(UINT idTimer) override {

    }

    void TxScrollWindowEx(INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate, UINT fuScroll) override {

    }

    void TxSetCapture(BOOL fCapture) override {

    }

    void TxSetFocus() override {

    }

    void TxSetCursor(HCURSOR hcur, BOOL fText) override {

    }

    BOOL TxScreenToClient(LPPOINT lppt) override {
        return FALSE;
    }

    BOOL TxClientToScreen(LPPOINT lppt) override {
        return FALSE;
    }

    HRESULT TxActivate(LONG * plOldState) override {
        return E_NOTIMPL;
    }

    HRESULT TxDeactivate(LONG lNewState) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetClientRect(LPRECT prc) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetViewInset(LPRECT prc) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetCharFormat(const CHARFORMATW **ppCF) override {

        if (char_format_ == nullptr) {
            char_format_ = std::make_unique<CHARFORMATW>();
            char_format_->cbSize = sizeof(CHARFORMATW);
        }

        *ppCF = char_format_.get();
        return S_OK;
    }

    HRESULT TxGetParaFormat(const PARAFORMAT **ppPF) override {

        if (para_format_ == nullptr) {
            para_format_ = std::make_unique<PARAFORMAT>();    
            para_format_->cbSize = sizeof PARAFORMAT;
        }

        *ppPF = para_format_.get();
        return S_OK;
    }

    COLORREF TxGetSysColor(int nIndex) override {
        return GetSysColor(nIndex);
    }

    HRESULT TxGetBackStyle(TXTBACKSTYLE *pstyle) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetMaxLength(DWORD *plength) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetScrollBars(DWORD *pdwScrollBar) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetPasswordChar(_Out_ TCHAR *pch) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetAcceleratorPos(LONG *pcp) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetExtent(LPSIZEL lpExtent) override {
        return E_NOTIMPL;
    }

    HRESULT OnTxCharFormatChange(const CHARFORMATW * pCF) override {
        return E_NOTIMPL;
    }

    HRESULT OnTxParaFormatChange(const PARAFORMAT * pPF) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits) override {
        *pdwBits = 0;
        return S_OK;
    }

    HRESULT TxNotify(DWORD iNotify, void *pv) override {
        return E_NOTIMPL;
    }

    HIMC TxImmGetContext() override {
        return nullptr;
    }

    void TxImmReleaseContext(HIMC himc) override {

    }

    HRESULT TxGetSelectionBarWidth(LONG *lSelBarWidth) override {
        *lSelBarWidth = 0;
        return S_OK;
    }

private:
    std::unique_ptr<CHARFORMATW> char_format_;
    std::unique_ptr<PARAFORMAT> para_format_;
};

HB_FUNC( PRNSAYRTF )
{
   IUnknown * unknown;
   TextHost textHost;
   HMODULE hDLL = LoadLibrary( "riched20.dll" );
   PCREATETEXTSERVICES pCreateTextServices = ( PCREATETEXTSERVICES ) GetProcAddress( hDLL, "CreateTextServices" );
   ITextServices * pTextServices;
   RECT rect;

   rect.top = 0;
   rect.left = 0;
   rect.bottom = 200;
   rect.right  = 200;

   pCreateTextServices( nullptr, &textHost, &unknown );

   unknown->QueryInterface( IID_ITextServices, ( void ** ) &pTextServices );
   pTextServices->TxSetText( L"Yes, its working!" );
   pTextServices->TxDraw( DVASPECT_CONTENT, 0, nullptr, nullptr, ( HDC ) hb_parnl( 1 ),
                          nullptr, ( LPCRECTL ) &rect, nullptr, nullptr, nullptr, 0, 0 );

   FreeLibrary( hDLL );
}

#pragma ENDDUMP
regards, saludos

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

Re: Printing RTF using CreateTextServices()

Postby Antonio Linares » Sat Feb 05, 2022 8:11 am

Enhanced version:

Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   local oWnd, cRTF

   TEXT INTO cRTF
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial Rounded MT Bold;}
{\f1\fnil\fcharset0 ARIAL;}}
{\colortbl ;\red0\green0\blue0;\red255\green0\blue0;\red0\green255\blue64;\red255\green255\blue0;}
{\*\generator Riched20 10.0.22000}\viewkind4\uc1
\pard\cf1\f0\fs28\lang3082 Printing \cf2 RTF\cf1  \i using\i0  \cf3 CreateTextServices\cf4 ()\cf0\f1\fs20\lang2057\par
}
   ENDTEXT

   DEFINE WINDOW oWnd

   ACTIVATE WINDOW oWnd ;
      ON PAINT PrnSayRTF( hDC, cRTF )

return nil

#pragma BEGINDUMP

#include <windows.h>
#include <hbapi.h>
#include <Richedit.h>
#include <TextServ.h>
#include <memory>

EXTERN_C const IID IID_ITextHost = {
    0xc5bdd8d0,
    0xd26e,
    0x11ce,
    { 0xa8, 0x9e, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5 }
};

EXTERN_C const IID IID_ITextServices = {
    0x8d33f740,
    0xcf58,
    0x11ce,
    { 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5 }
};

typedef HRESULT ( _stdcall * PCREATETEXTSERVICES ) ( IUnknown *, ITextHost *, IUnknown ** );

class TextHost : public ITextHost {
public:
    HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override {

        if (ppvObject == nullptr) {
            return E_POINTER;
        }

        if ((riid == IID_IUnknown) || (riid == IID_ITextHost)) {
            *ppvObject = this;
            return S_OK;
        }

        *ppvObject = nullptr;
        return E_NOINTERFACE;
    }

    ULONG __stdcall AddRef(void) override {
        return 0;
    }

    ULONG __stdcall Release(void) override {
        return 0;
    }

    HDC TxGetDC() override {
        return nullptr;
    }

    INT TxReleaseDC(HDC hdc) override {
        return 0;
    }

    BOOL TxShowScrollBar(INT fnBar, BOOL fShow) override {
        return FALSE;
    }

    BOOL TxEnableScrollBar(INT fuSBFlags, INT fuArrowflags) override {
        return FALSE;
    }

    BOOL TxSetScrollRange(INT fnBar, LONG nMinPos, INT nMaxPos, BOOL fRedraw) override {
        return FALSE;
    }

    BOOL TxSetScrollPos(INT fnBar, INT nPos, BOOL fRedraw) override {
        return FALSE;
    }

    void TxInvalidateRect(LPCRECT prc, BOOL fMode) override {

    }

    void TxViewChange(BOOL fUpdate) override {

    }

    BOOL TxCreateCaret(HBITMAP hbmp, INT xWidth, INT yHeight) override {
        return FALSE;
    }

    BOOL TxShowCaret(BOOL fShow) override {
        return FALSE;
    }

    BOOL TxSetCaretPos(INT x, INT y) override {
        return FALSE;
    }

    BOOL TxSetTimer(UINT idTimer, UINT uTimeout) override {
        return FALSE;
    }

    void TxKillTimer(UINT idTimer) override {

    }

    void TxScrollWindowEx(INT dx, INT dy, LPCRECT lprcScroll, LPCRECT lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate, UINT fuScroll) override {

    }

    void TxSetCapture(BOOL fCapture) override {

    }

    void TxSetFocus() override {

    }

    void TxSetCursor(HCURSOR hcur, BOOL fText) override {

    }

    BOOL TxScreenToClient(LPPOINT lppt) override {
        return FALSE;
    }

    BOOL TxClientToScreen(LPPOINT lppt) override {
        return FALSE;
    }

    HRESULT TxActivate(LONG * plOldState) override {
        return E_NOTIMPL;
    }

    HRESULT TxDeactivate(LONG lNewState) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetClientRect(LPRECT prc) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetViewInset(LPRECT prc) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetCharFormat(const CHARFORMATW **ppCF) override {

        if (char_format_ == nullptr) {
            char_format_ = std::make_unique<CHARFORMATW>();
            char_format_->cbSize = sizeof(CHARFORMATW);
        }

        *ppCF = char_format_.get();
        return S_OK;
    }

    HRESULT TxGetParaFormat(const PARAFORMAT **ppPF) override {

        if (para_format_ == nullptr) {
            para_format_ = std::make_unique<PARAFORMAT>();    
            para_format_->cbSize = sizeof PARAFORMAT;
        }

        *ppPF = para_format_.get();
        return S_OK;
    }

    COLORREF TxGetSysColor(int nIndex) override {
        return GetSysColor(nIndex);
    }

    HRESULT TxGetBackStyle(TXTBACKSTYLE *pstyle) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetMaxLength(DWORD *plength) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetScrollBars(DWORD *pdwScrollBar) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetPasswordChar(_Out_ TCHAR *pch) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetAcceleratorPos(LONG *pcp) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetExtent(LPSIZEL lpExtent) override {
        return E_NOTIMPL;
    }

    HRESULT OnTxCharFormatChange(const CHARFORMATW * pCF) override {
        return E_NOTIMPL;
    }

    HRESULT OnTxParaFormatChange(const PARAFORMAT * pPF) override {
        return E_NOTIMPL;
    }

    HRESULT TxGetPropertyBits(DWORD dwMask, DWORD *pdwBits) override {
        *pdwBits = 0;
        return S_OK;
    }

    HRESULT TxNotify(DWORD iNotify, void *pv) override {
        return E_NOTIMPL;
    }

    HIMC TxImmGetContext() override {
        return nullptr;
    }

    void TxImmReleaseContext(HIMC himc) override {

    }

    HRESULT TxGetSelectionBarWidth(LONG *lSelBarWidth) override {
        *lSelBarWidth = 0;
        return S_OK;
    }

private:
    std::unique_ptr<CHARFORMATW> char_format_;
    std::unique_ptr<PARAFORMAT> para_format_;
};

struct COOKIE
{
    bool isUnicode;
    union
    {
        char * ansi;
        WCHAR * unicode;
    };
    size_t cbSize, cbCount;
};

DWORD CALLBACK EditStreamInCallback( DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )
{
    COOKIE * pCookie = ( COOKIE * ) dwCookie;

    if( pCookie->isUnicode )
   {
        if( ( pCookie->cbSize - pCookie->cbCount ) * sizeof( WCHAR ) < ( size_t ) cb )
            * pcb = LONG( pCookie->cbSize - pCookie->cbCount ) * sizeof( WCHAR );
        else
            * pcb = cb & ~1UL;
        memcpy( pbBuff, pCookie->unicode + pCookie->cbCount, * pcb );
        pCookie->cbCount += *pcb / sizeof( WCHAR );
    }
    else
   {
        if( pCookie->cbSize - pCookie->cbCount < ( DWORD ) cb )
            * pcb = LONG( pCookie->cbSize - pCookie->cbCount );
        else
            * pcb = cb;
        memcpy( pbBuff, pCookie->ansi + pCookie->cbCount, * pcb );
        pCookie->cbCount += * pcb;
    }

    return 0;
}

HB_FUNC( PRNSAYRTF )
{
   IUnknown * unknown;
   TextHost textHost;
   HMODULE hDLL = LoadLibrary( "riched20.dll" );
   PCREATETEXTSERVICES pCreateTextServices = ( PCREATETEXTSERVICES ) GetProcAddress( hDLL, "CreateTextServices" );
   ITextServices * pTextServices;
   RECT rect;
   COOKIE editCookie;
   EDITSTREAM editStream;
   LRESULT lResult = 0;

   rect.top = 0;
   rect.left = 0;
   rect.bottom = 200;
   rect.right  = 200;

   pCreateTextServices( nullptr, &textHost, &unknown );

   unknown->QueryInterface( IID_ITextServices, ( void ** ) &pTextServices );

    editCookie.isUnicode   = false;
    editCookie.ansi        = ( char * ) hb_parc( 2 );
    editCookie.cbSize      = hb_parclen( 2 );
    editCookie.cbCount     = 0;

   editStream.dwCookie    = ( DWORD_PTR ) &editCookie;
   editStream.dwError     = 0;
   editStream.pfnCallback = EditStreamInCallback;

   pTextServices->TxSendMessage( EM_STREAMIN, ( WPARAM ) SF_RTF, ( LPARAM ) &editStream, &lResult );
   pTextServices->TxDraw( DVASPECT_CONTENT, 0, nullptr, nullptr, ( HDC ) hb_parnl( 1 ),
                          nullptr, ( LPCRECTL ) &rect, nullptr, nullptr, nullptr, 0, 0 );

   FreeLibrary( hDLL );
}

#pragma ENDDUMP
regards, saludos

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

Re: Printing RTF using CreateTextServices()

Postby Antonio Linares » Sun Feb 06, 2022 10:03 am

When we use SF_RTF it does not call the callback and does nothing. GetLastError() returns 2 which means "file not found" (???)
and dwError remains zero.

If we replace SF_RTF with SF_TEXT then it works but it is processed as standard text and not RTF.

I have placed a question in StackOverflow:
https://stackoverflow.com/questions/71005308/ptextservices-txsendmessage-em-streamin-wparam-sf-rtf-lparam-editst
regards, saludos

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

Re: Printing RTF using CreateTextServices()

Postby Antonio Linares » Thu Feb 10, 2022 11:41 pm

Fixed and properly working thanks to Bruno Cantero (C3) :-)

tim.prg
Code: Select all  Expand view  RUN
#include "FiveWin.ch"

function Main()

   local oWnd

   DEFINE WINDOW oWnd

   ACTIVATE WINDOW oWnd ;
      ON PAINT PrnSayRTF( hDC )

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <Richedit.h>
#include <textserv.h>

typedef struct
{
   char * szText;
   LONG lSize;
   LONG lCount;
} RTFTEXTINFO;

typedef HRESULT ( _stdcall * PCREATETEXTSERVICES ) ( IUnknown *, ITextHost *, IUnknown ** );

const IID IID_ITextServices = { 0x8d33f740, 0xcf58, 0x11ce, { 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5 } };

class TTextHost : public ITextHost
{
   public:
      /* IUnknown */
      STDMETHOD( QueryInterface )( REFIID, PVOID * ppvObject ) { * ppvObject = NULL; return S_FALSE; };
      STDMETHOD_( ULONG, AddRef )( void ) { return 0; };
      STDMETHOD_( ULONG, Release )( void ) { return 0; };

      /* ITextHost */
      HDC TxGetDC( void ) { return NULL; };
      INT TxReleaseDC( HDC ) { return 1; };
      BOOL TxShowScrollBar( INT, BOOL ) { return FALSE; };
      BOOL TxEnableScrollBar( INT, INT ) { return FALSE; };
      BOOL TxSetScrollRange( INT, LONG, INT, BOOL ) { return FALSE; };
      BOOL TxSetScrollPos( INT, INT, BOOL ) { return FALSE; };
      void TxInvalidateRect( LPCRECT, BOOL ) {};
      void TxViewChange( BOOL ) {};
      BOOL TxCreateCaret( HBITMAP, INT, INT ) { return FALSE; };
      BOOL TxShowCaret( BOOL ) { return FALSE; };
      BOOL TxSetCaretPos( INT, INT ) { return FALSE; };
      BOOL TxSetTimer( UINT, UINT ) { return FALSE; };
      void TxKillTimer( UINT ) {};
      void TxScrollWindowEx( INT, INT, LPCRECT, LPCRECT, HRGN, LPRECT, UINT ) {};
      void TxSetCapture( BOOL ) {};
      void TxSetFocus( void ) {};
      void TxSetCursor( HCURSOR, BOOL ) {};
      BOOL TxScreenToClient( LPPOINT ) { return FALSE; };
      BOOL TxClientToScreen( LPPOINT ) { return FALSE; };
      HRESULT TxActivate( LONG * ) { return S_OK; };
      HRESULT TxDeactivate( LONG ) { return S_OK; };
      HRESULT TxGetClientRect( LPRECT prc ) { SetRectEmpty( prc ); return S_OK; };
      HRESULT TxGetViewInset( LPRECT prc ) { SetRectEmpty( prc ); return S_OK; };
      HRESULT TxGetCharFormat( const CHARFORMATW ** ppCF ) { * ppCF = &FCharFormat; return S_OK; };
      HRESULT TxGetParaFormat( const PARAFORMAT ** ppPF ) { * ppPF = &FParaFormat; return S_OK; };
      COLORREF TxGetSysColor( int iIndex ) { return GetSysColor( iIndex ); };
      HRESULT TxGetBackStyle( TXTBACKSTYLE * pstyle ) { * pstyle = TXTBACK_TRANSPARENT; return S_OK; };
      HRESULT TxGetMaxLength( DWORD * plength ) { * plength = INFINITE; return S_OK; };
      HRESULT TxGetScrollBars( DWORD * pdwScrollBar ) { * pdwScrollBar = 0; return S_OK; };
      HRESULT TxGetPasswordChar( _Out_ TCHAR * pch ) { return S_FALSE; };
      HRESULT TxGetAcceleratorPos( LONG * pcp ) { * pcp = -1; return S_OK; };
      HRESULT TxGetExtent( LPSIZEL ) { return E_NOTIMPL; };
      HRESULT OnTxCharFormatChange( const CHARFORMATW * pCF ) { memcpy( &FCharFormat, ( void * ) pCF, pCF->cbSize ); return S_OK; };
      HRESULT OnTxParaFormatChange( const PARAFORMAT * pPF ) { memcpy( &FParaFormat, ( void * ) pPF, pPF->cbSize ); return S_OK; };
      HRESULT TxGetPropertyBits( DWORD, DWORD * pdwBits ) { * pdwBits = TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_WORDWRAP | TXTBIT_USECURRENTBKG; return S_OK; };
      HRESULT TxNotify( DWORD, void * ) { return S_OK; };
      HIMC TxImmGetContext( void ) { return NULL; };
      void TxImmReleaseContext( HIMC ) {};
      HRESULT TxGetSelectionBarWidth( LONG * lSelBarWidth ) { * lSelBarWidth = 100; return S_OK; };

      CHARFORMATW FCharFormat;
      PARAFORMAT  FParaFormat;
};

static DWORD CALLBACK EditStreamCallback( DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )
{
   RTFTEXTINFO * pRtfTextInfo;

   pRtfTextInfo = ( RTFTEXTINFO * ) dwCookie;

   if( pRtfTextInfo->lSize - pRtfTextInfo->lCount < cb )
      * pcb = pRtfTextInfo->lSize - pRtfTextInfo->lCount;
   else
      * pcb = cb;

   memcpy( pbBuff, pRtfTextInfo->szText, * pcb );
   pRtfTextInfo->lCount += * pcb;

   return 0;
}

HB_FUNC( PRNSAYRTF )
{
   LRESULT lResult;
   HDC hDC = ( HDC ) hb_parnl( 1 );
   HMODULE hDLL;
   RECT stRect;
   EDITSTREAM stEditStream;
   PCREATETEXTSERVICES pCreateTextServices;
   RTFTEXTINFO sRtfTextInfo;
   IUnknown * pUnknown;
   ITextServices * pTextServices = NULL;
   TTextHost pTextHost;

   stRect = { 10, 10, 200, 200 };
   hDLL = LoadLibrary( "Riched20.dll" );

   pCreateTextServices = ( PCREATETEXTSERVICES ) GetProcAddress( hDLL, "CreateTextServices" );

   pCreateTextServices( NULL, &pTextHost, &pUnknown );
   pUnknown->QueryInterface( IID_ITextServices, ( void ** ) &pTextServices );
   pUnknown->Release();

   if( pTextServices != NULL )
   {
      sRtfTextInfo.szText = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Tahoma;}{\\f1\\fswiss\\fcharset0 Arial;}}{\\colortbl ;\\red128\\green0\\blue0;\\red0\\green0\\blue128;\\red0\\green128\\blue0;}\\viewkind4\\uc1\\pard\\f0\\fs20 H\\fs24 E\\b L\\ul\\fs20 L\\i O\\ulnone\\b0\\i0   \\cf1 W\\b\\fs22 O\\cf2\\ul\\b0 R\\i\\fs28 L\\cf3\\ulnone\\b\\i0\\fs20 D\\cf0\\b0\\f1\\par}";
      sRtfTextInfo.lSize = lstrlen( sRtfTextInfo.szText );
      sRtfTextInfo.lCount = 0;
      stEditStream.dwCookie = ( DWORD_PTR ) &sRtfTextInfo;
      stEditStream.pfnCallback = EditStreamCallback;

      if( pTextServices->TxSendMessage( EM_STREAMIN, SF_RTF, ( LPARAM ) &stEditStream, &lResult ) == S_OK )
         pTextServices->TxDraw( DVASPECT_CONTENT, 0, NULL, NULL, hDC, NULL, ( RECTL * ) &stRect, NULL, NULL, NULL, 0, TXTVIEW_INACTIVE );

      pTextServices->Release();
   }

   FreeLibrary( hDLL );
}

#pragma ENDDUMP


Image
regards, saludos

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

Re: Printing RTF using CreateTextServices()

Postby TimStone » Mon Feb 14, 2022 6:10 pm

How do we translate this to an actual printout. Going back to the original question, when using the Printer class to output a document, such as an invoice, most areas are not RTF. However, I need to include a section as part of the report that does use the RTF format. How can we use this solution to accomplish that in a printed document?
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2945
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: Printing RTF using CreateTextServices()

Postby Antonio Linares » Mon Feb 14, 2022 7:07 pm

Dear Tim,

Now that we got it properly working we are implementing it in FWH.

Its coming, this time, for sure
regards, saludos

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

Re: Printing RTF using CreateTextServices()

Postby TimStone » Mon Feb 14, 2022 7:39 pm

Thank you.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2945
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA


Return to FiveWin for Harbour/xHarbour

Who is online

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