461 lines
11 KiB
C
461 lines
11 KiB
C
/*************************************************************************
|
|
**
|
|
** OLE 2 Sample Code
|
|
**
|
|
** outlntbl.c
|
|
**
|
|
** This file contains OutlineNameTable functions.
|
|
**
|
|
** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
|
|
**
|
|
*************************************************************************/
|
|
|
|
|
|
#include "outline.h"
|
|
|
|
OLEDBGDATA
|
|
|
|
extern LPOUTLINEAPP g_lpApp;
|
|
|
|
char ErrMsgNameTable[] = "Can't create NameTable!";
|
|
|
|
|
|
/* OutlineNameTable_Init
|
|
* ---------------------
|
|
*
|
|
* initialize a name table.
|
|
*/
|
|
BOOL OutlineNameTable_Init(LPOUTLINENAMETABLE lpOutlineNameTable, LPOUTLINEDOC lpOutlineDoc)
|
|
{
|
|
HWND lpParent = OutlineDoc_GetWindow(lpOutlineDoc);
|
|
|
|
lpOutlineNameTable->m_nCount = 0;
|
|
|
|
/* We will use an OwnerDraw listbox as our data structure to
|
|
** maintain the table of Names. this listbox will never be made
|
|
** visible. the listbox is just a convenient data structure to
|
|
** manage a collection.
|
|
*/
|
|
lpOutlineNameTable->m_hWndListBox = CreateWindow(
|
|
"listbox", /* Window class name */
|
|
NULL, /* Window's title */
|
|
WS_CHILDWINDOW |
|
|
LBS_OWNERDRAWFIXED,
|
|
0, 0, /* Use default X, Y */
|
|
0, 0, /* Use default X, Y */
|
|
lpParent, /* Parent window's handle */
|
|
(HMENU)IDC_NAMETABLE, /* Child Window ID */
|
|
g_lpApp->m_hInst, /* Instance of window */
|
|
NULL); /* Create struct for WM_CREATE */
|
|
|
|
if (! lpOutlineNameTable->m_hWndListBox) {
|
|
OutlineApp_ErrorMessage(g_lpApp, ErrMsgNameTable);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_Destroy
|
|
* ------------------------
|
|
*
|
|
* Free memory used by the name table.
|
|
*/
|
|
void OutlineNameTable_Destroy(LPOUTLINENAMETABLE lpOutlineNameTable)
|
|
{
|
|
// Delete all names
|
|
OutlineNameTable_ClearAll(lpOutlineNameTable);
|
|
|
|
DestroyWindow(lpOutlineNameTable->m_hWndListBox);
|
|
Delete(lpOutlineNameTable);
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_AddName
|
|
* ------------------------
|
|
*
|
|
* Add a name to the table
|
|
*/
|
|
void OutlineNameTable_AddName(LPOUTLINENAMETABLE lpOutlineNameTable, LPOUTLINENAME lpOutlineName)
|
|
{
|
|
SendMessage(
|
|
lpOutlineNameTable->m_hWndListBox,
|
|
LB_ADDSTRING,
|
|
0,
|
|
(DWORD)lpOutlineName
|
|
);
|
|
lpOutlineNameTable->m_nCount++;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_DeleteName
|
|
* ---------------------------
|
|
*
|
|
* Delete a name from table
|
|
*/
|
|
void OutlineNameTable_DeleteName(LPOUTLINENAMETABLE lpOutlineNameTable,int nIndex)
|
|
{
|
|
LPOUTLINENAME lpOutlineName = OutlineNameTable_GetName(lpOutlineNameTable, nIndex);
|
|
|
|
#if defined( OLE_SERVER )
|
|
/* OLE2NOTE: if there is a pseudo object attached to this name, it
|
|
** must first be closed before deleting the Name. this will
|
|
** cause OnClose notification to be sent to all linking clients.
|
|
*/
|
|
ServerName_ClosePseudoObj((LPSERVERNAME)lpOutlineName);
|
|
#endif
|
|
|
|
if (lpOutlineName)
|
|
Delete(lpOutlineName); // free memory for name
|
|
|
|
SendMessage(
|
|
lpOutlineNameTable->m_hWndListBox,
|
|
LB_DELETESTRING,
|
|
(WPARAM)nIndex,
|
|
0L
|
|
);
|
|
lpOutlineNameTable->m_nCount--;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_GetNameIndex
|
|
* -----------------------------
|
|
*
|
|
* Return the index of the Name given a pointer to the Name.
|
|
* Return -1 if the Name is not found.
|
|
*/
|
|
int OutlineNameTable_GetNameIndex(LPOUTLINENAMETABLE lpOutlineNameTable, LPOUTLINENAME lpOutlineName)
|
|
{
|
|
LRESULT lReturn;
|
|
|
|
if (! lpOutlineName) return -1;
|
|
|
|
lReturn = SendMessage(
|
|
lpOutlineNameTable->m_hWndListBox,
|
|
LB_FINDSTRING,
|
|
(WPARAM)-1,
|
|
(LPARAM)(LPCSTR)lpOutlineName
|
|
);
|
|
|
|
return ((lReturn == LB_ERR) ? -1 : (int)lReturn);
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_GetName
|
|
* ------------------------
|
|
*
|
|
* Retrieve the pointer to the Name given its index in the NameTable
|
|
*/
|
|
LPOUTLINENAME OutlineNameTable_GetName(LPOUTLINENAMETABLE lpOutlineNameTable, int nIndex)
|
|
{
|
|
LPOUTLINENAME lpOutlineName = NULL;
|
|
LRESULT lResult;
|
|
|
|
if (lpOutlineNameTable->m_nCount == 0 ||
|
|
nIndex > lpOutlineNameTable->m_nCount ||
|
|
nIndex < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
lResult = SendMessage(
|
|
lpOutlineNameTable->m_hWndListBox,
|
|
LB_GETTEXT,
|
|
nIndex,
|
|
(LPARAM)(LPCSTR)&lpOutlineName
|
|
);
|
|
OleDbgAssert(lResult != LB_ERR);
|
|
return lpOutlineName;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_FindName
|
|
* -------------------------
|
|
*
|
|
* Find a name in the name table given a string.
|
|
*/
|
|
LPOUTLINENAME OutlineNameTable_FindName(LPOUTLINENAMETABLE lpOutlineNameTable, LPSTR lpszName)
|
|
{
|
|
LPOUTLINENAME lpOutlineName;
|
|
BOOL fFound = FALSE;
|
|
int i;
|
|
|
|
for (i = 0; i < lpOutlineNameTable->m_nCount; i++) {
|
|
lpOutlineName = OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
if (lstrcmp(lpOutlineName->m_szName, lpszName) == 0) {
|
|
fFound = TRUE;
|
|
break; // FOUND MATCH!
|
|
}
|
|
}
|
|
|
|
return (fFound ? lpOutlineName : NULL);
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_FindNamedRange
|
|
* -------------------------------
|
|
*
|
|
* Find a name in the name table which matches a given line range.
|
|
*/
|
|
LPOUTLINENAME OutlineNameTable_FindNamedRange(LPOUTLINENAMETABLE lpOutlineNameTable, LPLINERANGE lplrSel)
|
|
{
|
|
LPOUTLINENAME lpOutlineName;
|
|
BOOL fFound = FALSE;
|
|
int i;
|
|
|
|
for (i = 0; i < lpOutlineNameTable->m_nCount; i++) {
|
|
lpOutlineName = OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
if ((lpOutlineName->m_nStartLine == lplrSel->m_nStartLine) &&
|
|
(lpOutlineName->m_nEndLine == lplrSel->m_nEndLine) ) {
|
|
fFound = TRUE;
|
|
break; // FOUND MATCH!
|
|
}
|
|
}
|
|
|
|
return (fFound ? lpOutlineName : NULL);
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_GetCount
|
|
* -------------------------
|
|
*
|
|
* Return number of names in nametable
|
|
*/
|
|
int OutlineNameTable_GetCount(LPOUTLINENAMETABLE lpOutlineNameTable)
|
|
{
|
|
if (!lpOutlineNameTable)
|
|
return 0;
|
|
|
|
return lpOutlineNameTable->m_nCount;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_ClearAll
|
|
* -------------------------
|
|
*
|
|
* Remove all names from table
|
|
*/
|
|
void OutlineNameTable_ClearAll(LPOUTLINENAMETABLE lpOutlineNameTable)
|
|
{
|
|
LPOUTLINENAME lpOutlineName;
|
|
int i;
|
|
int nCount = lpOutlineNameTable->m_nCount;
|
|
|
|
for (i = 0; i < nCount; i++) {
|
|
lpOutlineName = OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
Delete(lpOutlineName); // free memory for name
|
|
}
|
|
|
|
lpOutlineNameTable->m_nCount = 0;
|
|
SendMessage(lpOutlineNameTable->m_hWndListBox,LB_RESETCONTENT,0,0L);
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_AddLineUpdate
|
|
* ------------------------------
|
|
*
|
|
* Update table when a new line is added at nAddIndex
|
|
* The line used to be at nAddIndex is pushed down
|
|
*/
|
|
void OutlineNameTable_AddLineUpdate(LPOUTLINENAMETABLE lpOutlineNameTable, int nAddIndex)
|
|
{
|
|
LPOUTLINENAME lpOutlineName;
|
|
LINERANGE lrSel;
|
|
int i;
|
|
BOOL fRangeModified = FALSE;
|
|
|
|
for(i = 0; i < lpOutlineNameTable->m_nCount; i++) {
|
|
lpOutlineName=OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
OutlineName_GetSel(lpOutlineName, &lrSel);
|
|
|
|
if((int)lrSel.m_nStartLine > nAddIndex) {
|
|
lrSel.m_nStartLine++;
|
|
fRangeModified = !fRangeModified;
|
|
}
|
|
if((int)lrSel.m_nEndLine > nAddIndex) {
|
|
lrSel.m_nEndLine++;
|
|
fRangeModified = !fRangeModified;
|
|
}
|
|
|
|
OutlineName_SetSel(lpOutlineName, &lrSel, fRangeModified);
|
|
}
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_DeleteLineUpdate
|
|
* ---------------------------------
|
|
*
|
|
* Update the table when a line at nDeleteIndex is removed
|
|
*/
|
|
void OutlineNameTable_DeleteLineUpdate(LPOUTLINENAMETABLE lpOutlineNameTable, int nDeleteIndex)
|
|
{
|
|
LPOUTLINENAME lpOutlineName;
|
|
LINERANGE lrSel;
|
|
int i;
|
|
BOOL fRangeModified = FALSE;
|
|
|
|
for(i = 0; i < lpOutlineNameTable->m_nCount; i++) {
|
|
lpOutlineName=OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
OutlineName_GetSel(lpOutlineName, &lrSel);
|
|
|
|
if((int)lrSel.m_nStartLine > nDeleteIndex) {
|
|
lrSel.m_nStartLine--;
|
|
fRangeModified = !fRangeModified;
|
|
}
|
|
if((int)lrSel.m_nEndLine >= nDeleteIndex) {
|
|
lrSel.m_nEndLine--;
|
|
fRangeModified = !fRangeModified;
|
|
}
|
|
|
|
// delete the name if its entire range is deleted
|
|
if(lrSel.m_nStartLine > lrSel.m_nEndLine) {
|
|
OutlineNameTable_DeleteName(lpOutlineNameTable, i);
|
|
i--; // re-examine this name
|
|
} else {
|
|
OutlineName_SetSel(lpOutlineName, &lrSel, fRangeModified);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_SaveSelToStg
|
|
* -----------------------------
|
|
*
|
|
* Save only the names that refer to lines completely contained in the
|
|
* specified selection range.
|
|
*/
|
|
BOOL OutlineNameTable_SaveSelToStg(
|
|
LPOUTLINENAMETABLE lpOutlineNameTable,
|
|
LPLINERANGE lplrSel,
|
|
UINT uFormat,
|
|
LPSTREAM lpNTStm
|
|
)
|
|
{
|
|
HRESULT hrErr;
|
|
ULONG nWritten;
|
|
LPOUTLINENAME lpOutlineName;
|
|
short nNameCount = 0;
|
|
BOOL fNameSaved;
|
|
BOOL fStatus;
|
|
int i;
|
|
LARGE_INTEGER dlibZeroOffset;
|
|
LISet32( dlibZeroOffset, 0 );
|
|
|
|
/* initially write 0 for count of names. the correct count will be
|
|
** written at the end when we know how many names qualified to
|
|
** be written (within the selection).
|
|
*/
|
|
hrErr = lpNTStm->lpVtbl->Write(
|
|
lpNTStm,
|
|
(short FAR*)&nNameCount,
|
|
sizeof(nNameCount),
|
|
&nWritten
|
|
);
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Write NameTable header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
for(i = 0; i < lpOutlineNameTable->m_nCount; i++) {
|
|
lpOutlineName=OutlineNameTable_GetName(lpOutlineNameTable, i);
|
|
fStatus = OutlineName_SaveToStg(
|
|
lpOutlineName,
|
|
lplrSel,
|
|
uFormat,
|
|
lpNTStm,
|
|
(BOOL FAR*)&fNameSaved
|
|
);
|
|
if (! fStatus) goto error;
|
|
if (fNameSaved) nNameCount++;
|
|
}
|
|
|
|
/* write the final count of names written. */
|
|
hrErr = lpNTStm->lpVtbl->Seek(
|
|
lpNTStm,
|
|
dlibZeroOffset,
|
|
STREAM_SEEK_SET,
|
|
NULL
|
|
);
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Seek to NameTable header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
hrErr = lpNTStm->lpVtbl->Write(
|
|
lpNTStm,
|
|
(short FAR*)&nNameCount,
|
|
sizeof(nNameCount),
|
|
&nWritten
|
|
);
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Write NameTable count in header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
OleStdRelease((LPUNKNOWN)lpNTStm);
|
|
return TRUE;
|
|
|
|
error:
|
|
if (lpNTStm)
|
|
OleStdRelease((LPUNKNOWN)lpNTStm);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* OutlineNameTable_LoadFromStg
|
|
* ----------------------------
|
|
*
|
|
* Load Name Table from file
|
|
*
|
|
* Return TRUE if ok, FALSE if error
|
|
*/
|
|
BOOL OutlineNameTable_LoadFromStg(LPOUTLINENAMETABLE lpOutlineNameTable, LPSTORAGE lpSrcStg)
|
|
{
|
|
LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
|
|
HRESULT hrErr;
|
|
IStream FAR* lpNTStm;
|
|
ULONG nRead;
|
|
short nCount;
|
|
LPOUTLINENAME lpOutlineName;
|
|
BOOL fStatus;
|
|
short i;
|
|
|
|
hrErr = CallIStorageOpenStreamA(
|
|
lpSrcStg,
|
|
"NameTable",
|
|
NULL,
|
|
STGM_READ | STGM_SHARE_EXCLUSIVE,
|
|
0,
|
|
&lpNTStm
|
|
);
|
|
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("OpenStream NameTable returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
hrErr = lpNTStm->lpVtbl->Read(lpNTStm,&nCount,sizeof(nCount),&nRead);
|
|
if (hrErr != NOERROR) {
|
|
OleDbgOutHResult("Read NameTable header returned", hrErr);
|
|
goto error;
|
|
}
|
|
|
|
for (i = 0; i < nCount; i++) {
|
|
lpOutlineName = OutlineApp_CreateName(lpOutlineApp);
|
|
if (! lpOutlineName) goto error;
|
|
fStatus = OutlineName_LoadFromStg(lpOutlineName, lpNTStm);
|
|
if (! fStatus) goto error;
|
|
OutlineNameTable_AddName(lpOutlineNameTable, lpOutlineName);
|
|
}
|
|
|
|
OleStdRelease((LPUNKNOWN)lpNTStm);
|
|
return TRUE;
|
|
|
|
error:
|
|
if (lpNTStm)
|
|
OleStdRelease((LPUNKNOWN)lpNTStm);
|
|
|
|
return FALSE;
|
|
}
|