home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / ipc / ddeml / client / dialog.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  31KB  |  874 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples.
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved.
  6. *       This source code is only intended as a supplement to
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /***************************************************************************
  13.  *                                                                         *
  14.  *  MODULE      : dialog.c                                                 *
  15.  *                                                                         *
  16.  *  PURPOSE     : Contains all dialog procedures and related functions.    *
  17.  *                                                                         *
  18.  ***************************************************************************/
  19. #include "client.h"
  20. #include "infoctrl.h"
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include "huge.h"
  24.  
  25. #define MAX_NAME 100    // max size for edit controls with app/topic/item names.
  26. TCHAR szWild[] = TEXT("*");    // used to indicate wild names ("" is also cool)
  27. TCHAR szT[MAX_NAME];     // temp buf for munging names.
  28.  
  29.  
  30.  
  31. /****************************************************************************
  32.  *                                                                          *
  33.  *  FUNCTION   : DoDialog()                                                 *
  34.  *                                                                          *
  35.  *  PURPOSE    : Generic dialog invocation routine.  Handles procInstance   *
  36.  *               stuff, focus management and param passing.                 *
  37.  *  RETURNS    : result of dialog procedure.                                *
  38.  *                                                                          *
  39.  ****************************************************************************/
  40. INT FAR DoDialog(
  41. LPTSTR lpTemplateName,
  42. DLGPROC lpDlgProc,
  43. LONG param,
  44. BOOL fRememberFocus)
  45. {
  46.     INT iRet;
  47.     HWND hwndFocus;
  48.  
  49.     if (fRememberFocus)
  50.         hwndFocus = GetFocus();
  51.     lpDlgProc = MakeProcInstance(lpDlgProc, hInst);
  52.     iRet = DialogBoxParam(hInst, lpTemplateName, hwndFrame, lpDlgProc, param);
  53.     FreeProcInstance(lpDlgProc);
  54.     if (fRememberFocus)
  55.         SetFocus(hwndFocus);
  56.     return iRet;
  57. }
  58.  
  59.  
  60.  
  61. /****************************************************************************
  62.  *                                                                          *
  63.  *  FUNCTION   :                                                            *
  64.  *                                                                          *
  65.  *  PURPOSE    :                                                            *
  66.  *                                                                          *
  67.  *  RETURNS    :                                                            *
  68.  *                                                                          *
  69.  ****************************************************************************/
  70. BOOL  APIENTRY AboutDlgProc ( hwnd, msg, wParam, lParam )
  71. HWND          hwnd;
  72. UINT msg;
  73. WPARAM wParam;
  74. LPARAM lParam;
  75. {
  76.     switch (msg){
  77.         case WM_INITDIALOG:
  78.             /* nothing to initialize */
  79.             break;
  80.  
  81.         case WM_COMMAND:
  82.             switch (LOWORD(wParam)) {
  83.                 case IDOK:
  84.                 case IDCANCEL:
  85.                     EndDialog(hwnd, 0);
  86.                     break;
  87.  
  88.                 default:
  89.                     return FALSE;
  90.             }
  91.             break;
  92.  
  93.         default:
  94.             return(FALSE);
  95.     }
  96.  
  97.     return TRUE;
  98. }
  99.  
  100.  
  101.  
  102.  
  103. /****************************************************************************
  104.  *                                                                          *
  105.  *  FUNCTION   :                                                            *
  106.  *                                                                          *
  107.  *  PURPOSE    :                                                            *
  108.  *                                                                          *
  109.  *  RETURNS    :                                                            *
  110.  *                                                                          *
  111.  ****************************************************************************/
  112. BOOL  APIENTRY ConnectDlgProc(
  113. HWND          hwnd,
  114. UINT msg,
  115. WPARAM wParam,
  116. LPARAM lParam)
  117. {
  118.     static BOOL fReconnect;
  119.     TCHAR szT[MAX_NAME];
  120.     HSZ hszApp, hszTopic;
  121.     MYCONVINFO *pmci;
  122.  
  123.     switch (msg){
  124.     case WM_INITDIALOG:
  125.         SendDlgItemMessage(hwnd, IDEF_APPLICATION, EM_LIMITTEXT, MAX_NAME, 0);
  126.         SendDlgItemMessage(hwnd, IDEF_TOPIC, EM_LIMITTEXT, MAX_NAME, 0);
  127.         fReconnect = (BOOL)lParam;
  128.         if (fReconnect) {
  129.             PTSTR psz;
  130.  
  131.             pmci = (MYCONVINFO *)GetWindowLong(hwndActive, 0);
  132.             SetWindowText(hwnd, TEXT("DDE Reconnect List"));
  133.             psz = GetHSZName(pmci->hszApp);
  134.             SetDlgItemText(hwnd, IDEF_APPLICATION, psz);
  135.             MyFree(psz);
  136.             psz = GetHSZName(pmci->hszTopic);
  137.             SetDlgItemText(hwnd, IDEF_TOPIC, psz);
  138.             MyFree(psz);
  139.             ShowWindow(GetDlgItem(hwnd, IDCH_CONNECTLIST), SW_HIDE);
  140.         }
  141.         break;
  142.  
  143.     case WM_COMMAND:
  144.         switch (LOWORD(wParam)) {
  145.         case IDOK:
  146.             GetDlgItemText(hwnd, IDEF_APPLICATION, szT, MAX_NAME);
  147.             if (!_tcscmp(szT, szWild))
  148.                 szT[0] = TEXT('\0');
  149.             hszApp = DdeCreateStringHandle(idInst, szT, 0);
  150.  
  151.             GetDlgItemText(hwnd, IDEF_TOPIC, szT, MAX_NAME);
  152.             if (!_tcscmp(szT, szWild))
  153.                 szT[0] = TEXT('\0');
  154.             hszTopic = DdeCreateStringHandle(idInst, szT, 0);
  155.  
  156.             if (fReconnect) {
  157.                 HCONV hConv;
  158.                 CONVINFO ci;
  159.                 DWORD cHwnd;
  160.                 HWND *aHwnd, *pHwnd, hwndSave;
  161.  
  162.                 ci.cb = sizeof(CONVINFO);
  163.                 pmci = (MYCONVINFO *)GetWindowLong(hwndActive, 0);
  164.                 hwndSave = hwndActive;
  165.  
  166.                 // count the existing conversations and allocate aHwnd
  167.  
  168.                 cHwnd = 0;
  169.                 hConv = 0;
  170.                 while (hConv = DdeQueryNextServer((HCONVLIST)pmci->hConv, hConv))
  171.                     cHwnd++;
  172.                 aHwnd = (HWND *)MyAlloc(cHwnd * sizeof(HWND));
  173.  
  174.                 // save all the old conversation windows into aHwnd.
  175.  
  176.                 pHwnd = aHwnd;
  177.                 hConv = 0;
  178.                 while (hConv = DdeQueryNextServer((HCONVLIST)pmci->hConv, hConv)) {
  179.                     DdeQueryConvInfo(hConv, QID_SYNC, &ci);
  180.                     *pHwnd++ = (HWND)ci.hUser;
  181.                 }
  182.  
  183.                 // reconnect
  184.  
  185.                 if (!(hConv = (HCONV)DdeConnectList(idInst, hszApp, hszTopic,
  186.                         (HCONVLIST)pmci->hConv, &CCFilter))) {
  187.                     MPError(MB_OK, IDS_DDEMLERR,
  188.                             (LPTSTR)Error2String(DdeGetLastError(idInst)));
  189.                     DdeFreeStringHandle(idInst, hszApp);
  190.                     DdeFreeStringHandle(idInst, hszTopic);
  191.                     return 0;
  192.                 }
  193.  
  194.                 // fixup windows corresponding to the new conversations.
  195.  
  196.                 pmci->hConv = hConv;
  197.                 hConv = 0;
  198.                 while (hConv = DdeQueryNextServer((HCONVLIST)pmci->hConv, hConv)) {
  199.                     DdeQueryConvInfo(hConv, QID_SYNC, &ci);
  200.                     // preserve corresponding window by setting its list
  201.                     // entry to 0
  202.                     for (pHwnd = aHwnd; pHwnd < &aHwnd[cHwnd]; pHwnd++) {
  203.                         if (*pHwnd == (HWND)ci.hUser) {
  204.                             *pHwnd = NULL;
  205.                             break;
  206.                         }
  207.                     }
  208.                 }
  209.  
  210.                 // destroy all windows left in the old list
  211.  
  212.                 for (pHwnd = aHwnd; pHwnd < &aHwnd[cHwnd]; pHwnd++)
  213.                     if (*pHwnd) {
  214.                         SendMessage(hwndMDIClient, WM_MDIDESTROY,
  215.                                 (WPARAM)*pHwnd, 0L);
  216.                     }
  217.                 MyFree((PTSTR)aHwnd);
  218.  
  219.                 // create any new windows needed
  220.  
  221.                 hConv = 0;
  222.                 while (hConv = DdeQueryNextServer((HCONVLIST)pmci->hConv, hConv)) {
  223.                     DdeQueryConvInfo(hConv, QID_SYNC, &ci);
  224.                     if (ci.hUser) {
  225.                         InvalidateRect((HWND)ci.hUser, NULL, TRUE);
  226.                     } else {
  227.                         AddConv(ci.hszSvcPartner, ci.hszTopic, hConv, FALSE);
  228.                     }
  229.                 }
  230.  
  231.                 // make list window update itself
  232.  
  233.                 InvalidateRect(hwndSave, NULL, TRUE);
  234.                 SetFocus(hwndSave);
  235.             } else {
  236.                 if (!CreateConv(hszApp, hszTopic,
  237.                         IsDlgButtonChecked(hwnd, IDCH_CONNECTLIST))) {
  238.                     MPError(MB_OK, IDS_DDEMLERR, (LPTSTR)Error2String(DdeGetLastError(idInst)));
  239.                     return 0;
  240.                 }
  241.             }
  242.             DdeFreeStringHandle(idInst, hszApp);
  243.             DdeFreeStringHandle(idInst, hszTopic);
  244.             // fall through
  245.         case IDCANCEL:
  246.             EndDialog(hwnd, 0);
  247.             break;
  248.  
  249.         default:
  250.             return(FALSE);
  251.         }
  252.         break;
  253.  
  254.     default:
  255.         return(FALSE);
  256.     }
  257. }
  258.  
  259.  
  260.  
  261.  
  262. /*
  263.  * Fills a XACT structure and calls ProcessTransaction.
  264.  *
  265.  * On initiation lParam == hConv.
  266.  */
  267. /****************************************************************************
  268.  *                                                                          *
  269.  *  FUNCTION   :                                                            *
  270.  *                                                                          *
  271.  *  PURPOSE    :                                                            *
  272.  *                                                                          *
  273.  *  RETURNS    :                                                            *
  274.  *                                                                          *
  275.  ****************************************************************************/
  276. BOOL  APIENTRY TransactDlgProc(
  277. HWND          hwnd,
  278. UINT msg,
  279. WPARAM wParam,
  280. LPARAM lParam)
  281. {
  282.     static DWORD id2type[] = {
  283.         XTYP_REQUEST,       // IDCH_REQUEST
  284.         XTYP_ADVSTART,      // IDCH_ADVISE
  285.         XTYP_ADVSTOP,       // IDCH_UNADVISE
  286.         XTYP_POKE,          // IDCH_POKE
  287.         XTYP_EXECUTE,       // IDCH_EXECUTE
  288.     };
  289.     static XACT *pxact;     // ONLY ONE AT A TIME!
  290.     INT i;
  291.  
  292.     switch (msg){
  293.     case WM_INITDIALOG:
  294.         pxact = (XACT *)MyAlloc(sizeof(XACT));
  295.         pxact->hConv = (HCONV)lParam;
  296.         pxact->fsOptions = DefOptions;
  297.         pxact->ulTimeout = DefTimeout;
  298.  
  299.         // The item index == the index to the format atoms in aFormats[].
  300.         for (i = 0; i < CFORMATS; i++)
  301.             SendDlgItemMessage(hwnd, IDCB_FORMAT, CB_INSERTSTRING, i,
  302.                     (DWORD)(LPTSTR)aFormats[i].sz);
  303.         SendDlgItemMessage(hwnd, IDCB_FORMAT, CB_INSERTSTRING, i,
  304.                 (DWORD)(LPTSTR)TEXT("NULL"));
  305.         SendDlgItemMessage(hwnd, IDCB_FORMAT, CB_SETCURSEL, 0, 0);
  306.         CheckRadioButton(hwnd, IDCH_REQUEST, IDCH_EXECUTE, IDCH_REQUEST);
  307.         SendDlgItemMessage(hwnd, IDEF_ITEM, EM_LIMITTEXT, MAX_NAME, 0);
  308.  
  309.         // If there is a top transaction window, use its contents to
  310.         // anticipate what the user will want to do.
  311.  
  312.         if (IsWindow(hwndActive)) {
  313.             HWND hwndXaction;
  314.             XACT *pxact;
  315.             PTSTR pszItem;
  316.  
  317.             hwndXaction = GetWindow(hwndActive, GW_CHILD);
  318.             if (IsWindow(hwndXaction)) {
  319.                 pxact = (XACT *)GetWindowLong(hwndXaction, GWL_USER);
  320.                 pszItem = GetHSZName(pxact->hszItem);
  321.                 if ((pxact->wType & XTYP_ADVSTART) == XTYP_ADVSTART ||
  322.                         pxact->wType == XTYP_ADVDATA) {
  323.                     CheckRadioButton(hwnd, IDCH_REQUEST, IDCH_EXECUTE, IDCH_UNADVISE);
  324.                 }
  325.                 SetDlgItemText(hwnd, IDEF_ITEM, pszItem);
  326.                 for (i = 0; i < CFORMATS; i++) {
  327.                     if (aFormats[i].fmt == pxact->wFmt) {
  328.                         SendDlgItemMessage(hwnd, IDCB_FORMAT, CB_SETCURSEL, i, 0);
  329.                         break;
  330.                     }
  331.                 }
  332.                 MyFree(pszItem);
  333.             }
  334.         }
  335.         break;
  336.  
  337.     case WM_COMMAND:
  338.         switch (LOWORD(wParam)) {
  339.         case IDCH_EXECUTE:
  340.             SetDlgItemText(hwnd, IDEF_ITEM, TEXT(""));
  341.         case IDCH_REQUEST:
  342.         case IDCH_ADVISE:
  343.         case IDCH_UNADVISE:
  344.         case IDCH_POKE:
  345.             EnableWindow(GetDlgItem(hwnd, IDEF_ITEM), LOWORD(wParam) != IDCH_EXECUTE);
  346.             EnableWindow(GetDlgItem(hwnd, IDTX_ITEM), LOWORD(wParam) != IDCH_EXECUTE);
  347.             break;
  348.  
  349.         case IDOK:
  350.         case IDBN_OPTIONS:
  351.             {
  352.                 INT id;
  353.  
  354.                 // set pxact->wType
  355.  
  356.                 for (id = IDCH_REQUEST; id <= IDCH_EXECUTE; id++) {
  357.                     if (IsDlgButtonChecked(hwnd, id)) {
  358.                         pxact->wType = id2type[id - IDCH_REQUEST];
  359.                         break;
  360.                     }
  361.                 }
  362.  
  363.                 if (LOWORD(wParam) == IDBN_OPTIONS) {
  364.                     DoDialog(MAKEINTRESOURCE(IDD_ADVISEOPTS),
  365.                             (DLGPROC)AdvOptsDlgProc, (LONG)pxact, TRUE);
  366.                     return 0;
  367.                 }
  368.  
  369.                 id = (INT)SendDlgItemMessage(hwnd, IDCB_FORMAT, CB_GETCURSEL, 0, 0);
  370.                 if (id == LB_ERR) {
  371.                     return 0;
  372.                 }
  373.                 if (id == CFORMATS)
  374.                     pxact->wFmt = 0;
  375.                 else
  376.                     pxact->wFmt = aFormats[id].fmt;
  377.  
  378.                 if (pxact->wType == XTYP_ADVSTART) {
  379.                     if (pxact->fsOptions & XOPT_NODATA)
  380.                         pxact->wType |= XTYPF_NODATA;
  381.                     if (pxact->fsOptions & XOPT_ACKREQ)
  382.                         pxact->wType |= XTYPF_ACKREQ;
  383.                 }
  384.  
  385.                 GetDlgItemText(hwnd, IDEF_ITEM, szT, MAX_NAME);
  386.                 pxact->hszItem = DdeCreateStringHandle(idInst, szT, 0);
  387.  
  388.                 pxact->hDdeData = 0;
  389.                 /*
  390.                  * If this transaction needs data, invoke data input dialog.
  391.                  */
  392.                 if (pxact->wType == XTYP_POKE || pxact->wType == XTYP_EXECUTE) {
  393.                     if (!DoDialog(MAKEINTRESOURCE(IDD_TEXTENTRY),
  394.                             (DLGPROC)TextEntryDlgProc, (DWORD)(LPTSTR)pxact,
  395.                             TRUE))
  396.                         return 0;
  397.                 }
  398.  
  399.                 // now start the transaction
  400.  
  401.                 ProcessTransaction(pxact);
  402.                 MyFree((PTSTR)pxact);
  403.             }
  404.             EndDialog(hwnd, 1);
  405.             break;
  406.  
  407.         case IDCANCEL:
  408.             MyFree((PTSTR)pxact);
  409.             EndDialog(hwnd, 0);
  410.             break;
  411.  
  412.         default:
  413.             return(FALSE);
  414.         }
  415.         break;
  416.  
  417.     case WM_DESTROY:
  418.         break;
  419.  
  420.     default:
  421.         return(FALSE);
  422.     }
  423.     return 0;
  424. }
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432. /****************************************************************************
  433.  *                                                                          *
  434.  *  FUNCTION   : AdvOptsDlgProc                                             *
  435.  *                                                                          *
  436.  *  LIMITATIONS: Because we use Get/SetDlgItemInt() the timeout value used  *
  437.  *               can't be greater than 65K ms.                              *
  438.  *                                                                          *
  439.  *  RETURNS    :                                                            *
  440.  *                                                                          *
  441.  ****************************************************************************/
  442. BOOL  APIENTRY AdvOptsDlgProc(
  443. HWND          hwnd,
  444. UINT msg,
  445. WPARAM wParam,
  446. LPARAM lParam)
  447. {
  448.     static struct {
  449.         DWORD id;
  450.         DWORD opt;
  451.     } id2Opt[] = {
  452.         {   IDCH_NODATA        ,   XOPT_NODATA             }   ,
  453.         {   IDCH_ACKREQ        ,   XOPT_ACKREQ             }   ,
  454.         {   IDCH_DISABLEFIRST  ,   XOPT_DISABLEFIRST       }   ,
  455.         {   IDCH_ABANDON       ,   XOPT_ABANDONAFTERSTART  }   ,
  456.         {   IDCH_BLOCKRESULT   ,   XOPT_BLOCKRESULT        }   ,
  457.         {   IDCH_ASYNC         ,   XOPT_ASYNC              }   ,
  458.     };
  459. #define CCHBOX  6
  460.     INT i;
  461.     static XACT *pxact; // only one instance at a time!!
  462.  
  463.     switch (msg){
  464.     case WM_INITDIALOG:
  465.         pxact = (XACT *)lParam;
  466.  
  467.         for (i = 0; i < CCHBOX; i++) {
  468.             CheckDlgButton(hwnd, id2Opt[i].id, pxact->fsOptions & id2Opt[i].opt);
  469.         }
  470.         SetDlgItemInt(hwnd, IDEF_TIMEOUT, (DWORD)pxact->ulTimeout, FALSE);
  471.         if (pxact->wType != XTYP_ADVSTART) {
  472.             EnableWindow(GetDlgItem(hwnd, IDCH_NODATA), FALSE);
  473.             EnableWindow(GetDlgItem(hwnd, IDCH_ACKREQ), FALSE);
  474.         }
  475.         SendMessage(hwnd, WM_COMMAND, (WPARAM)MAKELONG(IDCH_ASYNC, 0), (LONG)(0));   // enable async checkboxes
  476.         break;
  477.  
  478.     case WM_COMMAND:
  479.         switch (LOWORD(wParam)) {
  480.         case IDCH_ASYNC:
  481.             {
  482.                 BOOL fEnable;
  483.  
  484.                 fEnable = IsDlgButtonChecked(hwnd, IDCH_ASYNC);
  485.                 EnableWindow(GetDlgItem(hwnd, IDCH_DISABLEFIRST), fEnable);
  486.                 EnableWindow(GetDlgItem(hwnd, IDCH_ABANDON), fEnable);
  487.                 EnableWindow(GetDlgItem(hwnd, IDCH_BLOCKRESULT), fEnable);
  488.                 EnableWindow(GetDlgItem(hwnd, IDEF_TIMEOUT), !fEnable);
  489.             }
  490.             break;
  491.  
  492.         case IDOK:
  493.             pxact->fsOptions = 0;
  494.             for (i = 0; i < CCHBOX; i++) {
  495.                 if (IsDlgButtonChecked(hwnd, id2Opt[i].id))
  496.                     pxact->fsOptions |= id2Opt[i].opt;
  497.             }
  498.             if (!(pxact->fsOptions & XOPT_ASYNC))
  499.                 pxact->ulTimeout = (DWORD)GetDlgItemInt(hwnd, IDEF_TIMEOUT,
  500.                     (BOOL *)&i, FALSE);
  501.             // fall through
  502.         case IDCANCEL:
  503.             EndDialog(hwnd, 0);
  504.             break;
  505.         }
  506.         break;
  507.  
  508.     default:
  509.         return(FALSE);
  510.     }
  511.     return 0;
  512. #undef CCHBOX
  513. }
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520. /****************************************************************************
  521.  *                                                                          *
  522.  *  FUNCTION   : TextEntryDlgProc                                           *
  523.  *                                                                          *
  524.  *  PURPOSE    : Allows user to enter text data which is to be sent to a    *
  525.  *               server.  The user can opt to have a huge text piece of     *
  526.  *               data created automaticlly.                                 *
  527.  *               It uses the XACT structure for passing info in and out.    *
  528.  *               Must have wFmt and hszItem set on entry.                   *
  529.  *               Sets hDDEData on return if TRUE was returned.              *
  530.  *                                                                          *
  531.  *  RETURNS    : TRUE on success, FALSE on failure or cancel                *
  532.  *                                                                          *
  533.  ****************************************************************************/
  534. BOOL  APIENTRY TextEntryDlgProc(
  535. HWND          hwnd,
  536. UINT msg,
  537. WPARAM wParam,
  538. LPARAM lParam)
  539. {
  540.     static XACT FAR *pxact;
  541.     DWORD cb;
  542.     LONG length;
  543.     LPBYTE pData;
  544.     BOOL fOwned;
  545.     INT id, i;
  546.  
  547.     switch (msg){
  548.     case WM_INITDIALOG:
  549.         pxact = (XACT FAR *)lParam;
  550.         fOwned = FALSE;
  551.         for (i = 0; i < (INT)cOwned; i++) {
  552.             if (aOwned[i].wFmt == pxact->wFmt &&
  553.                     aOwned[i].hszItem == pxact->hszItem) {
  554.                 fOwned = TRUE;
  555.                 break;
  556.             }
  557.         }
  558.         EnableWindow(GetDlgItem(hwnd, IDBN_USEOWNED), fOwned);
  559.         CheckDlgButton(hwnd, IDCH_MAKEOWNED, 0);
  560.         EnableWindow(GetDlgItem(hwnd, IDCH_MAKEOWNED), cOwned < MAX_OWNED);
  561.         break;
  562.  
  563.     case WM_COMMAND:
  564.         switch (LOWORD(wParam)) {
  565.         case IDOK:
  566.         case IDBN_GENHUGE:
  567.             fOwned = IsDlgButtonChecked(hwnd, IDCH_MAKEOWNED);
  568.             cb = (SendDlgItemMessage(hwnd, IDEF_DATA, WM_GETTEXTLENGTH, 0, 0) + 1) * sizeof(TCHAR);
  569.             pxact->hDdeData = DdeCreateDataHandle(idInst, NULL, 0,
  570.                     cb, pxact->hszItem,
  571.                     pxact->wFmt, fOwned ? HDATA_APPOWNED : 0);
  572.             if (pxact->hDdeData == 0) {
  573.                 MessageBeep(0);
  574.                 return(0);
  575.             }
  576.             //
  577.             // Note that at this time we have not yet given the data handle
  578.             // to DDEML for transmission to any application, therefore, we
  579.             // are at liberty to write to it using DdeAccessData() or any
  580.             // other DDEML api.  It is only data handles received from DDEML
  581.             // or given to DDEML for transmission that are readonly.
  582.             //
  583.             pData = DdeAccessData(pxact->hDdeData, NULL);
  584.             if (pData == NULL) {
  585.                 MessageBeep(0);
  586.                 return(0);
  587.             }
  588.             GetDlgItemText(hwnd, IDEF_DATA, (LPTSTR)pData, (DWORD)cb);
  589.             DdeUnaccessData(pxact->hDdeData);
  590.             if (LOWORD(wParam) == IDBN_GENHUGE) {
  591.                 TCHAR szT[40];
  592.  
  593.                 /*
  594.                  * we assume in this case that the text entered is the decimal
  595.                  * value of the size of the huge object desired.  We parse
  596.                  * this string and create a randomly generated huge block
  597.                  * of text data and place it into pxact->hDdeData.
  598.                  */
  599.                 memcpy(szT, pData, min((DWORD)cb, 40));
  600.                 szT[39] = TEXT('\0');
  601.                 if (_stscanf(szT, TEXT("%ld"), &length) == 1) {
  602.                     DdeFreeDataHandle(pxact->hDdeData);
  603.                     pxact->hDdeData = CreateHugeDataHandle(length, 4325,
  604.                             345, 5, pxact->hszItem, pxact->wFmt,
  605.                             fOwned ? HDATA_APPOWNED : 0);
  606.                 } else {
  607.                     /*
  608.                      * The string cannot be parsed.  Inform the user of
  609.                      * what is expected.
  610.                      */
  611.                     MPError(MB_OK, IDS_BADLENGTH);
  612.                     return 0;
  613.                 }
  614.             }
  615.             if (fOwned) {
  616.                 aOwned[cOwned].hData = pxact->hDdeData;
  617.                 aOwned[cOwned].hszItem = pxact->hszItem;
  618.                 aOwned[cOwned].wFmt = pxact->wFmt;
  619.                 cOwned++;
  620.             }
  621.             EndDialog(hwnd, TRUE);
  622.             break;
  623.  
  624.         case IDBN_USEOWNED:
  625.             /*
  626.              * the user has chosen to use an existing owned data for sending
  627.              * to the server.
  628.              */
  629.             id = DoDialog(MAKEINTRESOURCE(IDD_HDATAVIEW), (DLGPROC)ViewHandleDlgProc,
  630.                     (LONG)pxact, TRUE);
  631.  
  632.             switch (id) {
  633.             case IDCANCEL:
  634.                 return(0);
  635.  
  636.             case IDOK:
  637.                 EndDialog(hwnd, TRUE);
  638.  
  639.             case IDBN_VIEW:
  640.                 pData = DdeAccessData(pxact->hDdeData, NULL);
  641.                 SetDlgItemText(hwnd, IDEF_DATA, (LPTSTR)pData);
  642.                 DdeUnaccessData(pxact->hDdeData);
  643.                 break;
  644.             }
  645.             break;
  646.  
  647.         case IDCANCEL:
  648.             EndDialog(hwnd, FALSE);
  649.             break;
  650.         }
  651.         break;
  652.  
  653.     default:
  654.         return(FALSE);
  655.     }
  656. }
  657.  
  658.  
  659.  
  660. BOOL  APIENTRY ViewHandleDlgProc(
  661. HWND          hwnd,
  662. UINT msg,
  663. WPARAM wParam,
  664. LPARAM lParam)
  665. {
  666.     static XACT FAR *pxact;
  667.     INT i, itm;
  668.  
  669.     switch (msg){
  670.     case WM_INITDIALOG:
  671.         pxact = (XACT FAR *)lParam;
  672.         // load listbox with handles that fit pxact constraints
  673.  
  674.         for (i = 0; i < (INT)cOwned; i++) {
  675.             if (aOwned[i].hszItem == pxact->hszItem &&
  676.                     aOwned[i].wFmt == pxact->wFmt) {
  677.                 wsprintf(szT, TEXT("[%d] %lx : length=%ld"), i, aOwned[i].hData,
  678.                         DdeGetData(aOwned[i].hData, NULL, 0, 0));
  679.                 SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_ADDSTRING, 0, (LONG)(LPTSTR)szT);
  680.             }
  681.         }
  682.         SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_SETCURSEL, 0, 0);
  683.         break;
  684.  
  685.     case WM_COMMAND:
  686.         switch (LOWORD(wParam)) {
  687.         case IDOK:          // use selectted handle
  688.         case IDBN_DELETE:   // delete selected handle
  689.         case IDBN_VIEW:     // view selected handle
  690.             itm = (INT)SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_GETCURSEL, 0, 0);
  691.             if (itm != LB_ERR) {
  692.                 SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_GETTEXT, itm, (LONG)(LPTSTR)szT);
  693.                 _stscanf(szT, TEXT("[%d]"), &i);
  694.                 pxact->hDdeData = aOwned[i].hData;
  695.                 switch (LOWORD(wParam)) {
  696.                 case IDOK:          // use selectted handle
  697.                     EndDialog(hwnd, LOWORD(wParam));
  698.                     break;
  699.  
  700.                 case IDBN_DELETE:   // delete selected handle
  701.                     DdeFreeDataHandle(aOwned[i].hData);
  702.                     aOwned[i] = aOwned[--cOwned];
  703.                     SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_DELETESTRING, itm, 0);
  704.                     if (SendDlgItemMessage(hwnd, IDLB_HANDLES, LB_GETCOUNT, 0, 0) == 0)
  705.                         EndDialog(hwnd, IDCANCEL);
  706.                     break;
  707.  
  708.                 case IDBN_VIEW:     // view selected handle
  709.                     EndDialog(hwnd, LOWORD(wParam));
  710.                 }
  711.             }
  712.             break;
  713.  
  714.         case IDCANCEL:
  715.             EndDialog(hwnd, FALSE);
  716.             break;
  717.         }
  718.         break;
  719.  
  720.     default:
  721.         return(FALSE);
  722.     }
  723. }
  724.  
  725.  
  726.  
  727. BOOL  APIENTRY DelayDlgProc(
  728. HWND          hwnd,
  729. UINT msg,
  730. WPARAM wParam,
  731. LPARAM lParam)
  732. {
  733.     switch (msg){
  734.     case WM_INITDIALOG:
  735.         SetWindowText(hwnd, TEXT("Advise data response time"));
  736.         SetDlgItemInt(hwnd, IDEF_VALUE, wDelay, FALSE);
  737.         SetDlgItemText(hwnd, IDTX_VALUE, TEXT("Delay in milliseconds:"));
  738.         break;
  739.  
  740.     case WM_COMMAND:
  741.         switch (LOWORD(wParam)) {
  742.         case IDOK:
  743.             wDelay = (DWORD)GetDlgItemInt(hwnd, IDEF_VALUE, NULL, FALSE);
  744.         case IDCANCEL:
  745.             EndDialog(hwnd, 0);
  746.             break;
  747.  
  748.         default:
  749.             return(FALSE);
  750.         }
  751.         break;
  752.  
  753.     default:
  754.         return(FALSE);
  755.     }
  756. }
  757.  
  758.  
  759.  
  760.  
  761.  
  762. /****************************************************************************
  763.  *                                                                          *
  764.  *  FUNCTION   : TimeoutDlgProc()                                           *
  765.  *                                                                          *
  766.  *  PURPOSE    : Allows user to alter the synchronous timeout value.        *
  767.  *                                                                          *
  768.  *  RETURNS    : TRUE on success, FALSE on cancel or failure.               *
  769.  *                                                                          *
  770.  ****************************************************************************/
  771. BOOL  APIENTRY TimeoutDlgProc(
  772. HWND          hwnd,
  773. UINT msg,
  774. WPARAM wParam,
  775. LPARAM lParam)
  776. {
  777.     switch (msg){
  778.     case WM_INITDIALOG:
  779.         SetWindowText(hwnd, TEXT("Synchronous transaction timeout"));
  780.         SetDlgItemInt(hwnd, IDEF_VALUE, (INT)DefTimeout, FALSE);
  781.         SetDlgItemText(hwnd, IDTX_VALUE, TEXT("Timeout in milliseconds:"));
  782.         break;
  783.  
  784.     case WM_COMMAND:
  785.         switch (LOWORD(wParam)) {
  786.         case IDOK:
  787.             DefTimeout = GetDlgItemInt(hwnd, IDEF_VALUE, NULL, FALSE);
  788.         case IDCANCEL:
  789.             EndDialog(hwnd, 0);
  790.             break;
  791.  
  792.         default:
  793.             return(FALSE);
  794.         }
  795.         break;
  796.  
  797.     default:
  798.         return(FALSE);
  799.     }
  800. }
  801.  
  802.  
  803.  
  804.  
  805. BOOL  APIENTRY ContextDlgProc(
  806. HWND hwnd,
  807. UINT msg,
  808. WPARAM wParam,
  809. LPARAM lParam)
  810. {
  811.     BOOL fSuccess;
  812.  
  813.     switch (msg){
  814.     case WM_INITDIALOG:
  815.         SetDlgItemInt(hwnd, IDEF_FLAGS, CCFilter.wFlags, FALSE);
  816.         SetDlgItemInt(hwnd, IDEF_COUNTRY, CCFilter.wCountryID, FALSE);
  817.         SetDlgItemInt(hwnd, IDEF_CODEPAGE, CCFilter.iCodePage, TRUE);
  818.         SetDlgItemInt(hwnd, IDEF_LANG, CCFilter.dwLangID, FALSE);
  819.         SetDlgItemInt(hwnd, IDEF_SECURITY, CCFilter.dwSecurity, FALSE);
  820.         CheckRadioButton(hwnd, IDRB_IL_ANON, IDRB_IL_DELEGATE,
  821.                 IDRB_IL_ANON + (int)CCFilter.qos.ImpersonationLevel);
  822.         return(1);
  823.         break;
  824.  
  825.     case WM_COMMAND:
  826.         switch (LOWORD(wParam)) {
  827.         case IDOK:
  828.             CCFilter.wFlags = (WORD)GetDlgItemInt(hwnd, IDEF_FLAGS, &fSuccess, FALSE);
  829.             if (!fSuccess) return(0);
  830.             CCFilter.wCountryID = (WORD)GetDlgItemInt(hwnd, IDEF_COUNTRY, &fSuccess, FALSE);
  831.             if (!fSuccess) return(0);
  832.             CCFilter.iCodePage = GetDlgItemInt(hwnd, IDEF_CODEPAGE, &fSuccess, TRUE);
  833.             if (!fSuccess) return(0);
  834.             CCFilter.dwLangID = (DWORD)GetDlgItemInt(hwnd, IDEF_LANG, &fSuccess, FALSE);
  835.             if (!fSuccess) return(0);
  836.             CCFilter.dwSecurity = (DWORD)GetDlgItemInt(hwnd, IDEF_SECURITY, &fSuccess, FALSE);
  837.             if (!fSuccess) return(0);
  838.             if (IsDlgButtonChecked(hwnd, IDRB_IL_ANON)) {
  839.                 CCFilter.qos.ImpersonationLevel = SecurityAnonymous;
  840.             } else if (IsDlgButtonChecked(hwnd, IDRB_IL_ID)) {
  841.                 CCFilter.qos.ImpersonationLevel = SecurityIdentification;
  842.             } else if (IsDlgButtonChecked(hwnd, IDRB_IL_IMP)) {
  843.                 CCFilter.qos.ImpersonationLevel = SecurityImpersonation;
  844.             } else if (IsDlgButtonChecked(hwnd, IDRB_IL_DELEGATE)) {
  845.                 CCFilter.qos.ImpersonationLevel = SecurityDelegation;
  846.             }
  847.             // fall through
  848.         case IDCANCEL:
  849.             EndDialog(hwnd, 0);
  850.             break;
  851.  
  852.         default:
  853.             return(FALSE);
  854.         }
  855.         break;
  856.     }
  857.     return(FALSE);
  858. }
  859.  
  860.  
  861. VOID Delay(
  862. DWORD delay)
  863. {
  864.     MSG msg;
  865.  
  866.     delay = GetCurrentTime() + delay;
  867.     while (GetCurrentTime() < delay) {
  868.         if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  869.             TranslateMessage(&msg);
  870.             DispatchMessage(&msg);
  871.         }
  872.     }
  873. }
  874.