3248 lines
82 KiB
C
3248 lines
82 KiB
C
/*************************************************************************
|
|
**
|
|
** OLE 2 Sample Code
|
|
**
|
|
** outldoc.c
|
|
**
|
|
** This file contains OutlineDoc functions.
|
|
**
|
|
** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
|
|
**
|
|
*************************************************************************/
|
|
|
|
#include "outline.h"
|
|
|
|
#if !defined( OLE_VERSION )
|
|
#include <commdlg.h>
|
|
#endif
|
|
|
|
|
|
OLEDBGDATA
|
|
|
|
extern LPOUTLINEAPP g_lpApp;
|
|
|
|
// REVIEW: should use string resource for messages
|
|
char ErrMsgDocWnd[] = "Can't create Document Window!";
|
|
char ErrMsgFormatNotSupported[] = "Clipboard format not supported!";
|
|
char MsgSaveFile[] = "Save existing file ?";
|
|
char ErrMsgSaving[] = "Error in saving file!";
|
|
char ErrMsgOpening[] = "Error in opening file!";
|
|
char ErrMsgFormat[] = "Improper file format!";
|
|
char ErrOutOfMemory[] = "Error: out of memory!";
|
|
static char ErrMsgPrint[] = "Printing Error!";
|
|
|
|
static BOOL fCancelPrint; // TRUE if the user has canceled the print job
|
|
static HWND hWndPDlg; // Handle to the cancel print dialog
|
|
|
|
|
|
/* OutlineDoc_Init
|
|
* ---------------
|
|
*
|
|
* Initialize the fields of a new OutlineDoc object. The object is initially
|
|
* not associated with a file or an (Untitled) document. This function sets
|
|
* the docInitType to DOCTYPE_UNKNOWN. After calling this function the
|
|
* caller should call:
|
|
* 1. OutlineDoc_InitNewFile to set the OutlineDoc to (Untitled)
|
|
* 2. OutlineDoc_LoadFromFile to associate the OutlineDoc with a file.
|
|
* This function creates a new window for the document.
|
|
*
|
|
* NOTE: the window is initially created with a NIL size. it must be
|
|
* sized and positioned by the caller. also the document is initially
|
|
* created invisible. the caller must call OutlineDoc_ShowWindow
|
|
* after sizing it to make the document window visible.
|
|
*/
|
|
BOOL OutlineDoc_Init(LPOUTLINEDOC lpOutlineDoc, BOOL fDataTransferDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
lpOutlineDoc->m_hWndDoc = CreateWindow(
|
|
DOCWNDCLASS, // Window class name
|
|
NULL, // Window's title
|
|
|
|
/* OLE2NOTE: an in-place contanier MUST use
|
|
** WS_CLIPCHILDREN window style for the window
|
|
** that it uses as the parent for the server's
|
|
** in-place active window so that its
|
|
** painting does NOT interfere with the painting
|
|
** of the server's in-place active child window.
|
|
*/
|
|
|
|
WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
|
WS_CHILDWINDOW,
|
|
0, 0,
|
|
0, 0,
|
|
lpOutlineApp->m_hWndApp,// Parent window's handle
|
|
(HMENU)1, // child window id
|
|
lpOutlineApp->m_hInst, // Instance of window
|
|
NULL); // Create struct for WM_CREATE
|
|
|
|
#else
|
|
|
|
lpOutlineDoc->m_hWndDoc = CreateWindow(
|
|
DOCWNDCLASS, // Window class name
|
|
NULL, // Window's title
|
|
WS_CHILDWINDOW,
|
|
0, 0,
|
|
0, 0,
|
|
lpOutlineApp->m_hWndApp,// Parent window's handle
|
|
(HMENU)1, // child window id
|
|
lpOutlineApp->m_hInst, // Instance of window
|
|
NULL); // Create struct for WM_CREATE
|
|
#endif
|
|
|
|
if(! lpOutlineDoc->m_hWndDoc) {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgDocWnd);
|
|
return FALSE;
|
|
}
|
|
|
|
SetWindowLong(lpOutlineDoc->m_hWndDoc, 0, (LONG) lpOutlineDoc);
|
|
|
|
if (! LineList_Init(&lpOutlineDoc->m_LineList, lpOutlineDoc))
|
|
return FALSE;
|
|
|
|
lpOutlineDoc->m_lpNameTable = OutlineDoc_CreateNameTable(lpOutlineDoc);
|
|
if (! lpOutlineDoc->m_lpNameTable )
|
|
return FALSE;
|
|
|
|
lpOutlineDoc->m_docInitType = DOCTYPE_UNKNOWN;
|
|
lpOutlineDoc->m_cfSaveFormat = lpOutlineApp->m_cfOutline;
|
|
lpOutlineDoc->m_szFileName[0] = '\0';
|
|
lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
|
|
lpOutlineDoc->m_fDataTransferDoc = fDataTransferDoc;
|
|
lpOutlineDoc->m_uCurrentZoom = IDM_V_ZOOM_100;
|
|
lpOutlineDoc->m_scale.dwSxN = (DWORD) 1;
|
|
lpOutlineDoc->m_scale.dwSxD = (DWORD) 1;
|
|
lpOutlineDoc->m_scale.dwSyN = (DWORD) 1;
|
|
lpOutlineDoc->m_scale.dwSyD = (DWORD) 1;
|
|
lpOutlineDoc->m_uCurrentMargin = IDM_V_SETMARGIN_0;
|
|
lpOutlineDoc->m_nLeftMargin = 0;
|
|
lpOutlineDoc->m_nRightMargin = 0;
|
|
lpOutlineDoc->m_nDisableDraw = 0;
|
|
OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
|
|
|
|
#if defined( USE_HEADING )
|
|
if (! fDataTransferDoc) {
|
|
if (!Heading_Create((LPHEADING)&lpOutlineDoc->m_heading,
|
|
lpOutlineDoc->m_hWndDoc, lpOutlineApp->m_hInst)) {
|
|
return FALSE;
|
|
|
|
}
|
|
}
|
|
#endif // USE_HEADING
|
|
|
|
#if defined( USE_FRAMETOOLS )
|
|
if (! fDataTransferDoc) {
|
|
lpOutlineDoc->m_lpFrameTools = OutlineApp_GetFrameTools(lpOutlineApp);
|
|
FrameTools_AssociateDoc(
|
|
lpOutlineDoc->m_lpFrameTools,
|
|
lpOutlineDoc
|
|
);
|
|
}
|
|
#endif // USE_FRAMETOOLS
|
|
|
|
#if defined( OLE_VERSION )
|
|
/* OLE2NOTE: perform initialization required for OLE */
|
|
if (! OleDoc_Init((LPOLEDOC)lpOutlineDoc, fDataTransferDoc))
|
|
return FALSE;
|
|
#endif // OLE_VERSION
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_InitNewFile
|
|
* ----------------------
|
|
*
|
|
* Initialize the OutlineDoc object to be a new (Untitled) document.
|
|
* This function sets the docInitType to DOCTYPE_NEW.
|
|
*/
|
|
BOOL OutlineDoc_InitNewFile(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
#if defined( OLE_VERSION )
|
|
// OLE2NOTE: call OLE version of this function instead
|
|
return OleDoc_InitNewFile((LPOLEDOC)lpOutlineDoc);
|
|
|
|
#else
|
|
|
|
OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN);
|
|
|
|
// set file name to untitled
|
|
// REVIEW: should load from string resource
|
|
lstrcpy(lpOutlineDoc->m_szFileName, UNTITLED);
|
|
lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
|
|
lpOutlineDoc->m_docInitType = DOCTYPE_NEW;
|
|
|
|
if (! lpOutlineDoc->m_fDataTransferDoc)
|
|
OutlineDoc_SetTitle(lpOutlineDoc, FALSE /*fMakeUpperCase*/);
|
|
|
|
return TRUE;
|
|
|
|
#endif // BASE OUTLINE VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_CreateNameTable
|
|
* --------------------------
|
|
*
|
|
* Allocate a new NameTable of the appropriate type. Each document has
|
|
* a NameTable and a LineList.
|
|
* OutlineDoc --> creates standard OutlineNameTable type name tables.
|
|
* ServerDoc --> creates enhanced SeverNameTable type name tables.
|
|
*
|
|
* Returns lpNameTable for successful, NULL if error.
|
|
*/
|
|
LPOUTLINENAMETABLE OutlineDoc_CreateNameTable(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINENAMETABLE lpOutlineNameTable;
|
|
|
|
lpOutlineNameTable = (LPOUTLINENAMETABLE)New(
|
|
(DWORD)sizeof(OUTLINENAMETABLE)
|
|
);
|
|
|
|
OleDbgAssertSz(lpOutlineNameTable != NULL,"Error allocating NameTable");
|
|
if (lpOutlineNameTable == NULL)
|
|
return NULL;
|
|
|
|
// initialize new NameTable
|
|
if (! OutlineNameTable_Init(lpOutlineNameTable, lpOutlineDoc) )
|
|
goto error;
|
|
|
|
return lpOutlineNameTable;
|
|
|
|
error:
|
|
if (lpOutlineNameTable)
|
|
Delete(lpOutlineNameTable);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ClearCommand
|
|
* -----------------------
|
|
*
|
|
* Delete selection in list box by calling OutlineDoc_Delete
|
|
*/
|
|
void OutlineDoc_ClearCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
int i;
|
|
int nNumSel;
|
|
LINERANGE lrSel;
|
|
|
|
nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
|
|
for(i = 0; i < nNumSel; i++)
|
|
OutlineDoc_DeleteLine(lpOutlineDoc, lrSel.m_nStartLine);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
|
|
LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_CutCommand
|
|
* ---------------------
|
|
*
|
|
* Cut selection to clipboard
|
|
*/
|
|
void OutlineDoc_CutCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
OutlineDoc_CopyCommand(lpOutlineDoc);
|
|
OutlineDoc_ClearCommand(lpOutlineDoc);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_CopyCommand
|
|
* ----------------------
|
|
* Copy selection to clipboard.
|
|
* Post to the clipboard the formats that the app can render.
|
|
* the actual data is not rendered at this time. using the
|
|
* delayed rendering technique, Windows will send the clipboard
|
|
* owner window either a WM_RENDERALLFORMATS or a WM_RENDERFORMAT
|
|
* message when the actual data is requested.
|
|
*
|
|
* OLE2NOTE: the normal delayed rendering technique where Windows
|
|
* sends the clipboard owner window either a WM_RENDERALLFORMATS or
|
|
* a WM_RENDERFORMAT message when the actual data is requested is
|
|
* NOT exposed to the app calling OleSetClipboard. OLE internally
|
|
* creates its own window as the clipboard owner and thus our app
|
|
* will NOT get these WM_RENDER messages.
|
|
*/
|
|
void OutlineDoc_CopyCommand(LPOUTLINEDOC lpSrcOutlineDoc)
|
|
{
|
|
#if defined( OLE_VERSION )
|
|
// Call OLE version of this function instead
|
|
OleDoc_CopyCommand((LPOLEDOC)lpSrcOutlineDoc);
|
|
|
|
#else
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPOUTLINEDOC lpClipboardDoc;
|
|
|
|
OpenClipboard(lpSrcOutlineDoc->m_hWndDoc);
|
|
EmptyClipboard();
|
|
|
|
/* squirrel away a copy of the current selection to the ClipboardDoc */
|
|
lpClipboardDoc = OutlineDoc_CreateDataTransferDoc(lpSrcOutlineDoc);
|
|
|
|
if (! lpClipboardDoc)
|
|
return; // Error: could not create DataTransferDoc
|
|
|
|
lpOutlineApp->m_lpClipboardDoc = (LPOUTLINEDOC)lpClipboardDoc;
|
|
|
|
SetClipboardData(lpOutlineApp->m_cfOutline, NULL);
|
|
SetClipboardData(CF_TEXT, NULL);
|
|
|
|
CloseClipboard();
|
|
|
|
#endif // ! OLE_VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ClearAllLines
|
|
* ------------------------
|
|
*
|
|
* Delete all lines in the document.
|
|
*/
|
|
void OutlineDoc_ClearAllLines(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
int i;
|
|
|
|
for(i = 0; i < lpLL->m_nNumLines; i++)
|
|
OutlineDoc_DeleteLine(lpOutlineDoc, 0);
|
|
|
|
LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_CreateDataTransferDoc
|
|
* --------------------------------
|
|
*
|
|
* Create a document to be use to transfer data (either via a
|
|
* drag/drop operation of the clipboard). Copy the selection of the
|
|
* source doc to the data transfer document. A data transfer document is
|
|
* the same as a document that is created by the user except that it is
|
|
* NOT made visible to the user. it is specially used to hold a copy of
|
|
* data that the user should not be able to change.
|
|
*
|
|
* OLE2NOTE: in the OLE version the data transfer document is used
|
|
* specifically to provide an IDataObject* that renders the data copied.
|
|
*/
|
|
LPOUTLINEDOC OutlineDoc_CreateDataTransferDoc(LPOUTLINEDOC lpSrcOutlineDoc)
|
|
{
|
|
#if defined( OLE_VERSION )
|
|
// Call OLE version of this function instead
|
|
return OleDoc_CreateDataTransferDoc((LPOLEDOC)lpSrcOutlineDoc);
|
|
|
|
#else
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPOUTLINEDOC lpDestOutlineDoc;
|
|
LPLINELIST lpSrcLL = &lpSrcOutlineDoc->m_LineList;
|
|
LINERANGE lrSel;
|
|
int nCopied;
|
|
|
|
lpDestOutlineDoc = OutlineApp_CreateDoc(lpOutlineApp, TRUE);
|
|
if (! lpDestOutlineDoc) return NULL;
|
|
|
|
// set the ClipboardDoc to an (Untitled) doc.
|
|
if (! OutlineDoc_InitNewFile(lpDestOutlineDoc))
|
|
goto error;
|
|
|
|
LineList_GetSel(lpSrcLL, (LPLINERANGE)&lrSel);
|
|
nCopied = LineList_CopySelToDoc(
|
|
lpSrcLL,
|
|
(LPLINERANGE)&lrSel,
|
|
lpDestOutlineDoc
|
|
);
|
|
|
|
return lpDestOutlineDoc;
|
|
|
|
error:
|
|
if (lpDestOutlineDoc)
|
|
OutlineDoc_Destroy(lpDestOutlineDoc);
|
|
|
|
return NULL;
|
|
|
|
#endif // ! OLE_VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_PasteCommand
|
|
* -----------------------
|
|
*
|
|
* Paste lines from clipboard
|
|
*/
|
|
void OutlineDoc_PasteCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
#if defined( OLE_VERSION )
|
|
// Call OLE version of this function instead
|
|
OleDoc_PasteCommand((LPOLEDOC)lpOutlineDoc);
|
|
|
|
#else
|
|
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
int nIndex;
|
|
int nCount;
|
|
HGLOBAL hData;
|
|
LINERANGE lrSel;
|
|
UINT uFormat;
|
|
|
|
if (LineList_GetCount(lpLL) == 0)
|
|
nIndex = -1; // pasting to empty list
|
|
else
|
|
nIndex=LineList_GetFocusLineIndex(lpLL);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
|
|
|
|
OpenClipboard(lpOutlineDoc->m_hWndDoc);
|
|
|
|
uFormat = 0;
|
|
while(uFormat = EnumClipboardFormats(uFormat)) {
|
|
if(uFormat == lpOutlineApp->m_cfOutline) {
|
|
hData = GetClipboardData(lpOutlineApp->m_cfOutline);
|
|
nCount = OutlineDoc_PasteOutlineData(lpOutlineDoc, hData, nIndex);
|
|
break;
|
|
}
|
|
if(uFormat == CF_TEXT) {
|
|
hData = GetClipboardData(CF_TEXT);
|
|
nCount = OutlineDoc_PasteTextData(lpOutlineDoc, hData, nIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
lrSel.m_nStartLine = nIndex + nCount;
|
|
lrSel.m_nEndLine = nIndex + 1;
|
|
LineList_SetSel(lpLL, &lrSel);
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
|
|
CloseClipboard();
|
|
|
|
#endif // ! OLE_VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_PasteOutlineData
|
|
* ---------------------------
|
|
*
|
|
* Put an array of Line Objects (stored in hOutline) into the document
|
|
*
|
|
* Return the number of items added
|
|
*/
|
|
int OutlineDoc_PasteOutlineData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hOutline, int nStartIndex)
|
|
{
|
|
int nCount;
|
|
int i;
|
|
LPTEXTLINE arrLine;
|
|
|
|
nCount = (int) GlobalSize(hOutline) / sizeof(TEXTLINE);
|
|
arrLine = (LPTEXTLINE)GlobalLock(hOutline);
|
|
if (!arrLine)
|
|
return 0;
|
|
|
|
for(i = 0; i < nCount; i++)
|
|
Line_CopyToDoc((LPLINE)&arrLine[i], lpOutlineDoc, nStartIndex+i);
|
|
|
|
GlobalUnlock(hOutline);
|
|
|
|
return nCount;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_PasteTextData
|
|
* ------------------------
|
|
*
|
|
* Build Line Objects from the strings (separated by '\n') in hText
|
|
* and put them into the document
|
|
*/
|
|
int OutlineDoc_PasteTextData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hText, int nStartIndex)
|
|
{
|
|
LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
HDC hDC;
|
|
LPSTR lpszText;
|
|
LPSTR lpszEnd;
|
|
LPTEXTLINE lpLine;
|
|
int nLineCount;
|
|
int i;
|
|
UINT nTab;
|
|
char szBuf[MAXSTRLEN+1];
|
|
|
|
lpszText=(LPSTR)GlobalLock(hText);
|
|
if(!lpszText)
|
|
return 0;
|
|
|
|
lpszEnd = lpszText + lstrlen(lpszText);
|
|
nLineCount=0;
|
|
|
|
while(*lpszText && (lpszText<lpszEnd)) {
|
|
|
|
// count the tab level
|
|
nTab = 0;
|
|
while((*lpszText == '\t') && (lpszText<lpszEnd)) {
|
|
nTab++;
|
|
lpszText++;
|
|
}
|
|
|
|
// collect the text string character by character
|
|
for(i=0; (i<MAXSTRLEN) && (lpszText<lpszEnd); i++) {
|
|
if ((! *lpszText) || (*lpszText == '\n'))
|
|
break;
|
|
szBuf[i] = *lpszText++;
|
|
}
|
|
szBuf[i] = 0;
|
|
lpszText++;
|
|
if ((i > 0) && (szBuf[i-1] == '\r'))
|
|
szBuf[i-1] = 0; // remove carriage return at the end
|
|
|
|
hDC = LineList_GetDC(lpLL);
|
|
lpLine = TextLine_Create(hDC, nTab, szBuf);
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
OutlineDoc_AddLine(
|
|
lpOutlineDoc,
|
|
(LPLINE)lpLine,
|
|
nStartIndex + nLineCount
|
|
);
|
|
nLineCount++;
|
|
|
|
}
|
|
|
|
GlobalUnlock(hText);
|
|
|
|
return nLineCount;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_AddTextLineCommand
|
|
* -----------------------------
|
|
*
|
|
* Add a new text line following the current focus line.
|
|
*/
|
|
void OutlineDoc_AddTextLineCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
HDC hDC;
|
|
int nIndex = LineList_GetFocusLineIndex(lpLL);
|
|
char szBuf[MAXSTRLEN+1];
|
|
UINT nTab = 0;
|
|
LPLINE lpLine;
|
|
LPTEXTLINE lpTextLine;
|
|
|
|
szBuf[0] = '\0';
|
|
|
|
#if defined( USE_FRAMETOOLS )
|
|
FrameTools_FB_GetEditText(
|
|
lpOutlineDoc->m_lpFrameTools, szBuf, sizeof(szBuf));
|
|
#else
|
|
if (! InputTextDlg(lpOutlineDoc->m_hWndDoc, szBuf, "Add Line"))
|
|
return;
|
|
#endif
|
|
|
|
hDC = LineList_GetDC(lpLL);
|
|
lpLine = LineList_GetLine(lpLL, nIndex);
|
|
if (lpLine)
|
|
nTab = Line_GetTabLevel(lpLine);
|
|
|
|
lpTextLine=TextLine_Create(hDC, nTab, szBuf);
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
if (! lpTextLine) {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
|
|
return;
|
|
}
|
|
OutlineDoc_AddLine(lpOutlineDoc, (LPLINE)lpTextLine, nIndex);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_AddTopLineCommand
|
|
* ----------------------------
|
|
*
|
|
* Add a top (margin) line as the first line in the LineList.
|
|
* (do not change the current selection)
|
|
*/
|
|
void OutlineDoc_AddTopLineCommand(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
UINT nHeightInHimetric
|
|
)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
HDC hDC = LineList_GetDC(lpLL);
|
|
LPTEXTLINE lpTextLine = TextLine_Create(hDC, 0, NULL);
|
|
LPLINE lpLine = (LPLINE)lpTextLine;
|
|
LINERANGE lrSel;
|
|
int nNumSel;
|
|
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
if (! lpTextLine) {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
|
|
return;
|
|
}
|
|
|
|
Line_SetHeightInHimetric(lpLine, nHeightInHimetric);
|
|
|
|
nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
if (nNumSel > 0) {
|
|
// adjust current selection to keep equivalent selection
|
|
lrSel.m_nStartLine += 1;
|
|
lrSel.m_nEndLine += 1;
|
|
}
|
|
OutlineDoc_AddLine(lpOutlineDoc, lpLine, -1);
|
|
if (nNumSel > 0)
|
|
LineList_SetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
}
|
|
|
|
|
|
#if defined( USE_FRAMETOOLS )
|
|
|
|
|
|
/* OutlineDoc_SetFormulaBarEditText
|
|
* --------------------------------
|
|
*
|
|
* Fill the edit control in the formula with the text string from a
|
|
* TextLine in focus.
|
|
*/
|
|
void OutlineDoc_SetFormulaBarEditText(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
LPLINE lpLine
|
|
)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
char cBuf[MAXSTRLEN+1];
|
|
|
|
if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
|
|
return;
|
|
|
|
if (Line_GetLineType(lpLine) != TEXTLINETYPE) {
|
|
FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, NULL);
|
|
} else {
|
|
TextLine_GetTextData((LPTEXTLINE)lpLine, (LPSTR)cBuf);
|
|
FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, (LPSTR)cBuf);
|
|
}
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetFormulaBarEditFocus
|
|
* ---------------------------------
|
|
*
|
|
* Setup for formula bar to gain or loose edit focus.
|
|
* if gaining focus, setup up special accelerator table and scroll line
|
|
* into view.
|
|
* else restore normal accelerator table.
|
|
*/
|
|
void OutlineDoc_SetFormulaBarEditFocus(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
BOOL fEditFocus
|
|
)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL;
|
|
int nFocusIndex;
|
|
|
|
if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
|
|
return;
|
|
|
|
lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar = fEditFocus;
|
|
|
|
if (fEditFocus && lpOutlineDoc->m_lpFrameTools) {
|
|
lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
|
|
|
|
nFocusIndex = LineList_GetFocusLineIndex(lpLL);
|
|
LineList_ScrollLineIntoView(lpLL, nFocusIndex);
|
|
FrameTools_FB_FocusEdit(lpOutlineDoc->m_lpFrameTools);
|
|
}
|
|
|
|
OutlineApp_SetFormulaBarAccel(lpOutlineApp, fEditFocus);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_IsEditFocusInFormulaBar
|
|
** ----------------------------------
|
|
** Returns TRUE if edit focus is currently in the formula bar
|
|
** else FALSE if not.
|
|
*/
|
|
BOOL OutlineDoc_IsEditFocusInFormulaBar(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
|
|
return FALSE;
|
|
|
|
return lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_UpdateFrameToolButtons
|
|
** ---------------------------------
|
|
** Update the Enable/Disable states of the buttons in the formula
|
|
** bar and button bar.
|
|
*/
|
|
void OutlineDoc_UpdateFrameToolButtons(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
|
|
return;
|
|
FrameTools_UpdateButtons(lpOutlineDoc->m_lpFrameTools, lpOutlineDoc);
|
|
}
|
|
#endif // USE_FRAMETOOLS
|
|
|
|
|
|
/* OutlineDoc_EditLineCommand
|
|
* --------------------------
|
|
*
|
|
* Edit the current focus line.
|
|
*/
|
|
void OutlineDoc_EditLineCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
HDC hDC = LineList_GetDC(lpLL);
|
|
int nIndex = LineList_GetFocusLineIndex(lpLL);
|
|
LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
|
|
int nOrgLineWidthInHimetric;
|
|
int nNewLineWidthInHimetric;
|
|
BOOL fSizeChanged;
|
|
|
|
if (!lpLine)
|
|
return;
|
|
|
|
nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
|
|
if (Line_Edit(lpLine, lpOutlineDoc->m_hWndDoc, hDC)) {
|
|
nNewLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
|
|
|
|
if (nNewLineWidthInHimetric > nOrgLineWidthInHimetric) {
|
|
fSizeChanged = LineList_SetMaxLineWidthInHimetric(
|
|
lpLL,
|
|
nNewLineWidthInHimetric
|
|
);
|
|
} else {
|
|
fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
|
|
lpLL,
|
|
nOrgLineWidthInHimetric
|
|
);
|
|
}
|
|
|
|
#if defined( OLE_SERVER )
|
|
/* Update Name Table */
|
|
ServerNameTable_EditLineUpdate(
|
|
(LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
|
|
nIndex
|
|
);
|
|
#endif
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
|
|
|
|
LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
|
|
}
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_IndentCommand
|
|
* ------------------------
|
|
*
|
|
* Indent selection of lines
|
|
*/
|
|
void OutlineDoc_IndentCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
LPLINE lpLine;
|
|
HDC hDC = LineList_GetDC(lpLL);
|
|
int i;
|
|
int nIndex;
|
|
int nNumSel;
|
|
LINERANGE lrSel;
|
|
BOOL fSizeChanged = FALSE;
|
|
|
|
nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
|
|
|
|
for(i = 0; i < nNumSel; i++) {
|
|
nIndex = lrSel.m_nStartLine + i;
|
|
lpLine=LineList_GetLine(lpLL, nIndex);
|
|
if (! lpLine)
|
|
continue;
|
|
|
|
Line_Indent(lpLine, hDC);
|
|
if (LineList_SetMaxLineWidthInHimetric(lpLL,
|
|
Line_GetTotalWidthInHimetric(lpLine))) {
|
|
fSizeChanged = TRUE;
|
|
}
|
|
LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
|
|
|
|
#if defined( OLE_SERVER )
|
|
/* Update Name Table */
|
|
ServerNameTable_EditLineUpdate(
|
|
(LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
|
|
nIndex
|
|
);
|
|
#endif
|
|
|
|
}
|
|
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
}
|
|
|
|
|
|
/* OutlineDoc_UnindentCommand
|
|
* --------------------------
|
|
*
|
|
* Unindent selection of lines
|
|
*/
|
|
void OutlineDoc_UnindentCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
LPLINE lpLine;
|
|
HDC hDC = LineList_GetDC(lpLL);
|
|
int nOrgLineWidthInHimetric;
|
|
int nOrgMaxLineWidthInHimetric = 0;
|
|
int i;
|
|
int nIndex;
|
|
int nNumSel;
|
|
LINERANGE lrSel;
|
|
BOOL fSizeChanged;
|
|
|
|
nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
|
|
|
|
for(i = 0; i < nNumSel; i++) {
|
|
nIndex = lrSel.m_nStartLine + i;
|
|
lpLine=LineList_GetLine(lpLL, nIndex);
|
|
if (!lpLine)
|
|
continue;
|
|
|
|
nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
|
|
nOrgMaxLineWidthInHimetric =
|
|
(nOrgLineWidthInHimetric > nOrgMaxLineWidthInHimetric ?
|
|
nOrgLineWidthInHimetric : nOrgMaxLineWidthInHimetric);
|
|
Line_Unindent(lpLine, hDC);
|
|
LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
|
|
|
|
#if defined( OLE_SERVER )
|
|
/* Update Name Table */
|
|
ServerNameTable_EditLineUpdate(
|
|
(LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
|
|
nIndex
|
|
);
|
|
#endif
|
|
|
|
}
|
|
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
|
|
lpLL,
|
|
nOrgMaxLineWidthInHimetric
|
|
);
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetLineHeightCommand
|
|
* -------------------------------
|
|
*
|
|
* Set height of the selection of lines
|
|
*/
|
|
void OutlineDoc_SetLineHeightCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL;
|
|
HDC hDC;
|
|
LPLINE lpLine;
|
|
int nNewHeight;
|
|
int i;
|
|
int nIndex;
|
|
int nNumSel;
|
|
LINERANGE lrSel;
|
|
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
lpLL = &lpOutlineDoc->m_LineList;
|
|
nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
|
|
lpLine = LineList_GetLine(lpLL, lrSel.m_nStartLine);
|
|
if (!lpLine)
|
|
return;
|
|
|
|
nNewHeight = Line_GetHeightInHimetric(lpLine);
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
|
|
DialogBoxParam(
|
|
lpOutlineApp->m_hInst,
|
|
(LPSTR)"SetLineHeight",
|
|
lpOutlineDoc->m_hWndDoc,
|
|
(DLGPROC)SetLineHeightDlgProc,
|
|
(LPARAM)(LPINT)&nNewHeight
|
|
);
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
|
|
if (nNewHeight == 0)
|
|
return; /* user hit cancel */
|
|
|
|
hDC = LineList_GetDC(lpLL);
|
|
|
|
for (i = 0; i < nNumSel; i++) {
|
|
nIndex = lrSel.m_nStartLine + i;
|
|
lpLine=LineList_GetLine(lpLL, nIndex);
|
|
if (nNewHeight == -1) {
|
|
switch (Line_GetLineType(lpLine)) {
|
|
|
|
case TEXTLINETYPE:
|
|
|
|
TextLine_CalcExtents((LPTEXTLINE)lpLine, hDC);
|
|
break;
|
|
|
|
#if defined( OLE_CNTR )
|
|
case CONTAINERLINETYPE:
|
|
|
|
ContainerLine_SetHeightInHimetric(
|
|
(LPCONTAINERLINE)lpLine, -1);
|
|
break;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
else
|
|
Line_SetHeightInHimetric(lpLine, nNewHeight);
|
|
|
|
|
|
LineList_SetLineHeight(lpLL, nIndex,
|
|
Line_GetHeightInHimetric(lpLine));
|
|
}
|
|
|
|
LineList_ReleaseDC(lpLL, hDC);
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
|
|
LineList_ForceRedraw(lpLL, TRUE);
|
|
}
|
|
|
|
|
|
|
|
/* OutlineDoc_SelectAllCommand
|
|
* ---------------------------
|
|
*
|
|
* Select all the lines in the document.
|
|
*/
|
|
void OutlineDoc_SelectAllCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
LINERANGE lrSel;
|
|
|
|
lrSel.m_nStartLine = 0;
|
|
lrSel.m_nEndLine = LineList_GetCount(lpLL) - 1;
|
|
LineList_SetSel(lpLL, &lrSel);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_DefineNameCommand
|
|
* ----------------------------
|
|
*
|
|
* Define a name in the document
|
|
*/
|
|
void OutlineDoc_DefineNameCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
|
|
DialogBoxParam(
|
|
lpOutlineApp->m_hInst,
|
|
(LPSTR)"DefineName",
|
|
lpOutlineDoc->m_hWndDoc,
|
|
(DLGPROC)DefineNameDlgProc,
|
|
(LPARAM) lpOutlineDoc
|
|
);
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GotoNameCommand
|
|
* --------------------------
|
|
*
|
|
* Goto a predefined name in the document
|
|
*/
|
|
void OutlineDoc_GotoNameCommand(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
|
|
DialogBoxParam(
|
|
lpOutlineApp->m_hInst,
|
|
(LPSTR)"GotoName",
|
|
lpOutlineDoc->m_hWndDoc,
|
|
(DLGPROC)GotoNameDlgProc,
|
|
(LPARAM)lpOutlineDoc
|
|
);
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ShowWindow
|
|
* ---------------------
|
|
*
|
|
* Show the window of the document to the user.
|
|
*/
|
|
void OutlineDoc_ShowWindow(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
#if defined( _DEBUG )
|
|
OleDbgAssertSz(lpOutlineDoc->m_docInitType != DOCTYPE_UNKNOWN,
|
|
"OutlineDoc_ShowWindow: can't show unitialized document\r\n");
|
|
#endif
|
|
if (lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN)
|
|
return;
|
|
|
|
#if defined( OLE_VERSION )
|
|
// Call OLE version of this function instead
|
|
OleDoc_ShowWindow((LPOLEDOC)lpOutlineDoc);
|
|
#else
|
|
ShowWindow(lpOutlineDoc->m_hWndDoc, SW_SHOWNORMAL);
|
|
SetFocus(lpOutlineDoc->m_hWndDoc);
|
|
#endif
|
|
}
|
|
|
|
|
|
#if defined( USE_FRAMETOOLS )
|
|
|
|
void OutlineDoc_AddFrameLevelTools(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
#if defined( INPLACE_CNTR )
|
|
// Call OLE In-Place Container version of this function instead
|
|
ContainerDoc_AddFrameLevelTools((LPCONTAINERDOC)lpOutlineDoc);
|
|
|
|
#else // ! INPLACE_CNTR
|
|
RECT rcFrameRect;
|
|
BORDERWIDTHS frameToolWidths;
|
|
|
|
#if defined( INPLACE_SVR )
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
|
|
|
|
// if in-place active, add our tools to our in-place container's frame.
|
|
if (lpTopIPFrame) {
|
|
ServerDoc_AddFrameLevelTools(lpServerDoc);
|
|
return;
|
|
}
|
|
#endif // INPLACE_SVR
|
|
|
|
OutlineApp_GetFrameRect(g_lpApp, (LPRECT)&rcFrameRect);
|
|
FrameTools_GetRequiredBorderSpace(
|
|
lpOutlineDoc->m_lpFrameTools,
|
|
(LPBORDERWIDTHS)&frameToolWidths
|
|
);
|
|
OutlineApp_SetBorderSpace(g_lpApp, (LPBORDERWIDTHS)&frameToolWidths);
|
|
FrameTools_AttachToFrame(
|
|
lpOutlineDoc->m_lpFrameTools, OutlineApp_GetWindow(lpOutlineApp));
|
|
FrameTools_Move(lpOutlineDoc->m_lpFrameTools, (LPRECT)&rcFrameRect);
|
|
#endif // ! INPLACE_CNTR
|
|
|
|
}
|
|
|
|
#endif // USE_FRAMETOOLS
|
|
|
|
|
|
/* OutlineDoc_GetWindow
|
|
* --------------------
|
|
*
|
|
* Get the window handle of the document.
|
|
*/
|
|
HWND OutlineDoc_GetWindow(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if(! lpOutlineDoc) return NULL;
|
|
return lpOutlineDoc->m_hWndDoc;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_AddLine
|
|
* ------------------
|
|
*
|
|
* Add one line to the Document's LineList
|
|
*/
|
|
void OutlineDoc_AddLine(LPOUTLINEDOC lpOutlineDoc, LPLINE lpLine, int nIndex)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
|
|
LineList_AddLine(lpLL, lpLine, nIndex);
|
|
|
|
/* Update Name Table */
|
|
OutlineNameTable_AddLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
{
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
/* OLE2NOTE: after adding a line we need to
|
|
** update the PosRect of the In-Place active
|
|
** objects (if any) that follow the added line.
|
|
** NOTE: nIndex is index of line before new line.
|
|
** nIndex+1 is index of new line
|
|
** nIndex+2 is index of line after new line.
|
|
*/
|
|
ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex+2);
|
|
}
|
|
#endif
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_DeleteLine
|
|
* ---------------------
|
|
*
|
|
*
|
|
* Delete one line from the document's LineList
|
|
*/
|
|
void OutlineDoc_DeleteLine(LPOUTLINEDOC lpOutlineDoc, int nIndex)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
|
|
#if defined( OLE_CNTR )
|
|
LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
|
|
LPSTORAGE lpStgDoc = NULL;
|
|
char szSaveStgName[CWCSTORAGENAME];
|
|
BOOL fDeleteChildStg = FALSE;
|
|
|
|
if (lpLine && (Line_GetLineType(lpLine) == CONTAINERLINETYPE) ) {
|
|
|
|
/* OLE2NOTE: when a ContainerLine is being deleted by the user,
|
|
** it is important to delete the object's sub-storage
|
|
** otherwise it wastes space in the ContainerDoc's file.
|
|
** this function is called when lines are deleted by the
|
|
** Clear command and when lines are deleted by a DRAGMOVE
|
|
** operation.
|
|
*/
|
|
LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
|
|
|
|
// save name of child storage
|
|
LSTRCPYN(szSaveStgName, lpContainerLine->m_szStgName,
|
|
sizeof(szSaveStgName));
|
|
lpStgDoc = ((LPOLEDOC)lpContainerLine->m_lpDoc)->m_lpStg;
|
|
fDeleteChildStg = TRUE;
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
LineList_DeleteLine(lpLL, nIndex);
|
|
|
|
#if defined( OLE_CNTR )
|
|
if (fDeleteChildStg && lpStgDoc) {
|
|
HRESULT hrErr;
|
|
|
|
// delete the obsolete child storage. it is NOT fatal if this fails
|
|
|
|
hrErr = CallIStorageDestroyElementA(lpStgDoc, szSaveStgName);
|
|
|
|
#if defined( _DEBUG )
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("IStorage::DestroyElement return", hrErr);
|
|
}
|
|
#endif
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
/* Update Name Table */
|
|
OutlineNameTable_DeleteLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
{
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
/* OLE2NOTE: after deleting a line we need to
|
|
** update the PosRect of the In-Place active
|
|
** objects (if any).
|
|
*/
|
|
ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex);
|
|
}
|
|
#endif
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
|
|
|
|
#if defined( OLE_VERSION )
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
|
|
|
|
/* OLE2NOTE: if the document that is the source of data on the
|
|
** clipborad has just had lines deleted, then the copied data
|
|
** is no longer considered a valid potential link source.
|
|
** disable the offering of CF_LINKSOURCE from the clipboard
|
|
** document. this avoids problems that arise when the
|
|
** editing operation changes or deletes the original data
|
|
** copied. we will not go to the trouble of determining if
|
|
** the deleted line actually is part of the link source.
|
|
*/
|
|
if (lpClipboardDoc
|
|
&& lpClipboardDoc->m_fLinkSourceAvail
|
|
&& lpClipboardDoc->m_lpSrcDocOfCopy == (LPOLEDOC)lpOutlineDoc) {
|
|
lpClipboardDoc->m_fLinkSourceAvail = FALSE;
|
|
|
|
/* OLE2NOTE: since we are changing the list of formats on
|
|
** the clipboard (ie. removing CF_LINKSOURCE), we must
|
|
** call OleSetClipboard again. to be sure that the
|
|
** clipboard datatransfer document object does not get
|
|
** destroyed we will guard the call to OleSetClipboard
|
|
** within a pair of AddRef/Release.
|
|
*/
|
|
OleDoc_AddRef((LPOLEDOC)lpClipboardDoc); // guard obj life-time
|
|
|
|
OLEDBG_BEGIN2("OleSetClipboard called\r\n")
|
|
OleSetClipboard(
|
|
(LPDATAOBJECT)&((LPOLEDOC)lpClipboardDoc)->m_DataObject);
|
|
OLEDBG_END2
|
|
|
|
OleDoc_Release((LPOLEDOC)lpClipboardDoc); // rel. AddRef above
|
|
}
|
|
}
|
|
#endif // OLE_VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_AddName
|
|
* ------------------
|
|
*
|
|
* Add a Name to the Document's NameTable
|
|
*/
|
|
void OutlineDoc_AddName(LPOUTLINEDOC lpOutlineDoc, LPOUTLINENAME lpOutlineName)
|
|
{
|
|
LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
|
|
|
|
OutlineNameTable_AddName(lpOutlineNameTable, lpOutlineName);
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_DeleteName
|
|
* ---------------------
|
|
*
|
|
*
|
|
* Delete Name from the document's NameTable
|
|
*/
|
|
void OutlineDoc_DeleteName(LPOUTLINEDOC lpOutlineDoc, int nIndex)
|
|
{
|
|
LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
|
|
|
|
OutlineNameTable_DeleteName(lpOutlineNameTable, nIndex);
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_Destroy
|
|
* ------------------
|
|
*
|
|
* Free all memory that had been allocated for a document.
|
|
* this destroys the LineList & NameTable of the document.
|
|
*/
|
|
void OutlineDoc_Destroy(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
#if defined( OLE_VERSION )
|
|
LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
|
|
LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
|
|
|
|
if (lpOleDoc->m_fObjIsDestroying)
|
|
return; // doc destruction is in progress
|
|
#endif // OLE_VERSION
|
|
|
|
OLEDBG_BEGIN3("OutlineDoc_Destroy\r\n");
|
|
|
|
#if defined( OLE_VERSION )
|
|
|
|
/* OLE2NOTE: in order to guarantee that the application does not
|
|
** prematurely exit before the destruction of the document is
|
|
** complete, we intially AddRef the App refcnt later Release it.
|
|
** This initial AddRef is artificial; it simply guarantees that
|
|
** the app object does not get destroyed until the end of this
|
|
** routine.
|
|
*/
|
|
OleApp_AddRef(lpOleApp);
|
|
|
|
/* OLE2NOTE: perform processing required for OLE */
|
|
OleDoc_Destroy(lpOleDoc);
|
|
#endif
|
|
|
|
LineList_Destroy(lpLL);
|
|
OutlineNameTable_Destroy(lpOutlineDoc->m_lpNameTable);
|
|
|
|
#if defined( USE_HEADING )
|
|
if (! lpOutlineDoc->m_fDataTransferDoc)
|
|
Heading_Destroy((LPHEADING)&lpOutlineDoc->m_heading);
|
|
#endif
|
|
|
|
#if defined( USE_FRAMETOOLS )
|
|
if (! lpOutlineDoc->m_fDataTransferDoc)
|
|
FrameTools_AssociateDoc(lpOutlineDoc->m_lpFrameTools, NULL);
|
|
#endif // USE_FRAMETOOLS
|
|
|
|
DestroyWindow(lpOutlineDoc->m_hWndDoc);
|
|
Delete(lpOutlineDoc); // free memory for doc itself
|
|
OleDbgOut1("@@@@ DOC DESTROYED\r\n");
|
|
|
|
#if defined( OLE_VERSION )
|
|
OleApp_Release(lpOleApp); // release artificial AddRef above
|
|
#endif
|
|
|
|
OLEDBG_END3
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ReSize
|
|
* -----------------
|
|
*
|
|
* Resize the document and its components
|
|
*
|
|
* Parameter:
|
|
* lpRect the new size of the document. Use current size if NULL
|
|
*/
|
|
void OutlineDoc_Resize(LPOUTLINEDOC lpOutlineDoc, LPRECT lpRect)
|
|
{
|
|
RECT rect;
|
|
LPLINELIST lpLL;
|
|
|
|
#if defined( USE_HEADING )
|
|
LPHEADING lphead;
|
|
#endif // USE_HEADING
|
|
|
|
LPSCALEFACTOR lpscale;
|
|
HWND hWndLL;
|
|
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
|
|
hWndLL = LineList_GetWindow(lpLL);
|
|
|
|
if (lpRect) {
|
|
CopyRect((LPRECT)&rect, lpRect);
|
|
MoveWindow(lpOutlineDoc->m_hWndDoc, rect.left, rect.top,
|
|
rect.right-rect.left, rect.bottom-rect.top, TRUE);
|
|
}
|
|
|
|
GetClientRect(lpOutlineDoc->m_hWndDoc, (LPRECT)&rect);
|
|
|
|
#if defined( USE_HEADING )
|
|
lphead = OutlineDoc_GetHeading(lpOutlineDoc);
|
|
rect.left += Heading_RH_GetWidth(lphead, lpscale);
|
|
rect.top += Heading_CH_GetHeight(lphead, lpscale);
|
|
#endif // USE_HEADING
|
|
|
|
if (lpLL) {
|
|
MoveWindow(hWndLL, rect.left, rect.top,
|
|
rect.right-rect.left, rect.bottom-rect.top, TRUE);
|
|
}
|
|
|
|
#if defined( USE_HEADING )
|
|
if (lphead)
|
|
Heading_Move(lphead, lpOutlineDoc->m_hWndDoc, lpscale);
|
|
#endif // USE_HEADING
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetNameTable
|
|
* -----------------------
|
|
*
|
|
* Get nametable associated with the line list
|
|
*/
|
|
LPOUTLINENAMETABLE OutlineDoc_GetNameTable(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return NULL;
|
|
else
|
|
return lpOutlineDoc->m_lpNameTable;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetLineList
|
|
* ----------------------
|
|
*
|
|
* Get listlist associated with the OutlineDoc
|
|
*/
|
|
LPLINELIST OutlineDoc_GetLineList(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return NULL;
|
|
else
|
|
return (LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetNameCount
|
|
* -----------------------
|
|
*
|
|
* Return number of names in table
|
|
*/
|
|
int OutlineDoc_GetNameCount(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
return OutlineNameTable_GetCount(lpOutlineDoc->m_lpNameTable);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetLineCount
|
|
* -----------------------
|
|
*
|
|
* Return number of lines in the LineList
|
|
*/
|
|
int OutlineDoc_GetLineCount(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
return LineList_GetCount(&lpOutlineDoc->m_LineList);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetFileName
|
|
* ----------------------
|
|
*
|
|
* Set the filename of a document.
|
|
*
|
|
* OLE2NOTE: If the ServerDoc has a valid filename then, the object is
|
|
* registered in the running object table (ROT). if the name of the doc
|
|
* changes (eg. via SaveAs) then the previous registration must be revoked
|
|
* and the document re-registered under the new name.
|
|
*/
|
|
BOOL OutlineDoc_SetFileName(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszNewFileName, LPSTORAGE lpNewStg)
|
|
{
|
|
OleDbgAssertSz(lpszNewFileName != NULL, "Can't reset doc to Untitled!");
|
|
if (lpszNewFileName == NULL)
|
|
return FALSE;
|
|
|
|
AnsiLowerBuff(lpszNewFileName, (UINT)lstrlen(lpszNewFileName));
|
|
|
|
#if defined( OLE_CNTR )
|
|
{
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
|
|
|
|
/* OLE2NOTE: the container version of the application keeps its
|
|
** storage open at all times. if the document's storage is not
|
|
** open, then open it.
|
|
*/
|
|
|
|
if (lpNewStg) {
|
|
|
|
/* CASE 1 -- document is being loaded from a file. lpNewStg is
|
|
** still open from the OutlineDoc_LoadFromFile function.
|
|
*/
|
|
|
|
lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
|
|
|
|
} else {
|
|
|
|
/* CASE 2 -- document is being associated with a valid file
|
|
** that is not yet open. thus we must now open the file.
|
|
*/
|
|
|
|
if (lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE &&
|
|
lstrcmp(lpOutlineDoc->m_szFileName,lpszNewFileName)==0) {
|
|
|
|
/* CASE 2a -- new filename is same as current file. if the
|
|
** stg is already open, then the lpStg is still valid.
|
|
** if it is not open, then open it.
|
|
*/
|
|
if (! lpOleDoc->m_lpStg) {
|
|
lpOleDoc->m_lpStg = OleStdOpenRootStorage(
|
|
lpszNewFileName,
|
|
STGM_READWRITE | STGM_SHARE_DENY_WRITE
|
|
);
|
|
if (! lpOleDoc->m_lpStg) return FALSE;
|
|
}
|
|
|
|
} else {
|
|
|
|
/* CASE 2b -- new filename is NOT same as current file.
|
|
** a SaveAs operation is pending. open the new file and
|
|
** hold the storage pointer in m_lpNewStg. the
|
|
** subsequent call to Doc_SaveToFile will save the
|
|
** document into the new storage pointer and release the
|
|
** old storage pointer.
|
|
*/
|
|
|
|
lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
|
|
|
|
lpContainerDoc->m_lpNewStg = OleStdCreateRootStorage(
|
|
lpszNewFileName,
|
|
STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_CREATE
|
|
);
|
|
if (! lpContainerDoc->m_lpNewStg) return FALSE;
|
|
}
|
|
}
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
if (lpOutlineDoc->m_docInitType != DOCTYPE_FROMFILE ||
|
|
lstrcmp(lpOutlineDoc->m_szFileName, lpszNewFileName) != 0) {
|
|
|
|
/* A new valid file name is being associated with the document */
|
|
|
|
lstrcpy(lpOutlineDoc->m_szFileName, lpszNewFileName);
|
|
lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
|
|
|
|
// set lpszDocTitle to point to filename without path
|
|
lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName +
|
|
lstrlen(lpOutlineDoc->m_szFileName) - 1;
|
|
while (lpOutlineDoc->m_lpszDocTitle > lpOutlineDoc->m_szFileName
|
|
&& ! IS_FILENAME_DELIM(lpOutlineDoc->m_lpszDocTitle[-1])) {
|
|
lpOutlineDoc->m_lpszDocTitle--;
|
|
}
|
|
|
|
OutlineDoc_SetTitle(lpOutlineDoc, TRUE /*fMakeUpperCase*/);
|
|
|
|
#if defined( OLE_VERSION )
|
|
{
|
|
/* OLE2NOTE: both containers and servers must properly
|
|
** register in the RunningObjectTable. if the document
|
|
** is performing a SaveAs operation, then it must
|
|
** re-register in the ROT with the new moniker. in
|
|
** addition any embedded object, pseudo objects, and/or
|
|
** linking clients must be informed that the document's
|
|
** moniker has changed.
|
|
*/
|
|
|
|
LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
|
|
|
|
if (lpOleDoc->m_lpFileMoniker) {
|
|
OleStdRelease((LPUNKNOWN)lpOleDoc->m_lpFileMoniker);
|
|
lpOleDoc->m_lpFileMoniker = NULL;
|
|
}
|
|
|
|
CreateFileMonikerA(lpszNewFileName,
|
|
&lpOleDoc->m_lpFileMoniker);
|
|
|
|
OleDoc_DocRenamedUpdate(lpOleDoc, lpOleDoc->m_lpFileMoniker);
|
|
}
|
|
#endif // OLE_VERSION
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetTitle
|
|
* -------------------
|
|
*
|
|
* Set window text to be current filename.
|
|
* The following window hierarchy exits:
|
|
* hWndApp
|
|
* hWndDoc
|
|
* hWndListBox
|
|
* The frame window is the window which gets the title.
|
|
*/
|
|
void OutlineDoc_SetTitle(LPOUTLINEDOC lpOutlineDoc, BOOL fMakeUpperCase)
|
|
{
|
|
HWND hWnd;
|
|
LPSTR lpszText;
|
|
|
|
if (!lpOutlineDoc->m_hWndDoc) return;
|
|
if ((hWnd = GetParent(lpOutlineDoc->m_hWndDoc)) == NULL) return;
|
|
|
|
lpszText = OleStdMalloc((UINT)(lstrlen(APPNAME) + 4 +
|
|
lstrlen(lpOutlineDoc->m_lpszDocTitle)));
|
|
if (!lpszText) return;
|
|
|
|
lstrcpy(lpszText, APPNAME);
|
|
lstrcat(lpszText," - ");
|
|
lstrcat(lpszText, (LPSTR)lpOutlineDoc->m_lpszDocTitle);
|
|
|
|
if (fMakeUpperCase)
|
|
AnsiUpperBuff(lpszText, (UINT)lstrlen(lpszText));
|
|
|
|
SetWindowText(hWnd,lpszText);
|
|
OleStdFree(lpszText);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_Close
|
|
* ----------------
|
|
*
|
|
* Close active document. If modified, prompt the user if
|
|
* he wants to save.
|
|
*
|
|
* Returns:
|
|
* FALSE -- user canceled the closing of the doc.
|
|
* TRUE -- the doc was successfully closed
|
|
*/
|
|
BOOL OutlineDoc_Close(LPOUTLINEDOC lpOutlineDoc, DWORD dwSaveOption)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
|
|
#if defined( OLE_VERSION )
|
|
/* OLE2NOTE: call OLE specific function instead */
|
|
return OleDoc_Close((LPOLEDOC)lpOutlineDoc, dwSaveOption);
|
|
|
|
#else
|
|
|
|
if (! lpOutlineDoc)
|
|
return TRUE; // active doc's are already destroyed
|
|
|
|
if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, &dwSaveOption))
|
|
return FALSE; // abort closing the doc
|
|
|
|
OutlineDoc_Destroy(lpOutlineDoc);
|
|
|
|
OutlineApp_DocUnlockApp(lpOutlineApp, lpOutlineDoc);
|
|
|
|
return TRUE;
|
|
|
|
#endif // ! OLE_VERSION
|
|
}
|
|
|
|
|
|
/* OutlineDoc_CheckSaveChanges
|
|
* ---------------------------
|
|
*
|
|
* Check if the document has been modified. if so, prompt the user if
|
|
* the changes should be saved. if yes save them.
|
|
* Returns TRUE if the doc is safe to close (user answered Yes or No)
|
|
* FALSE if the user canceled the save changes option.
|
|
*/
|
|
BOOL OutlineDoc_CheckSaveChanges(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
LPDWORD lpdwSaveOption
|
|
)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
int nResponse;
|
|
|
|
if (*lpdwSaveOption == OLECLOSE_NOSAVE)
|
|
return TRUE;
|
|
|
|
if(! OutlineDoc_IsModified(lpOutlineDoc))
|
|
return TRUE; // saving is not necessary
|
|
|
|
/* OLE2NOTE: our document is dirty so it needs to be saved. if
|
|
** OLECLOSE_PROMPTSAVE the user should be prompted to see if the
|
|
** document should be saved. is specified but the document is NOT
|
|
** visible to the user, then the user can NOT be prompted. in
|
|
** the situation the document should be saved without prompting.
|
|
** if OLECLOSE_SAVEIFDIRTY is specified then, the document
|
|
** should also be saved without prompting.
|
|
*/
|
|
if (*lpdwSaveOption == OLECLOSE_PROMPTSAVE &&
|
|
IsWindowVisible(lpOutlineDoc->m_hWndDoc)) {
|
|
|
|
// prompt the user to see if changes should be saved.
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PreModalDialog(
|
|
(LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
|
|
#endif
|
|
nResponse = MessageBox(
|
|
lpOutlineApp->m_hWndApp,
|
|
MsgSaveFile,
|
|
APPNAME,
|
|
MB_ICONQUESTION | MB_YESNOCANCEL
|
|
);
|
|
#if defined( OLE_VERSION )
|
|
OleApp_PostModalDialog(
|
|
(LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
|
|
#endif
|
|
if(nResponse==IDCANCEL)
|
|
return FALSE; // close is canceled
|
|
if(nResponse==IDNO) {
|
|
// Reset the save option to NOSAVE per user choice
|
|
*lpdwSaveOption = OLECLOSE_NOSAVE;
|
|
return TRUE; // don't save, but is ok to close
|
|
}
|
|
} else if (*lpdwSaveOption != OLECLOSE_SAVEIFDIRTY) {
|
|
OleDbgAssertSz(FALSE, "Invalid dwSaveOption\r\n");
|
|
*lpdwSaveOption = OLECLOSE_NOSAVE;
|
|
return TRUE; // unknown *lpdwSaveOption; close w/o saving
|
|
}
|
|
|
|
#if defined( OLE_SERVER )
|
|
if (lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED) {
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
HRESULT hrErr;
|
|
|
|
/* OLE2NOTE: Update the container before closing without prompting
|
|
** the user. To update the container, we must ask our container
|
|
** to save us.
|
|
*/
|
|
OleDbgAssert(lpServerDoc->m_lpOleClientSite != NULL);
|
|
OLEDBG_BEGIN2("IOleClientSite::SaveObject called\r\n")
|
|
hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->SaveObject(
|
|
lpServerDoc->m_lpOleClientSite
|
|
);
|
|
OLEDBG_END2
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("IOleClientSite::SaveObject returned", hrErr);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE; // doc is safe to be closed
|
|
|
|
} else
|
|
#endif // OLE_SERVER
|
|
{
|
|
return OutlineApp_SaveCommand(lpOutlineApp);
|
|
}
|
|
}
|
|
|
|
|
|
/* OutlineDoc_IsModified
|
|
* ---------------------
|
|
*
|
|
* Return modify flag of OUTLINEDOC
|
|
*/
|
|
BOOL OutlineDoc_IsModified(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (lpOutlineDoc->m_fModified)
|
|
return lpOutlineDoc->m_fModified;
|
|
|
|
#if defined( OLE_CNTR )
|
|
{
|
|
/* OLE2NOTE: if there are OLE objects, then we must ask if any of
|
|
** them are dirty. if so we must consider our document
|
|
** as modified.
|
|
*/
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
LPLINELIST lpLL;
|
|
int nLines;
|
|
int nIndex;
|
|
LPLINE lpLine;
|
|
HRESULT hrErr;
|
|
|
|
lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpContainerDoc)->m_LineList;
|
|
nLines = LineList_GetCount(lpLL);
|
|
|
|
for (nIndex = 0; nIndex < nLines; nIndex++) {
|
|
lpLine = LineList_GetLine(lpLL, nIndex);
|
|
if (!lpLine)
|
|
break;
|
|
if (Line_GetLineType(lpLine) == CONTAINERLINETYPE) {
|
|
LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
|
|
if (lpContainerLine->m_lpPersistStg) {
|
|
hrErr = lpContainerLine->m_lpPersistStg->lpVtbl->IsDirty(
|
|
lpContainerLine->m_lpPersistStg);
|
|
/* OLE2NOTE: we will only accept an explicit "no i
|
|
** am NOT dirty statement" (ie. S_FALSE) as an
|
|
** indication that the object is clean. eg. if
|
|
** the object returns E_NOTIMPL we must
|
|
** interpret it as the object IS dirty.
|
|
*/
|
|
if (GetScode(hrErr) != S_FALSE)
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetModified
|
|
* ----------------------
|
|
*
|
|
* Set the modified flag of the document
|
|
*
|
|
*/
|
|
void OutlineDoc_SetModified(LPOUTLINEDOC lpOutlineDoc, BOOL fModified, BOOL fDataChanged, BOOL fSizeChanged)
|
|
{
|
|
lpOutlineDoc->m_fModified = fModified;
|
|
|
|
#if defined( OLE_SERVER )
|
|
if (! lpOutlineDoc->m_fDataTransferDoc) {
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
|
|
/* OLE2NOTE: if the document has changed, then broadcast the change
|
|
** to all clients who have set up Advise connections. notify
|
|
** them that our data (and possibly also our extents) have
|
|
** changed.
|
|
*/
|
|
if (fDataChanged) {
|
|
lpServerDoc->m_fDataChanged = TRUE;
|
|
lpServerDoc->m_fSizeChanged = fSizeChanged;
|
|
lpServerDoc->m_fSendDataOnStop = TRUE;
|
|
|
|
ServerDoc_SendAdvise(
|
|
lpServerDoc,
|
|
OLE_ONDATACHANGE,
|
|
NULL, /* lpmkDoc -- not relevant here */
|
|
0 /* advf -- no flags necessary */
|
|
);
|
|
}
|
|
}
|
|
#endif // OLE_SERVER
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetRedraw
|
|
* --------------------
|
|
*
|
|
* Enable/Disable the redraw of the document on screen.
|
|
* The calls to SetRedraw counted so that nested calls can be handled
|
|
* properly. calls to SetRedraw must be balanced.
|
|
*
|
|
* fEnbaleDraw = TRUE - enable redraw
|
|
* FALSE - disable redraw
|
|
*/
|
|
void OutlineDoc_SetRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fEnableDraw)
|
|
{
|
|
static HCURSOR hPrevCursor = NULL;
|
|
|
|
if (fEnableDraw) {
|
|
if (lpOutlineDoc->m_nDisableDraw == 0)
|
|
return; // already enabled; no state transition
|
|
|
|
if (--lpOutlineDoc->m_nDisableDraw > 0)
|
|
return; // drawing should still be disabled
|
|
} else {
|
|
if (lpOutlineDoc->m_nDisableDraw++ > 0)
|
|
return; // already disabled; no state transition
|
|
}
|
|
|
|
if (lpOutlineDoc->m_nDisableDraw > 0) {
|
|
// this may take a while, put up hourglass cursor
|
|
hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
} else {
|
|
if (hPrevCursor) {
|
|
SetCursor(hPrevCursor); // restore original cursor
|
|
hPrevCursor = NULL;
|
|
}
|
|
}
|
|
|
|
#if defined( OLE_SERVER )
|
|
/* OLE2NOTE: for the Server version, while Redraw is disabled
|
|
** postpone sending advise notifications until Redraw is re-enabled.
|
|
*/
|
|
{
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
LPSERVERNAMETABLE lpServerNameTable =
|
|
(LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable;
|
|
|
|
if (lpOutlineDoc->m_nDisableDraw == 0) {
|
|
/* drawing is being Enabled. if changes occurred while drawing
|
|
** was disabled, then notify clients now.
|
|
*/
|
|
if (lpServerDoc->m_fDataChanged)
|
|
ServerDoc_SendAdvise(
|
|
lpServerDoc,
|
|
OLE_ONDATACHANGE,
|
|
NULL, /* lpmkDoc -- not relevant here */
|
|
0 /* advf -- no flags necessary */
|
|
);
|
|
|
|
/* OLE2NOTE: send pending change notifications for pseudo objs. */
|
|
ServerNameTable_SendPendingAdvises(lpServerNameTable);
|
|
|
|
}
|
|
}
|
|
#endif // OLE_SERVER
|
|
|
|
#if defined( OLE_CNTR )
|
|
/* OLE2NOTE: for the Container version, while Redraw is disabled
|
|
** postpone updating the extents of OLE objects until Redraw is
|
|
** re-enabled.
|
|
*/
|
|
{
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
|
|
/* Update the extents of any OLE object that is marked that
|
|
** its size may have changed. when an
|
|
** IAdviseSink::OnViewChange notification is received,
|
|
** the corresponding ContainerLine is marked
|
|
** (m_fDoGetExtent==TRUE) and a message
|
|
** (WM_U_UPDATEOBJECTEXTENT) is posted to the document
|
|
** indicating that there are dirty objects.
|
|
*/
|
|
if (lpOutlineDoc->m_nDisableDraw == 0)
|
|
ContainerDoc_UpdateExtentOfAllOleObjects(lpContainerDoc);
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
// enable/disable redraw of the LineList listbox
|
|
LineList_SetRedraw(&lpOutlineDoc->m_LineList, fEnableDraw);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetSel
|
|
* -----------------
|
|
*
|
|
* Set the selection in the documents's LineList
|
|
*/
|
|
void OutlineDoc_SetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
|
|
{
|
|
LineList_SetSel(&lpOutlineDoc->m_LineList, lplrSel);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetSel
|
|
* -----------------
|
|
*
|
|
* Get the selection in the documents's LineList.
|
|
*
|
|
* Returns the count of items selected
|
|
*/
|
|
int OutlineDoc_GetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
|
|
{
|
|
return LineList_GetSel(&lpOutlineDoc->m_LineList, lplrSel);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ForceRedraw
|
|
* ----------------------
|
|
*
|
|
* Force the document window to repaint.
|
|
*/
|
|
void OutlineDoc_ForceRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fErase)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
LineList_ForceRedraw(&lpOutlineDoc->m_LineList, fErase);
|
|
Heading_CH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
|
|
Heading_RH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_RenderFormat
|
|
* -----------------------
|
|
*
|
|
* Render a clipboard format supported by ClipboardDoc
|
|
*/
|
|
void OutlineDoc_RenderFormat(LPOUTLINEDOC lpOutlineDoc, UINT uFormat)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
HGLOBAL hData = NULL;
|
|
|
|
if (uFormat == lpOutlineApp->m_cfOutline)
|
|
hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
|
|
|
|
else if (uFormat == CF_TEXT)
|
|
hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
|
|
|
|
else {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormatNotSupported);
|
|
return;
|
|
}
|
|
|
|
SetClipboardData(uFormat, hData);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_RenderAllFormats
|
|
* ---------------------------
|
|
*
|
|
* Render all formats supported by ClipboardDoc
|
|
*/
|
|
void OutlineDoc_RenderAllFormats(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
HGLOBAL hData = NULL;
|
|
|
|
OpenClipboard(lpOutlineDoc->m_hWndDoc);
|
|
|
|
hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
|
|
SetClipboardData(lpOutlineApp->m_cfOutline, hData);
|
|
|
|
hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
|
|
SetClipboardData(CF_TEXT, hData);
|
|
|
|
CloseClipboard();
|
|
}
|
|
|
|
|
|
|
|
/* OutlineDoc_GetOutlineData
|
|
* -------------------------
|
|
*
|
|
* Return a handle to an array of TextLine objects for the desired line
|
|
* range.
|
|
* NOTE: if lplrSel == NULL, then all lines are returned
|
|
*
|
|
*/
|
|
HGLOBAL OutlineDoc_GetOutlineData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
|
|
{
|
|
HGLOBAL hOutline = NULL;
|
|
LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
LPLINE lpLine;
|
|
LPTEXTLINE arrLine;
|
|
int i;
|
|
int nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
|
|
int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
|
|
int nLines = nEnd - nStart + 1;
|
|
int nCopied = 0;
|
|
|
|
hOutline=GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT,sizeof(TEXTLINE)*nLines);
|
|
|
|
if (! hOutline) return NULL;
|
|
|
|
arrLine=(LPTEXTLINE)GlobalLock(hOutline);
|
|
|
|
for (i = nStart; i <= nEnd; i++) {
|
|
lpLine=LineList_GetLine(lpLL, i);
|
|
if (lpLine && Line_GetOutlineData(lpLine, &arrLine[nCopied]))
|
|
nCopied++;
|
|
}
|
|
|
|
GlobalUnlock(hOutline);
|
|
|
|
return hOutline;
|
|
}
|
|
|
|
|
|
|
|
/* OutlineDoc_GetTextData
|
|
* ----------------------
|
|
*
|
|
* Return a handle to an object's data in text form for the desired line
|
|
* range.
|
|
* NOTE: if lplrSel == NULL, then all lines are returned
|
|
*
|
|
*/
|
|
HGLOBAL OutlineDoc_GetTextData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
|
|
{
|
|
LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
|
|
LPLINE lpLine;
|
|
HGLOBAL hText = NULL;
|
|
LPSTR lpszText = NULL;
|
|
DWORD dwMemSize=0;
|
|
int i,j;
|
|
int nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
|
|
int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
|
|
int nTabLevel;
|
|
|
|
// calculate memory size required
|
|
for(i = nStart; i <= nEnd; i++) {
|
|
lpLine=LineList_GetLine(lpLL, i);
|
|
if (! lpLine)
|
|
continue;
|
|
|
|
dwMemSize += Line_GetTabLevel(lpLine);
|
|
dwMemSize += Line_GetTextLen(lpLine);
|
|
|
|
dwMemSize += 2; // add 1 for '\r\n' at the end of each line
|
|
}
|
|
dwMemSize++; // add 1 for '\0' at the end of string
|
|
|
|
if(!(hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, dwMemSize)))
|
|
return NULL;
|
|
|
|
if(!(lpszText = (LPSTR)GlobalLock(hText)))
|
|
return NULL;
|
|
|
|
// put line text to memory
|
|
for(i = nStart; i <= nEnd; i++) {
|
|
lpLine=LineList_GetLine(lpLL, i);
|
|
if (! lpLine)
|
|
continue;
|
|
|
|
nTabLevel=Line_GetTabLevel(lpLine);
|
|
for(j = 0; j < nTabLevel; j++)
|
|
*lpszText++='\t';
|
|
|
|
Line_GetTextData(lpLine, lpszText);
|
|
while(*lpszText)
|
|
lpszText++; // advance to end of string
|
|
|
|
*lpszText++ = '\r';
|
|
*lpszText++ = '\n';
|
|
}
|
|
|
|
GlobalUnlock (hText);
|
|
|
|
return hText;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SaveToFile
|
|
* ---------------------
|
|
*
|
|
* Save the document to a file with the same name as stored in the
|
|
* document
|
|
*/
|
|
BOOL OutlineDoc_SaveToFile(LPOUTLINEDOC lpOutlineDoc, LPCSTR lpszFileName, UINT uFormat, BOOL fRemember)
|
|
{
|
|
#if defined( OLE_CNTR )
|
|
// Call OLE container specific function instead
|
|
return ContainerDoc_SaveToFile(
|
|
(LPCONTAINERDOC)lpOutlineDoc,
|
|
lpszFileName,
|
|
uFormat,
|
|
fRemember
|
|
);
|
|
|
|
#else
|
|
|
|
LPSTORAGE lpDestStg = NULL;
|
|
HRESULT hrErr;
|
|
BOOL fStatus;
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
|
|
if (fRemember) {
|
|
if (lpszFileName) {
|
|
fStatus = OutlineDoc_SetFileName(
|
|
lpOutlineDoc,
|
|
(LPSTR)lpszFileName,
|
|
NULL
|
|
);
|
|
if (! fStatus) goto error;
|
|
} else
|
|
lpszFileName = lpOutlineDoc->m_szFileName; // use cur. file name
|
|
} else if (! lpszFileName) {
|
|
goto error;
|
|
}
|
|
|
|
hrErr = StgCreateDocfileA(
|
|
lpszFileName,
|
|
STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
|
|
0,
|
|
&lpDestStg
|
|
);
|
|
|
|
OleDbgAssertSz(hrErr == NOERROR, "Could not create Docfile");
|
|
if (hrErr != NOERROR)
|
|
goto error;
|
|
|
|
#if defined( OLE_SERVER )
|
|
|
|
/* OLE2NOTE: we must be sure to write our class ID into our
|
|
** storage. this information is used by OLE to determine the
|
|
** class of the data stored in our storage. Even for top
|
|
** "file-level" objects this information should be written to
|
|
** the file.
|
|
*/
|
|
if(WriteClassStg(lpDestStg, &CLSID_APP) != NOERROR)
|
|
goto error;
|
|
#endif
|
|
|
|
fStatus = OutlineDoc_SaveSelToStg(
|
|
lpOutlineDoc,
|
|
NULL,
|
|
uFormat,
|
|
lpDestStg,
|
|
FALSE, /* fSameAsLoad */
|
|
fRemember
|
|
);
|
|
if (! fStatus) goto error;
|
|
|
|
OleStdRelease((LPUNKNOWN)lpDestStg);
|
|
|
|
if (fRemember)
|
|
OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
|
|
|
|
#if defined( OLE_SERVER )
|
|
|
|
/* OLE2NOTE: (SERVER-ONLY) inform any linking clients that the
|
|
** document has been saved. in addition, any currently active
|
|
** pseudo objects should also inform their clients.
|
|
*/
|
|
ServerDoc_SendAdvise (
|
|
(LPSERVERDOC)lpOutlineDoc,
|
|
OLE_ONSAVE,
|
|
NULL, /* lpmkDoc -- not relevant here */
|
|
0 /* advf -- not relevant here */
|
|
);
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
error:
|
|
if (lpDestStg)
|
|
OleStdRelease((LPUNKNOWN)lpDestStg);
|
|
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgSaving);
|
|
return FALSE;
|
|
|
|
#endif // ! OLE_CNTR
|
|
}
|
|
|
|
|
|
/* OutlineDoc_LoadFromFile
|
|
* -----------------------
|
|
*
|
|
* Load a document from a file
|
|
*/
|
|
BOOL OutlineDoc_LoadFromFile(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszFileName)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
HRESULT hrErr;
|
|
SCODE sc;
|
|
LPSTORAGE lpSrcStg;
|
|
BOOL fStatus;
|
|
|
|
hrErr = StgOpenStorageA(lpszFileName,
|
|
NULL,
|
|
#if defined( OLE_CNTR )
|
|
STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE,
|
|
#else
|
|
STGM_READ | STGM_SHARE_DENY_WRITE,
|
|
#endif
|
|
NULL,
|
|
0,
|
|
&lpSrcStg
|
|
);
|
|
|
|
if ((sc = GetScode(hrErr)) == STG_E_FILENOTFOUND) {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, "File not found");
|
|
return FALSE;
|
|
} else if (sc == STG_E_FILEALREADYEXISTS) {
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormat);
|
|
return FALSE;
|
|
} else if (sc != S_OK) {
|
|
OleDbgOutScode("StgOpenStorage returned", sc);
|
|
OutlineApp_ErrorMessage(
|
|
lpOutlineApp,
|
|
"File already in use--could not be opened"
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
if(! OutlineDoc_LoadFromStg(lpOutlineDoc, lpSrcStg)) goto error;
|
|
|
|
fStatus = OutlineDoc_SetFileName(lpOutlineDoc, lpszFileName, lpSrcStg);
|
|
if (! fStatus) goto error;
|
|
|
|
OleStdRelease((LPUNKNOWN)lpSrcStg);
|
|
|
|
return TRUE;
|
|
|
|
error:
|
|
OleStdRelease((LPUNKNOWN)lpSrcStg);
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgOpening);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/* OutlineDoc_LoadFromStg
|
|
* ----------------------
|
|
*
|
|
* Load entire document from an open IStorage pointer (lpSrcStg)
|
|
* Return TRUE if ok, FALSE if error.
|
|
*/
|
|
BOOL OutlineDoc_LoadFromStg(LPOUTLINEDOC lpOutlineDoc, LPSTORAGE lpSrcStg)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
HRESULT hrErr;
|
|
BOOL fStatus;
|
|
ULONG nRead;
|
|
LINERANGE lrSel = { 0, 0 };
|
|
LPSTREAM lpLLStm;
|
|
OUTLINEDOCHEADER_ONDISK docRecordOnDisk;
|
|
OUTLINEDOCHEADER docRecord;
|
|
|
|
hrErr = CallIStorageOpenStreamA(
|
|
lpSrcStg,
|
|
"LineList",
|
|
NULL,
|
|
STGM_READ | STGM_SHARE_EXCLUSIVE,
|
|
0,
|
|
&lpLLStm
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Open LineList Stream returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
/* read OutlineDoc header record */
|
|
hrErr = lpLLStm->lpVtbl->Read(
|
|
lpLLStm,
|
|
(LPVOID)&docRecordOnDisk,
|
|
sizeof(docRecordOnDisk),
|
|
&nRead
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Read OutlineDoc header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
// Transform docRecordOnDisk into docRecord
|
|
// Compilers should handle aligment correctly
|
|
strcpy(docRecord.m_szFormatName, docRecordOnDisk.m_szFormatName);
|
|
docRecord.m_narrAppVersionNo[0] = (int) docRecordOnDisk.m_narrAppVersionNo[0];
|
|
docRecord.m_narrAppVersionNo[1] = (int) docRecordOnDisk.m_narrAppVersionNo[1];
|
|
docRecord.m_fShowHeading = (BOOL) docRecordOnDisk.m_fShowHeading;
|
|
docRecord.m_reserved1 = docRecordOnDisk.m_reserved1;
|
|
docRecord.m_reserved2 = docRecordOnDisk.m_reserved2;
|
|
docRecord.m_reserved3 = docRecordOnDisk.m_reserved3;
|
|
docRecord.m_reserved4 = docRecordOnDisk.m_reserved4;
|
|
|
|
fStatus = OutlineApp_VersionNoCheck(
|
|
lpOutlineApp,
|
|
docRecord.m_szFormatName,
|
|
docRecord.m_narrAppVersionNo
|
|
);
|
|
|
|
/* storage is an incompatible version; file can not be read */
|
|
if (! fStatus)
|
|
goto error;
|
|
|
|
lpOutlineDoc->m_heading.m_fShow = docRecord.m_fShowHeading;
|
|
|
|
#if defined( OLE_SERVER )
|
|
{
|
|
// Load ServerDoc specific data
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
#if defined( SVR_TREATAS )
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
CLSID clsid;
|
|
CLIPFORMAT cfFmt;
|
|
LPSTR lpszType;
|
|
#endif // SVR_TREATAS
|
|
|
|
lpServerDoc->m_nNextRangeNo = (ULONG)docRecord.m_reserved1;
|
|
|
|
#if defined( SVR_TREATAS )
|
|
/* OLE2NOTE: if the Server is capable of supporting "TreatAs"
|
|
** (aka. ActivateAs), it must read the class that is written
|
|
** into the storage. if this class is NOT the app's own
|
|
** class ID, then this is a TreatAs operation. the server
|
|
** then must faithfully pretend to be the class that is
|
|
** written into the storage. it must also faithfully write
|
|
** the data back to the storage in the SAME format as is
|
|
** written in the storage.
|
|
**
|
|
** SVROUTL and ISVROTL can emulate each other. they have the
|
|
** simplification that they both read/write the identical
|
|
** format. thus for these apps no actual conversion of the
|
|
** native bits is actually required.
|
|
*/
|
|
lpServerDoc->m_clsidTreatAs = CLSID_NULL;
|
|
if (OleStdGetTreatAsFmtUserType(&CLSID_APP, lpSrcStg, &clsid,
|
|
(CLIPFORMAT FAR*)&cfFmt, (LPSTR FAR*)&lpszType)) {
|
|
|
|
if (cfFmt == lpOutlineApp->m_cfOutline) {
|
|
// We should perform TreatAs operation
|
|
if (lpServerDoc->m_lpszTreatAsType)
|
|
OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL);
|
|
|
|
lpServerDoc->m_clsidTreatAs = clsid;
|
|
((LPOUTLINEDOC)lpServerDoc)->m_cfSaveFormat = cfFmt;
|
|
lpServerDoc->m_lpszTreatAsType = lpszType;
|
|
|
|
OleDbgOut3("OutlineDoc_LoadFromStg: TreateAs ==> '");
|
|
OleDbgOutNoPrefix3(lpServerDoc->m_lpszTreatAsType);
|
|
OleDbgOutNoPrefix3("'\r\n");
|
|
} else {
|
|
// ERROR: we ONLY support TreatAs for CF_OUTLINE format
|
|
OleDbgOut("SvrDoc_PStg_InitNew: INVALID TreatAs Format\r\n");
|
|
OleStdFreeString(lpszType, NULL);
|
|
}
|
|
}
|
|
#endif // SVR_TREATAS
|
|
}
|
|
#endif // OLE_SVR
|
|
#if defined( OLE_CNTR )
|
|
{
|
|
// Load ContainerDoc specific data
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
|
|
lpContainerDoc->m_nNextObjNo = (ULONG)docRecord.m_reserved2;
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
|
|
|
|
if(! LineList_LoadFromStg(&lpOutlineDoc->m_LineList, lpSrcStg, lpLLStm))
|
|
goto error;
|
|
if(! OutlineNameTable_LoadFromStg(lpOutlineDoc->m_lpNameTable, lpSrcStg))
|
|
goto error;
|
|
|
|
OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
|
|
OutlineDoc_SetSel(lpOutlineDoc, &lrSel);
|
|
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
|
|
OleStdRelease((LPUNKNOWN)lpLLStm);
|
|
|
|
#if defined( OLE_CNTR )
|
|
{
|
|
LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
|
|
|
|
/* A ContainerDoc keeps its storage open at all times. it is necessary
|
|
* to AddRef the lpSrcStg in order to hang on to it.
|
|
*/
|
|
if (lpOleDoc->m_lpStg) {
|
|
OleStdVerifyRelease((LPUNKNOWN)lpOleDoc->m_lpStg,
|
|
"Doc Storage not released properly");
|
|
}
|
|
lpSrcStg->lpVtbl->AddRef(lpSrcStg);
|
|
lpOleDoc->m_lpStg = lpSrcStg;
|
|
}
|
|
#endif // OLE_CNTR
|
|
|
|
return TRUE;
|
|
|
|
error:
|
|
OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
|
|
if (lpLLStm)
|
|
OleStdRelease((LPUNKNOWN)lpLLStm);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL Booga(void)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SaveSelToStg
|
|
* -----------------------
|
|
*
|
|
* Save the specified selection of document into an IStorage*. All lines
|
|
* within the selection along with any names completely contained within the
|
|
* selection will be written
|
|
*
|
|
* Return TRUE if ok, FALSE if error
|
|
*/
|
|
BOOL OutlineDoc_SaveSelToStg(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
LPLINERANGE lplrSel,
|
|
UINT uFormat,
|
|
LPSTORAGE lpDestStg,
|
|
BOOL fSameAsLoad,
|
|
BOOL fRemember
|
|
)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
HRESULT hrErr = NOERROR;
|
|
LPSTREAM lpLLStm = NULL;
|
|
LPSTREAM lpNTStm = NULL;
|
|
ULONG nWritten;
|
|
BOOL fStatus;
|
|
OUTLINEDOCHEADER docRecord;
|
|
OUTLINEDOCHEADER_ONDISK docRecordOnDisk;
|
|
HCURSOR hPrevCursor;
|
|
|
|
#if defined( OLE_VERSION )
|
|
LPSTR lpszUserType;
|
|
LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
|
|
|
|
/* OLE2NOTE: we must be sure to write the information required for
|
|
** OLE into our docfile. this includes user type
|
|
** name, data format, etc. Even for top "file-level" objects
|
|
** this information should be written to the file. Both
|
|
** containters and servers should write this information.
|
|
*/
|
|
|
|
#if defined( OLE_SERVER ) && defined( SVR_TREATAS )
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
|
|
/* OLE2NOTE: if the Server is emulating another class (ie.
|
|
** "TreatAs" aka. ActivateAs), it must write the same user type
|
|
** name and format that was was originally written into the
|
|
** storage rather than its own user type name.
|
|
**
|
|
** SVROUTL and ISVROTL can emulate each other. they have the
|
|
** simplification that they both read/write the identical
|
|
** format. thus for these apps no actual conversion of the
|
|
** native bits is actually required.
|
|
*/
|
|
if (! IsEqualCLSID(&lpServerDoc->m_clsidTreatAs, &CLSID_NULL))
|
|
lpszUserType = lpServerDoc->m_lpszTreatAsType;
|
|
else
|
|
#endif // OLE_SERVER && SVR_TREATAS
|
|
|
|
lpszUserType = (LPSTR)FULLUSERTYPENAME;
|
|
|
|
hrErr = WriteFmtUserTypeStgA(lpDestStg, (CLIPFORMAT) uFormat,
|
|
lpszUserType);
|
|
|
|
if(hrErr != NOERROR) goto error;
|
|
|
|
if (fSameAsLoad) {
|
|
/* OLE2NOTE: we are saving into to same storage that we were
|
|
** passed an load time. we deliberatly opened the streams we
|
|
** need (lpLLStm and lpNTStm) at load time, so that we can
|
|
** robustly save at save time in a low-memory situation.
|
|
** this is particulary important the embedded objects do NOT
|
|
** consume additional memory when
|
|
** IPersistStorage::Save(fSameAsLoad==TRUE) is called.
|
|
*/
|
|
LARGE_INTEGER libZero;
|
|
ULARGE_INTEGER ulibZero;
|
|
LISet32( libZero, 0 );
|
|
LISet32( ulibZero, 0 );
|
|
lpLLStm = lpOleDoc->m_lpLLStm;
|
|
|
|
/* because this is the fSameAsLoad==TRUE case, we will save
|
|
** into the streams that we hold open. we will AddRef the
|
|
** stream here so that the release below will NOT close the
|
|
** stream.
|
|
*/
|
|
lpLLStm->lpVtbl->AddRef(lpLLStm);
|
|
|
|
// truncate the current stream and seek to beginning
|
|
lpLLStm->lpVtbl->SetSize(lpLLStm, ulibZero);
|
|
lpLLStm->lpVtbl->Seek(
|
|
lpLLStm, libZero, STREAM_SEEK_SET, NULL);
|
|
|
|
lpNTStm = lpOleDoc->m_lpNTStm;
|
|
lpNTStm->lpVtbl->AddRef(lpNTStm); // (see comment above)
|
|
|
|
// truncate the current stream and seek to beginning
|
|
lpNTStm->lpVtbl->SetSize(lpNTStm, ulibZero);
|
|
lpNTStm->lpVtbl->Seek(
|
|
lpNTStm, libZero, STREAM_SEEK_SET, NULL);
|
|
} else
|
|
#endif // OLE_VERSION
|
|
{
|
|
hrErr = CallIStorageCreateStreamA(
|
|
lpDestStg,
|
|
"LineList",
|
|
STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
|
|
0,
|
|
0,
|
|
&lpLLStm
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgAssertSz(hrErr==NOERROR,"Could not create LineList stream");
|
|
OleDbgOutHResult("LineList CreateStream returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
hrErr = CallIStorageCreateStreamA(
|
|
lpDestStg,
|
|
"NameTable",
|
|
STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
|
|
0,
|
|
0,
|
|
&lpNTStm
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgAssertSz(hrErr==NOERROR,"Could not create NameTable stream");
|
|
OleDbgOutHResult("NameTable CreateStream returned", hrErr);
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
// this may take a while, put up hourglass cursor
|
|
hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
_fmemset((LPOUTLINEDOCHEADER)&docRecord,0,sizeof(OUTLINEDOCHEADER));
|
|
GetClipboardFormatName(
|
|
uFormat,
|
|
docRecord.m_szFormatName,
|
|
sizeof(docRecord.m_szFormatName)
|
|
);
|
|
OutlineApp_GetAppVersionNo(lpOutlineApp, docRecord.m_narrAppVersionNo);
|
|
|
|
docRecord.m_fShowHeading = lpOutlineDoc->m_heading.m_fShow;
|
|
|
|
#if defined( OLE_SERVER )
|
|
{
|
|
// Store ServerDoc specific data
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
|
|
docRecord.m_reserved1 = (DWORD)lpServerDoc->m_nNextRangeNo;
|
|
}
|
|
#endif
|
|
#if defined( OLE_CNTR )
|
|
{
|
|
// Store ContainerDoc specific data
|
|
LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
|
|
|
|
docRecord.m_reserved2 = (DWORD)lpContainerDoc->m_nNextObjNo;
|
|
}
|
|
#endif
|
|
|
|
/* write OutlineDoc header record */
|
|
|
|
// Transform docRecord into docRecordOnDisk
|
|
// Compilers should handle aligment correctly
|
|
strcpy(docRecordOnDisk.m_szFormatName, docRecord.m_szFormatName);
|
|
docRecordOnDisk.m_narrAppVersionNo[0] = (short) docRecord.m_narrAppVersionNo[0];
|
|
docRecordOnDisk.m_narrAppVersionNo[1] = (short) docRecord.m_narrAppVersionNo[1];
|
|
docRecordOnDisk.m_fShowHeading = (USHORT) docRecord.m_fShowHeading;
|
|
docRecordOnDisk.m_reserved1 = docRecord.m_reserved1;
|
|
docRecordOnDisk.m_reserved2 = docRecord.m_reserved2;
|
|
docRecordOnDisk.m_reserved3 = docRecord.m_reserved3;
|
|
docRecordOnDisk.m_reserved4 = docRecord.m_reserved4;
|
|
|
|
hrErr = lpLLStm->lpVtbl->Write(
|
|
lpLLStm,
|
|
(LPVOID)&docRecordOnDisk,
|
|
sizeof(docRecordOnDisk),
|
|
&nWritten
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Write OutlineDoc header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
// Save LineList
|
|
/* OLE2NOTE: A ContainerDoc keeps its storage open at all times. It is
|
|
** necessary to pass the current open storage (lpOleDoc->m_lpStg)
|
|
** to the LineList_SaveSelToStg method so that currently written data
|
|
** for any embeddings is also saved to the new destination
|
|
** storage. The data required by a contained object is both the
|
|
** ContainerLine information and the associated sub-storage that is
|
|
** written directly by the embedded object.
|
|
*/
|
|
fStatus = LineList_SaveSelToStg(
|
|
&lpOutlineDoc->m_LineList,
|
|
lplrSel,
|
|
uFormat,
|
|
#if defined( OLE_CNTR )
|
|
lpOleDoc->m_lpStg,
|
|
#else
|
|
NULL,
|
|
#endif
|
|
lpDestStg,
|
|
lpLLStm,
|
|
fRemember
|
|
);
|
|
if (! fStatus) goto error;
|
|
|
|
// Save associated NameTable
|
|
fStatus = OutlineNameTable_SaveSelToStg(
|
|
lpOutlineDoc->m_lpNameTable,
|
|
lplrSel,
|
|
uFormat,
|
|
lpNTStm
|
|
);
|
|
|
|
if (! fStatus) goto error;
|
|
|
|
OleStdRelease((LPUNKNOWN)lpLLStm);
|
|
lpOutlineDoc->m_cfSaveFormat = uFormat; // remember format used to save
|
|
|
|
SetCursor(hPrevCursor); // restore original cursor
|
|
return TRUE;
|
|
|
|
error:
|
|
if (lpLLStm)
|
|
OleStdRelease((LPUNKNOWN)lpLLStm);
|
|
|
|
SetCursor(hPrevCursor); // restore original cursor
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_Print
|
|
* ----------------
|
|
* Prints the contents of the list box in HIMETRIC mapping mode. Origin
|
|
* remains to be the upper left corner and the print proceeds down the
|
|
* page using a negative y-cordinate.
|
|
*
|
|
*/
|
|
void OutlineDoc_Print(LPOUTLINEDOC lpOutlineDoc, HDC hDC)
|
|
{
|
|
LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
WORD nIndex;
|
|
WORD nTotal;
|
|
int dy;
|
|
BOOL fError = FALSE;
|
|
LPLINE lpLine;
|
|
RECT rcLine;
|
|
RECT rcPix;
|
|
RECT rcHim;
|
|
RECT rcWindowOld;
|
|
RECT rcViewportOld;
|
|
HFONT hOldFont;
|
|
DOCINFO di; /* Document information for StartDoc function */
|
|
|
|
/* Get dimension of page */
|
|
rcPix.left = 0;
|
|
rcPix.top = 0;
|
|
rcPix.right = GetDeviceCaps(hDC, HORZRES);
|
|
rcPix.bottom = GetDeviceCaps(hDC, VERTRES);
|
|
|
|
SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
|
|
(LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
|
|
|
|
// Set the default font size, and font face name
|
|
hOldFont = SelectObject(hDC, lpOutlineApp->m_hStdFont);
|
|
|
|
/* Get the lines in document */
|
|
nIndex = 0;
|
|
nTotal = LineList_GetCount(lpLL);
|
|
|
|
/* Create the Cancel dialog */
|
|
// REVIEW: should load dialog title from string resource file
|
|
hWndPDlg = CreateDialog (
|
|
lpOutlineApp->m_hInst,
|
|
"Print",
|
|
lpOutlineApp->m_hWndApp,
|
|
(DLGPROC)PrintDlgProc
|
|
);
|
|
|
|
if(!hWndPDlg)
|
|
goto getout;
|
|
|
|
/* Allow the app. to inform GDI of the abort function to call */
|
|
if(SetAbortProc(hDC, (ABORTPROC)AbortProc) < 0) {
|
|
fError = TRUE;
|
|
goto getout3;
|
|
}
|
|
|
|
/* Disable the main application window */
|
|
EnableWindow (lpOutlineApp->m_hWndApp, FALSE);
|
|
|
|
// initialize the rectangle for the first line
|
|
rcLine.left = rcHim.left;
|
|
rcLine.bottom = rcHim.top;
|
|
|
|
/* Initialize the document */
|
|
fCancelPrint = FALSE;
|
|
|
|
di.cbSize = sizeof(di);
|
|
di.lpszDocName = lpOutlineDoc->m_lpszDocTitle;
|
|
di.lpszOutput = NULL;
|
|
|
|
if(StartDoc(hDC, (DOCINFO FAR*)&di) <= 0) {
|
|
fError = TRUE;
|
|
OleDbgOut2("StartDoc error\n");
|
|
goto getout5;
|
|
}
|
|
|
|
if(StartPage(hDC) <= 0) { // start first page
|
|
fError = TRUE;
|
|
OleDbgOut2("StartPage error\n");
|
|
goto getout2;
|
|
}
|
|
|
|
/* While more lines print out the text */
|
|
while(nIndex < nTotal) {
|
|
lpLine = LineList_GetLine(lpLL, nIndex);
|
|
if (! lpLine)
|
|
continue;
|
|
|
|
dy = Line_GetHeightInHimetric(lpLine);
|
|
|
|
/* Reached end of page. Tell the device driver to eject a page */
|
|
if(rcLine.bottom - dy < rcHim.bottom) {
|
|
if (EndPage(hDC) < 0) {
|
|
fError=TRUE;
|
|
OleDbgOut2("EndPage error\n");
|
|
goto getout2;
|
|
}
|
|
|
|
// NOTE: Reset the Mapping mode of DC
|
|
SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
|
|
(LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
|
|
|
|
// Set the default font size, and font face name
|
|
SelectObject(hDC, lpOutlineApp->m_hStdFont);
|
|
|
|
if (StartPage(hDC) <= 0) {
|
|
fError=TRUE;
|
|
OleDbgOut2("StartPage error\n");
|
|
goto getout2;
|
|
}
|
|
|
|
rcLine.bottom = rcHim.top;
|
|
}
|
|
|
|
rcLine.top = rcLine.bottom;
|
|
rcLine.bottom -= dy;
|
|
rcLine.right = rcLine.left + Line_GetWidthInHimetric(lpLine);
|
|
|
|
/* Print the line */
|
|
Line_Draw(lpLine, hDC, &rcLine, NULL, FALSE /*fHighlight*/);
|
|
|
|
OleDbgOut2("a line is drawn\n");
|
|
|
|
/* Test and see if the Abort flag has been set. If yes, exit. */
|
|
if (fCancelPrint)
|
|
goto getout2;
|
|
|
|
/* Move down the page */
|
|
nIndex++;
|
|
}
|
|
|
|
{
|
|
int nCode;
|
|
|
|
/* Eject the last page. */
|
|
if((nCode = EndPage(hDC)) < 0) {
|
|
#if defined( _DEBUG )
|
|
char szBuf[255];
|
|
wsprintf(szBuf, "EndPage error code is %d\n", nCode);
|
|
OleDbgOut2(szBuf);
|
|
#endif
|
|
fError=TRUE;
|
|
goto getout2;
|
|
}
|
|
}
|
|
|
|
|
|
/* Complete the document. */
|
|
if(EndDoc(hDC) < 0) {
|
|
fError=TRUE;
|
|
OleDbgOut2("EndDoc error\n");
|
|
|
|
getout2:
|
|
/* Ran into a problem before NEWFRAME? Abort the document */
|
|
AbortDoc(hDC);
|
|
}
|
|
|
|
getout5:
|
|
/* Re-enable main app. window */
|
|
EnableWindow (lpOutlineApp->m_hWndApp, TRUE);
|
|
|
|
getout3:
|
|
/* Close the cancel dialog */
|
|
DestroyWindow (hWndPDlg);
|
|
|
|
getout:
|
|
|
|
/* Error? make sure the user knows... */
|
|
if(fError || CommDlgExtendedError())
|
|
OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgPrint);
|
|
|
|
SelectObject(hDC, hOldFont);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* OutlineDoc_DialogHelp
|
|
* ---------------------
|
|
*
|
|
* Show help message for ole2ui dialogs.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* hDlg HWND to the dialog the help message came from - use
|
|
* this in the call to WinHelp/MessageBox so that
|
|
* activation/focus goes back to the dialog, and not the
|
|
* main window.
|
|
*
|
|
* wParam ID of the dialog (so we know what type of dialog it is).
|
|
*/
|
|
void OutlineDoc_DialogHelp(HWND hDlg, WPARAM wDlgID)
|
|
{
|
|
|
|
char szMessageBoxText[64];
|
|
|
|
if (!IsWindow(hDlg)) // don't do anything if we've got a bogus hDlg.
|
|
return;
|
|
|
|
lstrcpy(szMessageBoxText, "Help Message for ");
|
|
|
|
switch (wDlgID)
|
|
{
|
|
|
|
case IDD_CONVERT:
|
|
lstrcat(szMessageBoxText, "Convert");
|
|
break;
|
|
|
|
case IDD_CHANGEICON:
|
|
lstrcat(szMessageBoxText, "Change Icon");
|
|
break;
|
|
|
|
case IDD_INSERTOBJECT:
|
|
lstrcat(szMessageBoxText, "Insert Object");
|
|
break;
|
|
|
|
case IDD_PASTESPECIAL:
|
|
lstrcat(szMessageBoxText, "Paste Special");
|
|
break;
|
|
|
|
case IDD_EDITLINKS:
|
|
lstrcat(szMessageBoxText, "Edit Links");
|
|
break;
|
|
|
|
case IDD_CHANGESOURCE:
|
|
lstrcat(szMessageBoxText, "Change Source");
|
|
break;
|
|
|
|
case IDD_INSERTFILEBROWSE:
|
|
lstrcat(szMessageBoxText, "Insert From File Browse");
|
|
break;
|
|
|
|
case IDD_CHANGEICONBROWSE:
|
|
lstrcat(szMessageBoxText, "Change Icon Browse");
|
|
break;
|
|
|
|
default:
|
|
lstrcat(szMessageBoxText, "Unknown");
|
|
break;
|
|
}
|
|
|
|
lstrcat(szMessageBoxText, " Dialog.");
|
|
|
|
// You'd probably really a call to WinHelp here.
|
|
MessageBox(hDlg, szMessageBoxText, "Help", MB_OK);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetCurrentZoomCommand
|
|
* --------------------------------
|
|
*
|
|
* Set current zoom level to be checked in the menu.
|
|
* Set the corresponding scalefactor for the document.
|
|
*/
|
|
void OutlineDoc_SetCurrentZoomCommand(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
UINT uCurrentZoom
|
|
)
|
|
{
|
|
SCALEFACTOR scale;
|
|
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
lpOutlineDoc->m_uCurrentZoom = uCurrentZoom;
|
|
|
|
switch (uCurrentZoom) {
|
|
|
|
#if !defined( OLE_CNTR )
|
|
case IDM_V_ZOOM_400:
|
|
scale.dwSxN = (DWORD) 4;
|
|
scale.dwSxD = (DWORD) 1;
|
|
scale.dwSyN = (DWORD) 4;
|
|
scale.dwSyD = (DWORD) 1;
|
|
break;
|
|
|
|
case IDM_V_ZOOM_300:
|
|
scale.dwSxN = (DWORD) 3;
|
|
scale.dwSxD = (DWORD) 1;
|
|
scale.dwSyN = (DWORD) 3;
|
|
scale.dwSyD = (DWORD) 1;
|
|
break;
|
|
|
|
case IDM_V_ZOOM_200:
|
|
scale.dwSxN = (DWORD) 2;
|
|
scale.dwSxD = (DWORD) 1;
|
|
scale.dwSyN = (DWORD) 2;
|
|
scale.dwSyD = (DWORD) 1;
|
|
break;
|
|
#endif // !OLE_CNTR
|
|
|
|
case IDM_V_ZOOM_100:
|
|
scale.dwSxN = (DWORD) 1;
|
|
scale.dwSxD = (DWORD) 1;
|
|
scale.dwSyN = (DWORD) 1;
|
|
scale.dwSyD = (DWORD) 1;
|
|
break;
|
|
|
|
case IDM_V_ZOOM_75:
|
|
scale.dwSxN = (DWORD) 3;
|
|
scale.dwSxD = (DWORD) 4;
|
|
scale.dwSyN = (DWORD) 3;
|
|
scale.dwSyD = (DWORD) 4;
|
|
break;
|
|
|
|
case IDM_V_ZOOM_50:
|
|
scale.dwSxN = (DWORD) 1;
|
|
scale.dwSxD = (DWORD) 2;
|
|
scale.dwSyN = (DWORD) 1;
|
|
scale.dwSyD = (DWORD) 2;
|
|
break;
|
|
|
|
case IDM_V_ZOOM_25:
|
|
scale.dwSxN = (DWORD) 1;
|
|
scale.dwSxD = (DWORD) 4;
|
|
scale.dwSyN = (DWORD) 1;
|
|
scale.dwSyD = (DWORD) 4;
|
|
break;
|
|
}
|
|
|
|
OutlineDoc_SetScaleFactor(lpOutlineDoc, (LPSCALEFACTOR)&scale, NULL);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetCurrentZoomMenuCheck
|
|
* ----------------------------------
|
|
*
|
|
* Get current zoom level to be checked in the menu.
|
|
*/
|
|
UINT OutlineDoc_GetCurrentZoomMenuCheck(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
return lpOutlineDoc->m_uCurrentZoom;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetScaleFactor
|
|
* -------------------------
|
|
*
|
|
* Set the scale factor of the document which will affect the
|
|
* size of the document on the screen
|
|
*
|
|
* Parameters:
|
|
*
|
|
* scale structure containing x and y scales
|
|
*/
|
|
void OutlineDoc_SetScaleFactor(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
LPSCALEFACTOR lpscale,
|
|
LPRECT lprcDoc
|
|
)
|
|
{
|
|
LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
|
|
HWND hWndLL = LineList_GetWindow(lpLL);
|
|
|
|
if (!lpOutlineDoc || !lpscale)
|
|
return;
|
|
|
|
InvalidateRect(hWndLL, NULL, TRUE);
|
|
|
|
lpOutlineDoc->m_scale = *lpscale;
|
|
LineList_ReScale((LPLINELIST)&lpOutlineDoc->m_LineList, lpscale);
|
|
|
|
#if defined( USE_HEADING )
|
|
Heading_ReScale((LPHEADING)&lpOutlineDoc->m_heading, lpscale);
|
|
#endif
|
|
|
|
OutlineDoc_Resize(lpOutlineDoc, lprcDoc);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetScaleFactor
|
|
* -------------------------
|
|
*
|
|
* Retrieve the scale factor of the document
|
|
*
|
|
* Parameters:
|
|
*
|
|
*/
|
|
LPSCALEFACTOR OutlineDoc_GetScaleFactor(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return NULL;
|
|
|
|
return (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetCurrentMarginCommand
|
|
* ----------------------------------
|
|
*
|
|
* Set current Margin level to be checked in the menu.
|
|
*/
|
|
void OutlineDoc_SetCurrentMarginCommand(
|
|
LPOUTLINEDOC lpOutlineDoc,
|
|
UINT uCurrentMargin
|
|
)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
lpOutlineDoc->m_uCurrentMargin = uCurrentMargin;
|
|
|
|
switch (uCurrentMargin) {
|
|
case IDM_V_SETMARGIN_0:
|
|
OutlineDoc_SetMargin(lpOutlineDoc, 0, 0);
|
|
break;
|
|
|
|
case IDM_V_SETMARGIN_1:
|
|
OutlineDoc_SetMargin(lpOutlineDoc, 1000, 1000);
|
|
break;
|
|
|
|
case IDM_V_SETMARGIN_2:
|
|
OutlineDoc_SetMargin(lpOutlineDoc, 2000, 2000);
|
|
break;
|
|
|
|
case IDM_V_SETMARGIN_3:
|
|
OutlineDoc_SetMargin(lpOutlineDoc, 3000, 3000);
|
|
break;
|
|
|
|
case IDM_V_SETMARGIN_4:
|
|
OutlineDoc_SetMargin(lpOutlineDoc, 4000, 4000);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetCurrentMarginMenuCheck
|
|
* ------------------------------------
|
|
*
|
|
* Get current Margin level to be checked in the menu.
|
|
*/
|
|
UINT OutlineDoc_GetCurrentMarginMenuCheck(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
return lpOutlineDoc->m_uCurrentMargin;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_SetMargin
|
|
* --------------------
|
|
*
|
|
* Set the left and right margin of the document
|
|
*
|
|
* Parameters:
|
|
* nLeftMargin - left margin in Himetric values
|
|
* nRightMargin - right margin in Himetric values
|
|
*/
|
|
void OutlineDoc_SetMargin(LPOUTLINEDOC lpOutlineDoc, int nLeftMargin, int nRightMargin)
|
|
{
|
|
LPLINELIST lpLL;
|
|
int nMaxWidthInHim;
|
|
|
|
if (!lpOutlineDoc)
|
|
return;
|
|
|
|
lpOutlineDoc->m_nLeftMargin = nLeftMargin;
|
|
lpOutlineDoc->m_nRightMargin = nRightMargin;
|
|
lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
|
|
|
|
// Force recalculation of Horizontal extent
|
|
nMaxWidthInHim = LineList_GetMaxLineWidthInHimetric(lpLL);
|
|
LineList_SetMaxLineWidthInHimetric(lpLL, -nMaxWidthInHim);
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
|
|
#endif
|
|
|
|
OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
|
|
}
|
|
|
|
|
|
/* OutlineDoc_GetMargin
|
|
* --------------------
|
|
*
|
|
* Get the left and right margin of the document
|
|
*
|
|
* Parameters:
|
|
* nLeftMargin - left margin in Himetric values
|
|
* nRightMargin - right margin in Himetric values
|
|
*
|
|
* Returns:
|
|
* low order word - left margin
|
|
* high order word - right margin
|
|
*/
|
|
LONG OutlineDoc_GetMargin(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (!lpOutlineDoc)
|
|
return 0;
|
|
|
|
return MAKELONG(lpOutlineDoc->m_nLeftMargin, lpOutlineDoc->m_nRightMargin);
|
|
}
|
|
|
|
#if defined( USE_HEADING )
|
|
|
|
/* OutlineDoc_GetHeading
|
|
* ---------------------
|
|
*
|
|
* Get Heading Object in OutlineDoc
|
|
*/
|
|
LPHEADING OutlineDoc_GetHeading(LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
if (!lpOutlineDoc || lpOutlineDoc->m_fDataTransferDoc)
|
|
return NULL;
|
|
else
|
|
return (LPHEADING)&lpOutlineDoc->m_heading;
|
|
}
|
|
|
|
|
|
/* OutlineDoc_ShowHeading
|
|
* ----------------------
|
|
*
|
|
* Show/Hide document row/column headings.
|
|
*/
|
|
void OutlineDoc_ShowHeading(LPOUTLINEDOC lpOutlineDoc, BOOL fShow)
|
|
{
|
|
LPHEADING lphead = OutlineDoc_GetHeading(lpOutlineDoc);
|
|
#if defined( INPLACE_SVR )
|
|
LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
|
|
#endif
|
|
|
|
if (! lphead)
|
|
return;
|
|
|
|
Heading_Show(lphead, fShow);
|
|
|
|
#if defined( INPLACE_SVR )
|
|
if (lpServerDoc->m_fUIActive) {
|
|
LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
|
|
|
|
/* OLE2NOTE: our extents have NOT changed; only our the size of
|
|
** our object-frame adornments is changing. we can use the
|
|
** current PosRect and ClipRect and simply resize our
|
|
** windows WITHOUT informing our in-place container.
|
|
*/
|
|
ServerDoc_ResizeInPlaceWindow(
|
|
lpServerDoc,
|
|
(LPRECT)&(lpIPData->rcPosRect),
|
|
(LPRECT)&(lpIPData->rcClipRect)
|
|
);
|
|
} else
|
|
#else // !INPLACE_SVR
|
|
|
|
OutlineDoc_Resize(lpOutlineDoc, NULL);
|
|
|
|
#if defined( INPLACE_CNTR )
|
|
ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
|
|
#endif // INPLACE_CNTR
|
|
|
|
#endif // INPLACE_SVR
|
|
|
|
OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
|
|
}
|
|
|
|
#endif // USE_HEADING
|
|
|
|
|
|
/* AbortProc
|
|
* ---------
|
|
* AborProc is called by GDI print code to check for user abort.
|
|
*/
|
|
BOOL FAR PASCAL EXPORT AbortProc (HDC hdc, WORD reserved)
|
|
{
|
|
MSG msg;
|
|
|
|
/* Allow other apps to run, or get abort messages */
|
|
while(! fCancelPrint && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
if(!hWndPDlg || !IsDialogMessage (hWndPDlg, &msg)) {
|
|
TranslateMessage (&msg);
|
|
DispatchMessage (&msg);
|
|
}
|
|
}
|
|
return !fCancelPrint;
|
|
}
|
|
|
|
|
|
/* PrintDlgProc
|
|
* ------------
|
|
* Dialog function for the print cancel dialog box.
|
|
*
|
|
* RETURNS : TRUE - OK to abort/ not OK to abort
|
|
* FALSE - otherwise.
|
|
*/
|
|
BOOL FAR PASCAL EXPORT PrintDlgProc(
|
|
HWND hwnd,
|
|
WORD msg,
|
|
WORD wParam,
|
|
LONG lParam
|
|
)
|
|
{
|
|
switch (msg) {
|
|
case WM_COMMAND:
|
|
/* abort printing if the only button gets hit */
|
|
fCancelPrint = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|