home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wfedit.zip / wfedit.C next >
C/C++ Source or Header  |  1993-12-02  |  28KB  |  780 lines

  1. /*+--------------------------------------------------------------------------+*/
  2. /*|WF/2 Editor DDE sample                                                    |*/
  3. /*|--------------------------------------------------------------------------|*/
  4. /*|                                                                          |*/
  5. /*| PROGRAM NAME: WFEDIT                                                     |*/
  6. /*| -------------                                                            |*/
  7. /*|                                                                          |*/
  8. /*| COPYRIGHT:                                                               |*/
  9. /*| ----------                                                               |*/
  10. /*|  Copyright (C) International Business Machines Corp., 1991,1992,1993.    |*/
  11. /*|                                                                          |*/
  12. /*| DISCLAIMER OF WARRANTIES:                                                |*/
  13. /*| -------------------------                                                |*/
  14. /*| The following [enclosed] code is sample code created by IBM              |*/
  15. /*| Corporation.  This sample code is not part of any standard IBM product   |*/
  16. /*| and is provided to you solely for the purpose of assisting you in the    |*/
  17. /*| development of your applications.  The code is provided "AS IS",         |*/
  18. /*| without warranty of any kind.  IBM shall not be liable for any damages   |*/
  19. /*| arising out of your use of the sample code, even if they have been       |*/
  20. /*| advised of the possibility of such damages.                              |*/
  21. /*|                                                                          |*/
  22. /*| REVISION LEVEL: 2.1                                                      |*/
  23. /*| -------------------                                                      |*/
  24. /*|                                                                          |*/
  25. /*|  This program illustrates the editor side of the DDE and D&D protocols   |*/
  26. /*|  used by WorkFrame/2 version 1.x and 2.1.                                |*/
  27. /*|                                                                          |*/
  28. /*|  You can send any questions through Internet at KEHM@VNET.IBM.COM        |*/
  29. /*|                                                                          |*/
  30. /*+--------------------------------------------------------------------------+*/
  31. #define INCL_DOSFILEMGR
  32. #define INCL_WINDDE
  33. #define INCL_WINFRAMEMGR
  34. #define INCL_WINHELP
  35. #define INCL_WINLISTBOXES
  36. #define INCL_WINMENUS
  37. #define INCL_WINPOINTERS
  38. #define INCL_WINSTDDRAG
  39. #define INCL_WINSYS
  40. #define INCL_ERRORS
  41. #include <os2.h>
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46.  
  47. #include "wkfedit.h"   /* DDE signatures       */
  48. #include "wfedit.h"    /* resource definitions */
  49.  
  50.  
  51. /* ----------------------------------------------------------------- */
  52. /* Function prototypes                                               */
  53. /* ----------------------------------------------------------------- */
  54. FNWP       fnwpClientWndProc;
  55.  
  56. MRESULT    mrCreate       ( HWND hwnd );
  57. MRESULT    mrDragOver     ( HWND hwnd, PDRAGINFO pDraginfo );
  58. MRESULT    mrDrop         ( HWND hwnd, PDRAGINFO pDraginfo );
  59. MRESULT    mrDropHelp     ( HWND hwnd, PDRAGINFO pDraginfo );
  60. MRESULT    mrPaint        ( HWND hwnd, CHAR *szErrorMsg );
  61. MRESULT    mrSize         ( HWND hwnd, MPARAM mp2 );
  62.  
  63. VOID       ddeExecute     ( HWND hwnd, HWND hwndMsg, PDDESTRUCT pDDE );
  64. VOID       ddeInitiate    ( HWND hwnd, HWND hwndMsg, PDDEINIT pDDEi );
  65. PDDESTRUCT pddeMakeRequest( USHORT usFormat,
  66.                             PSZ    pszItemName,
  67.                             PVOID  pvData,
  68.                             USHORT usDataSize );
  69. BOOL       ddeSendGoto    ( HWND hwnd );
  70. VOID       ddeTerminate   ( HWND hwnd, HWND hwndMsg );
  71.  
  72.  
  73. /* ----------------------------------------------------------------- */
  74. /* Globals                                                           */
  75. /* ----------------------------------------------------------------- */
  76. CHAR szClientClass[] = "WorkFrame/2 Sample Editor";
  77.  
  78. HAB  hAB;                              /* anchor block handle        */
  79. HMQ  hMQ;                              /* message queue handle       */
  80. HWND hwndFrame;                        /* frame window handle        */
  81. HWND hwndClient;                       /* client window handle       */
  82. HWND hwndMenu;                         /* menu window handle         */
  83. HWND hwndHelp;                         /* help instance handle       */
  84.  
  85. BOOL fConnected;                       /* DDE connection status      */
  86. HWND hwndDDE;                          /* DDE client window handle   */
  87. CHAR szTopicName[CCHMAXPATH];          /* DDE topic name buffer      */
  88.  
  89. CHAR szSourceFile[CCHMAXPATH];         /* qualified source name      */
  90. CHAR szLibraryFile[CCHMAXPATH];        /* library name buffer        */
  91.  
  92. CHAR szErrorLine[300];                 /* error text buffer          */
  93.  
  94. PULONG pulErrorLines;                  /* array of error lines       */
  95. PULONG pulErrorOffsets;                /* array of error offsets     */
  96. PULONG pulCookies;                     /* array of error cookies     */
  97.  
  98. ULONG ulErrorCount=0L;                 /* error count                */
  99. ULONG ulErrorIndex=0L;                 /* error index                */
  100. ULONG ulErrorLimit=0L;                 /* error limit                */
  101.  
  102. ULONG ulCurrentError;                  /* current error line         */
  103. ULONG ulCurrentOffset;                 /* current error offset       */
  104. ULONG ulCurrentCookie;                 /* current magic cookie       */
  105. ULONG ulCurrentResID;                  /* current resource ID        */
  106.  
  107.  
  108. /* ----------------------------------------------------------------- */
  109. /* Trace definitions                                                 */
  110. /* ----------------------------------------------------------------- */
  111.  
  112. HWND hwndTrace;                        /* listbox window handle      */
  113. CHAR szTrace[CCHMAXPATH+128];          /* Trace data buffer          */
  114.  
  115. #define TRACE(hwnd,psz) \
  116. {SHORT s = (SHORT)WinSendMsg(hwnd,LM_INSERTITEM,MPFROMSHORT(LIT_END), \
  117.    MPFROMP(psz)); WinSendMsg(hwnd,LM_SETTOPINDEX,MPFROMSHORT(s),NULL);}
  118.  
  119. #define FRAMEFLAGS \
  120.         FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU                  \
  121.         | FCF_SIZEBORDER | FCF_MINMAX | FCF_TASKLIST
  122.  
  123.  
  124. /* ----------------------------------------------------------------- */
  125. /* main()                                                            */
  126. /* ----------------------------------------------------------------- */
  127.  
  128. int main( int argc, char** argv )
  129.    {
  130.    ULONG flFrameFlags =  FRAMEFLAGS;
  131.    QMSG  qMsg;
  132.  
  133.  
  134.    /* Fetch filename if specified */
  135.    if( argc != 2 )
  136.       *szSourceFile = (char) NULL;
  137.    else
  138.       strcpy( szSourceFile, argv[1] );
  139.  
  140.  
  141.    /* --------------------------------------------------------------- */
  142.    /* Initialize with Presentation Mangager                           */
  143.    /* --------------------------------------------------------------- */
  144.    hAB = WinInitialize(0);
  145.    hMQ = WinCreateMsgQueue(hAB, 0);
  146.    WinRegisterClass( hAB, szClientClass, fnwpClientWndProc, 0L, 0 );
  147.  
  148.    hwndFrame = WinCreateStdWindow( HWND_DESKTOP,
  149.                                    WS_VISIBLE,
  150.                                    &flFrameFlags,
  151.                                    szClientClass,
  152.                                    NULL,
  153.                                    0L,
  154.                                    (HMODULE)NULL,
  155.                                    ID_SERVER,
  156.                                    &hwndClient );
  157.  
  158.    hwndMenu = WinWindowFromID( hwndFrame, FID_MENU );
  159.    hwndHelp = NULLHANDLE;
  160.  
  161.    WinSetWindowPos( hwndFrame,
  162.                     HWND_TOP, 200, 200,
  163.                     LONGFROMMR( WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ) )
  164.                           / 2,
  165.                     LONGFROMMR( WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) )
  166.                           / 2,
  167.                     SWP_SIZE | SWP_MOVE);
  168.  
  169.    WinSendMsg( hwndFrame,
  170.                WM_SETICON,
  171.                MPFROMLONG(WinQuerySysPointer( HWND_DESKTOP,
  172.                                               SPTR_APPICON,
  173.                                               FALSE)),
  174.                NULL );
  175.  
  176.    while( WinGetMsg( hAB, &qMsg, NULLHANDLE, 0, 0 ))
  177.       WinDispatchMsg( hAB, &qMsg );
  178.  
  179.    WinDestroyWindow( hwndFrame );
  180.    WinDestroyMsgQueue( hMQ );
  181.    WinTerminate( hAB );
  182.    return( 0 );
  183.    }
  184.  
  185.  
  186. /* ----------------------------------------------------------------- */
  187. /* fnwpClientWndProc()                                               */
  188. /* ----------------------------------------------------------------- */
  189.  
  190. MRESULT fnwpClientWndProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  191.    {
  192.    switch( msg )
  193.       {
  194.       case WM_CREATE:
  195.            return( mrCreate( hwnd ));
  196.  
  197.       case WM_SIZE:
  198.            return( mrSize( hwnd, mp2 ));
  199.  
  200.       case WM_PAINT:
  201.            return( mrPaint( hwnd, szErrorLine ));
  202.  
  203.       case WM_ERASEBACKGROUND:
  204.            return( (MRESULT)TRUE  );
  205.  
  206.       case WM_INITMENU:
  207.            if ( SHORT1FROMMP( mp1 ) == IDM_ERROR )
  208.               {
  209.               WinEnableMenuItem( hwndMenu,
  210.                                  IDM_NEXT,
  211.                                  ( ulErrorIndex < ulErrorLimit ));
  212.               WinEnableMenuItem( hwndMenu,
  213.                                  IDM_PREVIOUS,
  214.                                  ( ulErrorIndex > 0L ));
  215.               }
  216.            break;
  217.  
  218.       case WM_COMMAND:
  219.            switch( LOUSHORT( mp1 ))
  220.               {
  221.               case IDM_NEXT:
  222.                    ++ulErrorIndex;
  223.                    ddeSendGoto( hwnd );
  224.                    return( NULL );
  225.  
  226.               case IDM_PREVIOUS:
  227.                    --ulErrorIndex;
  228.                    ddeSendGoto( hwnd );
  229.                    return( NULL );
  230.  
  231.               case IDM_DESCRIBE:
  232.                    if ( WinSendMsg( hwndHelp,
  233.                                     HM_DISPLAY_HELP,
  234.                                     MPFROMLONG( MAKELONG( ulCurrentResID, NULL )),
  235.                                     MPFROMSHORT( HM_RESOURCEID )))
  236.                       WinAlarm( HWND_DESKTOP, WA_ERROR );
  237.                    return( NULL );
  238.               }
  239.            break;
  240.  
  241.       case WM_CLOSE:
  242.            if ( fConnected )
  243.                WinDdePostMsg( hwndDDE, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  244.            WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
  245.            return( NULL );
  246.  
  247.       case DM_DRAGOVER:
  248.            return( mrDragOver( hwnd, (PDRAGINFO) PVOIDFROMMP( mp1 )));
  249.  
  250.       case DM_DRAGLEAVE:
  251.            return( NULL );
  252.  
  253.       case DM_DROPHELP:
  254.            return( mrDropHelp( hwnd, (PDRAGINFO) PVOIDFROMMP( mp1 )));
  255.  
  256.       case DM_DROP:
  257.            return( mrDrop( hwnd, (PDRAGINFO) PVOIDFROMMP( mp1 )));
  258.  
  259.       case WM_DDE_INITIATE:
  260.            ddeInitiate( hwnd, HWNDFROMMP( mp1 ), PVOIDFROMMP( mp2 ));
  261.            break;
  262.  
  263.       case WM_DDE_EXECUTE:
  264.            ddeExecute( hwnd, HWNDFROMMP( mp1 ), PVOIDFROMMP( mp2 ));
  265.            return( NULL );
  266.  
  267.       case WM_DDE_TERMINATE:
  268.            ddeTerminate( hwnd, HWNDFROMMP( mp1 ));
  269.            break;
  270.  
  271.       case WM_USER:
  272.            if ( *szSourceFile
  273.                 && WinDdeInitiate( hwnd, CV_DDEAPPNAME, szTopicName, NULL ))
  274.               WinSetWindowText( hwndFrame, szSourceFile );
  275.            else
  276.               {
  277.               WinSetWindowText( hwndFrame, szClientClass );
  278.               WinEnableMenuItem( hwndMenu, IDM_ERROR, FALSE );
  279.               }
  280.            return( NULL );
  281.       }
  282.    return( WinDefWindowProc( hwnd, msg, mp1, mp2 ));
  283.    }
  284.  
  285.  
  286. /* ----------------------------------------------------------------- */
  287. /* mrCreate()                                                        */
  288. /* ----------------------------------------------------------------- */
  289.  
  290. MRESULT mrCreate( HWND hwnd )
  291.    {
  292.    RECTL rclClient;
  293.    LONG  cxClient, cyClient;
  294.  
  295.  
  296.    WinQueryWindowRect( hwnd, &rclClient );
  297.    cyClient  = (rclClient.yTop - rclClient.yBottom) / 2;
  298.    cxClient  = (rclClient.xRight - rclClient.xLeft) - 1;
  299.    hwndTrace = WinCreateWindow( hwnd,
  300.                                 WC_LISTBOX,
  301.                                 NULL,
  302.                                 WS_VISIBLE | LS_HORZSCROLL,
  303.                                 0,
  304.                                 0,
  305.                                 cxClient,
  306.                                 cyClient,
  307.                                 hwnd,
  308.                                 HWND_TOP,
  309.                                 ID_TRACE,
  310.                                 NULL,
  311.                                 NULL );
  312.  
  313.    *szErrorLine = '\0';
  314.    fConnected   = FALSE;
  315.    WinPostMsg( hwnd, WM_USER, NULL, NULL );
  316.    return( NULL );
  317.    }
  318.  
  319.  
  320. /* ----------------------------------------------------------------- */
  321. /* mrDragOver()                                                      */
  322. /* ----------------------------------------------------------------- */
  323.  
  324. MRESULT mrDragOver( HWND hwnd, PDRAGINFO pDraginfo )
  325.    {
  326.    PDRAGITEM pDragitem;
  327.    USHORT    usCount;
  328.    USHORT    usIndex;
  329.    USHORT    usIndicator;
  330.  
  331.    DrgAccessDraginfo( pDraginfo );
  332.    usCount     = DrgQueryDragitemCount( pDraginfo );
  333.    usIndicator = DOR_DROP;
  334.  
  335.    for( usIndex = 0; usIndex < usCount; ++usIndex )
  336.       {
  337.       pDragitem = DrgQueryDragitemPtr( pDraginfo, usIndex );
  338.       if ( !DrgVerifyRMF( pDragitem, "DRM_DDE", "DDE3ERRORS" ))
  339.          {
  340.          usIndicator = DOR_NODROP;
  341.          break;
  342.          }
  343.       }
  344.  
  345.    DrgFreeDraginfo( pDraginfo );
  346.  
  347.    return( MRFROM2SHORT( usIndicator, DO_COPY ));
  348.    }
  349.  
  350.  
  351. /* ----------------------------------------------------------------- */
  352. /* mrDrop()                                                          */
  353. /* ----------------------------------------------------------------- */
  354.  
  355. MRESULT mrDrop( HWND hwnd, PDRAGINFO pDraginfo )
  356.    {
  357.    USHORT usCount;
  358.    USHORT usItem;
  359.    PDRAGITEM pDragitem;
  360.  
  361.  
  362.    DrgAccessDraginfo( pDraginfo );
  363.    usCount = DrgQueryDragitemCount( pDraginfo );
  364.  
  365.    for( usItem = 0; usItem < usCount; usItem++ )
  366.       {
  367.       pDragitem = DrgQueryDragitemPtr( pDraginfo, usItem );
  368.       DrgQueryStrName( pDragitem->hstrSourceName,
  369.                        sizeof( szTopicName ),
  370.                        szTopicName );
  371.       DrgQueryStrName( pDragitem->hstrContainerName,
  372.                        sizeof( szSourceFile ),
  373.                        szSourceFile );
  374.  
  375.       sprintf( szTrace, "DROP: %s", szTopicName );
  376.       TRACE( hwndTrace, szTrace );
  377.  
  378.       sprintf( szTrace, "FROM: %s", szSourceFile );
  379.       TRACE( hwndTrace, szTrace );
  380.  
  381.       if( strchr( szTopicName, '\\' ) || strchr( szTopicName, ':' ))
  382.          strcpy( szSourceFile, szTopicName );
  383.       else
  384.          strcat( szSourceFile, szTopicName );
  385.  
  386.       DrgSendTransferMsg( pDragitem->hwndItem,
  387.                           DM_ENDCONVERSATION,
  388.                           MPFROMLONG( pDragitem->ulItemID ),
  389.                           MPFROMSHORT( DMFL_TARGETSUCCESSFUL ));
  390.       }
  391.  
  392.    if ( fConnected )
  393.       {
  394.       WinDdePostMsg( hwndDDE, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  395.       if ( hwndHelp )
  396.          {
  397.          WinDestroyHelpInstance( hwndHelp );
  398.          hwndHelp = NULLHANDLE;
  399.          }
  400.  
  401.       hwndDDE = NULLHANDLE;
  402.       fConnected = FALSE;
  403.       }
  404.  
  405.    WinPostMsg( hwnd, WM_USER, MPFROMHWND(pDraginfo->hwndSource), NULL );
  406.  
  407.    DrgDeleteDraginfoStrHandles( pDraginfo );
  408.    DrgFreeDraginfo( pDraginfo );
  409.    return( NULL );
  410.    }
  411.  
  412.  
  413. /* ----------------------------------------------------------------- */
  414. /* mrDropHelp()                                                      */
  415. /* ----------------------------------------------------------------- */
  416.  
  417. MRESULT mrDropHelp( HWND hwnd, PDRAGINFO pDraginfo )
  418.    {
  419.    DrgAccessDraginfo( pDraginfo );
  420.    WinAlarm( HWND_DESKTOP, WA_NOTE );
  421.  
  422.    if ( hwnd != pDraginfo->hwndSource )
  423.       DrgDeleteDraginfoStrHandles( pDraginfo );
  424.    DrgFreeDraginfo( pDraginfo );
  425.    return( NULL );
  426.    }
  427.  
  428.  
  429. /* ----------------------------------------------------------------- */
  430. /* mrPaint()                                                         */
  431. /* ----------------------------------------------------------------- */
  432.  
  433. MRESULT mrPaint( HWND hwnd, CHAR *szErrorMsg )
  434.    {
  435.    HPS    hPS;
  436.    RECTL  rclPaint;
  437.    LONG   lDivisor;
  438.    CHAR   szPaintStr[91];
  439.    CHAR   szWorkStr[16];
  440.    USHORT i;
  441.    ULONG  j;
  442.    PULONG pulWorklines;
  443.    PULONG pulWorkoff;
  444.    PULONG pulWorkcookie;
  445.  
  446.  
  447.    hPS = WinBeginPaint( hwnd, NULLHANDLE, NULL );
  448.    GpiErase( hPS );
  449.    WinQueryWindowRect( hwnd, &rclPaint );
  450.    rclPaint.yBottom = rclPaint.yTop / 2 + 1;
  451.  
  452.    if( !*szSourceFile )
  453.       WinDrawText( hPS,
  454.                    -1,
  455.                    "No file selected",
  456.                    &rclPaint,
  457.          CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  458.  
  459.    else if ( ulErrorCount == 0 )
  460.       WinDrawText( hPS,
  461.                    -1,
  462.                    "No errors",
  463.                    &rclPaint,
  464.          CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  465.  
  466.    else
  467.       {
  468.       lDivisor = ( rclPaint.yTop - rclPaint.yBottom )
  469.                  / ( 6 + ( ulErrorCount / 5 ));
  470.       rclPaint.yBottom = rclPaint.yTop - lDivisor;
  471.       WinDrawText( hPS,
  472.                    -1,
  473.                    "Error Lines:(line,offset,magic)",
  474.                    &rclPaint,
  475.          CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  476.  
  477.       j = 0;
  478.       pulWorklines  = pulErrorLines;
  479.       pulWorkoff    = pulErrorOffsets;
  480.       pulWorkcookie = pulCookies;
  481.  
  482.       while( j  < ulErrorCount )
  483.          {
  484.          rclPaint.yTop = rclPaint.yBottom;
  485.          rclPaint.yBottom = rclPaint.yTop - lDivisor;
  486.          *szPaintStr = '\0';
  487.          i = 5;
  488.          while(( i > 0 ) && ( j < ulErrorCount ))
  489.             {
  490.             sprintf( szWorkStr,
  491.                      "(%4ld,%3ld,%4ld)",
  492.                      *pulWorklines, *pulWorkoff, *pulWorkcookie );
  493.             ++pulWorklines;
  494.             ++pulWorkoff  ;
  495.             ++pulWorkcookie ;
  496.             strcat( szPaintStr, szWorkStr );
  497.             strcat( szPaintStr, "  " );
  498.             --i;
  499.             ++j;
  500.             }
  501.  
  502.          WinDrawText( hPS,
  503.                       -1,
  504.                       szPaintStr,
  505.                       &rclPaint,
  506.             CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  507.          }
  508.  
  509.       if ( ulCurrentError > 0 )
  510.          {
  511.          sprintf( szPaintStr,
  512.                   "Current Error - %ld,%ld,%ld",
  513.                   ulCurrentError,
  514.  
  515.          ulCurrentOffset, ulCurrentCookie );
  516.          rclPaint.yTop = rclPaint.yBottom;
  517.          rclPaint.yBottom = rclPaint.yTop - lDivisor;
  518.          WinDrawText( hPS,
  519.                       -1,
  520.                       szPaintStr,
  521.                       &rclPaint,
  522.             CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  523.  
  524.          rclPaint.yTop    = rclPaint.yBottom;
  525.          rclPaint.yBottom = rclPaint.yTop - lDivisor;
  526.          WinDrawText( hPS,
  527.                       -1,
  528.                       szErrorMsg,
  529.                       &rclPaint,
  530.             CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  531.  
  532.          sprintf( szPaintStr, "Library - %s (%ld)", szLibraryFile, ulCurrentResID );
  533.          rclPaint.yTop = rclPaint.yBottom;
  534.          rclPaint.yBottom = rclPaint.yTop - lDivisor;
  535.          WinDrawText( hPS, -1, szPaintStr, &rclPaint,
  536.             CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  537.       }
  538.    }
  539.    WinEndPaint( hPS );
  540.  
  541.    WinInvalidateRect( hwndTrace, NULL, FALSE );
  542.    return( NULL );
  543. }
  544.  
  545.  
  546.  
  547. /* ----------------------------------------------------------------- */
  548. /* mrSize()                                                          */
  549. /* ----------------------------------------------------------------- */
  550.  
  551. MRESULT mrSize( HWND hwnd, MPARAM mp2 )
  552.    {
  553.    LONG  cxClient, cyClient;
  554.  
  555.  
  556.    if ( hwndTrace )
  557.       {
  558.       cyClient = SHORT2FROMMP( mp2 ) / 2;
  559.       cxClient = SHORT1FROMMP( mp2 ) - 1;
  560.       WinSetWindowPos( hwndTrace,
  561.                        HWND_TOP,
  562.                        0,
  563.                        0,
  564.                        cxClient,
  565.                         cyClient,
  566.                        SWP_MOVE | SWP_SIZE | SWP_SHOW );
  567.       }
  568.  
  569.    WinInvalidateRect( hwnd, NULL, FALSE );
  570.    return( NULL );
  571.    }
  572.  
  573.  
  574. /* ----------------------------------------------------------------- */
  575. /* ddeExecute()                                                      */
  576. /* ----------------------------------------------------------------- */
  577.  
  578. VOID ddeExecute( HWND hwnd, HWND hwndMsg, PDDESTRUCT pDDE )
  579.    {
  580.    PULONG pulWorkLines;
  581.    PULONG pulLineWork;
  582.    PULONG pulOffWork;
  583.    PULONG pulCookieWork;
  584.    ULONG ulIndex;
  585.    ULONG ulNewCookie;
  586.    PVOID pvWork;
  587.    HELPINIT hlpInit;
  588.  
  589.  
  590.    if ( pDDE && ( hwndMsg == hwndDDE ))
  591.       {
  592.       sprintf( szTrace, "DDE_EXECUTE: %s", DDES_PSZITEMNAME( pDDE ));
  593.       TRACE( hwndTrace, szTrace );
  594.  
  595.       if ( !strcmp( DDES_PSZITEMNAME( pDDE ), CV_DDEINITIAL ))
  596.          {
  597.          pulWorkLines = (PULONG) DDES_PABDATA( pDDE );
  598.          ulErrorCount = *pulWorkLines;
  599.          ulErrorIndex = 0L;
  600.          ulErrorLimit = ulErrorCount - 1L;
  601.  
  602.          pulErrorLines = malloc( (size_t) ulErrorCount * 4 );
  603.          pulErrorOffsets = malloc( (size_t) ulErrorCount * 4 );
  604.          pulCookies = malloc( (size_t) ulErrorCount * 4 );
  605.  
  606.          pulLineWork = pulErrorLines;
  607.          pulOffWork = pulErrorOffsets;
  608.          pulCookieWork = pulCookies;
  609.          ++pulWorkLines;
  610.  
  611.          for( ulIndex=0; ulIndex < ulErrorCount; ulIndex++ )
  612.             {
  613.             *pulLineWork++ = *pulWorkLines;
  614.             *pulOffWork++ = *(pulWorkLines+1);
  615.                         /* ignore length in pulWorkLines+2) */
  616.             *pulCookieWork++ = *(pulWorkLines+3);
  617.             pulWorkLines += 4;
  618.             }
  619.          strcpy( szLibraryFile, (PSZ)(pulWorkLines+1));
  620.  
  621.          sprintf( szTrace, "LIBRARY: [%s]", szLibraryFile );
  622.          TRACE( hwndTrace, szTrace );
  623.  
  624.          memset( &hlpInit, 0, sizeof( hlpInit ));
  625.          hlpInit.pszHelpLibraryName = szLibraryFile;
  626.          if( hwndHelp = WinCreateHelpInstance( hAB, &hlpInit ))
  627.             WinAssociateHelpInstance( hwndHelp, hwndFrame );
  628.  
  629.          WinEnableMenuItem( hwndMenu, IDM_ERROR, ( ulErrorCount > 0L ));
  630.          WinEnableMenuItem( hwndMenu, IDM_NEXT, ( ulErrorLimit > 0L ));
  631.          WinEnableMenuItem( hwndMenu, IDM_PREVIOUS, FALSE );
  632.          WinInvalidateRect( hwnd, NULL, FALSE );
  633.          }
  634.       else if( !strcmp( DDES_PSZITEMNAME( pDDE ), CV_DDEGOTO ))
  635.          {
  636.          pvWork = (PVOID) DDES_PABDATA( pDDE );
  637.          ulNewCookie = *((PULONG) pvWork+3 );
  638.  
  639.          for( ulIndex = 0; ulIndex < ulErrorCount; ulIndex++ )
  640.             if ( ulNewCookie == pulCookies[ulIndex] )
  641.                {
  642.                if ( ulCurrentCookie != ulNewCookie )
  643.                   {
  644.                   sprintf( szTrace, "Adjust error index (%ld)", ulIndex );
  645.                   TRACE( hwndTrace, szTrace );
  646.                   ulErrorIndex = ulIndex;
  647.  
  648.                   ulCurrentError = *(PULONG) pvWork;
  649.                   ulCurrentOffset = *((PULONG) pvWork+1 );
  650.                   ulCurrentResID = *((PULONG) pvWork+2 );
  651.                   ulCurrentCookie = ulNewCookie;
  652.                   pvWork = (PSZ) pvWork + 20;
  653.                   strcpy( szErrorLine, pvWork );
  654.                   WinInvalidateRect( hwnd, NULL, FALSE );
  655.                   }
  656.                break;
  657.                }
  658.          }
  659.       WinDdePostMsg( hwndDDE, hwnd, WM_DDE_ACK, pDDE, TRUE );
  660.       }
  661.    }
  662.  
  663.  
  664. /* ----------------------------------------------------------------- */
  665. /* ddeInitiate()                                                     */
  666. /* ----------------------------------------------------------------- */
  667.  
  668. VOID ddeInitiate( HWND hwnd, HWND hwndMsg, PDDEINIT pDDEi )
  669.    {
  670.    sprintf( szTrace, "DDE_INITIATE: FROM=%p TO=%p", hwndMsg, hwnd );
  671.    TRACE( hwndTrace, szTrace );
  672.    sprintf( szTrace, "APPNAME: %s", pDDEi->pszAppName ) ;
  673.    TRACE( hwndTrace, szTrace );
  674.    sprintf( szTrace, "TOPIC: %s", pDDEi->pszTopic ) ;
  675.    TRACE( hwndTrace, szTrace );
  676.  
  677.    if ( !fConnected && ( hwndMsg != hwnd )
  678.          && !strcmp( CV_DDEAPPNAME, pDDEi->pszAppName )
  679.          && !strcmp( szTopicName, pDDEi->pszTopic ))
  680.       {
  681.       fConnected = TRUE;
  682.       hwndDDE = hwndMsg;
  683.       WinDdeRespond( hwndDDE, hwnd, CV_DDEAPPNAME, szTopicName, NULL );
  684.       }
  685.    DosFreeMem( pDDEi );   /* REQUIRED msj v4n3 may 89   */
  686.    }
  687.  
  688.  
  689. /* ----------------------------------------------------------------- */
  690. /* pddeMakeRequest()                                                 */
  691. /*                                                                   */
  692. /* Entry:   Format, item name, and fsStatus are valid.               */
  693. /*                                                                   */
  694. /* Exit:    Valid data segment for WM_DDE_DATA message is built.     */
  695. /*                                                                   */
  696. /* Return:  pDDEstruct if successful, otherwise NULL.                */
  697. /*                                                                   */
  698. /* ----------------------------------------------------------------- */
  699.  
  700. PDDESTRUCT pddeMakeRequest( USHORT usFormat, PSZ pszItemName,
  701.    PVOID pvData, USHORT usDataSize )
  702.    {
  703.    PDDESTRUCT pDDE;
  704.    PVOID      pvMemory;
  705.    USHORT     usSegSize;
  706.    USHORT     usTotalSize;
  707.  
  708.    /* Allocate a givable memory segment. */
  709.  
  710.    usSegSize = (USHORT) strlen( pszItemName ) + 1;
  711.    usTotalSize = sizeof( DDESTRUCT ) + usDataSize + usSegSize;
  712.  
  713.    if ( DosAllocSharedMem( &pvMemory, NULL, usTotalSize, fALLOCSHR ))
  714.       {
  715.       WinAlarm( HWND_DESKTOP, WA_ERROR );
  716.       WinAlarm( HWND_DESKTOP, WA_WARNING );
  717.       WinAlarm( HWND_DESKTOP, WA_NOTE );
  718.       return( NULL );
  719.       }
  720.  
  721.    /* Fill in the new DDE structure. */
  722.  
  723.    pDDE = (PDDESTRUCT) pvMemory;
  724.  
  725.    memset( (PVOID) pDDE, 0, (size_t) usSegSize );
  726.    pDDE->usFormat = usFormat;
  727.    pDDE->offszItemName = (USHORT) sizeof( DDESTRUCT );
  728.    memcpy( DDES_PSZITEMNAME( pDDE ), pszItemName, usSegSize );
  729.    pDDE->offabData = (USHORT) sizeof( DDESTRUCT ) + usSegSize;
  730.    memcpy( DDES_PABDATA( pDDE ), pvData, usDataSize );
  731.    pDDE->fsStatus = 0;
  732.    pDDE->cbData = (ULONG) usTotalSize;
  733.  
  734.    return( pDDE );
  735.    }
  736.  
  737.  
  738. /* ----------------------------------------------------------------- */
  739. /* ddeSendGoto()                                                     */
  740. /* ----------------------------------------------------------------- */
  741.  
  742. BOOL ddeSendGoto( HWND hwnd )
  743.    {
  744.    PDDESTRUCT pDDE;
  745.  
  746.  
  747.    pDDE = pddeMakeRequest( DDEFMT_TEXT, CV_SENDGOTO,
  748.       &pulCookies[ ulErrorIndex ], sizeof( PULONG ));
  749.    if ( !pDDE )
  750.       {
  751.       WinAlarm( HWND_DESKTOP, WA_ERROR );
  752.       return( FALSE );
  753.       }
  754.  
  755.    WinDdePostMsg( hwndDDE, hwnd, WM_DDE_DATA, pDDE, TRUE );
  756.    return( TRUE );
  757.    }
  758.  
  759.  
  760. /* ----------------------------------------------------------------- */
  761. /* ddeTerminate()                                                    */
  762. /* ----------------------------------------------------------------- */
  763.  
  764. VOID ddeTerminate( HWND hwnd, HWND hwndMsg )
  765.    {
  766.    TRACE( hwndTrace, "DDE_TERMINATE" );
  767.  
  768.    if ( hwndMsg == hwndDDE )
  769.       {
  770.       WinDdePostMsg( hwndDDE, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  771.       if( hwndHelp )
  772.          WinDestroyHelpInstance( hwndHelp );
  773.       hwndDDE = NULLHANDLE;
  774.       fConnected = FALSE;
  775.       *szSourceFile = '\0';
  776.       WinPostMsg( hwnd, WM_USER, NULL, NULL );
  777.  
  778.       }
  779.    }
  780.