diff options
Diffstat (limited to 'private/oleutest/ole1/clidemo/dialog.c')
-rw-r--r-- | private/oleutest/ole1/clidemo/dialog.c | 1150 |
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; +} |