/************************************************************************* ** ** OLE 2 Sample Code ** ** outltxtl.c ** ** This file contains TextLine methods and related support functions. ** ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved ** *************************************************************************/ #include "outline.h" OLEDBGDATA extern LPOUTLINEAPP g_lpApp; /* TextLine_Create * --------------- * * Create a text line object and return the pointer */ LPTEXTLINE TextLine_Create(HDC hDC, UINT nTab, LPSTR lpszText) { LPTEXTLINE lpTextLine; lpTextLine=(LPTEXTLINE) New((DWORD)sizeof(TEXTLINE)); if (lpTextLine == NULL) { OleDbgAssertSz(lpTextLine!=NULL,"Error allocating TextLine"); return NULL; } TextLine_Init(lpTextLine, nTab, hDC); if (lpszText) { lpTextLine->m_nLength = lstrlen(lpszText); lstrcpy((LPSTR)lpTextLine->m_szText, lpszText); } else { lpTextLine->m_nLength = 0; lpTextLine->m_szText[0] = '\0'; } TextLine_CalcExtents(lpTextLine, hDC); return(lpTextLine); } /* TextLine_Init * ------------- * * Calculate the width/height of a text line object. */ void TextLine_Init(LPTEXTLINE lpTextLine, int nTab, HDC hDC) { Line_Init((LPLINE)lpTextLine, nTab, hDC); // init the base class fields ((LPLINE)lpTextLine)->m_lineType = TEXTLINETYPE; lpTextLine->m_nLength = 0; lpTextLine->m_szText[0] = '\0'; } /* TextLine_Delete * --------------- * * Delete the TextLine structure */ void TextLine_Delete(LPTEXTLINE lpTextLine) { Delete((LPVOID)lpTextLine); } /* TextLine_Edit * ------------- * * Edit the text line object. * * Returns TRUE if line was changed * FALSE if the line was NOT changed */ BOOL TextLine_Edit(LPTEXTLINE lpLine, HWND hWndDoc, HDC hDC) { #if defined( USE_FRAMETOOLS ) LPFRAMETOOLS lptb = OutlineApp_GetFrameTools(g_lpApp); #endif BOOL fStatus = FALSE; #if defined( USE_FRAMETOOLS ) FrameTools_FB_GetEditText(lptb, lpLine->m_szText, sizeof(lpLine->m_szText)); #else if (! InputTextDlg(hWndDoc, lpLine->m_szText, "Edit Line")) return FALSE; #endif lpLine->m_nLength = lstrlen(lpLine->m_szText); TextLine_CalcExtents(lpLine, hDC); fStatus = TRUE; return fStatus; } /* TextLine_CalcExtents * -------------------- * * Calculate the width/height of a text line object. */ void TextLine_CalcExtents(LPTEXTLINE lpTextLine, HDC hDC) { SIZE size; LPLINE lpLine = (LPLINE)lpTextLine; if (lpTextLine->m_nLength) { GetTextExtentPoint(hDC, lpTextLine->m_szText, lpTextLine->m_nLength, &size); lpLine->m_nWidthInHimetric=size.cx; lpLine->m_nHeightInHimetric=size.cy; } else { // we still need to calculate proper height even for NULL string TEXTMETRIC tm; GetTextMetrics(hDC, &tm); // required to set height lpLine->m_nHeightInHimetric = tm.tmHeight; lpLine->m_nWidthInHimetric = 0; } #if defined( _DEBUG ) { RECT rc; rc.left = 0; rc.top = 0; rc.right = XformWidthInHimetricToPixels(hDC, lpLine->m_nWidthInHimetric); rc.bottom = XformHeightInHimetricToPixels(hDC, lpLine->m_nHeightInHimetric); OleDbgOutRect3("TextLine_CalcExtents", (LPRECT)&rc); } #endif } /* TextLine_SetHeightInHimetric * ---------------------------- * * Set the height of a textline object. */ void TextLine_SetHeightInHimetric(LPTEXTLINE lpTextLine, int nHeight) { if (!lpTextLine) return; ((LPLINE)lpTextLine)->m_nHeightInHimetric = nHeight; } /* TextLine_GetTextLen * ------------------- * * Return length of string of the TextLine (not considering the tab level). */ int TextLine_GetTextLen(LPTEXTLINE lpTextLine) { return lstrlen((LPSTR)lpTextLine->m_szText); } /* TextLine_GetTextData * -------------------- * * Return the string of the TextLine (not considering the tab level). */ void TextLine_GetTextData(LPTEXTLINE lpTextLine, LPSTR lpszBuf) { lstrcpy(lpszBuf, (LPSTR)lpTextLine->m_szText); } /* TextLine_GetOutlineData * ----------------------- * * Return the CF_OUTLINE format data for the TextLine. */ BOOL TextLine_GetOutlineData(LPTEXTLINE lpTextLine, LPTEXTLINE lpBuf) { TextLine_Copy((LPTEXTLINE)lpTextLine, lpBuf); return TRUE; } /* TextLine_Draw * ------------- * * Draw a text line object on a DC. * Parameters: * hDC - DC to which the line will be drawn * lpRect - the object rectangle in logical coordinates * lpRectWBounds - bounding rect of the metafile underneath hDC * (NULL if hDC is not a metafile DC) * this is used by ContainerLine_Draw to draw the OLE obj * fHighlight - TRUE use selection highlight text color */ void TextLine_Draw( LPTEXTLINE lpTextLine, HDC hDC, LPRECT lpRect, LPRECT lpRectWBounds, BOOL fHighlight ) { RECT rc; int nBkMode; COLORREF clrefOld; if (!lpTextLine) return; rc = *lpRect; rc.left += ((LPLINE)lpTextLine)->m_nTabWidthInHimetric; rc.right += ((LPLINE)lpTextLine)->m_nTabWidthInHimetric; nBkMode = SetBkMode(hDC, TRANSPARENT); if (fHighlight) { /*Get proper txt colors */ clrefOld = SetTextColor(hDC,GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { clrefOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); } ExtTextOut( hDC, rc.left, rc.top, ETO_CLIPPED, (LPRECT)&rc, lpTextLine->m_szText, lpTextLine->m_nLength, (LPINT) NULL /* default char spacing */ ); SetTextColor(hDC, clrefOld); SetBkMode(hDC, nBkMode); } /* TextLine_DrawSelHilight * ----------------------- * * Handles selection of textline */ void TextLine_DrawSelHilight(LPTEXTLINE lpTextLine, HDC hDC, LPRECT lpRect, UINT itemAction, UINT itemState) { if (itemAction & ODA_SELECT) { // check if there is a selection state change, ==> invert rect if (itemState & ODS_SELECTED) { if (!((LPLINE)lpTextLine)->m_fSelected) { ((LPLINE)lpTextLine)->m_fSelected = TRUE; InvertRect(hDC, (LPRECT)lpRect); } } else { if (((LPLINE)lpTextLine)->m_fSelected) { ((LPLINE)lpTextLine)->m_fSelected = FALSE; InvertRect(hDC, lpRect); } } } else if (itemAction & ODA_DRAWENTIRE) { ((LPLINE)lpTextLine)->m_fSelected=((itemState & ODS_SELECTED) ? TRUE : FALSE); InvertRect(hDC, lpRect); } } /* TextLine_Copy * ------------- * * Duplicate a textline */ BOOL TextLine_Copy(LPTEXTLINE lpSrcLine, LPTEXTLINE lpDestLine) { _fmemcpy(lpDestLine, lpSrcLine, sizeof(TEXTLINE)); return TRUE; } /* TextLine_CopyToDoc * ------------------ * * Copy a textline to another Document (usually ClipboardDoc) */ BOOL TextLine_CopyToDoc(LPTEXTLINE lpSrcLine, LPOUTLINEDOC lpDestDoc, int nIndex) { LPTEXTLINE lpDestLine; BOOL fStatus = FALSE; lpDestLine = (LPTEXTLINE) New((DWORD)sizeof(TEXTLINE)); if (lpDestLine == NULL) { OleDbgAssertSz(lpDestLine!=NULL,"Error allocating TextLine"); return FALSE; } if (TextLine_Copy(lpSrcLine, lpDestLine)) { OutlineDoc_AddLine(lpDestDoc, (LPLINE)lpDestLine, nIndex); fStatus = TRUE; } return fStatus; } /* TextLine_SaveToStg * ------------------ * * Save a textline into a storage * * Return TRUE if successful, FALSE otherwise */ BOOL TextLine_SaveToStm(LPTEXTLINE lpTextLine, LPSTREAM lpLLStm) { HRESULT hrErr; ULONG nWritten; USHORT nLengthOnDisk; nLengthOnDisk = (USHORT) lpTextLine->m_nLength; hrErr = lpLLStm->lpVtbl->Write( lpLLStm, (LPVOID)&nLengthOnDisk, sizeof(nLengthOnDisk), &nWritten ); if (hrErr != NOERROR) { OleDbgOutHResult("Write TextLine data (1) returned", hrErr); return FALSE; } hrErr = lpLLStm->lpVtbl->Write( lpLLStm, (LPVOID)lpTextLine->m_szText, lpTextLine->m_nLength, &nWritten ); if (hrErr != NOERROR) { OleDbgOutHResult("Write TextLine data (2) returned", hrErr); return FALSE; } return TRUE; } /* TextLine_LoadFromStg * -------------------- * * Load a textline from storage */ LPLINE TextLine_LoadFromStg(LPSTORAGE lpSrcStg, LPSTREAM lpLLStm, LPOUTLINEDOC lpDestDoc) { HRESULT hrErr; ULONG nRead; LPTEXTLINE lpTextLine; USHORT nLengthOnDisk; lpTextLine=(LPTEXTLINE) New((DWORD)sizeof(TEXTLINE)); if (lpTextLine == NULL) { OleDbgAssertSz(lpTextLine!=NULL,"Error allocating TextLine"); return NULL; } TextLine_Init(lpTextLine, 0, NULL); hrErr = lpLLStm->lpVtbl->Read( lpLLStm, (LPVOID)&nLengthOnDisk, sizeof(nLengthOnDisk), &nRead ); if (hrErr != NOERROR) { OleDbgOutHResult("Read TextLine data (1) returned", hrErr); return NULL; } lpTextLine->m_nLength = (UINT) nLengthOnDisk; OleDbgAssert(lpTextLine->m_nLength < sizeof(lpTextLine->m_szText)); hrErr = lpLLStm->lpVtbl->Read( lpLLStm, (LPVOID)&lpTextLine->m_szText, lpTextLine->m_nLength, &nRead ); if (hrErr != NOERROR) { OleDbgOutHResult("Read TextLine data (1) returned", hrErr); return NULL; } lpTextLine->m_szText[lpTextLine->m_nLength] = '\0'; // add str terminator return (LPLINE)lpTextLine; }