409 lines
8.8 KiB
C
409 lines
8.8 KiB
C
/*************************************************************************
|
|
**
|
|
** 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;
|
|
}
|