home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / podstawy / os2 / nakladki / pc2v190.exe / SOURCE.ZIP / Source / WPS2PC2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-01  |  56.8 KB  |  1,195 lines

  1.  
  2. /*
  3.  * This file was generated by the SOM Compiler.
  4.  * FileName: Source\WPS2PC2.c.
  5.  * Generated using:
  6.  *     SOM Precompiler spc: 1.22
  7.  *     SOM Emitter emitc: 1.24
  8.  */
  9.  
  10. /*
  11.  *
  12.  *                              WPS2PC2.c
  13.  *              Copyright (C) by Stangl Roman, 1994, 1995
  14.  * This Code may be freely distributed, provided the Copyright isn't
  15.  * removed, under the conditions indicated in the documentation.
  16.  *
  17.  * WPS2PC2.C    PC/2's interface to the WPS. This WPS DLL allows you
  18.  *              to drag WPS objects onto, which are then converted
  19.  *              into a format understandable by PC/2. This newly
  20.  *              structure can then be dropped onto PC/2's Setup dialog
  21.  *              to add Menuentries corresponding to the dropped WPS
  22.  *              objects to PC/2's Popup Menu. E.g. this allows you to
  23.  *              create a Menuentry that is equivalent to a WPS DOS
  24.  *              program object, inclusive any DOS settings.
  25.  *
  26.  * SOMObject
  27.  *    WPObject
  28.  *       WPAbstract
  29.  *
  30.  */
  31.  
  32.  
  33. #define Wps2Pc2_Class_Source
  34. #include "Wps2Pc2.ih"
  35.                                         /* Header files for classes we use */
  36. #include    <wpObject.h>
  37. #include    <wpFolder.h>
  38. #include    <wpShadow.h>
  39. #include    <wpPgm.h>
  40. #include    <wpDesk.h>
  41.                                         /* Define method wpQueryObjectID which is available
  42.                                            but not documented in wpObject.h (as are about
  43.                                            20 other methods too) */
  44. /*
  45.  * New Method: wpQueryObjectID
  46.  */
  47. typedef PSZ SOMLINK somTP_WPObject_wpQueryObjectID(WPObject *somSelf);
  48. #pragma linkage(somTP_WPObject_wpQueryObjectID, system)
  49. typedef somTP_WPObject_wpQueryObjectID *somTD_WPObject_wpQueryObjectID;
  50. #define somMD_WPObject_wpQueryObjectID "----"
  51. #define WPObject_wpQueryObjectID(somSelf)\
  52.         (SOM_Resolve(somSelf, WPObject, wpQueryObjectID)\
  53.         (somSelf))
  54. #define _wpQueryObjectID WPObject_wpQueryObjectID
  55.  
  56.                                         /* C Header files */
  57. #include    <stdio.h>
  58. #include    <string.h>
  59.  
  60. typedef struct  _DLLPC2WPS              DLLPC2WPS;
  61. typedef struct  _CLIENTWINDOW           CLIENTWINDOW;
  62.  
  63. struct          _DLLPC2WPS
  64. {
  65.     HMODULE     hDLLWps2Pc2;            /* Handle of WPS2PC2.DLL */
  66.     HAB         habWps2Pc2;             /* Anchor block of the window we create */
  67.     HWND        hwndFrameWps2Pc2;       /* Frame window handle */
  68.     HWND        hwndClientWps2Pc2;      /* Client window handle */
  69.     Wps2Pc2    *psomSelf;               /* Pointer to WPS 2 PC/2 instance. We just assume that
  70.                                            WPS 2 PC/2 just exists once (i.e. it is installed once
  71.                                            and is never copied...) */
  72.     USEITEM     UseItem;                /* Global class usage information */
  73.     VIEWITEM    ViewItem;               /* Global class view information */
  74.     PBYTE       pbSharedMem;            /* Pointer to unnamed shared memory allocated with
  75.                                            DosAllocSharedMem() which is passed to PC2.EXE
  76.                                            during Drag'n Drop and retrieved by DosGetSharedMem().
  77.                                            This pointer is NULL when nothing is allocated. */
  78.     PBYTE       pbSharedMemNextFree;    /* Because shared memory is allocated by not commited
  79.                                            this pointer points to the next free space in shared
  80.                                            memory. It is commited during handling the exception
  81.                                            of the first access.
  82.                                            This pointer is NULL when nothing is allocated. */
  83.     WPSOBJECTLIST
  84.                *pListRoot;              /* Pointer to the first element of the LIST of WPS
  85.                                            Objects extracted from the WPS for the root
  86.                                            recursion depth.
  87.                                            This pointer is NULL if nothing has been extracted
  88.                                            from the WPS, or the user has pressed the Clear
  89.                                            button. */
  90. };
  91.  
  92. DLLPC2WPS   DLLPc2Wps;                  /* WPS2PC2 WPS DLL control structure */
  93.  
  94. struct          _CLIENTWINDOW
  95. {
  96.     PSZ         pszClass;
  97.     PSZ         pszName;
  98.     ULONG       flStyle;
  99.     POINTL      ptlPosition;
  100.     POINTL      ptlSize;
  101.     ULONG       Id;
  102. };
  103.  
  104. CLIENTWINDOW    FrameArea=
  105.     {NULL      , ""                     , 0,
  106.         {9  , 10 }, {266, 126}, 0};
  107.  
  108. CLIENTWINDOW    StatusArea=
  109.     {NULL      , ""                     , 0,
  110.         {200, 70 }, {27 , 20 }, WPBM_STATUSBITMAP};
  111.  
  112. CLIENTWINDOW    ClientArea[]= {
  113.     {WC_STATIC , "WPS Objects extracted:", WS_VISIBLE | SS_TEXT | DT_CENTER,
  114.         {5  , 115}, {175, 8  }, WPTF_EXTRACTEDOBJECTS},
  115.     {WC_STATIC , "Status:"               , WS_VISIBLE | SS_TEXT | DT_CENTER,
  116.         {200, 115}, {50 , 8  }, WPTF_STATUSBITMAP},
  117.     {WC_LISTBOX, ""                      , WS_VISIBLE | WS_GROUP | LS_HORZSCROLL,
  118.         {5  , 5  }, {175, 106}, WPLB_EXTRACTEDOBJECTS},
  119.     {WC_BUTTON , "~Clear"                , WS_VISIBLE | WS_GROUP | BS_PUSHBUTTON | BS_DEFAULT,
  120.         {207, 25 }, {40 , 14 }, WPPB_CLEAR},
  121.     {WC_BUTTON , "~Help"                 , WS_VISIBLE | BS_PUSHBUTTON,
  122.         {207, 5  }, {40 , 14 }, WPPB_HELP} };
  123. #define         CLIENTAREASIZE          (sizeof(ClientArea)/sizeof(ClientArea[0]))
  124.  
  125. /*
  126.  *
  127.  *  OVERRIDE: wpDragOver                                                     ( ) Private
  128.  *                                                                           (x) Public
  129.  *  DESCRIPTION:
  130.  *       Called when a WPS Object is dragged over the WPS 2 PC2 icon. Accept object if
  131.  *       rendering method DRM_OBJECT and format DRF_OBJECT.
  132.  *
  133.  */
  134.  
  135. SOM_Scope MRESULT   SOMLINK Wps2Pc2X_wpDragOver(Wps2Pc2 *somSelf,
  136.                 HWND hwndCnr,
  137.                 PDRAGINFO pdrgInfo)
  138. {
  139.     ULONG   ulItemIndex, ulItemCount;   /* Drag'n Drop counters */
  140.     USHORT  usDORResponse;              /* Drag'n Drop response (DOR_DROP|DOR_NEVERDROP) */
  141.  
  142.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  143.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpDragOver");
  144.  
  145.     usDORResponse=DOR_DROP;             /* Assume we can accept the instances dropped */
  146.                                         /* Get the number of instances dropped */
  147.     ulItemCount=DrgQueryDragitemCount(pdrgInfo);
  148.     for(ulItemIndex=0; ulItemIndex<ulItemCount;ulItemIndex++)
  149.         {                               /* All instances dropped must be of an WPS object class */
  150.         DRAGITEM    Dragitem;
  151.  
  152.         DrgQueryDragitem(pdrgInfo, sizeof(Dragitem), &Dragitem, ulItemIndex);
  153.                                         /* WPS objects have a rendering protocol of
  154.                                            DRM_OBJECT, DRF_OBJECT */
  155.         if(!(DrgVerifyRMF(&Dragitem, "DRM_OBJECT", "DRF_OBJECT")))
  156.             {                           /* It isn't a WPS object, don't accept all instances dropped */
  157.             usDORResponse=DOR_NEVERDROP;
  158.             }
  159.         }
  160.     return(MPFROM2SHORT(usDORResponse, DO_UNKNOWN));
  161. /*
  162.  *  return (parent_wpDragOver(somSelf,hwndCnr,pdrgInfo));
  163.  */
  164. }
  165.  
  166. /*
  167.  *
  168.  *  OVERRIDE: wpDrop                                                         ( ) Private
  169.  *                                                                           (x) Public
  170.  *  DESCRIPTION:
  171.  *       Called when a WPS Object was dropped over the WPS 2 PC2 icon. Query all objects
  172.  *       dropped, allocate a unnamed shared memory, copy object data into and allow this
  173.  *       shared memory to be dragged to PC/2, which will add Menuentries according to
  174.  *       the objects dropped.
  175.  *
  176.  */
  177.  
  178. #pragma handler (ConvertObject2MenuData)
  179. SOM_Scope MRESULT   SOMLINK Wps2Pc2X_wpDrop(Wps2Pc2 *somSelf,
  180.                 HWND hwndCnr,
  181.                 PDRAGINFO pdrgInfo,
  182.                 PDRAGITEM pdrgItem)
  183. {
  184.     WPObject   *pWPObjectDropped;       /* WPS instance dropped */
  185.     WPSOBJECTLIST
  186.                *pListInsert;            /* WPS Object extracted */
  187.  
  188.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  189.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpDrop");
  190.  
  191.                                         /* Allocate unnamed shared memory if required */
  192.     if(!DLLPc2Wps.pbSharedMem) AllocateSharedMem();
  193.                                         /* In DRAGITEM->ulItemID is a pointer to the WPS
  194.                                            instance dropped. This pointer is also available
  195.                                            for non WPS programs, but points not in their address
  196.                                            spaces, so using it only makes sense for WPS
  197.                                            programs running in the WPS address space */
  198.     pWPObjectDropped=OBJECT_FROM_PREC(pdrgItem->ulItemID);
  199.                                         /* Now convert the WPS object classes into a WPSOBJECTLIST
  200.                                            type list structure, sub-allocated in the unnamed shared
  201.                                            memory allocated by AllocateSharedMem(). The list of
  202.                                            PROGDETAILS and UCHAR[] elements (for WPProgram and
  203.                                            WPFolder WPS objects) is recursively filled by
  204.                                            ConvertObject2MenuData() starting with recursion depth 1.
  205.                                            The shared memory can subsequently be dragged onto PC/2's
  206.                                            Config dialog from where the LIST is converted to menuitems of
  207.                                            PC/2's Popup-Menu */
  208.     pListInsert=ConvertObject2MenuData(pWPObjectDropped, 1);
  209.                                         /* We insert the newly extracted element as the last LIST
  210.                                            element into the LIST DLLPc2Wps.pListRoot. pListRoot
  211.                                            is NULL for the first dropping from WPS or after pressing
  212.                                            the Clear button or points to previously extracted elements
  213.                                            otherwise */
  214.     if(DLLPc2Wps.pListRoot)
  215.         {                               /* If this is not the first LIST element to insert, insert
  216.                                            at the end of the list */
  217.         WPSOBJECTLIST  *pListTemp;
  218.  
  219.                                         /* Find the last element, which is the one that has nothing
  220.                                            following */
  221.         for(pListTemp=DLLPc2Wps.pListRoot; pListTemp->pNext; pListTemp=pListTemp->pNext);
  222.                                         /* Insert it */
  223.         pListTemp->pNext=pListInsert;
  224.         }
  225.     else
  226.         {                               /* If this is the first LIST element to insert, set it as
  227.                                            the first element */
  228.         DLLPc2Wps.pListRoot=pListInsert;
  229.         }
  230.                                         /* Invalidate client area (if available) to redraw status bitmap */
  231.     if(DLLPc2Wps.hwndFrameWps2Pc2)
  232.         WinInvalidateRect(DLLPc2Wps.hwndClientWps2Pc2, NULL, FALSE);
  233.     return (parent_wpDrop(somSelf,hwndCnr,pdrgInfo,pdrgItem));
  234. }
  235.  
  236. /*
  237.  *
  238.  *  OVERRIDE: wpModifyPopupMenu                                              ( ) Private
  239.  *                                                                           (x) Public
  240.  *  DESCRIPTION:
  241.  *       Overwrite to add the "Open->WPS 2 PC/2" menuitem to the "Open->" context menu.
  242.  *
  243.  */
  244.  
  245. SOM_Scope BOOL   SOMLINK Wps2Pc2X_wpModifyPopupMenu(Wps2Pc2 *somSelf,
  246.                 HWND hwndMenu,
  247.                 HWND hwndCnr,
  248.                 ULONG iPosition)
  249. {
  250.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  251.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpModifyPopupMenu");
  252.  
  253.                                         /* Insert "WPS 2 PC/2" as a submenu menuitem into
  254.                                            the "Open->" menuitem of the context menu */
  255.     _wpInsertPopupMenuItems(somSelf, hwndMenu, 0, DLLPc2Wps.hDLLWps2Pc2,
  256.         ID_WPS2PC2OPENMENU, WPMENUID_OPEN);
  257.  
  258.     return (parent_wpModifyPopupMenu(somSelf,hwndMenu,hwndCnr,iPosition));
  259. }
  260.  
  261. /*
  262.  *
  263.  *  OVERRIDE: wpMenuItemHelpSelected                                         ( ) Private
  264.  *                                                                           (x) Public
  265.  *  DESCRIPTION:
  266.  *       Called when receiving an help event from our menuitem we added to the context menu.
  267.  *
  268.  */
  269.  
  270. SOM_Scope BOOL   SOMLINK Wps2Pc2X_wpMenuItemHelpSelected(Wps2Pc2 *somSelf,
  271.                 ULONG MenuId)
  272. {
  273.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  274.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpMenuItemHelpSelected");
  275.  
  276.                                         /* Display help */
  277.     if(MenuId==ID_WPS2PC2OPEN)
  278.         return(_wpDisplayHelp(somSelf, ID_WPS2PC2MAINWINDOW, PC2_WPS2PC2_HELP));
  279.     return(FALSE);
  280. /*
  281.  *  return (parent_wpMenuItemHelpSelected(somSelf,MenuId));
  282.  */
  283. }
  284.  
  285. /*
  286.  *
  287.  *  OVERRIDE: wpMenuItemSelected                                             ( ) Private
  288.  *                                                                           (x) Public
  289.  *  DESCRIPTION:
  290.  *       Called when receiving an event from our menuitem we added to the context menu.
  291.  *
  292.  */
  293.  
  294. SOM_Scope BOOL   SOMLINK Wps2Pc2X_wpMenuItemSelected(Wps2Pc2 *somSelf,
  295.                 HWND hwndFrame,
  296.                 ULONG ulMenuId)
  297. {
  298.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  299.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpMenuItemSelected");
  300.  
  301.                                         /* Switch according to the menuitem selected */
  302.     switch(ulMenuId)
  303.     {
  304.                                         /* "Open -> WPS 2 PC/2" is the only thing we
  305.                                             handle, other selections are passed on to WPS */
  306.     case ID_WPS2PC2OPEN:
  307.                                         /* Using wpViewOpen() instead of wpOpen() allows to
  308.                                            switch to an open view instead of opening another
  309.                                            instance */
  310.         _wpViewObject(somSelf, NULLHANDLE, ID_WPS2PC2OPENMENU, 0);
  311.         break;
  312.  
  313.     default:
  314.         return(parent_wpMenuItemSelected(somSelf, hwndFrame, ulMenuId));
  315.     }
  316.     return(TRUE);                       /* We have processed the message */
  317. /*
  318.  *  return (parent_wpMenuItemSelected(somSelf,hwndFrame,ulMenuId));
  319.  */
  320. }
  321.  
  322. /*
  323.  *
  324.  *  OVERRIDE: wpOpen                                                         ( ) Private
  325.  *                                                                           (x) Public
  326.  *  DESCRIPTION:
  327.  *       Called when the WPS2PC2 WPS icon gets opened via the context menu.
  328.  *
  329.  *
  330.  * Class override methods.
  331.  */
  332.  
  333. SOM_Scope HWND   SOMLINK Wps2Pc2X_wpOpen(Wps2Pc2 *somSelf,
  334.                 HWND hwndCnr,
  335.                 ULONG ulView,
  336.                 ULONG param)
  337. {
  338.     Wps2Pc2Data *somThis = Wps2Pc2GetData(somSelf);
  339.     Wps2Pc2MethodDebug("Wps2Pc2","Wps2Pc2X_wpOpen");
  340.  
  341.                                         /* Switch accoring to identifier selected */
  342.     switch(ulView)
  343.     {
  344.                                         /* "Open -> WPS 2 PC/2" is the only thing we
  345.                                             handle, other selections are passed on to WPS */
  346.     case ID_WPS2PC2OPENMENU:
  347.         if(!_wpSwitchTo(somSelf, ulView))
  348.             {
  349.             HAB         hab;
  350.             FRAMECDATA  fcdFrameCtrlData;
  351.             SWP         swp;
  352.  
  353.                                         /* Save the instance going to be opened (We assume
  354.                                            that only one instance is opened) */
  355.             DLLPc2Wps.psomSelf=somSelf;
  356.                                         /* Get an anchor block */
  357.             hab=WinQueryAnchorBlock(HWND_DESKTOP);
  358.                                         /* Register class */
  359.             WinRegisterClass(hab, PC2_CLASSNAME_WPS2PC2, (PFNWP)WPS2PC2_MainWindowProc,
  360.                 CS_CLIPSIBLINGS | CS_SYNCPAINT, 0);
  361.                                         /* Create the WPS 2 PC/2 window consisting of a frame
  362.                                            window and a client as its child */
  363.             fcdFrameCtrlData.cb=sizeof(FRAMECDATA);
  364.             fcdFrameCtrlData.flCreateFlags=FCF_WPS2PC2WINDOW;
  365.             fcdFrameCtrlData.hmodResources=DLLPc2Wps.hDLLWps2Pc2;
  366.             fcdFrameCtrlData.idResources=ID_WPS2PC2MAINWINDOW;
  367.             DLLPc2Wps.hwndFrameWps2Pc2=WinCreateWindow(
  368.                 HWND_DESKTOP, WC_FRAME, _wpQueryTitle(somSelf), WS_CLIPCHILDREN,
  369.                 0, 0, 0, 0, NULLHANDLE, HWND_TOP, 269,
  370.                 (PVOID)&fcdFrameCtrlData, NULL);
  371.             if(!DLLPc2Wps.hwndFrameWps2Pc2)
  372.                 DebugBox("WPS 2 PC/2", "Creating frame failed");
  373.             DLLPc2Wps.hwndClientWps2Pc2=WinCreateWindow(
  374.                 DLLPc2Wps.hwndFrameWps2Pc2, PC2_CLASSNAME_WPS2PC2, NULL, WS_CLIPCHILDREN,
  375.                 0, 0, 0, 0, DLLPc2Wps.hwndFrameWps2Pc2, HWND_TOP, FID_CLIENT,
  376.                 0, NULL);
  377.             if(!DLLPc2Wps.hwndClientWps2Pc2)
  378.                 {
  379.                 WinDestroyWindow(DLLPc2Wps.hwndFrameWps2Pc2);
  380.                 DebugBox("WPS 2 PC/2", "Creating client failed");
  381.                 }
  382.             WinSendMsg(DLLPc2Wps.hwndFrameWps2Pc2, WM_SETICON, MPFROMP(_wpQueryIcon(somSelf)), NULL);
  383.             DLLPc2Wps.habWps2Pc2=WinQueryAnchorBlock(DLLPc2Wps.hwndFrameWps2Pc2);
  384.                                         /* Set window title and position */
  385.             WinSetWindowText(DLLPc2Wps.hwndFrameWps2Pc2, PC2_WPS2PC2_WINDOW);
  386.             WinQueryTaskSizePos(DLLPc2Wps.habWps2Pc2, 0, &swp);
  387.             swp.fl=SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_ZORDER;
  388.             swp.cx=FrameArea.ptlSize.x,
  389.             swp.cy=FrameArea.ptlSize.y,
  390.             swp.hwndInsertBehind=HWND_TOP;
  391.             swp.hwnd=DLLPc2Wps.hwndFrameWps2Pc2;
  392.             WinSetMultWindowPos(DLLPc2Wps.habWps2Pc2, &swp, 1);
  393.             WinShowWindow(DLLPc2Wps.hwndFrameWps2Pc2, TRUE);
  394.                                         /* Return window handle of created window */
  395.             return(DLLPc2Wps.hwndFrameWps2Pc2);
  396.             }
  397.         break;
  398.  
  399.     default:
  400.         return(parent_wpOpen(somSelf, hwndCnr, ulView, param));
  401.     }
  402.     return(NULLHANDLE);
  403. /*
  404.  * return (parent_wpOpen(somSelf,hwndCnr,ulView,param));
  405.  */
  406. }
  407.  
  408. #undef SOM_CurrentClass
  409. #define SOM_CurrentClass SOMMeta
  410. /*
  411.  *
  412.  *  OVERRIDE: wpclsQueryIconData                                             ( ) Private
  413.  *                                                                           (x) Public
  414.  *  DESCRIPTION:
  415.  *       Called when querying the class's icon.
  416.  *
  417.  */
  418.  
  419. SOM_Scope ULONG   SOMLINK Wps2Pc2C_wpclsQueryIconData(M_Wps2Pc2 *somSelf,
  420.                 PICONINFO pIconInfo)
  421. {
  422.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  423.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsQueryIconData");
  424.  
  425.                                         /* Fill in class's icon information */
  426.     if(pIconInfo)
  427.         {
  428.         pIconInfo->fFormat=ICON_RESOURCE;
  429.         pIconInfo->hmod=DLLPc2Wps.hDLLWps2Pc2;
  430.         pIconInfo->resid=ID_WPS2PC2MAINWINDOW;
  431.         }
  432.     return(sizeof(ICONINFO));
  433.  
  434. /*
  435.  *  return (parent_wpclsQueryIconData(somSelf,pIconInfo));
  436.  */
  437. }
  438.  
  439. /*
  440.  *
  441.  *  OVERRIDE: wpclsInitData                                                  ( ) Private
  442.  *                                                                           (x) Public
  443.  *  DESCRIPTION:
  444.  *       Called during class initalization.
  445.  *
  446.  */
  447.  
  448. SOM_Scope void   SOMLINK Wps2Pc2C_wpclsInitData(M_Wps2Pc2 *somSelf)
  449. {
  450.     UCHAR   ucBuffer[256];              /* Error message buffer */
  451.     ULONG   ulControlSize;
  452.     ULONG   ulTemp;
  453.  
  454.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  455.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsInitData");
  456.  
  457.                                         /* Initialized control structure */
  458.     memset((void *)&DLLPc2Wps, '\0', sizeof(DLLPc2Wps));
  459.                                         /* Get module handle to extract resources from */
  460.     DosLoadModule((PSZ)ucBuffer, sizeof(ucBuffer), "WPS2PC2", &DLLPc2Wps.hDLLWps2Pc2);
  461.                                         /* Map dialog coordinates from dialog editor to
  462.                                            window coordinates */
  463.     WinMapDlgPoints(HWND_DESKTOP, &FrameArea.ptlPosition, 1, TRUE);
  464.     WinMapDlgPoints(HWND_DESKTOP, &FrameArea.ptlSize, 1, TRUE);
  465.     ulControlSize=WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
  466.     FrameArea.ptlSize.x+=ulControlSize*2;
  467.     FrameArea.ptlSize.y+=WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  468.     FrameArea.ptlSize.y+=ulControlSize*2;
  469.     WinMapDlgPoints(HWND_DESKTOP, &StatusArea.ptlPosition, 1, TRUE);
  470.     WinMapDlgPoints(HWND_DESKTOP, &StatusArea.ptlSize, 1, TRUE);
  471.     for(ulTemp=0; ulTemp<CLIENTAREASIZE; ulTemp++)
  472.         {
  473.         WinMapDlgPoints(HWND_DESKTOP, &ClientArea[ulTemp].ptlPosition, 1, TRUE);
  474.         ClientArea[ulTemp].ptlPosition.x+=ulControlSize;
  475.         ClientArea[ulTemp].ptlPosition.y+=ulControlSize;
  476.         WinMapDlgPoints(HWND_DESKTOP, &ClientArea[ulTemp].ptlSize, 1, TRUE);
  477.         }
  478.  
  479.     parent_wpclsInitData(somSelf);
  480. }
  481.  
  482. /*
  483.  *
  484.  *  OVERRIDE: wpclsUnInitData                                                ( ) Private
  485.  *                                                                           (x) Public
  486.  *  DESCRIPTION:
  487.  *       Called during class termination.
  488.  *
  489.  */
  490.  
  491. SOM_Scope void   SOMLINK Wps2Pc2C_wpclsUnInitData(M_Wps2Pc2 *somSelf)
  492. {
  493.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  494.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsUnInitData");
  495.  
  496.     parent_wpclsUnInitData(somSelf);
  497. }
  498.  
  499. /*
  500.  *
  501.  *  OVERRIDE: wpclsQueryDefaultHelp                                          ( ) Private
  502.  *                                                                           (x) Public
  503.  *  DESCRIPTION:
  504.  *       Add default halp panels for WPS2PC2.
  505.  *
  506.  */
  507.  
  508. SOM_Scope BOOL   SOMLINK Wps2Pc2C_wpclsQueryDefaultHelp(M_Wps2Pc2 *somSelf,
  509.                 PULONG pHelpPanelId,
  510.                 PSZ pszHelpLibrary)
  511. {
  512.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  513.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsQueryDefaultHelp");
  514.  
  515.     if(pHelpPanelId)                    /* Set default help panel ID */
  516.         *pHelpPanelId=ID_WPS2PC2MAINWINDOW;
  517.     if(pszHelpLibrary)                  /* Copy WPS 2 PC/2 help file name */
  518.         strcpy(pszHelpLibrary, PC2_WPS2PC2_HELP);
  519.     return(TRUE);
  520.  
  521. /*
  522.  *  return (parent_wpclsQueryDefaultHelp(somSelf,pHelpPanelId,pszHelpLibrary));
  523.  */
  524. }
  525.  
  526. /*
  527.  *  OVERRIDE: wpclsQueryDefaultView                                          ( ) Private
  528.  *                                                                           (x) Public
  529.  *  DESCRIPTION:
  530.  *       Returns the default view for a new instance of this object, but WPS2PC2 should
  531.  *       be used only once, we just tell what the default open view is.
  532.  */
  533.  
  534. SOM_Scope ULONG   SOMLINK Wps2Pc2C_wpclsQueryDefaultView(M_Wps2Pc2 *somSelf)
  535. {
  536.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  537.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsQueryDefaultView");
  538.  
  539.                                         /* Return default view to be the program not
  540.                                            the settings */
  541.     return(ID_WPS2PC2OPENMENU);
  542. /*
  543.  *   return (parent_wpclsQueryDefaultView(somSelf));
  544.  */
  545. }
  546.  
  547. /*
  548.  *
  549.  *  OVERRIDE: wpclsQueryStyle                                                ( ) Private
  550.  *                                                                           (x) Public
  551.  *  DESCRIPTION:
  552.  *       Returns the default style, used to inhibit creation of shadows, copies or
  553.  *       templates because WPS 2 PC/2 supports only one instance systemwide.
  554.  *
  555.  */
  556.  
  557. SOM_Scope ULONG   SOMLINK Wps2Pc2C_wpclsQueryStyle(M_Wps2Pc2 *somSelf)
  558. {
  559.     /* M_Wps2Pc2Data *somThis = M_Wps2Pc2GetData(somSelf); */
  560.     M_Wps2Pc2MethodDebug("M_Wps2Pc2","Wps2Pc2C_wpclsQueryStyle");
  561.  
  562.     return(parent_wpclsQueryStyle(somSelf) | CLSSTYLE_NEVERLINK | CLSSTYLE_NEVERTEMPLATE |
  563.         CLSSTYLE_NEVERCOPY);
  564. /*
  565.  *  return (parent_wpclsQueryStyle(somSelf));
  566.  */
  567. }
  568.  
  569. #undef  SOM_CurrentClass
  570.  
  571. /*
  572.  *
  573.  *  FUNCTION: ConvertObject2MenuData()                                       (x) Private
  574.  *                                                                           ( ) Public
  575.  *  DESCRIPTION:
  576.  *       Called when a WPS instances have been dropped over WPS2PC2 to query the
  577.  *       instances data, allocate MENUDATA structures in unnamed shared memory and
  578.  *       convert WPS object data into a WPSOBJECTLIST LIST understandable by PC/2.
  579.  *
  580.  */
  581.  
  582. WPSOBJECTLIST *
  583.         ConvertObject2MenuData(WPObject *pWPObject, ULONG ulRecursionLevel)
  584. {
  585.                                         /* Buffer to write WPS Object title into
  586.                                            WPLB_EXTRACTEDOBJECTS */
  587.     static UCHAR
  588.                 ucObjectTitle[CCHMAXPATH];
  589.     PSZ         pszObjectTitle;         /* WPS instance title */
  590.     PSZ         pszObjectClass;         /* WPS instancs class */
  591.     PSZ         pszObjectID;            /* Object ID of "WPObject" dropped, which we take
  592.                                            if it isn't a "WPFolder" or "WPProgram" class
  593.                                            WPS Object */
  594.     UCHAR      *pucFilter;              /* Filter \x0A (LF) characters from the string which
  595.                                            will be used in a MENUDATA.PgmTitle element */
  596.     SOMClass   *pObjectClass;           /* SOM Class definitions for dropped instance */
  597.     SOMClass   *pSOMFolderClass;        /* SOM Class definition for "WPFolder" class */
  598.     SOMCLASS   *pSOMProgramClass;       /* SOM Class definition for "WPProgram" class */
  599.     SOMCLASS   *pSOMShadowClass;        /* SOM Class definition for "WPShadow" class */
  600.     WPSOBJECTLIST
  601.                *pListSelf;              /* WPS object saved into list element which can then be
  602.                                            chained into the list */
  603.     VOID       *pData;                  /* Pointer to the Data element of the LIST WPSOBJECTLIST
  604.                                            structure */
  605.     ULONG       ulProgramDetailsSize;   /* Size of the PROGDETAILS extracted from the WPS, inserted as
  606.                                            the Data element into the LIST for WPProgram objects */
  607.  
  608.                                         /* Get instance's title */
  609.     pszObjectTitle=_wpQueryTitle(pWPObject);
  610.                                         /* Get instance's class */
  611.     pszObjectClass=(PSZ)_somGetClassName(pWPObject);
  612.                                         /* Get classes of dropped instance and SOM classes it
  613.                                            may belong to */
  614.     pObjectClass=_somClassFromId(SOMClassMgrObject, SOM_IdFromString(pszObjectClass));
  615.                                         /* Get classes for "WPFolder" and "WPFileSytem" */
  616.     pSOMFolderClass=_somClassFromId(SOMClassMgrObject, SOM_IdFromString("WPFolder"));
  617.                                         /* Get class for "WPProgram" */
  618.     pSOMProgramClass=_somClassFromId(SOMClassMgrObject, SOM_IdFromString("WPProgram"));
  619.                                         /* Get class for "WPShadow" */
  620.     pSOMShadowClass=_somClassFromId(SOMClassMgrObject, SOM_IdFromString("WPShadow"));
  621.                                         /* Fill buffer with spaces, because the number of spaces
  622.                                            preceeding the WPS Object title is a measure of the
  623.                                            current recursion depth */
  624.     memset(ucObjectTitle, ' ', sizeof(ucObjectTitle));
  625.     ucObjectTitle[sizeof(ucObjectTitle)-1]='\0';
  626.                                         /* If the Object is a WPShadow, query original and
  627.                                            get data necessary to extract the original Object */
  628.     if(_somDescendedFrom(pObjectClass, pSOMShadowClass))
  629.         {
  630.         pWPObject=_wpQueryShadowedObject(pWPObject, FALSE);
  631.         pszObjectClass=(PSZ)_somGetClassName(pWPObject);
  632.         pObjectClass=_somClassFromId(SOMClassMgrObject, SOM_IdFromString(pszObjectClass));
  633.         }
  634.                                         /* Try to get the WPObject's ObjectID, which we use
  635.                                            for Objects not being of type WPFolder or WPProgram */
  636.     pszObjectID=_wpQueryObjectID(pWPObject);
  637.                                         /* If the current instance is of class "WPProgram" then
  638.                                            query its program details */
  639.     if(_somDescendedFrom(pObjectClass, pSOMProgramClass))
  640.         {
  641.                                         /* Allocate a WPSOBJECTLIST structure for the current
  642.                                            WPProgram type WPS object */
  643.         pListSelf=(WPSOBJECTLIST *)GetFreeSharedMem(sizeof(WPSOBJECTLIST));
  644.         pListSelf->ulType=WPSOBJECTPROGRAM;
  645.                                         /* First request program details, but provide no
  646.                                            space to copy them into. The WPS method returns
  647.                                            the required space then */
  648.         ulProgramDetailsSize=0;
  649.         _wpQueryProgDetails(pWPObject , NULL, &ulProgramDetailsSize);
  650.                                         /* Now allocate required space from shared memory */
  651.         pData=(VOID *)GetFreeSharedMem(++ulProgramDetailsSize);
  652.                                         /* Now we can actually get the details data. Accessing
  653.                                            the allocated shared memory may create an access violation,
  654.                                            which calls the exception handler to commit the memory */
  655.         _wpQueryProgDetails(pWPObject, (PROGDETAILS *)pData, &ulProgramDetailsSize);
  656.                                         /* Link the PROGDETAILS into the WPSOBJECTLIST structure
  657.                                            of the newly extracted WPProgram */
  658.         pListSelf->pData=pData;
  659.                                         /* Replace \x0A chars by spaces */
  660.         for(pucFilter=strchr(((PROGDETAILS *)pListSelf->pData)->pszTitle, '\n');
  661.             pucFilter;
  662.             pucFilter=strchr(pucFilter+1, '\n'))
  663.             *pucFilter=' ';
  664.                                         /* If status window is available add WPProgram's object
  665.                                            title to listbox */
  666.         strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), ((PROGDETAILS *)pListSelf->pData)->pszTitle);
  667.         if(DLLPc2Wps.hwndFrameWps2Pc2)
  668.             WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  669.                 LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP(ucObjectTitle));
  670.         return(pListSelf);              /* Return the newly created WPProgram element */
  671.         }
  672.  
  673.                                         /* If the current instance is of class "WPFolder" then
  674.                                            recursively chain into the folder */
  675.     if(_somDescendedFrom(pObjectClass, pSOMFolderClass))
  676.         {
  677.                                         /* Allocate a WPSOBJECTLIST structure for the current
  678.                                            WPFolder type WPS object */
  679.         pListSelf=(WPSOBJECTLIST *)GetFreeSharedMem(sizeof(WPSOBJECTLIST));
  680.         pListSelf->ulType=WPSOBJECTFOLDER;
  681.                                         /* Now allocate required space from shared memory */
  682.         if(pszObjectTitle)
  683.             {
  684.             pData=(VOID *)GetFreeSharedMem(strlen(pszObjectTitle)+1);
  685.                                         /* Copy the folder's name used on the WPS */
  686.             strcpy(pData, pszObjectTitle);
  687.             }
  688.         else
  689.             {
  690.             pData=(VOID *)GetFreeSharedMem(strlen("Unknown")+1);
  691.                                         /* Copy the folder's name used on the WPS */
  692.             strcpy(pData, "Unknown");
  693.             }
  694.                                         /* Link the folder's name into the LIST WPSOBJECTLIST
  695.                                            structure of the newly extracted WPFolder */
  696.         pListSelf->pData=pData;
  697.                                         /* Replace \x0A chars by spaces */
  698.         for(pucFilter=strchr((char *)pListSelf->pData, '\n');
  699.             pucFilter;
  700.             pucFilter=strchr(pucFilter+1, '\n'))
  701.             *pucFilter=' ';
  702.         strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), pListSelf->pData);
  703.         strcat(ucObjectTitle, " >>");
  704.                                         /* If status window is available add WPFolder's object
  705.                                            title to listbox */
  706.         if(DLLPc2Wps.hwndFrameWps2Pc2)
  707.             WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  708.                 LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP(ucObjectTitle));
  709.                                         /* Populate folder */
  710.         if(_wpPopulate(pWPObject, 0L, (PSZ)pListSelf->pData, FALSE))
  711.             {
  712.             WPObject       *pWPObjectInFolder;
  713.             WPSOBJECTLIST  *pListObjectInFolder;
  714.  
  715.                                         /* Enumerate folder and recurively call this
  716.                                            function again to chain through whole tree like
  717.                                            folder structure (depth-first search) */
  718.             for(pWPObjectInFolder=_wpQueryContent(pWPObject, pWPObjectInFolder, QC_FIRST);
  719.                 pWPObjectInFolder!=NULL;
  720.                 pWPObjectInFolder=_wpQueryContent(pWPObject, pWPObjectInFolder, QC_NEXT))
  721.                 {
  722.                                         /* Call function recursively to extract object by object
  723.                                            in this folder. The returned pointer pListSelf can
  724.                                            subsequently be linked into the LIST pListCurrent */
  725.                 pListObjectInFolder=ConvertObject2MenuData(pWPObjectInFolder, ulRecursionLevel+1);
  726.                                         /* Now add the extracted objects within the folder to as
  727.                                            child objects within the current LIST level pListCurrent.
  728.                                            The returned pListObjectInFolder is not NULL only for
  729.                                            WPProgram and WPFolder type WPS Objects */
  730.                 if(pListObjectInFolder)
  731.                     {
  732.                     if(pListSelf->pFolder)
  733.                         {               /* If this is not the first element within the current folder
  734.                                            to be inserted, insert it as the last one */
  735.                         WPSOBJECTLIST  *pListTemp;
  736.  
  737.                                         /* Find the last element, which is the one that has nothing
  738.                                            following */
  739.                         for(pListTemp=pListSelf->pFolder; pListTemp->pNext; pListTemp=pListTemp->pNext);
  740.                         pListTemp->pNext=pListObjectInFolder;
  741.                         }
  742.                     else
  743.                         {               /* If this is the first element within the current folder
  744.                                            to be inserted, insert it as the first one */
  745.                         pListSelf->pFolder=pListObjectInFolder;
  746.                         }
  747.                     }
  748.                 }
  749.             }
  750.         return(pListSelf);              /* Return the newly created WPFolder element */
  751.         }
  752.                                         /* If the current object is not of class WPFolder or
  753.                                            WPProgram, the last thing we may try to extract that
  754.                                            may be of use for PC/2 is the ObjectID */
  755.     if(pszObjectID)
  756.         {
  757.                                         /* Allocate a WPSOBJECTLIST structure for the current
  758.                                            WPObject type WPS object */
  759.         pListSelf=(WPSOBJECTLIST *)GetFreeSharedMem(sizeof(WPSOBJECTLIST));
  760.         pListSelf->ulType=WPSOBJECTOBJECT;
  761.         if(pszObjectTitle)
  762.             {
  763.                                         /* Now allocate required space from shared memory */
  764.             pData=(VOID *)GetFreeSharedMem(strlen(pszObjectTitle)+strlen(pszObjectID)+3);
  765.                                         /* Copy the ObjectID used on the WPS */
  766.             strcpy(pData, pszObjectTitle);
  767.             strcat(pData, "@");
  768.             strcat(pData, pszObjectID);
  769.             }
  770.         else
  771.             {
  772.             pData=(VOID *)GetFreeSharedMem(strlen("Unknown")+strlen(pszObjectID)+3);
  773.                                         /* Copy the ObjectID used on the WPS */
  774.             strcpy(pData, "Unknown");
  775.             strcat(pData, "@");
  776.             strcat(pData, pszObjectID);
  777.             }
  778.                                         /* Link the WPObject's ObjectID into the LIST WPSOBJECTLIST
  779.                                            structure of the newly extracted WPObject */
  780.                                         /* If status window is available add WPObjects's
  781.                                            ObjectID to listbox */
  782.         pListSelf->pData=pData;
  783.                                         /* Replace \x0A chars by spaces */
  784.         for(pucFilter=strchr((char *)pListSelf->pData, '\n');
  785.             pucFilter;
  786.             pucFilter=strchr(pucFilter+1, '\n'))
  787.             *pucFilter=' ';
  788.         strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), pListSelf->pData);
  789.                                         /* If status window is available add WPObjects's
  790.                                            ObjectID to listbox */
  791.         if(DLLPc2Wps.hwndFrameWps2Pc2)
  792.             WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  793.                 LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP(ucObjectTitle));
  794.         return(pListSelf);              /* Return the newly created WPObject element */
  795.         }
  796.     return(NULL);                       /* For all other WPS Objects return NULL */
  797. }
  798.  
  799. /*
  800.  *
  801.  *  FUNCTION: AllocateSharedMem()                                            (x) Private
  802.  *                                                                           ( ) Public
  803.  *  DESCRIPTION:
  804.  *       This function allocates a memory block of an unnamed shared memory, whose
  805.  *       starting address is passed to PC2.EXE via Drag'n Drop which also frees this
  806.  *       memory (otherwise WPS2PC2.DLL provides a menuitem to free it) before a new
  807.  *       shared memory can be allocated. The allocated memory is not commited, so any
  808.  *       access leads to an access violation, which invokes the exception handler to
  809.  *       commit it.
  810.  *
  811.  */
  812.  
  813. PBYTE   AllocateSharedMem()
  814. {
  815.     APIRET      rc;                     /* DOS APIs return code */
  816.  
  817.                                         /* Allocate 128kB unnamed shared memory */
  818.     rc=DosAllocSharedMem((PVOID *)&DLLPc2Wps.pbSharedMem, (PSZ)NULL, 131072,
  819.         OBJ_GIVEABLE | OBJ_GETTABLE | PAG_READ | PAG_WRITE);
  820.                                         /* If successful return it, otherwise return NULL */
  821.     if(rc==NO_ERROR)
  822.         DLLPc2Wps.pbSharedMemNextFree=DLLPc2Wps.pbSharedMem;
  823.     else
  824.         {
  825.         DLLPc2Wps.pbSharedMemNextFree=DLLPc2Wps.pbSharedMem=NULL;
  826.         DebugBox("WPS 2 PC/2", "Allocating shared memory failed");
  827.         }
  828.     return(DLLPc2Wps.pbSharedMem);
  829. }
  830.  
  831. /*
  832.  *
  833.  *  FUNCTION: GetFreeSharedMem()                                             (x) Private
  834.  *                                                                           ( ) Public
  835.  *  DESCRIPTION:
  836.  *      This function allocated the next free ulSharedMemSize sized block within the
  837.  *      shared memory allocated by AllocateSharedMem(). Pointer DLLPc2Wps.pbSharedMemNextFree
  838.  *      is updated accordingly.
  839.  *
  840.  */
  841.  
  842. PBYTE   GetFreeSharedMem(ULONG ulSharedMemSize)
  843. {
  844.     PBYTE       pbSharedMemReturned;
  845.  
  846.                                         /* We can suballocate only when a shared memory
  847.                                            was allocated before */
  848.     if(DLLPc2Wps.pbSharedMem)
  849.         {
  850.                                         /* Round up to nearest DWORD boundary */
  851.         ulSharedMemSize=(ulSharedMemSize+3)&0xFFFFFFFC;
  852.                                         /* Allocate requested shared memory and clear it */
  853.         pbSharedMemReturned=DLLPc2Wps.pbSharedMemNextFree;
  854.         memset(pbSharedMemReturned, '\0', ulSharedMemSize);
  855.         DLLPc2Wps.pbSharedMemNextFree+=ulSharedMemSize;
  856.                                         /* Return suballocated shared memory */
  857.         return(pbSharedMemReturned);
  858.         }
  859.     else                                /* If no shared memory is available return NULL */
  860.         return(NULL);
  861. }
  862.  
  863. /*
  864.  *
  865.  *  FUNCTION: DeAllocateSharedMem()                                          (x) Private
  866.  *                                                                           ( ) Public
  867.  *  DESCRIPTION:
  868.  *       This function deallocates the unnamed shared memory allocated with AllocateSharedMem().
  869.  *       The control structure entries about shared memory are updated accordingly.
  870.  *
  871.  */
  872.  
  873. void    DeAllocateSharedMem(void)
  874. {
  875.                                         /* Return unnamed shared memory to memory pool */
  876.     DosFreeMem(DLLPc2Wps.pbSharedMem);
  877.     DLLPc2Wps.pbSharedMem=DLLPc2Wps.pbSharedMemNextFree=NULL;
  878. }
  879.  
  880. /*
  881.  *
  882.  *  FUNCTION: _Exception()                                                   (x) Private
  883.  *                                                                           ( ) Public
  884.  *  DESCRIPTION:
  885.  *       This function is the exception handler for WPS2PC2.DLL. It is only used to commit
  886.  *       unnamed shared memory, which was allocated uncommited and accessed, leading to an
  887.  *       access violation.
  888.  *
  889.  */
  890.  
  891. ULONG   _Exception(PEXCEPTIONREPORTRECORD pExcRepRecord,
  892.                    PEXCEPTIONREGISTRATIONRECORD pExcRegRecord,
  893.                    PCONTEXTRECORD pCtxRecord,
  894.                    PVOID  pVoid)
  895. {
  896.                                         /* If exception was an access violation, not being
  897.                                            at an unknown address */
  898.     if((pExcRepRecord->ExceptionNum==XCPT_ACCESS_VIOLATION) &&
  899.         (pExcRepRecord->ExceptionAddress!=(PVOID)XCPT_DATA_UNKNOWN))
  900.         {
  901.                                         /* If it was an read or write violation, commit
  902.                                            shared memory block (current 4096B memory page) */
  903.         if((pExcRepRecord->ExceptionInfo[0]==XCPT_READ_ACCESS) ||
  904.             (pExcRepRecord->ExceptionInfo[0]==XCPT_WRITE_ACCESS) ||
  905.             (pExcRepRecord->ExceptionInfo[1]!=XCPT_DATA_UNKNOWN))
  906.             {
  907.             ULONG   ulMemSize;
  908.             ULONG   ulMemAttrs;
  909.             APIRET  rc;                 /* DOS APIs return code */
  910.  
  911.             ulMemSize=1;
  912.             rc=DosQueryMem((PVOID)pExcRepRecord->ExceptionInfo[1],
  913.                 &ulMemSize, &ulMemAttrs);
  914.                                         /* On error continue exception handler chain
  915.                                            probably leading to a trap */
  916.             if(rc!=NO_ERROR) return(XCPT_CONTINUE_SEARCH);
  917.                                         /* If memory is not commited and free, commit it */
  918.             if(!(ulMemAttrs & (PAG_FREE|PAG_COMMIT)))
  919.                 {
  920.                                         /* Commit current 4096B page with same access protection
  921.                                            used during creation */
  922.                 rc=DosSetMem((PVOID)pExcRepRecord->ExceptionInfo[1], 4096,
  923.                     PAG_COMMIT|PAG_DEFAULT);
  924.                                         /* On error continue exception handler chain
  925.                                            probably leading to a trap */
  926.                 if(rc!=NO_ERROR) return(XCPT_CONTINUE_SEARCH);
  927.                                         /* On success continue execution at access violation */
  928.                 else return(XCPT_CONTINUE_EXECUTION);
  929.                 }
  930.             }
  931.         }
  932.                                         /* For other exceptions continue handler chain to
  933.                                            next exception handler */
  934.     return(XCPT_CONTINUE_SEARCH);
  935. }
  936.  
  937. /*
  938.  *
  939.  *  FUNCTION: WPS2PC2_MainWindowProc()                                       (x) Private
  940.  *                                                                           ( ) Public
  941.  *  DESCRIPTION:
  942.  *       This function is the main window procedure of the window created when selecting
  943.  *       "Open -> WPS 2 PC/2" from the "Open ->" submenu at the context menu.
  944.  *
  945.  */
  946.  
  947. MRESULT WPS2PC2_MainWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  948. {
  949.     static HBITMAP  hbmEmpty;           /* Bitmap handle of empty status bitmap */
  950.     static HBITMAP  hbmFull;            /* Bitmap handle of filled status bitmap */
  951.     switch(msg)
  952.     {
  953.     case WM_CREATE:
  954.         {
  955.         ULONG       ulTemp;
  956.         HPS         hpsTemp;
  957.  
  958.         WinDefWindowProc(hwnd, msg, mp1, mp2);
  959.                                         /* Add the window to the in-use list */
  960.         DLLPc2Wps.UseItem.type=USAGE_OPENVIEW;
  961.         DLLPc2Wps.ViewItem.view=ID_WPS2PC2OPENMENU;
  962.         DLLPc2Wps.ViewItem.handle=DLLPc2Wps.hwndFrameWps2Pc2;
  963.         if(!_wpAddToObjUseList(DLLPc2Wps.psomSelf, &DLLPc2Wps.UseItem))
  964.             DebugBox("WPS 2 PC/2", "wpAddToObjUseList failed");
  965.                                         /* Register the window as a new open view */
  966.         if(!_wpRegisterView(DLLPc2Wps.psomSelf, DLLPc2Wps.hwndFrameWps2Pc2,
  967.             _wpQueryTitle(DLLPc2Wps.psomSelf)))
  968.             DebugBox("WPS 2 PC/2", "wpRegisterView failed");
  969.         for(ulTemp=0; ulTemp<CLIENTAREASIZE; ulTemp++)
  970.             {
  971.             HWND    hwndCtl;
  972.  
  973.             hwndCtl=WinCreateWindow(DLLPc2Wps.hwndFrameWps2Pc2, ClientArea[ulTemp].pszClass,
  974.                 ClientArea[ulTemp].pszName, ClientArea[ulTemp].flStyle,
  975.                 ClientArea[ulTemp].ptlPosition.x, ClientArea[ulTemp].ptlPosition.y,
  976.                 ClientArea[ulTemp].ptlSize.x, ClientArea[ulTemp].ptlSize.y,
  977.                 DLLPc2Wps.hwndFrameWps2Pc2, HWND_TOP,
  978.                 ClientArea[ulTemp].Id, 0, NULL);
  979.             if(!hwndCtl)
  980.                 DebugBox("WPS 2 PC/2", "Creating windows in client area failed");
  981.             }
  982.                                         /* Insert LIST into listbox (the called function
  983.                                            takes care of a possibly empty LIST */
  984.         FillList2Listbox(DLLPc2Wps.pListRoot, 1);
  985.                                         /* Get a PS to load status bitmaps */
  986.         hpsTemp=WinBeginPaint(hwnd, NULLHANDLE, NULL);
  987.         hbmEmpty=GpiLoadBitmap(hpsTemp, DLLPc2Wps.hDLLWps2Pc2, WPBM_EMPTY, 0, 0);
  988.         hbmFull=GpiLoadBitmap(hpsTemp, DLLPc2Wps.hDLLWps2Pc2, WPBM_FULL, 0, 0);
  989.         WinEndPaint(hpsTemp);
  990.                                         /* Set focus to client area */
  991.         WinSetFocus(HWND_DESKTOP, hwnd);
  992.         }
  993.         break;
  994.  
  995.     case WM_PAINT:
  996.         {
  997.         HPS         hpsClient;
  998.         RECTL       rectlClient;
  999.  
  1000.  
  1001.         hpsClient=WinBeginPaint(hwnd, NULLHANDLE, &rectlClient);
  1002.         WinFillRect(hpsClient, &rectlClient, CLR_WHITE);
  1003.         if(DLLPc2Wps.pListRoot)
  1004.             {                           /* If at least one WPS Object has been extracted
  1005.                                            already, draw filled status bitmap */
  1006.             WinDrawBitmap(hpsClient, hbmFull, NULL, &StatusArea.ptlPosition, 0, 0, DBM_NORMAL);
  1007.             }
  1008.         else
  1009.             {                           /* If no WPS Object has been extracted, draw
  1010.                                            empty status bitmap */
  1011.             WinDrawBitmap(hpsClient, hbmEmpty, NULL, &StatusArea.ptlPosition, 0, 0, DBM_NORMAL);
  1012.  
  1013.             }
  1014.         WinEndPaint(hpsClient);
  1015.         break;
  1016.         }
  1017.  
  1018.     case WM_BEGINDRAG:
  1019.         {
  1020.         DRAGINFO   *pDraginfo;
  1021.         DRAGITEM    Dragitem;
  1022.         DRAGIMAGE   Dragimage;
  1023.         HPS         hpsTemp;
  1024.         HWND        hwndTarget;
  1025.  
  1026.         if(!DLLPc2Wps.pbSharedMem)      /* If nothing is available to be dragged,
  1027.                                            don't accept Drag'n Drop request */
  1028.             break;
  1029.         hpsTemp=WinBeginPaint(hwnd, NULLHANDLE, NULL);
  1030.         pDraginfo=DrgAllocDraginfo(1);  /* Allocate and initialize a DRAGINFO structure */
  1031.         pDraginfo->cbDraginfo=sizeof(DRAGINFO);
  1032.         pDraginfo->cbDragitem=sizeof(DRAGITEM);
  1033.         pDraginfo->usOperation=DO_MOVE; /* The shared memory passed during Drag'n Drop is
  1034.                                            moved, that is freed in WPS2PC2.DLL */
  1035.         pDraginfo->hwndSource=hwnd;
  1036.         pDraginfo->xDrop=
  1037.         pDraginfo->yDrop=0;
  1038.         pDraginfo->cditem=1;            /* We drop one item, the pointer to the shared memory */
  1039.         pDraginfo->usReserved=0;
  1040.                                         /* Initialize the item we drag */
  1041.         Dragitem.ulItemID=(ULONG)DLLPc2Wps.pbSharedMem;
  1042.         Dragitem.hstrType=DrgAddStrHandle(DRT_WPS2PC2);
  1043.         Dragitem.hstrRMF=DrgAddStrHandle(RMF_WPS2PC2);
  1044.         Dragitem.hstrContainerName=DrgAddStrHandle(_wpQueryTitle(DLLPc2Wps.psomSelf));
  1045.         Dragitem.hstrSourceName=DrgAddStrHandle("");
  1046.         Dragitem.hstrTargetName=DrgAddStrHandle("");
  1047.         Dragitem.cxOffset=
  1048.         Dragitem.cyOffset=0;
  1049.                                         /* Object can't be recoverd after move operation */
  1050.         Dragitem.fsControl=DC_REMOVEABLEMEDIA;
  1051.         Dragitem.fsSupportedOps=DO_MOVEABLE;
  1052.                                         /* Initialize the image we drag */
  1053.         Dragimage.cb=sizeof(DRAGIMAGE);
  1054.         Dragimage.cptl=0;
  1055.         Dragimage.hImage=GpiLoadBitmap(hpsTemp, DLLPc2Wps.hDLLWps2Pc2, WPBM_FULL, 0, 0);
  1056.                                         /* Size the WPBM_FULL bitmap to icon size and
  1057.                                            use it as the image during Drag'n Drop */
  1058.         Dragimage.sizlStretch.cx=
  1059.         Dragimage.sizlStretch.cy=WinQuerySysValue(HWND_DESKTOP, SV_CXICON);
  1060.         Dragimage.fl=DRG_BITMAP | DRG_STRETCH;
  1061.         Dragimage.cxOffset=
  1062.         Dragimage.cyOffset=0;
  1063.                                         /* Add DRAGITEM to DRAGINFO before calling DrgDrag() */
  1064.         DrgSetDragitem(pDraginfo, &Dragitem, sizeof(DRAGITEM), 0);
  1065.                                         /* Now start dragging */
  1066.         hwndTarget=DrgDrag(hwnd, pDraginfo, &Dragimage, 1, VK_ENDDRAG, NULL);
  1067.         DrgFreeDraginfo(pDraginfo);
  1068.         WinEndPaint(hpsTemp);
  1069.         if(hwndTarget)
  1070.             {                           /* If Drag'n Drop operation was successfull,
  1071.                                            deallocated dragged shared memory */
  1072.                                         /* If unnamed shared memory was already allocated
  1073.                                            free it */
  1074.             DosFreeMem(DLLPc2Wps.pbSharedMem);
  1075.             DLLPc2Wps.pbSharedMem=DLLPc2Wps.pbSharedMemNextFree=NULL;
  1076.             DLLPc2Wps.pListRoot=NULL;   /* The LIST is empty again */
  1077.                                         /* Delete all listbox entries */
  1078.             WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  1079.                 LM_DELETEALL, NULL, NULL);
  1080.             }
  1081.         }
  1082.                                         /* Invalidate client area to redraw status bitmap */
  1083.         WinInvalidateRect(DLLPc2Wps.hwndClientWps2Pc2, NULL, FALSE);
  1084.         break;
  1085.  
  1086.     case WM_COMMAND:
  1087.         switch(SHORT1FROMMP(mp1))
  1088.         {
  1089.         case WPPB_CLEAR:
  1090.                                         /* The user has requested to delete the LIST of
  1091.                                            WPS Objects extracted so far */
  1092.             if(DLLPc2Wps.pbSharedMem)
  1093.                 {                       /* If unnamed shared memory was already allocated
  1094.                                            free it */
  1095.                 DosFreeMem(DLLPc2Wps.pbSharedMem);
  1096.                 DLLPc2Wps.pbSharedMem=DLLPc2Wps.pbSharedMemNextFree=NULL;
  1097.                 }
  1098.             DLLPc2Wps.pListRoot=NULL;   /* The LIST is empty again */
  1099.                                         /* Delete all listbox entries */
  1100.             WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  1101.                 LM_DELETEALL, NULL, NULL);
  1102.                                         /* Invalidate client area to redraw status bitmap */
  1103.             WinInvalidateRect(DLLPc2Wps.hwndClientWps2Pc2, NULL, FALSE);
  1104.             break;
  1105.  
  1106.          case WPPB_HELP:
  1107.                                         /* Display help */
  1108.             _wpDisplayHelp(DLLPc2Wps.psomSelf, WPID_WPS2PC2DIALOG, PC2_WPS2PC2_HELP);
  1109.             break;
  1110.         }
  1111.         break;
  1112.  
  1113.     case WM_CLOSE:
  1114.         if(!_wpDeleteFromObjUseList(DLLPc2Wps.psomSelf, &DLLPc2Wps.UseItem))
  1115.             DebugBox("WPS 2 PC/2", "wpDeleteFromObjUseList failed");
  1116.                                         /* Destray allocated PM resources */
  1117.         GpiDeleteBitmap(hbmEmpty);
  1118.         GpiDeleteBitmap(hbmFull);
  1119.         WinDestroyWindow(DLLPc2Wps.hwndFrameWps2Pc2);
  1120.         DLLPc2Wps.hwndFrameWps2Pc2=DLLPc2Wps.hwndClientWps2Pc2=NULLHANDLE;
  1121.         break;
  1122.  
  1123.     default:                            /* Default window procedure must be called */
  1124.         return((MRESULT)WinDefWindowProc(hwnd, msg, mp1, mp2));
  1125.     }
  1126.     return((MRESULT)FALSE);             /* We have handled the message */
  1127. }
  1128.  
  1129. void *time(void *timer)
  1130. {
  1131. return(timer);
  1132. }
  1133.  
  1134. /*
  1135.  *
  1136.  *  FUNCTION: FillList2Listbox()                                             (x) Private
  1137.  *                                                                           ( ) Public
  1138.  *  DESCRIPTION:
  1139.  *       This function fills the listbox WPLB_EXTRACTEDOBJECT with the current contents of
  1140.  *       the LIST DLLPc2Wps.pListRoot. This is necessary, when WPS Objects have been
  1141.  *       dropped onto WPS 2 PC/2's Object icon, but the WPS 2 PC/2 Object was not open.
  1142.  *       This function is called during WM_CREATE of the window that gets created when
  1143.  *       the Object WPS 2 PC/2 is opened.
  1144.  *
  1145.  */
  1146.  
  1147. void    FillList2Listbox(WPSOBJECTLIST *pListRoot, ULONG ulRecursionLevel)
  1148. {
  1149.                                         /* Buffer to write WPS Object title into
  1150.                                            WPLB_EXTRACTEDOBJECTS */
  1151.     static UCHAR
  1152.                 ucObjectTitle[CCHMAXPATH];
  1153.     WPSOBJECTLIST
  1154.                *pListTemp;
  1155.  
  1156.     pListTemp=pListRoot;
  1157.     while(pListTemp)
  1158.         {                               /* An empty list can't be inserted (test just to be
  1159.                                            sure to avoid access vialoations) */
  1160.                                         /* Fill buffer with spaces, because the number of spaces
  1161.                                            preceeding the WPS Object title is a measure of the
  1162.                                            current recursion depth */
  1163.         memset(ucObjectTitle, ' ', sizeof(ucObjectTitle));
  1164.         if(pListTemp->ulType==WPSOBJECTFOLDER)
  1165.             {                           /* If this item was extracted from a WPFolder, pData points
  1166.                                            to the character string of a folder's name */
  1167.             strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), (char *)pListTemp->pData);
  1168.             strcat(ucObjectTitle, " >>");
  1169.             }
  1170.         if(pListTemp->ulType==WPSOBJECTPROGRAM)
  1171.             {                           /* If this item was extracted from a WPProgram, pData points to
  1172.                                            a PROGDETAILS structure, containing the program's properties */
  1173.             strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), ((PROGDETAILS *)pListTemp->pData)->pszTitle);
  1174.             }
  1175.         if(pListTemp->ulType==WPSOBJECTOBJECT)
  1176.             {                           /* If this item was extracted neiter from a WPFolder nor a
  1177.                                            WPProgram, but has an ObjectID, pData points to the character
  1178.                                            string of the WPObject's ObjectID */
  1179.             strcpy(ucObjectTitle+((ulRecursionLevel-1)<<2), (char *)pListTemp->pData);
  1180.             }
  1181.                                         /* Insert into listbox */
  1182.         WinSendMsg(WinWindowFromID(DLLPc2Wps.hwndFrameWps2Pc2, WPLB_EXTRACTEDOBJECTS),
  1183.             LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP(ucObjectTitle));
  1184.                                         /* If the current LIST element is a folder, insert
  1185.                                            recursively the folder contents. The pointer
  1186.                                            pTempList->pFolder may be NULL, the function
  1187.                                            will return immediately */
  1188.         if(pListTemp->ulType==WPSOBJECTFOLDER)
  1189.             FillList2Listbox(pListTemp->pFolder, ulRecursionLevel+1);
  1190.                                         /* Adjust to next LIST element */
  1191.         pListTemp=pListTemp->pNext;
  1192.         }
  1193. }
  1194.  
  1195.