summaryrefslogtreecommitdiffstats
path: root/private/oleutest/ole1/clidemo/dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleutest/ole1/clidemo/dialog.c')
-rw-r--r--private/oleutest/ole1/clidemo/dialog.c1150
1 files changed, 1150 insertions, 0 deletions
diff --git a/private/oleutest/ole1/clidemo/dialog.c b/private/oleutest/ole1/clidemo/dialog.c
new file mode 100644
index 000000000..1e5eb6cc0
--- /dev/null
+++ b/private/oleutest/ole1/clidemo/dialog.c
@@ -0,0 +1,1150 @@
+/*
+ * dialog.c - Handles the Windows 3.1 common dialogs.
+ *
+ * Created by Microsoft Corporation.
+ * (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
+ */
+
+//*** INCLUDES ****
+
+#include <windows.h> //* WINDOWS
+#include <ole.h> //* OLE
+
+#include "global.h" //* global
+#include "demorc.h" //* String table constants
+#include "register.h" //* Class registration library
+#include "utility.h"
+#include "dialog.h"
+#include "object.h"
+
+//*** GLOBALS ***
+ //* strings used with commdlg
+CHAR szDefExtension[CBMESSAGEMAX];
+CHAR szFilterSpec[CBFILTERMAX];
+CHAR szInsertFilter[CBFILTERMAX];
+CHAR szLastDir[CBPATHMAX];
+OPENFILENAME OFN;
+HWND hwndProp = NULL;
+HWND hRetry;
+
+/***************************************************************************
+ * OfnInit()
+ * Initializes the standard file dialog OFN structure.
+ **************************************************************************/
+
+VOID FAR OfnInit( //* ENTRY:
+ HANDLE hInst //* instance handle
+){ //* LOCAL:
+ LPSTR lpstr; //* string pointer
+
+ LoadString(hInst, IDS_FILTER, szFilterSpec, CBMESSAGEMAX);
+ LoadString(hInst, IDS_EXTENSION, szDefExtension, CBMESSAGEMAX);
+
+ OFN.lStructSize = sizeof(OPENFILENAME);
+ OFN.hInstance = hInst;
+ OFN.nMaxCustFilter = CBFILTERMAX;
+ OFN.nMaxFile = CBPATHMAX;
+ OFN.lCustData = 0;
+ OFN.lpfnHook = NULL;
+ OFN.lpTemplateName = NULL;
+ OFN.lpstrFileTitle = NULL;
+ //* Construct the filter string
+ //* for the Open and Save dialogs
+ lpstr = (LPSTR)szFilterSpec;
+ lstrcat(lpstr, " (*.");
+ lstrcat(lpstr, szDefExtension);
+ lstrcat(lpstr, ")");
+ lpstr += lstrlen(lpstr) + 1;
+
+ lstrcpy(lpstr, "*.");
+ lstrcat(lpstr, szDefExtension);
+ lpstr += lstrlen(lpstr) + 1;
+ *lpstr = 0;
+
+ RegMakeFilterSpec(NULL, NULL, (LPSTR)szInsertFilter);
+
+}
+
+/***************************************************************************
+ * OfnGetName()
+ *
+ * Calls the standard file dialogs to get a file name
+ **************************************************************************/
+
+BOOL FAR OfnGetName( //* ENTRY:
+ HWND hwnd, //* parent window handle
+ LPSTR szFileName, //* File name
+ WORD msg //* operation
+){ //* LOCAL:
+ BOOL frc; //* return flag
+ CHAR szCaption[CBMESSAGEMAX];//* dialog caption
+
+ OFN.hwndOwner = hwnd; //* window
+ OFN.nFilterIndex = 1;
+ OFN.lpstrInitialDir = (LPSTR)szLastDir;
+ OFN.Flags = OFN_HIDEREADONLY;
+
+ switch (msg) //* message
+ {
+ case IDM_OPEN: //* open file
+ Normalize(szFileName);
+ OFN.lpstrDefExt = (LPSTR)szDefExtension;
+ OFN.lpstrFile = (LPSTR)szFileName;
+ OFN.lpstrFilter = (LPSTR)szFilterSpec;
+ LoadString(hInst, IDS_OPENFILE, szCaption, CBMESSAGEMAX);
+ OFN.lpstrTitle = (LPSTR)szCaption;
+ OFN.Flags |= OFN_FILEMUSTEXIST;
+ return GetOpenFileName((LPOPENFILENAME)&OFN);
+ break;
+
+ case IDM_SAVEAS: //* save as file
+ Normalize(szFileName);
+ OFN.lpstrDefExt = (LPSTR)szDefExtension;
+ OFN.lpstrFile = (LPSTR)szFileName;
+ OFN.lpstrFilter = (LPSTR)szFilterSpec;
+ LoadString(hInst, IDS_SAVEFILE, szCaption, CBMESSAGEMAX);
+ OFN.lpstrTitle = (LPSTR)szCaption;
+ OFN.Flags |= OFN_PATHMUSTEXIST;
+ return GetSaveFileName((LPOPENFILENAME)&OFN);
+ break;
+
+ case IDM_INSERTFILE: //* insert file
+ OFN.lpstrDefExt = NULL;
+ OFN.lpstrFile = (LPSTR)szFileName;
+ OFN.lpstrFilter = (LPSTR)szInsertFilter;
+ LoadString(hInst, IDS_INSERTFILE, szCaption, CBMESSAGEMAX);
+ OFN.lpstrTitle = (LPSTR)szCaption;
+ OFN.Flags |= OFN_FILEMUSTEXIST;
+ frc = GetOpenFileName((LPOPENFILENAME)&OFN);
+ AddExtension(&OFN);
+ return frc;
+ break;
+
+ default: //* default
+ break;
+ }
+
+}
+
+/***************************************************************************
+ * OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
+ *
+ * returns LPSTR - fully qualified filename
+ **************************************************************************/
+
+LPSTR FAR OfnGetNewLinkName( //* ENTRY:
+ HWND hwnd, //* calling window or dialog
+ LPSTR lpstrData //* link data
+){ //* LOCAL:
+ LPSTR lpReturn = NULL; //* return string
+ LPSTR lpstrFile = NULL; //* non-qualified file name
+ LPSTR lpstrPath = NULL; //* pathname
+ LPSTR lpstrTemp = NULL; //* work string
+ CHAR szDocFile[CBPATHMAX];//* document name
+ CHAR szDocPath[CBPATHMAX];//* document path name
+ CHAR szServerFilter[CBPATHMAX];
+ CHAR szCaption[CBMESSAGEMAX];
+
+ //* Figure out the link's path
+ //* name and file name
+ lpstrTemp = lpstrData;
+ while (*lpstrTemp++);
+ lpstrPath = lpstrFile = lpstrTemp;
+
+ while (*(lpstrTemp = AnsiNext(lpstrTemp)))
+ if (*lpstrTemp == '\\')
+ lpstrFile = lpstrTemp + 1;
+ //* Copy the document name
+ lstrcpy(szDocFile, lpstrFile);
+ *(lpstrFile - 1) = 0;
+ //* Copy the path name
+ lstrcpy(szDocPath, ((lpstrPath != lpstrFile) ? lpstrPath : ""));
+ if (lpstrPath != lpstrFile) //* Restore the backslash
+ *(lpstrFile - 1) = '\\';
+ while (*lpstrFile != '.' && *lpstrFile)//* Get the extension
+ lpstrFile++;
+ //* Make a filter that respects
+ //* the link's class name
+ OFN.hwndOwner = hwnd;
+ OFN.nFilterIndex = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
+ OFN.lpstrDefExt = NULL;
+ OFN.lpstrFile = (LPSTR)szDocFile;
+ OFN.lpstrFilter = (LPSTR)szServerFilter;
+ OFN.lpstrInitialDir = (LPSTR)szDocPath;
+ LoadString(hInst, IDS_CHANGELINK, szCaption, CBMESSAGEMAX);
+ OFN.lpstrTitle = (LPSTR)szCaption;
+ OFN.lpstrCustomFilter = NULL;
+ OFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
+
+ //* If we get a file... */
+ if (GetOpenFileName((LPOPENFILENAME)&OFN))
+ {
+ if (!(lpReturn = GlobalLock(GlobalAlloc(LHND, CBPATHMAX))))
+ goto Error;
+
+ AddExtension(&OFN);
+ lstrcpy(lpReturn, szDocFile);
+
+ OFN.lpstrInitialDir = (LPSTR)szLastDir;
+ }
+
+ return lpReturn; //* SUCCESS return
+
+Error: //* ERROR Tag
+
+ return NULL; //* ERROR return
+
+}
+
+/***************************************************************************
+ * Normalize()
+ * Removes the path specification from the file name.
+ *
+ * Note: It isn't possible to get "<drive>:<filename>" as input because
+ * the path received will always be fully qualified.
+ **************************************************************************/
+
+VOID Normalize( //* ENTRY:
+ LPSTR lpstrFile //* file name
+){ //* LOCAL:
+ LPSTR lpstrBackslash = NULL;//* back slash
+ LPSTR lpstrTemp = lpstrFile;//* file name
+
+ while (*lpstrTemp)
+ {
+ if (*lpstrTemp == '\\')
+ lpstrBackslash = lpstrTemp;
+
+ lpstrTemp = AnsiNext(lpstrTemp);
+ }
+ if (lpstrBackslash)
+ lstrcpy(lpstrFile, lpstrBackslash + 1);
+
+}
+
+/***************************************************************************
+ * AddExtension()
+ *
+ * Adds the extension corresponding to the filter dropdown.
+ **************************************************************************/
+
+VOID AddExtension( //* ENTRY:
+ LPOPENFILENAME lpOFN //* open file structure
+){
+
+ if (lpOFN->nFileExtension == (WORD)lstrlen(lpOFN->lpstrFile)
+ && lpOFN->nFilterIndex)
+ {
+ LPSTR lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
+
+ while (*lpstrFilter && --lpOFN->nFilterIndex)
+ {
+ while (*lpstrFilter++) ;
+ while (*lpstrFilter++) ;
+ }
+ //* If we got to the filter,
+ if (*lpstrFilter) //* retrieve the extension
+ {
+ while (*lpstrFilter++) ;
+ lpstrFilter++;
+ //* Copy the extension
+ if (lpstrFilter[1] != '*')
+ lstrcat(lpOFN->lpstrFile, lpstrFilter);
+ }
+ }
+
+}
+/****************************************************************************
+ * fnInsertNew()
+ *
+ * Dialog procedure for the Insert New dialog.
+ *
+ * Returns int - TRUE if message processed, FALSE otherwise
+ ***************************************************************************/
+
+BOOL APIENTRY fnInsertNew( //* ENTRY:
+ HWND hDlg, //* standard dialog box paramters
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam //* (LPSTR) class name
+){ //* LOCAL:
+ HWND hwndList; //* handle to listbox
+ static LPSTR lpClassName; //* classname for return value
+
+ hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ if (!RegGetClassNames(hwndList))
+ EndDialog(hDlg, IDCANCEL);
+
+ lpClassName = (LPSTR)lParam;
+ SetFocus(hwndList);
+ SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
+ return (FALSE);
+
+ case WM_COMMAND:
+ {
+ WORD wID = LOWORD(wParam);
+ WORD wCmd = HIWORD(wParam);
+
+ switch (wID)
+ {
+ case IDD_LISTBOX:
+ if (wCmd != LBN_DBLCLK)
+ break;
+
+ case IDOK:
+ if (!RegCopyClassName(hwndList, lpClassName))
+ wParam = IDCANCEL;
+
+ case IDCANCEL:
+ EndDialog(hDlg, wParam);
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+
+}
+
+/***************************************************************************
+ * LinkProperties();
+ *
+ * Manage the link properties dialog box.
+ **************************************************************************/
+
+VOID FAR LinkProperties()
+{ //* LOCAL
+
+ DialogBox (
+ hInst,
+ MAKEINTRESOURCE(DTPROP),
+ hwndFrame,
+ (DLGPROC)fnProperties
+ );
+
+}
+
+/***************************************************************************
+ * fnProperties()
+ *
+ * Dialog procedure for link properties. The Links dialog allows the user to
+ * change the link options, edit/play the object, cancel the link as
+ * well change links.
+ *
+ * returns BOOL - TRUE if processed, FALSE otherwise
+ **************************************************************************/
+
+BOOL APIENTRY fnProperties( //* ENTRY:
+ HWND hDlg, //* standard dialog box parameters
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam //* (HWND) child window with focus
+){ //* LOCAL:
+ static APPITEMPTR *pLinks; //* pointer to links (associated windows)
+ static INT nLinks; //* number of links
+ static HWND hwndList; //* handle to listbox window
+ static BOOL fTry;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ hwndProp = hDlg;
+ hwndList = GetDlgItem(hDlg, IDD_LINKNAME);
+ if (!(InitLinkDlg(hDlg, &nLinks, hwndList, &pLinks)))
+ EndDialog(hDlg, TRUE);
+ UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
+ break;
+
+ case WM_COMMAND:
+ {
+ WORD wID = LOWORD(wParam);
+
+ switch (wID)
+ {
+ case IDD_CHANGE: //* change links
+ BLOCK_BUSY(fTry);
+ if (ChangeLinks(hDlg,nLinks,hwndList,pLinks))
+ DisplayUpdate(nLinks,hwndList,pLinks, FALSE);
+ return TRUE;
+
+ case IDD_FREEZE: //* cancel links
+ BLOCK_BUSY(fTry);
+ CancelLinks(hDlg,nLinks,hwndList,pLinks);
+ UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
+ return TRUE;
+
+ case IDD_UPDATE: //* update links
+ BLOCK_BUSY(fTry);
+ DisplayUpdate(nLinks,hwndList,pLinks,TRUE);
+ UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
+ return TRUE;
+
+ case IDD_AUTO:
+ case IDD_MANUAL: //* change link update options
+ BLOCK_BUSY(fTry);
+ if (!SendMessage(GetDlgItem(hDlg,wParam),BM_GETCHECK, 0, 0L))
+ {
+ CheckRadioButton(hDlg, IDD_AUTO ,IDD_MANUAL ,wParam);
+ ChangeUpdateOptions(hDlg,nLinks,hwndList,pLinks,
+ (wParam == IDD_AUTO ? oleupdate_always : oleupdate_oncall));
+ UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
+ }
+ return TRUE;
+
+ case IDD_LINKNAME:
+ if (HIWORD(wParam) == LBN_SELCHANGE)
+ UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
+ return TRUE;
+
+ case IDCANCEL:
+ BLOCK_BUSY(fTry);
+ UndoObjects();
+ END_PROP_DLG(hDlg,pLinks);
+ return TRUE;
+
+ case IDOK:
+ BLOCK_BUSY(fTry);
+ DelUndoObjects(FALSE);
+ END_PROP_DLG(hDlg,pLinks);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/****************************************************************************
+ * InitLinkDlg();
+ *
+ * Initialize the list box of links.
+ ***************************************************************************/
+
+static BOOL InitLinkDlg ( //* ENTRY:
+ HWND hDlg, //* dialog box handle
+ INT *nLinks, //* pointer to number of links
+ HWND hwndList, //* listbox handle
+ APPITEMPTR **pLinks //* list of window handles of links
+){ //* LOCAL
+ APPITEMPTR pItem; //* application item pointer
+ LPSTR lpstrData = NULL; //* pointer to link data
+ CHAR szFull[CBMESSAGEMAX * 4];//* list box entry string
+ CHAR pLinkData[OBJECT_LINK_MAX];//* holder of link data
+ BOOL fSelect = FALSE; //* item selected flag
+ HANDLE hWork; //* working memory handle
+ APPITEMPTR pTop; //* pointer to the top object
+
+ if (!(*pLinks = (APPITEMPTR *)LocalLock(LocalAlloc(LHND,sizeof(APPITEMPTR)*10))))
+ {
+ ErrorMessage(E_FAILED_TO_ALLOC);
+ return 0;
+ }
+ *nLinks = 0;
+ //* set tabs
+ SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
+ //* enumerate child windows
+ for (pTop = pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
+ {
+ if (pItem->otObject == OT_LINK && pItem->fVisible)
+ {
+ *(*pLinks + *nLinks) = pItem;
+ if (!((*nLinks += 1)%10))
+ { //* add blocks of ten
+ hWork = LocalHandle((LPSTR)(*pLinks));
+ LocalUnlock(hWork);
+ if (!(hWork = LocalReAlloc(hWork,(*nLinks+10)*sizeof(APPITEMPTR),0)))
+ {
+ ErrorMessage(E_FAILED_TO_ALLOC);
+ return FALSE; //* ERROR return
+ }
+ *pLinks = (APPITEMPTR *)LocalLock(hWork);
+ }
+
+ if (pTop == pItem)
+ fSelect = TRUE;
+
+ if (!ObjGetData(pItem, pLinkData))
+ continue;
+ //* make listbox entry
+ MakeListBoxString(pLinkData, szFull, pItem->uoObject);
+ //* add listbox entry
+ SendMessage(hwndList, LB_ADDSTRING, 0, (LONG)(LPSTR)szFull);
+ }
+ }
+
+ if (fSelect)
+ SendMessage(hwndList, LB_SETSEL, 1, 0L);
+
+ SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
+ UpdateWindow(hwndList);
+
+ return TRUE; //* SUCCESS return
+
+}
+
+/****************************************************************************
+ * MakeListBoxString()
+ *
+ * build an listbox entry string
+ ***************************************************************************/
+
+static VOID MakeListBoxString( //* ENTRY:
+ LPSTR lpLinkData, //* pointer to link data
+ LPSTR lpBoxData, //* return string
+ OLEOPT_UPDATE oleopt_update //* OLE update option
+){ //* LOCAL:
+ CHAR szType[CBMESSAGEMAX];//* holds update option string
+ LPSTR lpTemp; //* working string pointer
+ INT i; //* index
+
+ //* get classname
+ RegGetClassId(lpBoxData, lpLinkData);
+ lstrcat(lpBoxData, " - "); //* ads tab
+
+ while (*lpLinkData++); //* skip to document name
+
+ lpTemp = lpLinkData;
+ while (*lpTemp) //* copy document name;
+ { //* strip drive an directory
+ if (*lpTemp == '\\' || *lpTemp == ':')
+ lpLinkData = lpTemp + 1;
+ lpTemp = AnsiNext(lpTemp);
+ }
+ lstrcat(lpBoxData, lpLinkData);
+ lstrcat(lpBoxData, " - ");
+
+ while (*lpLinkData++); //* copy item data
+ lstrcat(lpBoxData, lpLinkData);
+ lstrcat(lpBoxData, " - ");
+ //* add update option string
+ switch (oleopt_update)
+ {
+ case oleupdate_always: i = SZAUTO; break;
+ case oleupdate_oncall: i = SZMANUAL; break;
+ default: i = SZFROZEN;
+ }
+ LoadString(hInst, i, szType, CBMESSAGEMAX);
+ lstrcat(lpBoxData, szType);
+
+} //* SUCCESS return
+
+/***************************************************************************
+ * UpdateLinkButtons()
+ *
+ * Keep link buttons active as appropriate. This routine is called after
+ * a selection is made so the buttons reflect the selected items.
+ **************************************************************************/
+
+static VOID UpdateLinkButtons( //* ENTRY:
+ HWND hDlg, //* dialog box handle
+ INT nLinks, //* number of links
+ HWND hwndList, //* listbox handle
+ APPITEMPTR *pLinks //* pointer to link's window handles
+){ //* LOCAL:
+ ATOM aCurName=0; //* atom of current doc
+ BOOL fChangeLink = TRUE; //* enable/disable changelink button
+ INT iAuto,iManual,i; //* count of manual and auto links
+ APPITEMPTR pItem; //* application item pointer
+ INT iStatic;
+
+ iStatic = iAuto = iManual = 0;
+
+ for (i = 0; i < nLinks; i++) //* enum selected links
+ {
+ if (SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ if (pItem->otObject == OT_STATIC)
+ iStatic++;
+ else
+ {
+ switch(pItem->uoObject)
+ { //* count number of manual and
+ case oleupdate_always: //* automatic links selected
+ iAuto++;
+ break;
+ case oleupdate_oncall:
+ iManual++;
+ break;
+ }
+ //* check if all selected links are
+ if (!aCurName) //* linked to same file
+ aCurName = pItem->aLinkName;
+ else if (aCurName != pItem->aLinkName)
+ fChangeLink = FALSE;
+ }
+ }
+ }
+
+ if (!(iAuto || iManual || iStatic) //* if no links disable all buttons
+ || (!iAuto && !iManual && iStatic))
+ {
+ EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE );
+ EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), FALSE );
+ EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE );
+ CheckDlgButton(hDlg, IDD_AUTO, FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
+ CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), TRUE );
+ EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), TRUE );
+
+ if (iAuto && iManual || !(iAuto || iManual))
+ { //* Set update buttons
+ CheckDlgButton(hDlg, IDD_AUTO, FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
+ CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDD_AUTO), TRUE);
+ if (iAuto)
+ {
+ CheckDlgButton(hDlg, IDD_AUTO, TRUE);
+ CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
+ }
+ else
+ {
+ CheckDlgButton(hDlg, IDD_AUTO, FALSE);
+ CheckDlgButton(hDlg, IDD_MANUAL, TRUE);
+ }
+ }
+ }
+
+ EnableWindow(GetDlgItem(hDlg, IDD_CHANGE),fChangeLink && aCurName);
+
+}
+
+/****************************************************************************
+ * ChangeLinks()
+ *
+ * This routine changes the linked data if the user chooses a new file to
+ * replace the old document data portion of the linked date. The routine
+ * does nothing if the user cancels.
+ *
+ * returns TRUE - if data changed FALSE if user cancel or err.
+ ***************************************************************************/
+
+static BOOL ChangeLinks( //* ENTRY:
+ HWND hDlg, //* dialog handle
+ INT nLinks, //* number of links in listbox
+ HWND hwndList, //* listbox
+ APPITEMPTR *pLinks //* list of application link handles
+){ //* LOCAL
+ INT i; //* general index
+ HANDLE hWork; //* work
+ APPITEMPTR pItem; //* application item
+ LPSTR lpNewDoc = NULL; //* new document
+ ATOM aOldDoc; //* atom of old doc. name
+ ATOM aCurDoc = 0; //* atom of change-to doc. name
+ BOOL fMessage = FALSE; //* error message flag
+ LPSTR lpLinkData; //* pointer to link data
+
+ lpLinkData = NULL;
+ //* This loop finds all selected links
+ for (i = 0; i < nLinks; i++) //* and updates them
+ {
+ if (SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ CHECK_IF_STATIC(pItem);
+
+ pItem->lpLinkData = lpLinkData;
+ if (!ObjGetData(pItem,NULL))
+ continue;
+
+ if (!lpNewDoc)
+ {
+ if (!(lpNewDoc = OfnGetNewLinkName(hDlg, pItem->lpLinkData)))
+ return FALSE; //* ERROR jump
+ aOldDoc = pItem->aLinkName;
+ aCurDoc = AddAtom(lpNewDoc);
+ SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
+ }
+
+ ObjSaveUndo(pItem);
+ ObjChangeLinkData(pItem,lpNewDoc);
+ pItem->aLinkName = aCurDoc;
+ lpLinkData = pItem->lpLinkData;
+
+ CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
+
+ pItem->lpLinkData = NULL;
+ }
+ }
+
+ /*************************************************************************
+ * now deal with non-selected links and look for a match...
+ *************************************************************************/
+
+ //* this loop finds non-selected links
+ for (i = 0; i < nLinks; i++) //* and asks the user to update these?
+ {
+ if (!SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ if (pItem->otObject == OT_STATIC)
+ continue;
+
+ if (!ObjGetData(pItem,NULL))
+ continue;
+
+ if (pItem->aLinkName == aOldDoc)
+ {
+ if (!fMessage)
+ {
+ CHAR szMessage[2*CBMESSAGEMAX+3*CBPATHMAX];
+ CHAR szRename[2*CBMESSAGEMAX];
+ CHAR szOldDoc[CBMESSAGEMAX];
+ LPSTR pOldDoc;
+
+ GetAtomName(aOldDoc,szOldDoc,CBMESSAGEMAX);
+ pOldDoc =(LPSTR)UnqualifyPath(szOldDoc);
+ LoadString(hInst, IDS_RENAME, szRename, 2*CBMESSAGEMAX);
+ wsprintf(
+ szMessage,
+ szRename,
+ pOldDoc,
+ (LPSTR)UnqualifyPath(szFileName),
+ pOldDoc
+ );
+
+ if (MessageBox(hDlg, szMessage,
+ szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
+ break;
+ fMessage = TRUE;
+ }
+
+ ObjSaveUndo(pItem);
+ ObjChangeLinkData(pItem,lpNewDoc);
+ CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
+
+ pItem->aLinkName = aCurDoc;
+ }
+ }
+ }
+
+ if(lpNewDoc)
+ {
+ hWork = GlobalHandle(lpNewDoc);
+ GlobalUnlock(hWork);
+ GlobalFree(hWork);
+ }
+
+#if 0
+// This is bogus -- this memory is owned by OLECLI32.DLL, not this app,
+// so it should not be freed here.
+ if (lpLinkData)
+ FreeLinkData(lpLinkData);
+#endif
+
+ SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
+ InvalidateRect(hwndList,NULL,TRUE);
+ UpdateWindow(hwndList);
+
+ WaitForAllObjects();
+
+ if (aCurDoc)
+ DeleteAtom(aCurDoc);
+
+ return(TRUE);
+}
+
+/****************************************************************************
+ * DisplayUpdate()
+ *
+ * Get the most up to date rendering information and show it.
+ ***************************************************************************/
+
+static VOID DisplayUpdate( //* ENTRY:
+ INT nLinks, //* number of links in listbox
+ HWND hwndList, //* listbox
+ APPITEMPTR *pLinks, //* list of application link handles
+ BOOL fSaveUndo //* save undo objects
+){ //* LOCAL:
+ INT i; //* index
+ APPITEMPTR pItem; //* temporary item pointer
+
+
+ for (i = 0; i < nLinks; i++)
+ if (SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ CHECK_IF_STATIC(pItem);
+ if (fSaveUndo)
+ ObjSaveUndo(pItem);
+ Error(OleUpdate(pItem->lpObject));
+ }
+
+ WaitForAllObjects();
+
+}
+
+/****************************************************************************
+ * UndoObjects()
+ *
+ * Bring objects back to their original state.
+ ***************************************************************************/
+
+static VOID UndoObjects()
+{
+ APPITEMPTR pItem; //* application item pointer
+ //* enum objects
+ for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
+ if (pItem->lpObjectUndo)
+ ObjUndo(pItem);
+
+ WaitForAllObjects();
+
+}
+
+
+/****************************************************************************
+ * DelUndoObjects()
+ *
+ * remove all objects created for undo operation.
+ ***************************************************************************/
+
+static VOID DelUndoObjects( //* ENTRY:
+ BOOL fPrompt //* prompt user?
+){ //* LOCAL:
+ APPITEMPTR pItem; //* application item pointer
+ BOOL fPrompted = FALSE; //* prompted user?
+
+ for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
+ {
+ if (pItem->lpObjectUndo)
+ {
+ if (fPrompt && !fPrompted) //* prompt user in activation case
+ {
+ CHAR szPrompt[CBMESSAGEMAX];
+
+ LoadString(hInst, IDS_SAVE_CHANGES, szPrompt, CBMESSAGEMAX);
+
+ if (MessageBox(hwndFrame, szPrompt,
+ szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
+ {
+ UndoObjects();
+ return; //* user canceled operation
+ }
+ fPrompted = TRUE;
+ }
+ ObjDelUndo(pItem); //* delete udo object
+ }
+ }
+
+ WaitForAllObjects();
+
+} //* SUCCESS return
+
+/****************************************************************************
+ * CancelLinks()
+ ***************************************************************************/
+
+static VOID CancelLinks( //* ENTRY:
+ HWND hDlg, //* calling dialog
+ INT nLinks, //* number of links in listbox
+ HWND hwndList, //* listbox
+ APPITEMPTR *pLinks //* list of application link handles
+){ //* LOCAL:
+ APPITEMPTR pItem; //* application item pointer
+ INT i; //* index
+ CHAR pLinkData[OBJECT_LINK_MAX];//* holder of link data
+
+ SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
+ for (i = 0; i < nLinks; i++)
+ if (SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ CHECK_IF_STATIC(pItem);
+ ObjGetData(pItem,pLinkData);
+ ObjSaveUndo(pItem);
+ ObjFreeze(pItem);
+
+ CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
+ }
+
+ SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
+ InvalidateRect(hwndList,NULL,TRUE);
+ UpdateWindow(hwndList);
+
+}
+
+
+/****************************************************************************
+ * ChangeUpdateOptions()
+ *
+ * Change the update options for all selected objects.
+ ***************************************************************************/
+
+static VOID ChangeUpdateOptions( //* ENTRY:
+ HWND hDlg, //* calling dialog
+ INT nLinks, //* number of links in listbox
+ HWND hwndList, //* listbox
+ APPITEMPTR *pLinks, //* list of application link handles
+ OLEOPT_UPDATE lUpdate //* update option
+){ //* LOCAL:
+ APPITEMPTR pItem; //* application item
+ INT i; //* index
+ CHAR pLinkData[OBJECT_LINK_MAX];
+
+ SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
+
+ for (i = 0; i < nLinks; i++) //* enum selected objects
+ {
+ if (SendMessage(hwndList, LB_GETSEL, i, 0L))
+ {
+ pItem = *(pLinks+i);
+ CHECK_IF_STATIC(pItem);
+ ObjGetData(pItem,pLinkData);
+ ObjSaveUndo(pItem);
+ if (Error(OleSetLinkUpdateOptions(pItem->lpObject,lUpdate)))
+ continue;
+ pItem->uoObject = lUpdate;
+
+ CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
+ }
+ }
+
+ SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
+ InvalidateRect(hwndList,NULL,TRUE);
+ UpdateWindow(hwndList);
+ WaitForAllObjects();
+
+}
+/****************************************************************************
+ * InvalidLink()
+ *
+ * Deal with letting the user know that the program has inadvertently come
+ * across an invalid link.
+ *
+ * Global fPropBoxActive - flag to determine whether or not the link dialog
+ * box is active. If it is not active we give the
+ * user an opportunity to enter the links property
+ * dialog directly from here.
+ ***************************************************************************/
+
+VOID FAR InvalidLink()
+{
+
+ if (!hwndProp)
+ DialogBox(hInst, "InvalidLink", hwndFrame, (DLGPROC)fnInvalidLink);
+ else
+ ErrorMessage(E_FAILED_TO_CONNECT);
+
+}
+
+/****************************************************************************
+ * fnABout()
+ *
+ * About box dialog box procedure.
+ ***************************************************************************/
+
+BOOL APIENTRY fnInvalidLink( //* ENTRY:
+ HWND hDlg, //* standard windows dialog box
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+){
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return (TRUE);
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDD_CHANGE)
+ LinkProperties();
+ EndDialog(hDlg, TRUE);
+ return (TRUE);
+ }
+ return (FALSE);
+
+}
+
+/****************************************************************************
+ * AboutBox()
+ *
+ * Show the About Box dialog.
+ ***************************************************************************/
+
+VOID FAR AboutBox()
+{
+
+ DialogBox(hInst, "AboutBox", hwndFrame, (DLGPROC)fnAbout);
+
+}
+
+/****************************************************************************
+ * fnABout()
+ *
+ * About box dialog box procedure.
+ ***************************************************************************/
+
+BOOL APIENTRY fnAbout( //* ENTRY:
+ HWND hDlg, //* standard windows dialog box
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+){
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return (TRUE);
+
+ case WM_COMMAND:
+ {
+ WORD wID = LOWORD(wParam);
+
+ if (wID == IDOK || wID == IDCANCEL)
+ {
+ EndDialog(hDlg, TRUE);
+ return (TRUE);
+ }
+ break;
+ }
+ }
+ return (FALSE);
+
+}
+
+
+
+/***************************************************************************
+ * RetryMessage()
+ *
+ * give the user the chance to abort when a server is in retry case.
+ *
+ * Returns BOOL - TRUE if user chooses to cancel
+ **************************************************************************/
+
+VOID FAR RetryMessage ( //* ENTRY:
+ APPITEMPTR paItem, //* application item pointer
+ LONG lParam
+){
+ RETRYPTR pRetry;
+ LONG objectType;
+ HANDLE hData;
+ static CHAR szServerName[KEYNAMESIZE];
+ HWND hwnd; //* window handle
+
+ if (IsWindow(hwndProp))
+ hwnd = hwndProp;
+ else if (IsWindow(hwndFrame))
+ hwnd = hwndFrame;
+ else
+ return; //* should not happen
+ //* get the busy servers name
+ lstrcpy(szServerName, "server application");
+
+ if (paItem)
+ {
+ if (!paItem->aServer)
+ {
+ OleQueryType(paItem->lpObject, &objectType );
+ if (OLE_OK == OleGetData(paItem->lpObject, (OLECLIPFORMAT) (objectType == OT_LINK ? vcfLink : vcfOwnerLink), &hData ))
+ {
+ RegGetClassId(szServerName, GlobalLock(hData));
+ paItem->aServer = AddAtom(szServerName);
+ GlobalUnlock( hData );
+ }
+ }
+ else
+ GetAtomName(paItem->aServer,szServerName,KEYNAMESIZE);
+
+ }
+
+ hData = LocalAlloc(LHND,sizeof(RETRYSTRUCT));
+ if(!(pRetry = (RETRYPTR)LocalLock(hData)))
+ return;
+
+ pRetry->lpserver = (LPSTR)szServerName;
+ pRetry->bCancel = (BOOL)(lParam & RD_CANCEL);
+ pRetry->paItem = paItem;
+
+ DialogBoxParam(hInst, "RetryBox", hwnd, (DLGPROC)fnRetry, (LONG)pRetry );
+
+ LocalUnlock(hData);
+ LocalFree(hData);
+
+ hRetry = NULL;
+
+}
+
+/****************************************************************************
+ * fnRetry()
+ *
+ * Retry message box nothing to tricky; however, when a server becomes
+ * unbusy a message is posted to automatically get rid of this dialog.
+ * I send a no.
+ ***************************************************************************/
+
+BOOL APIENTRY fnRetry( //* ENTRY
+ HWND hDlg, //* standard dialog entry
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+){
+ static RETRYPTR pRetry;
+
+ switch (message)
+ {
+ case WM_COMMAND:
+ {
+ WORD wID = LOWORD(wParam);
+
+ switch (wParam)
+ {
+ case IDD_SWITCH:
+ DefWindowProc( hDlg, WM_SYSCOMMAND, SC_TASKLIST, 0);
+ break;
+
+ case IDCANCEL:
+ if (pRetry->paItem)
+ pRetry->paItem->fRetry = FALSE;
+ EndDialog(hDlg, TRUE);
+ return TRUE;
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ case WM_INITDIALOG:
+ {
+ CHAR szBuffer[CBMESSAGEMAX];
+ CHAR szText[2*CBMESSAGEMAX];
+
+ pRetry = (RETRYPTR)lParam;
+ hRetry = hDlg;
+
+ LoadString(hInst, IDS_RETRY_TEXT1, szBuffer, CBMESSAGEMAX);
+ wsprintf(szText, szBuffer, pRetry->lpserver);
+ SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT1), szText);
+
+ LoadString(hInst, IDS_RETRY_TEXT2, szBuffer, CBMESSAGEMAX);
+ wsprintf(szText, szBuffer, pRetry->lpserver);
+ SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT2), szText);
+
+ EnableWindow (GetDlgItem(hDlg, IDCANCEL), pRetry->bCancel);
+
+ return TRUE;
+ }
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}