home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / ddeml / ddespy / ddespy.c next >
Encoding:
C/C++ Source or Header  |  1990-06-22  |  22.6 KB  |  741 lines

  1. /***************************** Module Header ******************************\
  2. * Module Name: ddespy
  3. *
  4. * This is a small DDE ddespyr which lets me see whats going on.
  5. *
  6. * Created:      sanfords
  7. *
  8. * Copyright (c) 1988, 1989  Microsoft Corporation
  9. \***************************************************************************/
  10. #include "ddespy.h"
  11.  
  12. /*********** declares *********/
  13.  
  14. HWND hwndExec = NULL;
  15.  
  16. SWP gswp[IW_LAST - IW_FIRST + 1];
  17. PSZ apszTitles[] = {
  18.         "Applications", "Topics", "System Items", "Data"
  19.                    };
  20.  
  21.  
  22. PSZ apszType[] = {
  23.                         "0-Type"        ,
  24.                         "ACK"           ,
  25.                         "ADVDATA"       ,   
  26.                         "ADVREQ"        ,    
  27.                         "ADVSTART"      ,  
  28.                         "ADVSTOP"       ,   
  29.                         "EXEC"          ,      
  30.                         "INIT"          ,
  31.                         "INITCONF"      ,
  32.                         "MONITOR"       ,
  33.                         "PKT"           ,
  34.                         "POKE"          ,
  35.                         "REGISTER"      ,  
  36.                         "REQUEST"       ,
  37.                         "RTNPKT"        ,
  38.                         "TERM"          ,      
  39.                         "UNREGISTER"    ,
  40.                         "WILDINIT"      ,
  41.                         "XFERCOMP"      ,
  42.                         "19"            ,
  43.                         "20"            ,
  44.                         "21"            ,
  45.                         "22"            ,
  46.                         "23"            ,
  47.                         "24"            ,
  48.                         "25"            ,
  49.                         "26"            ,
  50.                         "27"            ,
  51.                         "28"            ,
  52.                         "29"            ,
  53.                         "30"            ,
  54.                         "31"            ,
  55.                };
  56.  
  57. PSZ apszState[] = {         /* corresponds to convinfo.usStatus */
  58.                         "DISCONNECTED"      ,
  59.                         "CONNECTED"         ,
  60.                         "NOADVISE"          ,
  61.                         "ADVISE"            ,
  62.                   };
  63.  
  64. PSZ apszStatus[] = {        /* corresponds to convionfi.usConvst */
  65.                         "NOACTIVITY"    ,     
  66.                         "INCOMPLETE"    ,    
  67.                         "TERMINATED"    ,    
  68.                         "CONNECTED"     ,
  69.                         "INITIATING"    ,         
  70.                         "REQSENT"       ,       
  71.                         "DATARCVD"      ,      
  72.                         "POKESENT"      ,      
  73.                         "POKEACKRCVD"   ,   
  74.                         "EXECSENT"      ,      
  75.                         "EXECACKRCVD"   ,   
  76.                         "ADVSENT"       ,       
  77.                         "UNADVSENT"     ,     
  78.                         "ADVACKRCVD"    ,    
  79.                         "UNADVACKRCVD"  ,  
  80.                         "ADVDATASENT"   ,   
  81.                         "ADVDATAACKRCVD",
  82.                    };
  83.  
  84.  
  85. #define GetLBCount(hw) (SHORT)WinSendMsg((hw), LM_QUERYITEMCOUNT, 0L, 0L)
  86. #define GetLBSelectedItem(hw) \
  87.             (SHORT)WinSendMsg((hw), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, 0L)
  88. #define GetLBItemHandle(hw, i) \
  89.             (ULONG)WinSendMsg((hw), LM_QUERYITEMHANDLE, (MPARAM)(i), 0L)
  90. #define GetLBItemText(hw, i, cch, psz) \
  91.             (ULONG)WinSendMsg((hw), LM_QUERYITEMTEXT, MPFROM2SHORT((i),(cch)), (MPARAM)(psz))
  92. #define DeleteLBItem(hw, i) WinSendMsg(hw, LM_DELETEITEM, MPFROMSHORT(i), 0L)
  93. #define NotifyOwner(hwnd, msg, mp1, mp2) \
  94.             (WinSendMsg(WinQueryWindow(hwnd, QW_OWNER, FALSE), msg, mp1, mp2))
  95.  
  96.  
  97. void cdecl main(int argc, char **argv);
  98. void ResizeChildren(USHORT cxNew, USHORT cyNew);
  99. HDMGDATA EXPENTRY dataxfer(HCONV hConv, HSZ hszTopic, HSZ hszItem,
  100.         USHORT usFmt, USHORT usType, HDMGDATA hDmgData);
  101. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  102. MRESULT EXPENTRY GetTimeoutDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  103. MRESULT EXPENTRY EnhancedEFWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  104. MRESULT EXPENTRY ExecDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  105. void Refresh(void);
  106. SHORT InsertLBItem(HWND hwndLB, PSZ psz, ULONG ulHandle);
  107. void SetLBEntries(HCONV hConv, HSZ hszItem, USHORT iwlb);
  108. void UpdateQueue(HWND hwndCB, HCONV hConv);
  109. void ConvInfoToString(PCONVINFO pci, PSZ psz, USHORT cbMax);
  110. PSZ mylstrcat(PSZ psz1, PSZ psz2, PSZ pszLast);
  111. int lstrlen(PSZ psz);
  112.  
  113. /************* GLOBAL VARIABLES  ************/
  114.  
  115. HAB hab;
  116. HMQ hmq;
  117. HHEAP hheap;
  118. HWND hwndFrame;
  119. HWND hwndClient;
  120. USHORT cyTitles;
  121. USHORT cxBorder;
  122. HCONVLIST hConvListMain;
  123. HSZ hszSysTopic;
  124. HSZ hszSysItemTopics;
  125. HSZ hszSysItemSysItems;
  126. ULONG gTimeout = 1000L;
  127. PFNWP lpfnSysEFWndProc;
  128.  
  129. void cdecl main(argc, argv)
  130. int argc;
  131. char **argv;
  132. {
  133.     USHORT err;
  134.     QMSG qmsg;
  135.  
  136.     argc; argv;
  137.     
  138.     hab = WinInitialize(0);
  139.     hmq = WinCreateMsgQueue(hab, 0);
  140.     hheap = WinCreateHeap(0, 0, 0, 0, 0, HM_MOVEABLE);
  141.  
  142.     if (!WinRegisterClass(hab, "DDESpyr Class", ClientWndProc, CS_SIZEREDRAW, 0))
  143.         goto abort;
  144.  
  145.     cyTitles = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  146.     cxBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
  147.  
  148.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, NULL,
  149.             (PSZ)"DDESpyr Class",
  150.             (PSZ)"", WS_VISIBLE, (HMODULE)NULL, IDR_MAIN,
  151.             &hwndClient);
  152.  
  153.     WinSetWindowText(hwndFrame, "DDE Spy");
  154.     if (err = DdeInitialize((PFNCALLBACK)dataxfer, 0L, 0L)) {
  155.         DdePostError(err);
  156.         goto abort;
  157.     }
  158.  
  159.     hszSysTopic = DdeGetHsz((PSZ)SZDDESYS_TOPIC, 0, 0);
  160.     hszSysItemTopics = DdeGetHsz((PSZ)SZDDESYS_ITEM_TOPICS, 0, 0);
  161.     hszSysItemSysItems = DdeGetHsz((PSZ)SZDDESYS_ITEM_SYSITEMS, 0, 0);
  162.  
  163.     Refresh();
  164.  
  165.     while (WinGetMsg(hab, &qmsg, 0, 0, 0)) {
  166.         WinDispatchMsg(hab, &qmsg);
  167.     }
  168.  
  169.     DdeUninitialize();
  170. abort:
  171.     if (hwndFrame)
  172.         WinDestroyWindow(hwndFrame);
  173.     if (hheap) {
  174.         WinDestroyHeap(hheap);
  175.     }
  176.     WinTerminate(hab);
  177.     DosExit(TRUE, 0);
  178. }
  179.  
  180.  
  181. MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2)
  182. HWND hwnd;
  183. USHORT msg;
  184. MPARAM mp1, mp2;
  185. {
  186.     USHORT i;
  187.  
  188.     switch (msg) {
  189.     case WM_CREATE:
  190.         /*
  191.          * initialize globals
  192.          */
  193.         hwndClient = hwnd;
  194.         for (i = IW_APPSLBOX; i <= IW_ITEMSLBOX; i++) {
  195.             gswp[i].hwnd = WinCreateWindow(hwndClient, WC_LISTBOX, "",
  196.                     WS_VISIBLE | LS_NOADJUSTPOS, 0, 0, 0, 0, hwndClient,
  197.                     HWND_TOP, i, NULL, NULL);
  198.         }
  199.         for (i = IW_APPSTITLE; i <= IW_DATATITLE; i++) {
  200.             gswp[i].hwnd = WinCreateWindow(hwndClient, WC_STATIC,
  201.                     apszTitles[i - IW_APPSTITLE],
  202.                     WS_VISIBLE | SS_TEXT | DT_CENTER | DT_BOTTOM,
  203.                     0, 0, 0, 0, hwndClient,
  204.                     HWND_TOP, i, NULL, NULL);
  205.         }
  206.         gswp[IW_DATATEXT].hwnd = WinCreateWindow(hwndClient, WC_STATIC, "",
  207.                 WS_VISIBLE | SS_TEXT | DT_WORDBREAK,
  208.                 0, 0, 0, 0, hwndClient,
  209.                 HWND_TOP, i, NULL, NULL);
  210.  
  211.         break;
  212.  
  213.     case WM_COMMAND:
  214.         switch (LOUSHORT(mp1)) {
  215.         case IDM_REFRESH:
  216.             Refresh();
  217.             break;
  218.  
  219.         case IDM_SETTIMEOUT:
  220.             gTimeout = (USHORT)WinDlgBox(hwndFrame, NULL,
  221.                     (PFNWP)GetTimeoutDlgProc,
  222.                     (HMODULE)NULL, IDD_GETTIMEOUT, NULL);
  223.             break;
  224.  
  225.         case IDM_EXEC:
  226.             WinDlgBox(HWND_DESKTOP, hwnd, ExecDlgProc, NULL, IDD_EXEC, NULL);
  227.             break;
  228.         }
  229.         break;
  230.  
  231.     case WM_CONTROL:
  232.         switch (LOUSHORT(mp1)) {
  233.         case IW_APPSLBOX:
  234.             switch (HIUSHORT(mp1)) {
  235.             case LN_SELECT:
  236.                 hwnd = gswp[IW_APPSLBOX].hwnd;
  237.                 SetLBEntries((HCONV)GetLBItemHandle(hwnd,
  238.                         GetLBSelectedItem(hwnd)),
  239.                         hszSysItemTopics, IW_TOPICSLBOX);
  240.                 SetLBEntries((HCONV)GetLBItemHandle(hwnd,
  241.                         GetLBSelectedItem(hwnd)),
  242.                         hszSysItemSysItems, IW_ITEMSLBOX);
  243.                 break;
  244.             }
  245.             break;
  246.  
  247.         case IW_TOPICSLBOX:
  248.             break;
  249.  
  250.         case IW_ITEMSLBOX:
  251.             break;
  252.  
  253.         default:
  254.             goto DoDefAction;
  255.         }
  256.         break;
  257.  
  258.     case WM_SIZE:
  259.         /*
  260.          * resize children
  261.          */
  262.         ResizeChildren(SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
  263.         break;
  264.  
  265.     case WM_ERASEBACKGROUND:
  266.         return(TRUE);
  267.         break;
  268.  
  269.     default:
  270. DoDefAction:
  271.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  272.     }
  273.     return(0L);
  274. }
  275.  
  276.  
  277.  
  278. void ResizeChildren(cxNew, cyNew)
  279. USHORT cxNew, cyNew;
  280. {
  281.     USHORT i;
  282.  
  283.     for (i = IW_FIRST; i <= IW_LAST; i++) {
  284.         gswp[i].fs = SWP_SIZE | SWP_MOVE | SWP_SHOW;
  285.         gswp[i].hwndInsertBehind = HWND_TOP;
  286.     }
  287.  
  288.     for (i = IW_APPSTITLE; i <= IW_ITEMSTITLE; i++) {
  289.         gswp[i].x =
  290.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].x = i == IW_APPSTITLE ? -cxBorder :
  291.                 gswp[i - 1].x + gswp[i - 1].cx - cxBorder;
  292.  
  293.         gswp[i].y = cyNew - cyTitles;
  294.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].y = cyNew / 2;
  295.  
  296.         gswp[i].cx =
  297.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].cx = cxNew / 3;
  298.  
  299.         gswp[i].cy = cyTitles;
  300.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].cy = (cyNew / 2) - cyTitles;
  301.     }
  302.  
  303.     gswp[IW_ITEMSLBOX].cx = cxNew - gswp[IW_ITEMSLBOX].x + cxBorder;
  304.  
  305.     gswp[IW_DATATITLE].cy = cyTitles;
  306.     gswp[IW_DATATITLE].y =
  307.     gswp[IW_DATATEXT].cy = cyNew / 2 - cyTitles;
  308.  
  309.     gswp[IW_DATATITLE].cx =
  310.     gswp[IW_DATATEXT].cx = cxNew;
  311.  
  312.     WinSetMultWindowPos(hab, gswp, IW_DATATEXT - IW_APPSTITLE + 1);
  313. }
  314.  
  315.  
  316. void Refresh()
  317. {
  318.     HCONV hConv;
  319.     register NPSZ npszAppName;
  320.     CONVINFO ci;
  321.     USHORT cb;
  322.  
  323.     WinLockWindowUpdate(HWND_DESKTOP, gswp[IW_APPSLBOX].hwnd);
  324.     WinSendMsg(gswp[IW_APPSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
  325.     WinSendMsg(gswp[IW_TOPICSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
  326.     WinSendMsg(gswp[IW_ITEMSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
  327.     
  328.     hConvListMain = DdeBeginEnumServers(0L, hszSysTopic, hConvListMain, NULL, NULL);
  329.     if (hConvListMain) {
  330.         hConv = 0;
  331.         while (hConv = DdeGetNextServer(hConvListMain, hConv)) {
  332.             DdeQueryConvInfo(hConv, &ci, QID_SYNC);
  333.             if (ci.hszAppPartner != 0) {
  334.                 cb = DdeGetHszString(ci.hszAppPartner, NULL, 0L) + 1;
  335.                 npszAppName = WinAllocMem(hheap, cb);
  336.                 DdeGetHszString(ci.hszAppPartner, (PSZ)npszAppName, (ULONG)cb);
  337.                 InsertLBItem(gswp[IW_APPSLBOX].hwnd, (PSZ)npszAppName,
  338.                         (ULONG)hConv);
  339.                 WinFreeMem(hheap, npszAppName, cb);
  340.             } else {
  341.                 InsertLBItem(gswp[IW_APPSLBOX].hwnd, SZINDETERMINATE,
  342.                         (ULONG)hConv);
  343.             }
  344.         }
  345.     }
  346.     WinLockWindowUpdate(HWND_DESKTOP, NULL);
  347. }
  348.  
  349.  
  350. SHORT InsertLBItem(hwndLB, psz, ulHandle)
  351. HWND hwndLB;
  352. PSZ psz;
  353. ULONG ulHandle;
  354. {
  355.     SHORT ili;
  356.  
  357.     ili = (SHORT)WinSendMsg(hwndLB, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING,
  358.             (MPARAM)psz);
  359.     WinSendMsg(hwndLB, LM_SETITEMHANDLE, MPFROMSHORT(ili), (MPARAM)ulHandle);
  360.     return(ili);
  361. }
  362.  
  363.  
  364. void SetLBEntries(hConv, hszItem, iwlb)
  365. HCONV hConv;
  366. HSZ hszItem;
  367. USHORT iwlb;
  368. {
  369.     NPSZ npsz, npszT1, npszT2;
  370.     BOOL fDone = 0;
  371.     ULONG cb;
  372.     HDMGDATA hDmgData;
  373.  
  374.     hDmgData = DdeClientXfer(0L, 0L, hConv, hszItem, DDEFMT_TEXT,
  375.         XTYP_REQUEST, gTimeout, NULL);
  376.  
  377.     if (hDmgData == 0) {
  378.         DdePostError(DdeGetLastError());
  379.         return;
  380.     }
  381.  
  382.     cb = DdeGetData(hDmgData, NULL, 0L, 0L);
  383.     /*
  384.      * BUG - may later want to handle the case for cb > 0xFFFF
  385.      */
  386.     npsz = WinAllocMem(hheap, (USHORT)cb);
  387.     if (npsz == NULL) {
  388.         DdePostError(DMGERR_MEMORY_ERROR);
  389.         return;
  390.     }
  391.     if (DdeGetData(hDmgData, (PBYTE)npsz, cb, 0L) == 0) {
  392.         DdePostError(DdeGetLastError());
  393.         goto Exit;
  394.     }
  395.     npszT1 = npszT2 = npsz;
  396.     WinLockWindowUpdate(HWND_DESKTOP, gswp[iwlb].hwnd);
  397.     WinSendMsg(gswp[iwlb].hwnd, LM_DELETEALL, 0L, 0L);
  398.     while (!fDone) {
  399.         while (*npszT2 != '\t' && *npszT2 != '\0')
  400.             npszT2++;
  401.         if (*npszT2 == '\t') {
  402.             *npszT2 = '\0';
  403.             npszT2++;
  404.         } else
  405.             fDone = TRUE;
  406.         InsertLBItem(gswp[iwlb].hwnd, (PSZ)npszT1,
  407.                 (ULONG)DdeGetHsz(npszT1, 0, 0));
  408.         npszT1 = npszT2;
  409.     }
  410.     WinLockWindowUpdate(HWND_DESKTOP, NULL);
  411.  
  412. Exit:
  413.     WinFreeMem(hheap, (NPBYTE)npsz, (USHORT)cb);
  414.     return;
  415. }
  416.  
  417.  
  418.  
  419. HDMGDATA EXPENTRY dataxfer(hConv, hszTopic, hszItem, usFmt, usType,
  420.         hDmgData)
  421. HCONV hConv;
  422. HSZ hszTopic;
  423. HSZ hszItem;
  424. USHORT usFmt;
  425. USHORT usType;
  426. HDMGDATA hDmgData;
  427. {
  428.     hConv; hszTopic; hszItem; usFmt; usType; hDmgData;
  429.  
  430.     switch (usType) {
  431.     case XTYP_XFERCOMPLETE:
  432.         if (hwndExec) {
  433.             if (DdeCheckQueue(hConv, &hDmgData, (ULONG)hDmgData, 0L)) {
  434.                 PSZ psz;
  435.                 if (psz = (PSZ)DdeAccessData(hDmgData)) {
  436.                     WinSetDlgItemText(hwndExec, IDEF_DATA, psz);
  437.                     /*
  438.                      * Free this data here.
  439.                      */
  440.                     DdeFreeData(hDmgData);
  441.                 }
  442.             }
  443.         }
  444.         break;
  445.     }
  446.     return(0);
  447. }
  448.  
  449.  
  450. MRESULT EXPENTRY GetTimeoutDlgProc(hwnd, msg, mp1, mp2)
  451. HWND hwnd;
  452. USHORT msg;
  453. MPARAM mp1;
  454. MPARAM mp2;
  455. {
  456.     USHORT usValue;
  457.  
  458.     switch (msg) {
  459.     case WM_INITDLG: 
  460.         /*
  461.          * set up our entryfield to be enhanced.
  462.          */
  463.         WinSetDlgItemShort(hwnd, IDC_EF, (USHORT)gTimeout, FALSE);
  464.         lpfnSysEFWndProc = WinSubclassWindow(WinWindowFromID(hwnd, IDC_EF),
  465.                 EnhancedEFWndProc);
  466.         break;
  467.  
  468.     case ENHAN_ENTER:
  469.         /*
  470.          * when the user hits the enter key, it will be passed from the
  471.          * entryfield to here and we will use it as a signal to exit.
  472.          */
  473.         WinQueryDlgItemShort(hwnd, IDC_EF, &usValue, FALSE);
  474.         WinDismissDlg(hwnd, usValue);
  475.         break;
  476.  
  477.     default:
  478.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  479.         break;
  480.     }
  481.     return(0);
  482. }
  483.  
  484. MRESULT EXPENTRY EnhancedEFWndProc(hwnd, msg, mp1, mp2)
  485. HWND hwnd;
  486. USHORT msg;
  487. MPARAM mp1;
  488. MPARAM mp2;
  489. {
  490.     switch (msg) {
  491.     case WM_CHAR:
  492.         if (LOUSHORT(mp1) & KC_SCANCODE &&
  493.                 LOUSHORT(mp1) & KC_KEYUP &&
  494.                 /*---HACK ALERT!---*/
  495.                 LOBYTE(LOUSHORT(mp2)) == 0x0d) {
  496.             NotifyOwner(hwnd, ENHAN_ENTER,
  497.                     (MPARAM)WinQueryWindowUShort(hwnd, QWS_ID), 0L);
  498.         }
  499.         break;
  500.     }
  501.     return(lpfnSysEFWndProc(hwnd, msg, mp1, mp2));
  502. }
  503.  
  504.  
  505.  
  506. MRESULT EXPENTRY ExecDlgProc(hwnd, msg, mp1, mp2)
  507. HWND hwnd;
  508. USHORT msg;
  509. MPARAM mp1;
  510. MPARAM mp2;
  511. {
  512.     static UCHAR szT[255];
  513.     static HCONV hConv = NULL;
  514.     register USHORT i;
  515.     USHORT cb;
  516.     register USHORT xtyp;
  517.     HDMGDATA hDmgData;
  518.     HSZ hszApp, hszItem, hszTopic;
  519.     BOOL fAssync;
  520.     ULONG xid;
  521.  
  522.     switch (msg) {
  523.     case WM_INITDLG:
  524.         hwndExec = hwnd;
  525.         WinSendDlgItemMsg(hwnd, IDEF_DATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTRING, 0L);
  526.         WinSendDlgItemMsg(hwnd, IDCB_QDATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTRING, 0L);
  527.         if ((i = GetLBSelectedItem(gswp[IW_APPSLBOX].hwnd)) != LIT_NONE) {
  528.             GetLBItemText(gswp[IW_APPSLBOX].hwnd, i, 255, szT);
  529.             WinSetDlgItemText(hwnd, IDEF_APP, szT);
  530.         }
  531.         if ((i = GetLBSelectedItem(gswp[IW_TOPICSLBOX].hwnd)) != LIT_NONE) {
  532.             GetLBItemText(gswp[IW_TOPICSLBOX].hwnd, i, 255, szT);
  533.             WinSetDlgItemText(hwnd, IDEF_TOPIC, szT);
  534.         }
  535.         if ((i = GetLBSelectedItem(gswp[IW_ITEMSLBOX].hwnd)) != LIT_NONE) {
  536.             GetLBItemText(gswp[IW_ITEMSLBOX].hwnd, i, 255, szT);
  537.             WinSetDlgItemText(hwnd, IDEF_ITEM, szT);
  538.         }
  539.         WinSendDlgItemMsg(hwnd, IDRB_REQUEST, BM_CLICK, 0L, 0L);
  540.         break;
  541.  
  542.     case WM_CONTROL:
  543.     case WM_COMMAND:
  544.         switch (LOUSHORT(mp1)) {
  545.         case MBID_CANCEL:
  546.             if (hConv != NULL)
  547.                 DdeDisconnect(hConv);
  548.             hConv = NULL;
  549.             WinDismissDlg(hwnd, 0);
  550.             break;
  551.             
  552.         case IDC_QFLUSH:
  553.             DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_FLUSH);
  554.             WinSetDlgItemText(hwnd, IDCB_QDATA, "");
  555.             UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
  556.             break;
  557.             
  558.         case IDC_QUPDATE:
  559.             UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
  560.             WinSendDlgItemMsg(hwnd, IDCB_QDATA, CBM_SHOWLIST, (MPARAM)TRUE, 0L);
  561.             break;
  562.             
  563.         case IDC_DOIT:
  564.             i = (USHORT)WinSendDlgItemMsg(hwnd, IDRB_ADVSTART,
  565.                     BM_QUERYCHECKINDEX, 0L, 0L) + IDRB_ADVSTART;
  566.             WinQueryDlgItemText(hwnd, IDEF_APP, 255, szT);
  567.             hszApp = DdeGetHsz(szT, 0, 0);
  568.             WinQueryDlgItemText(hwnd, IDEF_TOPIC, 255, szT);
  569.             hszTopic = DdeGetHsz(szT, 0, 0);
  570.             WinQueryDlgItemText(hwnd, IDEF_ITEM, 255, szT);
  571.             hszItem = DdeGetHsz(szT, 0, 0);
  572.             if (i != IDRB_REQUEST) {
  573.                 WinQueryDlgItemText(hwnd, IDEF_DATA, 255, szT);
  574.                 cb = WinQueryDlgItemTextLength(hwnd, IDEF_DATA);
  575.             }
  576.             if (hConv == NULL && !(hConv = DdeConnect(hszApp, hszTopic, NULL, 0L))) {
  577.                 DdePostError(DdeGetLastError());
  578.                 if (LOUSHORT(mp1) == MBID_OK)
  579.                     WinDismissDlg(hwnd, 0);
  580.                 return(0);
  581.             }
  582.             switch (i) {
  583.             case IDRB_REQUEST:
  584.                 xtyp = XTYP_REQUEST;
  585.                 goto XferOut;
  586.                 break;
  587.             case IDRB_ADVSTART:
  588.                 xtyp = XTYP_ADVSTART;
  589.                 goto XferOut;
  590.                 break;
  591.             case IDRB_ADVSTOP:
  592.                 xtyp = XTYP_ADVSTOP;
  593.                 goto XferOut;
  594.                 break;
  595.             case IDRB_POKE:
  596.                 xtyp = XTYP_POKE;
  597.                 goto XferOut;
  598.                 break;
  599.             case IDRB_EXECUTE:
  600.                 xtyp = XTYP_EXEC;
  601. XferOut:
  602.                 fAssync = (BOOL)WinSendDlgItemMsg(hwnd, IDCBX_ASSYNC,
  603.                         BM_QUERYCHECK, 0L, 0L);
  604.                 if (!(hDmgData = DdeClientXfer((PBYTE)szT, (ULONG)cb + 1,
  605.                         hConv, hszItem, DDEFMT_TEXT, xtyp,
  606.                         fAssync ? TIMEOUT_ASYNC : gTimeout, &xid)))
  607.                     DdePostError(DdeGetLastError());
  608.                     
  609.                 if (fAssync) {
  610.                     UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
  611.                 } else {
  612.                     if (i == IDRB_REQUEST) {
  613.                         DdeGetData(hDmgData, szT, 255L, 0L);
  614.                         DdeFreeData(hDmgData);
  615.                         WinSetWindowText(gswp[IW_DATATEXT].hwnd, szT);
  616.                         WinSetDlgItemText(hwnd, IDEF_DATA, szT);
  617.                     }
  618.                 }
  619.                 
  620.             }
  621.             break;
  622.         }
  623.         break;
  624.  
  625.     case WM_DESTROY:
  626.         hwndExec = NULL;
  627.     default:
  628.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  629.         break;
  630.     }
  631.     return(0);
  632. }
  633.  
  634.  
  635.  
  636. void UpdateQueue(hwndCB, hConv)
  637. HWND hwndCB;
  638. HCONV hConv;
  639. {
  640.     SHORT lit;
  641.     SHORT litSel = LIT_FIRST;
  642.     CONVINFO ci;
  643.     ULONG id, idSel;
  644.     USHORT cItems;
  645.     char szT[MAX_QSTRING];
  646.     
  647.     lit = (SHORT)WinSendMsg(hwndCB, LM_QUERYSELECTION,
  648.             MPFROMSHORT(LIT_FIRST), 0L);
  649.     idSel = (SHORT)WinSendMsg(hwndCB, LM_QUERYITEMHANDLE, MPFROMSHORT(lit), 0L);
  650.     WinSendMsg(hwndCB, LM_DELETEALL, 0L, 0L);
  651.     cItems = (USHORT)DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_COUNT);
  652.     id = DdeCheckQueue(hConv, NULL, QID_NEWEST, 0L);
  653.     while (cItems--) {
  654.         DdeQueryConvInfo(hConv, &ci, id);
  655.         ConvInfoToString(&ci, szT, MAX_QSTRING);
  656.         lit = (SHORT)WinSendMsg(hwndCB, LM_INSERTITEM, MPFROMSHORT(LIT_END), szT);
  657.         WinSendMsg(hwndCB, LM_SETITEMHANDLE, MPFROMSHORT(lit), (MPARAM)id);
  658.         if (id == idSel) 
  659.             litSel = lit;
  660.         id = DdeCheckQueue(hConv, NULL, id, CQ_NEXT);
  661.     }
  662.     WinSendMsg(hwndCB, LM_SELECTITEM, MPFROMSHORT(litSel), (MPARAM)TRUE);
  663. }
  664.  
  665.  
  666.  
  667. void ConvInfoToString(pci, psz, cbMax)
  668. PCONVINFO pci;
  669. PSZ psz;
  670. USHORT cbMax;
  671. {
  672.     PSZ pszLast;
  673.     char szT[100];
  674.     
  675.     pszLast = psz + cbMax - 1;
  676.     *psz = '\0';
  677.     psz = mylstrcat(psz, apszType[(pci->usType >> 4) && 0x1F], pszLast);
  678.     psz = mylstrcat(psz, ": ", pszLast);
  679.     psz = mylstrcat(psz, apszState[pci->usStatus & ST_CONNECTED ? 1 : 0], pszLast);
  680.     psz = mylstrcat(psz, " ", pszLast);
  681.     psz = mylstrcat(psz, apszState[pci->usStatus & ST_ADVISE ? 3 : 2], pszLast);
  682.     psz = mylstrcat(psz, " ", pszLast);
  683.     psz = mylstrcat(psz, apszStatus[pci->usConvst], pszLast);
  684.     psz = mylstrcat(psz, " ", pszLast);
  685.     if (pci->usFmt == DDEFMT_TEXT) {
  686.         psz = mylstrcat(psz, "TEXT", pszLast);
  687.     } else {   
  688.         DdeGetHszString(pci->hszItem, szT, 100L);
  689.         psz = mylstrcat(psz, szT, pszLast);
  690.     }
  691.     psz = mylstrcat(psz, " ", pszLast);
  692.     DdeGetHszString(pci->hszItem, szT, 100L);
  693.     psz = mylstrcat(psz, szT, pszLast);
  694.     
  695.     if (pci->LastError) {
  696.         psz = mylstrcat(psz, " ", pszLast);
  697.         DdeGetErrorString(pci->LastError, pszLast - psz, psz);
  698.     }
  699.     pszLast = '\0';
  700. }
  701.  
  702.  
  703. /***************************** Public  Function ****************************\
  704. * Concatonates psz1 and psz2 into psz1.
  705. * returns psz pointing to end of concatonated string.
  706. * pszLast marks point at which copying must stop.  This makes this operation
  707. * safe for limited buffer sizes.
  708. *
  709. * History:  1/1/89  created sanfords
  710. \***************************************************************************/
  711. PSZ mylstrcat(psz1, psz2, pszLast)
  712. PSZ psz1, psz2, pszLast;
  713. {
  714.     psz1 += lstrlen(psz1);
  715.     while (*psz2 != '\0' && psz1 < pszLast) {
  716.         *psz1++ = *psz2++;
  717.     }
  718.     *psz1 = '\0';
  719.     return(psz1);
  720. }
  721.  
  722.  
  723. /***************************** Private Function ****************************\
  724. *
  725. * returns string length not counting null terminator.
  726. *
  727. * History:  1/1/89  created     sanfords
  728. \***************************************************************************/
  729. int lstrlen(psz)
  730. PSZ psz;
  731. {
  732.     int c = 0;
  733.  
  734.     while (*psz != 0) {
  735.         psz++;
  736.         c++;
  737.     }
  738.     return(c);
  739. }
  740.  
  741.