home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 17.ddi / SAMPLES / CLIDEMO / DIALOG.C_ / DIALOG.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  38.3 KB  |  1,148 lines

  1. /*
  2.  * dialog.c - Handles the Windows 3.1 common dialogs.
  3.  *
  4.  * Created by Microsoft Corporation.
  5.  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
  6.  */
  7.  
  8. //--- INCLUDES ---
  9. //The order of the includes matters for compile efficiency ... /YX
  10.  
  11. #include <windows.h>                   //- WINDOWS
  12. #include <ole.h>                       //- OLE
  13. #include "demorc.h"                       //- String table constants
  14. #include "global.h"                    //- global
  15.  
  16. #include "register.h"                    //- Class registration library
  17. #include "utility.h"
  18. #include "dialog.h"
  19. #include "object.h"
  20.  
  21. //--- GLOBALS ---
  22.                                        //- strings used with commdlg
  23. char        szDefExtension[CBMESSAGEMAX];
  24. char        szFilterSpec[CBFILTERMAX];
  25. char        szInsertFilter[CBFILTERMAX];
  26. char        szLastDir[CBPATHMAX];
  27. OPENFILENAME OFN;
  28. HWND        hwndProp = NULL;
  29. HWND        hRetry;
  30.  
  31. /***************************************************************************
  32.  * OfnInit()
  33.  * Initializes the standard file dialog OFN structure.
  34.  **************************************************************************/
  35.  
  36. void FAR OfnInit(                      //- ENTRY:
  37.    HANDLE         hInst                //- instance handle
  38. ){                                     //- LOCAL:
  39.    LPSTR          lpstr;               //- string pointer
  40.  
  41.    LoadString(hInst, IDS_FILTER, szFilterSpec, CBMESSAGEMAX);
  42.    LoadString(hInst, IDS_EXTENSION, szDefExtension, CBMESSAGEMAX);
  43.  
  44.    OFN.lStructSize    = sizeof(OPENFILENAME);
  45.    OFN.hInstance      = hInst;
  46.    OFN.nMaxCustFilter = CBFILTERMAX;
  47.    OFN.nMaxFile       = CBPATHMAX;
  48.    OFN.lCustData      = NULL;
  49.    OFN.lpfnHook       = NULL;
  50.    OFN.lpTemplateName = NULL;
  51.    OFN.lpstrFileTitle = NULL;
  52.                                        //- Construct the filter string
  53.                                        //- for the Open and Save dialogs
  54.    lpstr = (LPSTR)szFilterSpec;
  55.    lstrcat(lpstr, " (*.");
  56.    lstrcat(lpstr, szDefExtension);
  57.    lstrcat(lpstr, ")");
  58.    lpstr += lstrlen(lpstr) + 1;
  59.  
  60.    lstrcpy(lpstr, "*.");
  61.    lstrcat(lpstr, szDefExtension);
  62.    lpstr += lstrlen(lpstr) + 1;
  63.    *lpstr = 0;
  64.  
  65.    RegMakeFilterSpec(NULL, NULL, (LPSTR)szInsertFilter);
  66.  
  67. }
  68.  
  69. /***************************************************************************
  70.  * OfnGetName()
  71.  *
  72.  * Calls the standard file dialogs to get a file name
  73.  **************************************************************************/
  74.  
  75. BOOL FAR OfnGetName(                   //- ENTRY:
  76.    HWND           hwnd,                //- parent window handle
  77.    LPSTR          szFileName,          //- File name
  78.    WORD           msg                  //- operation
  79. ){                                     //- LOCAL:
  80.    BOOL           frc;                 //- return flag
  81.    char           szCaption[CBMESSAGEMAX];//- dialog caption
  82.  
  83.    OFN.hwndOwner       = hwnd;               //- window
  84.    OFN.nFilterIndex    = 1;
  85.    OFN.lpstrInitialDir = (LPSTR)szLastDir;
  86.    OFN.Flags           = OFN_HIDEREADONLY;
  87.  
  88.    switch (msg)                        //- message
  89.    {
  90.       case IDM_OPEN:                   //- open file
  91.          Normalize(szFileName);
  92.          OFN.lpstrDefExt = (LPSTR)szDefExtension;
  93.          OFN.lpstrFile   = (LPSTR)szFileName;
  94.          OFN.lpstrFilter = (LPSTR)szFilterSpec;
  95.          LoadString(hInst, IDS_OPENFILE, szCaption, CBMESSAGEMAX);
  96.          OFN.lpstrTitle  = (LPSTR)szCaption;
  97.          OFN.Flags       |= OFN_FILEMUSTEXIST;
  98.          return GetOpenFileName((LPOPENFILENAME)&OFN);
  99.          break;
  100.  
  101.       case IDM_SAVEAS:                 //- save as file
  102.          Normalize(szFileName);
  103.          OFN.lpstrDefExt = (LPSTR)szDefExtension;
  104.          OFN.lpstrFile   = (LPSTR)szFileName;
  105.          OFN.lpstrFilter = (LPSTR)szFilterSpec;
  106.          LoadString(hInst, IDS_SAVEFILE, szCaption, CBMESSAGEMAX);
  107.          OFN.lpstrTitle  = (LPSTR)szCaption;
  108.          OFN.Flags       |= OFN_PATHMUSTEXIST;
  109.          return GetSaveFileName((LPOPENFILENAME)&OFN);
  110.          break;
  111.  
  112.       case IDM_INSERTFILE:             //- insert file
  113.          OFN.lpstrDefExt = NULL;
  114.          OFN.lpstrFile   = (LPSTR)szFileName;
  115.          OFN.lpstrFilter = (LPSTR)szInsertFilter;
  116.          LoadString(hInst, IDS_INSERTFILE, szCaption, CBMESSAGEMAX);
  117.          OFN.lpstrTitle  = (LPSTR)szCaption;
  118.          OFN.Flags      |= OFN_FILEMUSTEXIST;
  119.          frc             = GetOpenFileName((LPOPENFILENAME)&OFN);
  120.          AddExtension(&OFN);
  121.          return frc;
  122.          break;
  123.  
  124.       default:                         //- default
  125.          break;
  126.    }
  127.  
  128. }
  129.  
  130. /***************************************************************************
  131.  * OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
  132.  *
  133.  * returns LPSTR - fully qualified filename
  134.  **************************************************************************/
  135.  
  136. LPSTR FAR OfnGetNewLinkName(           //- ENTRY:
  137.    HWND           hwnd,                //- calling window or dialog
  138.    LPSTR          lpstrData            //- link data
  139. ){                                     //- LOCAL:
  140.    LPSTR          lpReturn = NULL;     //- return string
  141.    LPSTR          lpstrFile = NULL;    //- non-qualified file name
  142.    LPSTR          lpstrPath = NULL;    //- pathname
  143.    LPSTR          lpstrTemp = NULL;    //- work string
  144.    char           szDocFile[CBPATHMAX];//- document name
  145.    char           szDocPath[CBPATHMAX];//- document path name
  146.    char           szServerFilter[CBPATHMAX];
  147.    char           szCaption[CBMESSAGEMAX];
  148.  
  149.                                        //- Figure out the link's path
  150.                                        //- name and file name
  151.    lpstrTemp = lpstrData;
  152.    while (*lpstrTemp++);
  153.    lpstrPath = lpstrFile = lpstrTemp;
  154.  
  155.    while (*(lpstrTemp = AnsiNext(lpstrTemp)))
  156.       if (*lpstrTemp == '\\')
  157.          lpstrFile = lpstrTemp + 1;
  158.                                         //- Copy the document name
  159.    lstrcpy(szDocFile, lpstrFile);
  160.    *(lpstrFile - 1) = 0;
  161.                                           //- Copy the path name
  162.    lstrcpy(szDocPath, ((lpstrPath != lpstrFile) ? lpstrPath : ""));
  163.    if (lpstrPath != lpstrFile)           //- Restore the backslash
  164.       *(lpstrFile - 1) = '\\';
  165.    while (*lpstrFile != '.' && *lpstrFile)//- Get the extension
  166.     lpstrFile++;
  167.                                           //- Make a filter that respects
  168.                                           //- the link's class name
  169.    OFN.hwndOwner       = hwnd;
  170.    OFN.nFilterIndex    = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
  171.    OFN.lpstrDefExt     = NULL;
  172.    OFN.lpstrFile       = (LPSTR)szDocFile;
  173.    OFN.lpstrFilter     = (LPSTR)szServerFilter;
  174.    OFN.lpstrInitialDir = (LPSTR)szDocPath;
  175.    LoadString(hInst, IDS_CHANGELINK, szCaption, CBMESSAGEMAX);
  176.    OFN.lpstrTitle     = (LPSTR)szCaption;
  177.    OFN.lpstrCustomFilter = NULL;
  178.    OFN.Flags          = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  179.  
  180.                                            //- If we get a file... */
  181.    if (GetOpenFileName((LPOPENFILENAME)&OFN))
  182.    {
  183.       if (!(lpReturn = GlobalLock(GlobalAlloc(LHND, CBPATHMAX))))
  184.          goto Error;
  185.  
  186.       AddExtension(&OFN);
  187.       lstrcpy(lpReturn, szDocFile);
  188.  
  189.       OFN.lpstrInitialDir = (LPSTR)szLastDir;
  190.    }
  191.  
  192.    return lpReturn;                    //- SUCCESS return
  193.  
  194. Error:                                 //- ERROR Tag
  195.  
  196.    return NULL;                        //- ERROR return
  197.  
  198. }
  199.  
  200. /***************************************************************************
  201.  * Normalize()
  202.  * Removes the path specification from the file name.
  203.  *
  204.  * Note:  It isn't possible to get "<drive>:<filename>" as input because
  205.  *        the path received will always be fully qualified.
  206.  **************************************************************************/
  207.  
  208. void Normalize(                        //- ENTRY:
  209.    LPSTR          lpstrFile            //- file name
  210. ){                                     //- LOCAL:
  211.    LPSTR          lpstrBackslash = NULL;//- back slash
  212.    LPSTR          lpstrTemp = lpstrFile;//- file name
  213.  
  214.    while (*lpstrTemp)
  215.    {
  216.       if (*lpstrTemp == '\\')
  217.          lpstrBackslash = lpstrTemp;
  218.  
  219.       lpstrTemp = AnsiNext(lpstrTemp);
  220.    }
  221.    if (lpstrBackslash)
  222.       lstrcpy(lpstrFile, lpstrBackslash + 1);
  223.  
  224. }
  225.  
  226. /***************************************************************************
  227.  * AddExtension()
  228.  *
  229.  * Adds the extension corresponding to the filter dropdown.
  230.  **************************************************************************/
  231.  
  232. void AddExtension(                     //- ENTRY:
  233.    LPOPENFILENAME lpOFN                //- open file structure
  234. ){
  235.  
  236.    if (lpOFN->nFileExtension == (WORD)lstrlen(lpOFN->lpstrFile)
  237.          && lpOFN->nFilterIndex)
  238.    {
  239.       LPSTR   lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
  240.  
  241.       while (*lpstrFilter && --lpOFN->nFilterIndex)
  242.       {
  243.          while (*lpstrFilter++) ;
  244.          while (*lpstrFilter++) ;
  245.       }
  246.                                        //- If we got to the filter,
  247.       if (*lpstrFilter)                //- retrieve the extension
  248.       {
  249.          while (*lpstrFilter++) ;
  250.          lpstrFilter++;
  251.                                        //- Copy the extension
  252.          if (lpstrFilter[1] != '*')
  253.             lstrcat(lpOFN->lpstrFile, lpstrFilter);
  254.       }
  255.    }
  256.  
  257. }
  258. /****************************************************************************
  259.  *  fnInsertNew()
  260.  *
  261.  *  Dialog procedure for the Insert New dialog.
  262.  *
  263.  *  Returns int - TRUE if message processed, FALSE otherwise
  264.  ***************************************************************************/
  265.  
  266. BOOL FAR PASCAL __export fnInsertNew(  //- ENTRY:
  267.    HWND           hDlg,                //- standard dialog box paramters
  268.    unsigned       msg,
  269.    WORD           wParam,
  270.    LONG           lParam               //- (LPSTR) class name
  271. ){                                     //- LOCAL:
  272.    HWND           hwndList;            //- handle to listbox
  273.    static LPSTR   lpClassName;         //- classname for return value
  274.  
  275.    hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
  276.  
  277.    switch (msg)
  278.    {
  279.       case WM_INITDIALOG:
  280.          if (!RegGetClassNames(hwndList))
  281.             EndDialog(hDlg, IDCANCEL);
  282.  
  283.          lpClassName = (LPSTR)lParam;
  284.          SetFocus(hwndList);
  285.          SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
  286.          return (FALSE);
  287.  
  288.       case WM_COMMAND:
  289.          switch (wParam)
  290.          {
  291.             case IDD_LISTBOX:
  292.                if (HIWORD(lParam) != LBN_DBLCLK)
  293.                break;
  294.  
  295.             case IDOK:
  296.                if (!RegCopyClassName(hwndList, lpClassName))
  297.                   wParam = IDCANCEL;
  298.  
  299.             case IDCANCEL:
  300.                EndDialog(hDlg, wParam);
  301.                break;
  302.          }
  303.          break;
  304.    }
  305.    return FALSE;
  306.  
  307. }
  308.  
  309. /***************************************************************************
  310.  * LinkProperties();
  311.  *
  312.  * Manage the link properties dialog box.
  313.  **************************************************************************/
  314.  
  315. void FAR LinkProperties()
  316. {                                      //- LOCAL
  317.    FARPROC        lpfnProperties;      //- Properties
  318.  
  319.    lpfnProperties   = MakeProcInstance(fnProperties, hInst);
  320.    DialogBox (
  321.       hInst,
  322.       MAKEINTRESOURCE(DTPROP),
  323.       hwndFrame,
  324.       lpfnProperties
  325.    );
  326.    FreeProcInstance(lpfnProperties);
  327.  
  328. }
  329.  
  330. /***************************************************************************
  331.  * fnProperties()
  332.  *
  333.  * Dialog procedure for link properties. The Links dialog allows the user to
  334.  * change the link options, edit/play the object, cancel the link as
  335.  * well change links.
  336.  *
  337.  *    returns BOOL - TRUE if processed, FALSE otherwise
  338.  **************************************************************************/
  339.  
  340. BOOL FAR PASCAL __export fnProperties(          //- ENTRY:
  341.    HWND           hDlg,                //- standard dialog box parameters
  342.    unsigned       msg,
  343.    WORD           wParam,
  344.    LONG           lParam               //- (HWND) child window with focus
  345. ){                                     //- LOCAL:
  346.   static APPITEMPTR *pLinks;           //- pointer to links (associated windows)
  347.   static int      nLinks;              //- number of links
  348.   static HWND     hwndList;            //- handle to listbox window
  349.   static BOOL     fTry;
  350.  
  351.    switch (msg)
  352.    {
  353.        case WM_INITDIALOG:
  354.          hwndProp = hDlg;
  355.          hwndList = GetDlgItem(hDlg, IDD_LINKNAME);
  356.          if (!(InitLinkDlg(hDlg, &nLinks, hwndList, &pLinks)))
  357.             EndDialog(hDlg, TRUE);
  358.          UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  359.          break;
  360.  
  361.       case WM_COMMAND:
  362.       {
  363.          switch (wParam)
  364.          {
  365.            case IDD_CHANGE:            //- change links
  366.                BLOCK_BUSY(fTry);
  367.                if (ChangeLinks(hDlg,nLinks,hwndList,pLinks))
  368.                   DisplayUpdate(nLinks,hwndList,pLinks, FALSE);
  369.                return TRUE;
  370.  
  371.            case IDD_FREEZE:            //- cancel links
  372.                BLOCK_BUSY(fTry);
  373.                CancelLinks(hDlg,nLinks,hwndList,pLinks);
  374.                UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  375.                return TRUE;
  376.  
  377.            case IDD_UPDATE:            //- update links
  378.                BLOCK_BUSY(fTry);
  379.                DisplayUpdate(nLinks,hwndList,pLinks,TRUE);
  380.                UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  381.                return TRUE;
  382.  
  383.             case IDD_AUTO:
  384.             case IDD_MANUAL:           //- change link update options
  385.                BLOCK_BUSY(fTry);
  386.                if (!SendMessage(GetDlgItem(hDlg,wParam),BM_GETCHECK, 0, 0L))
  387.                {
  388.                   CheckRadioButton(hDlg, IDD_AUTO ,IDD_MANUAL ,wParam);
  389.                   ChangeUpdateOptions(hDlg,nLinks,hwndList,pLinks,
  390.                      (wParam == IDD_AUTO ? oleupdate_always : oleupdate_oncall));
  391.                   UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  392.                }
  393.                return TRUE;
  394.  
  395.            case IDD_LINKNAME:
  396.                if (HIWORD(lParam) == LBN_SELCHANGE)
  397.                   UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  398.                return TRUE;
  399.  
  400.             case IDCANCEL:
  401.                BLOCK_BUSY(fTry);
  402.                UndoObjects();
  403.                END_PROP_DLG(hDlg,pLinks);
  404.                return TRUE;
  405.  
  406.             case IDOK:
  407.                BLOCK_BUSY(fTry);
  408.                DelUndoObjects(FALSE);
  409.                END_PROP_DLG(hDlg,pLinks);
  410.                return TRUE;
  411.          }
  412.       }
  413.    }
  414.    return FALSE;
  415. }
  416.  
  417.  
  418. /****************************************************************************
  419.  * InitLinkDlg();
  420.  *
  421.  * Initialize the list box of links.
  422.  ***************************************************************************/
  423.  
  424. static BOOL InitLinkDlg (              //- ENTRY:
  425.    HWND           hDlg,                //- dialog box handle
  426.    int            *nLinks,             //- pointer to number of links
  427.    HWND           hwndList,            //- listbox handle
  428.    APPITEMPTR     **pLinks             //- list of window handles of links
  429. ){                                     //- LOCAL
  430.    APPITEMPTR     pItem;               //- application item pointer
  431.    LPSTR          lpstrData = NULL;    //- pointer to link data
  432.    char           szFull[CBMESSAGEMAX * 4];//- list box entry string
  433.    char           pLinkData[OBJECT_LINK_MAX];//- holder of link data
  434.    BOOL           fSelect = FALSE;     //- item selected flag
  435.    HANDLE         hWork;               //- working memory handle
  436.    APPITEMPTR     pTop;                //- pointer to the top object
  437.  
  438.    if (!(*pLinks = (APPITEMPTR *)LocalLock(LocalAlloc(LHND,sizeof(APPITEMPTR)*10))))
  439.    {
  440.       ErrorMessage(E_FAILED_TO_ALLOC);
  441.       return NULL;
  442.    }
  443.    *nLinks = 0;
  444.                                        //- set tabs
  445.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  446.                                        //- enumerate child windows
  447.    for (pTop = pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  448.    {
  449.       if (pItem->otObject == OT_LINK && pItem->fVisible)
  450.       {
  451.          *(*pLinks + *nLinks) = pItem;
  452.          if (!((*nLinks += 1)%10))
  453.          {                             //- add blocks of ten
  454.             hWork = LocalHandle((WORD)*pLinks);
  455.             LocalUnlock(hWork);
  456.             if (!(hWork = LocalReAlloc(hWork,(*nLinks+10)*sizeof(APPITEMPTR),NULL)))
  457.             {
  458.                ErrorMessage(E_FAILED_TO_ALLOC);
  459.                return FALSE;           //- ERROR return
  460.             }
  461.             *pLinks = (APPITEMPTR *)LocalLock(hWork);
  462.          }
  463.  
  464.          if (pTop == pItem)
  465.             fSelect = TRUE;
  466.  
  467.          if (!ObjGetData(pItem, pLinkData))
  468.             continue;
  469.                                        //- make listbox entry
  470.          MakeListBoxString(pLinkData, szFull, pItem->uoObject);
  471.                                        //- add listbox entry
  472.          SendMessage(hwndList, LB_ADDSTRING, 0, (LONG)(LPSTR)szFull);
  473.       }
  474.    }
  475.  
  476.    if (fSelect)
  477.       SendMessage(hwndList, LB_SETSEL, 1, 0L);
  478.  
  479.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  480.    UpdateWindow(hwndList);
  481.  
  482.    return TRUE;                        //- SUCCESS return
  483.  
  484. }
  485.  
  486. /****************************************************************************
  487.  * MakeListBoxString()
  488.  *
  489.  * build an listbox entry string
  490.  ***************************************************************************/
  491.  
  492. static void MakeListBoxString(         //- ENTRY:
  493.    LPSTR          lpLinkData,          //- pointer to link data
  494.    LPSTR          lpBoxData,           //- return string
  495.    OLEOPT_UPDATE  oleopt_update        //- OLE update option
  496. ){                                     //- LOCAL:
  497.    char           szType[CBMESSAGEMAX];//- holds update option string
  498.    LPSTR          lpTemp;              //- working string pointer
  499.    int            i;                   //- index
  500.  
  501.                                        //- get classname
  502.    RegGetClassId(lpBoxData, lpLinkData);
  503.    lstrcat(lpBoxData, " - ");           //- ads tab
  504.  
  505.    while (*lpLinkData++);              //- skip to document name
  506.  
  507.    lpTemp = lpLinkData;
  508.    while (*lpTemp)                     //- copy document name;
  509.    {                                   //- strip drive an directory
  510.       if (*lpTemp == '\\' || *lpTemp == ':')
  511.          lpLinkData = lpTemp + 1;
  512.       lpTemp = AnsiNext(lpTemp);
  513.    }
  514.    lstrcat(lpBoxData, lpLinkData);
  515.    lstrcat(lpBoxData, " - ");
  516.  
  517.    while (*lpLinkData++);              //- copy item data
  518.    lstrcat(lpBoxData, lpLinkData);
  519.    lstrcat(lpBoxData, " - ");
  520.                                        //- add update option string
  521.    switch (oleopt_update)
  522.    {
  523.       case oleupdate_always: i = SZAUTO; break;
  524.       case oleupdate_oncall: i = SZMANUAL; break;
  525.       default: i = SZFROZEN;
  526.    }
  527.    LoadString(hInst, i, szType, CBMESSAGEMAX);
  528.    lstrcat(lpBoxData, szType);
  529.  
  530. }                                      //- SUCCESS return
  531.  
  532. /***************************************************************************
  533.  * UpdateLinkButtons()
  534.  *
  535.  * Keep link buttons active as appropriate.  This routine is called after
  536.  * a selection is made so the buttons reflect the selected items.
  537.  **************************************************************************/
  538.  
  539. static void UpdateLinkButtons(         //- ENTRY:
  540.    HWND           hDlg,                //- dialog box handle
  541.    int            nLinks,              //- number of links
  542.    HWND           hwndList,            //- listbox handle
  543.    APPITEMPTR     *pLinks              //- pointer to link's window handles
  544. ){                                     //- LOCAL:
  545.    ATOM           aCurName=0;          //- atom of current doc
  546.    BOOL           fChangeLink = TRUE;  //- enable/disable changelink button
  547.    int            iAuto,iManual,i;     //- count of manual and auto links
  548.    APPITEMPTR     pItem;               //- application item pointer
  549.    int            iStatic;
  550.  
  551.    iStatic = iAuto = iManual = 0;
  552.  
  553.    for (i = 0; i < nLinks; i++)        //- enum selected links
  554.    {
  555.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  556.       {
  557.          pItem = *(pLinks+i);
  558.          if (pItem->otObject == OT_STATIC)
  559.             iStatic++;
  560.          else
  561.          {
  562.             switch(pItem->uoObject)
  563.             {                          //- count number of manual and
  564.                case oleupdate_always:  //- automatic links selected
  565.                   iAuto++;
  566.                   break;
  567.                case oleupdate_oncall:
  568.                   iManual++;
  569.                   break;
  570.             }
  571.                                        //- check if all selected links are
  572.             if (!aCurName)             //- linked to same file
  573.                aCurName = pItem->aLinkName;
  574.             else if (aCurName != pItem->aLinkName)
  575.                fChangeLink = FALSE;
  576.          }
  577.       }
  578.    }
  579.  
  580.    if (!(iAuto || iManual || iStatic)  //- if no links disable all buttons
  581.       || (!iAuto && !iManual && iStatic))
  582.    {
  583.       EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE );
  584.       EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), FALSE );
  585.       EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE );
  586.       CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  587.       EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  588.       CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  589.       EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  590.    }
  591.    else
  592.    {
  593.       EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), TRUE );
  594.       EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), TRUE );
  595.  
  596.       if (iAuto && iManual || !(iAuto || iManual))
  597.       {                                //- Set update buttons
  598.          CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  599.          EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  600.          CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  601.          EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  602.       }
  603.       else
  604.       {
  605.          EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), TRUE);
  606.          EnableWindow(GetDlgItem(hDlg, IDD_AUTO), TRUE);
  607.          if (iAuto)
  608.          {
  609.             CheckDlgButton(hDlg, IDD_AUTO, TRUE);
  610.             CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  611.          }
  612.          else
  613.          {
  614.             CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  615.             CheckDlgButton(hDlg, IDD_MANUAL, TRUE);
  616.          }
  617.       }
  618.    }
  619.  
  620.    EnableWindow(GetDlgItem(hDlg, IDD_CHANGE),fChangeLink && aCurName);
  621.  
  622. }
  623.  
  624. /****************************************************************************
  625.  * ChangeLinks()
  626.  *
  627.  * This routine changes the linked data if the user chooses a new file to
  628.  * replace the old document data portion of the linked date.  The routine
  629.  * does nothing if the user cancels.
  630.  *
  631.  * returns TRUE - if data changed FALSE if user cancel or err.
  632.  ***************************************************************************/
  633.  
  634. static BOOL ChangeLinks(               //- ENTRY:
  635.    HWND           hDlg,                //- dialog handle
  636.    int            nLinks,              //- number of links in listbox
  637.    HWND           hwndList,            //- listbox
  638.    APPITEMPTR     *pLinks              //- list of application link handles
  639. ){                                     //- LOCAL
  640.    int            i;                   //- general index
  641.    HANDLE         hWork;               //- work
  642.    APPITEMPTR     pItem;               //- application item
  643.    LPSTR          lpNewDoc = NULL;     //- new document
  644.    ATOM           aOldDoc;             //- atom of old doc. name
  645.    ATOM           aCurDoc = NULL;      //- atom of change-to doc. name
  646.    BOOL           fMessage = FALSE;    //- error message flag
  647.    LPSTR          lpLinkData;          //- pointer to link data
  648.  
  649.    lpLinkData = NULL;
  650.                                        //- This loop finds all selected links
  651.    for (i = 0; i < nLinks; i++)        //- and updates them
  652.    {
  653.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  654.       {
  655.          pItem = *(pLinks+i);
  656.          CHECK_IF_STATIC(pItem);
  657.  
  658.          pItem->lpLinkData = lpLinkData;
  659.          if (!ObjGetData(pItem,NULL))
  660.             continue;
  661.  
  662.          if (!lpNewDoc)
  663.          {
  664.             if (!(lpNewDoc = OfnGetNewLinkName(hDlg, pItem->lpLinkData)))
  665.               return FALSE;            //- ERROR jump
  666.             aOldDoc = pItem->aLinkName;
  667.             aCurDoc = AddAtom(lpNewDoc);
  668.             SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  669.          }
  670.  
  671.          ObjSaveUndo(pItem);
  672.          ObjChangeLinkData(pItem,lpNewDoc);
  673.          pItem->aLinkName = aCurDoc;
  674.          lpLinkData = pItem->lpLinkData;
  675.  
  676.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  677.  
  678.          pItem->lpLinkData = NULL;
  679.       }
  680.    }
  681.  
  682.    /*************************************************************************
  683.    * now deal with non-selected links and look for a match...
  684.    *************************************************************************/
  685.  
  686.                                        //- this loop finds non-selected links
  687.    for (i = 0; i < nLinks; i++)        //- and asks the user to update these?
  688.    {
  689.       if (!SendMessage(hwndList, LB_GETSEL, i, 0L))
  690.       {
  691.          pItem = *(pLinks+i);
  692.          if (pItem->otObject == OT_STATIC)
  693.             continue;
  694.  
  695.          if (!ObjGetData(pItem,NULL))
  696.             continue;
  697.  
  698.          if (pItem->aLinkName == aOldDoc)
  699.          {
  700.             if (!fMessage)
  701.             {
  702.                char szMessage[2*CBMESSAGEMAX+3*CBPATHMAX];
  703.                char szRename[2*CBMESSAGEMAX];
  704.                char szOldDoc[CBMESSAGEMAX];
  705.                LPSTR pOldDoc;
  706.  
  707.                GetAtomName(aOldDoc,szOldDoc,CBMESSAGEMAX);
  708.                pOldDoc =(LPSTR)UnqualifyPath(szOldDoc);
  709.                LoadString(hInst, IDS_RENAME, szRename, 2*CBMESSAGEMAX);
  710.                wsprintf(
  711.                      szMessage,
  712.                      szRename,
  713.                      pOldDoc,
  714.                      (LPSTR)UnqualifyPath(szFileName),
  715.                      pOldDoc
  716.                );
  717.  
  718.                if (MessageBox(hDlg, szMessage,
  719.                   szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  720.                   break;
  721.                fMessage = TRUE;
  722.             }
  723.  
  724.             ObjSaveUndo(pItem);
  725.             ObjChangeLinkData(pItem,lpNewDoc);
  726.             CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  727.  
  728.             pItem->aLinkName = aCurDoc;
  729.          }
  730.       }
  731.    }
  732.  
  733.    if(lpNewDoc)
  734.    {
  735.       hWork = (HANDLE)GlobalHandle(HIWORD(lpNewDoc));
  736.       GlobalUnlock(hWork);
  737.       GlobalFree(hWork);
  738.    }
  739.  
  740.    if (lpLinkData)
  741.       FreeLinkData(lpLinkData);
  742.  
  743.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  744.    InvalidateRect(hwndList,NULL,TRUE);
  745.    UpdateWindow(hwndList);
  746.  
  747.    WaitForAllObjects();
  748.  
  749.    if (aCurDoc)
  750.       DeleteAtom(aCurDoc);
  751.  
  752.    return(TRUE);
  753. }
  754.  
  755. /****************************************************************************
  756.  * DisplayUpdate()
  757.  *
  758.  * Get the most up to date rendering information and show it.
  759.  ***************************************************************************/
  760.  
  761. static void DisplayUpdate(             //- ENTRY:
  762.    int            nLinks,              //- number of links in listbox
  763.    HWND           hwndList,            //- listbox
  764.    APPITEMPTR     *pLinks,             //- list of application link handles
  765.    BOOL           fSaveUndo            //- save undo objects
  766. ){                                     //- LOCAL:
  767.    int            i;                   //- index
  768.    APPITEMPTR     pItem;               //- temporary item pointer
  769.  
  770.  
  771.    for (i = 0; i < nLinks; i++)
  772.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  773.       {
  774.          pItem = *(pLinks+i);
  775.          CHECK_IF_STATIC(pItem);
  776.          if (fSaveUndo)
  777.             ObjSaveUndo(pItem);
  778.          Error(OleUpdate(pItem->lpObject));
  779.       }
  780.  
  781.    WaitForAllObjects();
  782.  
  783. }
  784.  
  785. /****************************************************************************
  786.  * UndoObjects()
  787.  *
  788.  * Bring objects back to their original state.
  789.  ***************************************************************************/
  790.  
  791. static void UndoObjects()
  792. {
  793.    APPITEMPTR     pItem;               //- application item pointer
  794.                                        //- enum objects
  795.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  796.       if (pItem->lpObjectUndo)
  797.          ObjUndo(pItem);
  798.  
  799.    WaitForAllObjects();
  800.  
  801. }
  802.  
  803.  
  804. /****************************************************************************
  805.  * DelUndoObjects()
  806.  *
  807.  * remove all objects created for undo operation.
  808.  ***************************************************************************/
  809.  
  810. static void DelUndoObjects(            //- ENTRY:
  811.    BOOL           fPrompt              //- prompt user?
  812. ){                                     //- LOCAL:
  813.    APPITEMPTR     pItem;               //- application item pointer
  814.    BOOL           fPrompted = FALSE;   //- prompted user?
  815.  
  816.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  817.    {
  818.       if (pItem->lpObjectUndo)
  819.       {
  820.          if (fPrompt && !fPrompted)    //- prompt user in activation case
  821.          {
  822.             char szPrompt[CBMESSAGEMAX];
  823.  
  824.             LoadString(hInst, IDS_SAVE_CHANGES, szPrompt, CBMESSAGEMAX);
  825.  
  826.             if (MessageBox(hwndFrame, szPrompt,
  827.                   szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  828.             {
  829.                UndoObjects();
  830.                return;                 //- user canceled operation
  831.             }
  832.             fPrompted = TRUE;
  833.          }
  834.         ObjDelUndo(pItem);             //- delete udo object
  835.       }
  836.    }
  837.  
  838.    WaitForAllObjects();
  839.  
  840. }                                      //- SUCCESS return
  841.  
  842. /****************************************************************************
  843.  * CancelLinks()
  844.  ***************************************************************************/
  845.  
  846. static void CancelLinks(               //- ENTRY:
  847.    HWND           hDlg,                //- calling dialog
  848.    int            nLinks,              //- number of links in listbox
  849.    HWND           hwndList,            //- listbox
  850.    APPITEMPTR     *pLinks              //- list of application link handles
  851. ){                                     //- LOCAL:
  852.    APPITEMPTR     pItem;               //- application item pointer
  853.    int            i;                   //- index
  854.    char           pLinkData[OBJECT_LINK_MAX];//- holder of link data
  855.  
  856.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  857.    for (i = 0; i < nLinks; i++)
  858.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  859.       {
  860.          pItem = *(pLinks+i);
  861.          CHECK_IF_STATIC(pItem);
  862.          ObjGetData(pItem,pLinkData);
  863.          ObjSaveUndo(pItem);
  864.          ObjFreeze(pItem);
  865.  
  866.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  867.       }
  868.  
  869.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  870.    InvalidateRect(hwndList,NULL,TRUE);
  871.    UpdateWindow(hwndList);
  872.  
  873. }
  874.  
  875.  
  876. /****************************************************************************
  877.  * ChangeUpdateOptions()
  878.  *
  879.  * Change the update options for all selected objects.
  880.  ***************************************************************************/
  881.  
  882. static void ChangeUpdateOptions(       //- ENTRY:
  883.    HWND           hDlg,                //- calling dialog
  884.    int            nLinks,              //- number of links in listbox
  885.    HWND           hwndList,            //- listbox
  886.    APPITEMPTR     *pLinks,             //- list of application link handles
  887.    OLEOPT_UPDATE  lUpdate              //- update option
  888. ){                                     //- LOCAL:
  889.    APPITEMPTR     pItem;               //- application item
  890.    int            i;                   //- index
  891.    char           pLinkData[OBJECT_LINK_MAX];
  892.  
  893.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  894.  
  895.    for (i = 0; i < nLinks; i++)        //- enum selected objects
  896.    {
  897.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  898.       {
  899.          pItem = *(pLinks+i);
  900.          CHECK_IF_STATIC(pItem);
  901.          ObjGetData(pItem,pLinkData);
  902.          ObjSaveUndo(pItem);
  903.          if (Error(OleSetLinkUpdateOptions(pItem->lpObject,lUpdate)))
  904.             continue;
  905.          pItem->uoObject = lUpdate;
  906.  
  907.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  908.       }
  909.    }
  910.  
  911.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  912.    InvalidateRect(hwndList,NULL,TRUE);
  913.    UpdateWindow(hwndList);
  914.    WaitForAllObjects();
  915.  
  916. }
  917. /****************************************************************************
  918.  * InvalidLink()
  919.  *
  920.  * Deal with letting the user know that the program has inadvertently come
  921.  * across an invalid link.
  922.  *
  923.  * Global fPropBoxActive - flag to determine whether or not the link dialog
  924.  *                         box is active.  If it is not active we give the
  925.  *                         user an opportunity to enter the links property
  926.  *                         dialog directly from here.
  927.  ***************************************************************************/
  928.  
  929. void FAR InvalidLink()
  930. {
  931.  
  932.    if (!hwndProp)
  933.    {
  934.       FARPROC lpfnInvalidLink=NULL;
  935.  
  936.       lpfnInvalidLink = MakeProcInstance(fnInvalidLink, hInst);
  937.       DialogBox(hInst, "InvalidLink", hwndFrame, lpfnInvalidLink);
  938.       FreeProcInstance(lpfnInvalidLink);
  939.    }
  940.    else
  941.       ErrorMessage(E_FAILED_TO_CONNECT);
  942.  
  943. }
  944.  
  945. /****************************************************************************
  946.  *  fnABout()
  947.  *
  948.  *  About box dialog box procedure.
  949.  ***************************************************************************/
  950.  
  951. BOOL FAR PASCAL __export fnInvalidLink(//- ENTRY:
  952.    HWND           hDlg,                //- standard windows dialog box
  953.    unsigned       message,
  954.    WORD           wParam,
  955.    LONG           lParam
  956. ){
  957.  
  958.    switch (message)
  959.    {
  960.       case WM_INITDIALOG:
  961.          return (TRUE);
  962.  
  963.       case WM_COMMAND:
  964.          if (wParam == IDD_CHANGE)
  965.             LinkProperties();
  966.          EndDialog(hDlg, TRUE);
  967.          return (TRUE);
  968.     }
  969.     return (FALSE);
  970.  
  971. }
  972.  
  973. /****************************************************************************
  974.  *  AboutBox()
  975.  *
  976.  *  Show the About Box dialog.
  977.  ***************************************************************************/
  978.  
  979. void FAR AboutBox()
  980. {
  981.    FARPROC lpfnProcAbout=NULL;
  982.  
  983.    lpfnProcAbout = MakeProcInstance(fnAbout, hInst);
  984.    DialogBox(hInst, "AboutBox", hwndFrame, lpfnProcAbout);
  985.    FreeProcInstance(lpfnProcAbout);
  986.  
  987. }
  988.  
  989. /****************************************************************************
  990.  *  fnABout()
  991.  *
  992.  *  About box dialog box procedure.
  993.  ***************************************************************************/
  994.  
  995. BOOL FAR PASCAL __export fnAbout(      //- ENTRY:
  996.    HWND           hDlg,                //- standard windows dialog box
  997.    unsigned       message,
  998.    WORD           wParam,
  999.    LONG           lParam
  1000. ){
  1001.  
  1002.    switch (message)
  1003.    {
  1004.       case WM_INITDIALOG:
  1005.          return (TRUE);
  1006.  
  1007.       case WM_COMMAND:
  1008.          if (wParam == IDOK || wParam == IDCANCEL)
  1009.          {
  1010.             EndDialog(hDlg, TRUE);
  1011.             return (TRUE);
  1012.          }
  1013.          break;
  1014.     }
  1015.     return (FALSE);
  1016.  
  1017. }
  1018.  
  1019.  
  1020.  
  1021. /***************************************************************************
  1022.  * RetryMessage()
  1023.  *
  1024.  * give the user the chance to abort when a server is in retry case.
  1025.  *
  1026.  * Returns BOOL - TRUE if user chooses to cancel
  1027.  **************************************************************************/
  1028.  
  1029. void FAR RetryMessage (                //- ENTRY:
  1030.    APPITEMPTR     paItem,              //- application item pointer
  1031.    LONG           lParam
  1032. ){
  1033.    RETRYPTR    pRetry;
  1034.    LONG          objectType;
  1035.    HANDLE       hData;
  1036.    static char szServerName[KEYNAMESIZE];
  1037.    HWND        hwnd;                   //- window handle
  1038.    FARPROC     lpfn;                   //- pointer to far
  1039.  
  1040.    if (IsWindow(hwndProp))
  1041.       hwnd = hwndProp;
  1042.    else if (IsWindow(hwndFrame))
  1043.       hwnd = hwndFrame;
  1044.    else
  1045.       return;                          //- should not happen
  1046.                                        //- get the busy servers name
  1047.    lstrcpy(szServerName, "server application");
  1048.  
  1049.    if (paItem)
  1050.    {
  1051.       if (!paItem->aServer)
  1052.       {
  1053.          OleQueryType(paItem->lpObject, &objectType );
  1054.          if (OLE_OK == OleGetData(paItem->lpObject, (objectType == OT_LINK ? vcfLink : vcfOwnerLink), &hData ))
  1055.          {
  1056.             RegGetClassId(szServerName, GlobalLock(hData));
  1057.             paItem->aServer = AddAtom(szServerName);
  1058.             GlobalUnlock( hData );
  1059.          }
  1060.       }
  1061.       else
  1062.          GetAtomName(paItem->aServer,szServerName,KEYNAMESIZE);
  1063.  
  1064.    }
  1065.  
  1066.    hData = LocalAlloc(LHND,sizeof(RETRYSTRUCT));
  1067.    if(!(pRetry = (RETRYPTR)LocalLock(hData)))
  1068.      return;
  1069.  
  1070.    pRetry->lpserver = (LPSTR)szServerName;
  1071.    pRetry->bCancel  = (BOOL)(lParam & RD_CANCEL);
  1072.    pRetry->paItem   = paItem;
  1073.  
  1074.    lpfn = MakeProcInstance(fnRetry,hInst);
  1075.    DialogBoxParam(hInst, "RetryBox", hwnd, lpfn, (LPARAM)MAKELONG(pRetry,0));
  1076.    FreeProcInstance((FARPROC)lpfn);
  1077.  
  1078.    LocalUnlock(hData);
  1079.    LocalFree(hData);
  1080.  
  1081.    hRetry = NULL;
  1082.  
  1083. }
  1084.  
  1085. /****************************************************************************
  1086.  *  fnRetry()
  1087.  *
  1088.  * Retry message box nothing to tricky; however, when a server becomes
  1089.  * unbusy a message is posted to automatically get rid of this dialog.
  1090.  * I send a no.
  1091.  ***************************************************************************/
  1092.  
  1093. BOOL FAR PASCAL __export fnRetry(      //- ENTRY
  1094.    HWND hDlg,                          //- standard dialog entry
  1095.    WORD message,
  1096.    WORD wParam,
  1097.    DWORD lParam
  1098. ){
  1099.    static RETRYPTR   pRetry;
  1100.  
  1101.    switch (message)
  1102.    {
  1103.       case WM_COMMAND:
  1104.          switch (wParam)
  1105.          {
  1106.                case IDD_SWITCH:
  1107.                      DefWindowProc( hDlg, WM_SYSCOMMAND, SC_TASKLIST, NULL);
  1108.                   break;
  1109.  
  1110.                case IDCANCEL:
  1111.                   if (pRetry->paItem)
  1112.                      pRetry->paItem->fRetry = FALSE;
  1113.                   EndDialog(hDlg, TRUE);
  1114.                   return TRUE;
  1115.  
  1116.                default:
  1117.                    break;
  1118.          }
  1119.          break;
  1120.  
  1121.       case WM_INITDIALOG:
  1122.       {
  1123.           char       szBuffer[CBMESSAGEMAX];
  1124.           char       szText[2*CBMESSAGEMAX];
  1125.  
  1126.           pRetry = (RETRYPTR)lParam;
  1127.           hRetry = hDlg;
  1128.  
  1129.           LoadString(hInst, IDS_RETRY_TEXT1, szBuffer, CBMESSAGEMAX);
  1130.           wsprintf(szText, szBuffer, pRetry->lpserver);
  1131.           SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT1), szText);
  1132.  
  1133.           LoadString(hInst, IDS_RETRY_TEXT2, szBuffer, CBMESSAGEMAX);
  1134.           wsprintf(szText, szBuffer, pRetry->lpserver);
  1135.           SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT2), szText);
  1136.  
  1137.           EnableWindow (GetDlgItem(hDlg, IDCANCEL), pRetry->bCancel);
  1138.  
  1139.           return TRUE;
  1140.       }
  1141.  
  1142.       default:
  1143.            break;
  1144.    }
  1145.  
  1146.    return FALSE;
  1147. }
  1148.