Annotation of mstools/samples/ddeml/client/ddemlcl.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  *                                                                         *
                      3:  *  PROGRAM     : client.c                                                 *
                      4:  *                                                                         *
                      5:  *  PURPOSE     : To demonstrate how to use the DDEML library from the     *
                      6:  *                client side and for basic testing of the DDEML API.      *
                      7:  *                                                                         *
                      8:  ***************************************************************************/
                      9: 
                     10: #include "client.h"
                     11: #include <string.h>
                     12: #include <memory.h>
                     13: #include "infoctrl.h"
                     14: 
                     15: /* global variables used in this module or among more than one module */
                     16: CONVCONTEXT CCFilter = { sizeof(CONVCONTEXT), 0, 0, 0, 0L, 0L };
                     17: DWORD idInst = 0;
                     18: HANDLE hInst;                       /* Program instance handle               */
                     19: HANDLE hAccel;                      /* Main accelerator resource             */
                     20: HWND hwndFrame           = NULL;    /* Handle to main window                 */
                     21: HWND hwndMDIClient       = NULL;    /* Handle to MDI client                  */
                     22: HWND hwndActive          = NULL;    /* Handle to currently activated child   */
                     23: LONG DefTimeout      = DEFTIMEOUT;  /* default synchronous transaction timeout */
                     24: DWORD wDelay = 0;
                     25: BOOL fBlockNextCB = FALSE;     /* set if next callback causes a CBR_BLOCK    */
                     26: BOOL fTermNextCB = FALSE;      /* set to call DdeDisconnect() on next callback */
                     27: BOOL fAutoReconnect = FALSE;   /* set if DdeReconnect() is to be called on XTYP_DISCONNECT callbacks */
                     28: HDDEDATA hDataOwned = NULL;    /* Current owned huge data handle             */
                     29: DWORD fmtLink = 0;                   /* link clipboard format number          */
                     30: DWORD DefOptions = 0;                /* default transaction optons            */
                     31: OWNED aOwned[MAX_OWNED];            /* list of all owned handles.            */
                     32: DWORD cOwned = 0;                    /* number of existing owned handles.     */
                     33: FARPROC lpMsgFilterProc;            /* instance proc from MSGF_DDEMGR filter */
                     34: 
                     35: /*
                     36:  * This is the array of formats we support
                     37:  */
                     38: FORMATINFO aFormats[] = {
                     39:     { CF_TEXT, "CF_TEXT" },       // exception!  predefined format
                     40:     { 0, "Dummy1"  },
                     41:     { 0, "Dummy2"  },
                     42: };
                     43: 
                     44: /* Forward declarations of helper functions in this module */
                     45: VOID NEAR PASCAL CloseAllChildren(VOID);
                     46: VOID NEAR PASCAL InitializeMenu (HANDLE);
                     47: VOID NEAR PASCAL CommandHandler (HWND,DWORD);
                     48: VOID NEAR PASCAL SetWrap (HWND,BOOL);
                     49: 
                     50: /****************************************************************************
                     51:  *                                                                          *
                     52:  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                        *
                     53:  *                                                                          *
                     54:  *  PURPOSE    : Creates the "frame" window, does some initialization and   *
                     55:  *               enters the message loop.                                   *
                     56:  *                                                                          *
                     57:  ****************************************************************************/
                     58: int APIENTRY WinMain(
                     59:     HANDLE hInstance,
                     60:     HANDLE hPrevInstance,
                     61:     LPSTR lpszCmdLine,
                     62:     int nCmdShow
                     63:     )
                     64: {
                     65:     MSG msg;
                     66: 
                     67:     hInst = hInstance;
                     68: 
                     69:     /* If this is the first instance of the app. register window classes */
                     70:     if (!hPrevInstance){
                     71:         if (!InitializeApplication ())
                     72:             return 0;
                     73:     }
                     74: 
                     75:     /* Create the frame and do other initialization */
                     76:     if (!InitializeInstance(nCmdShow))
                     77:         return 0;
                     78: 
                     79:     /* Enter main message loop */
                     80:     while (GetMessage (&msg, NULL, 0, 0)){
                     81:         (*lpMsgFilterProc)(MSGF_DDEMGR, 0, (LONG)(LPMSG)&msg);
                     82:     }
                     83: 
                     84:     // free up any appowned handles
                     85:     while (cOwned) {
                     86:         DdeFreeDataHandle(aOwned[--cOwned].hData);
                     87:     }
                     88:     DdeUninitialize(idInst);
                     89: 
                     90:     UnhookWindowsHook(WH_MSGFILTER, lpMsgFilterProc);
                     91:     FreeProcInstance(lpMsgFilterProc);
                     92: 
                     93:     return 0;
                     94: }
                     95: 
                     96: /****************************************************************************
                     97:  *                                                                          *
                     98:  *  FUNCTION   : FrameWndProc (hwnd, msg, wParam, lParam )                  *
                     99:  *                                                                          *
                    100:  *  PURPOSE    : The window function for the "frame" window, which controls *
                    101:  *               the menu and encompasses all the MDI child windows. Does   *
                    102:  *               the major part of the message processing. Specifically, in *
                    103:  *               response to:                                               *
                    104:  *                                                                          *
                    105:  ****************************************************************************/
                    106: LONG  APIENTRY FrameWndProc ( hwnd, msg, wParam, lParam )
                    107: HWND   hwnd;
                    108: UINT   msg;
                    109: WPARAM wParam;
                    110: LPARAM lParam;
                    111: 
                    112: {
                    113:     switch (msg){
                    114:         case WM_CREATE:{
                    115:             CLIENTCREATESTRUCT ccs;
                    116: 
                    117:             /* Find window menu where children will be listed */
                    118:             ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd),WINDOWMENU);
                    119:             ccs.idFirstChild = IDM_WINDOWCHILD;
                    120: 
                    121:             /* Create the MDI client filling the client area */
                    122:             hwndMDIClient = CreateWindow ("mdiclient",
                    123:                                           NULL,
                    124:                                           WS_CHILD | WS_CLIPCHILDREN |
                    125:                                           WS_VSCROLL | WS_HSCROLL,
                    126:                                           0,
                    127:                                           0,
                    128:                                           0,
                    129:                                           0,
                    130:                                           hwnd,
                    131:                                           (HMENU)0xCAC,
                    132:                                           hInst,
                    133:                                           (LPSTR)&ccs);
                    134: 
                    135: 
                    136:             ShowWindow (hwndMDIClient,SW_SHOW);
                    137:             break;
                    138:         }
                    139: 
                    140:         case WM_INITMENU:
                    141:             InitializeMenu ((HMENU)wParam);
                    142:             break;
                    143: 
                    144:         case WM_COMMAND:
                    145:             CommandHandler (hwnd, GET_WM_COMMAND_ID(wParam, lParam));
                    146:             break;
                    147: 
                    148:         case WM_CLOSE:
                    149:             CloseAllChildren();
                    150:             DestroyWindow(hwnd);
                    151:             break;
                    152: 
                    153:         case WM_DESTROY:
                    154:             PostQuitMessage(0);
                    155:             break;
                    156: 
                    157:         default:
                    158:             /*  use DefFrameProc() instead of DefWindowProc() since there
                    159:              *  are things that have to be handled differently because of MDI
                    160:              */
                    161:             return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam);
                    162:     }
                    163:     return 0;
                    164: }
                    165: 
                    166: 
                    167: 
                    168: 
                    169: 
                    170: /****************************************************************************
                    171:  *                                                                          *
                    172:  *  FUNCTION   : MDIChildWndProc                                            *
                    173:  *                                                                          *
                    174:  *  PURPOSE    : The window function for the "child" conversation and list  *
                    175:  *               windows.                                                   *
                    176:  *                                                                          *
                    177:  ****************************************************************************/
                    178: LONG  APIENTRY MDIChildWndProc( hwnd, msg, wParam, lParam )
                    179: HWND   hwnd;
                    180: UINT   msg;
                    181: WPARAM wParam;
                    182: LPARAM lParam;
                    183: {
                    184:     MYCONVINFO *pmci;
                    185:     RECT rc;
                    186: 
                    187:     switch (msg){
                    188:     case WM_CREATE:
                    189:         /*
                    190:          * Create a coresponding conversation info structure to link this
                    191:          * window to the conversation or conversation list it represents.
                    192:          *
                    193:          * lParam: points to the conversation info to initialize our copy to.
                    194:          */
                    195:         pmci = (MYCONVINFO *)MyAlloc(sizeof(MYCONVINFO));
                    196:         if (pmci != NULL) {
                    197:             _fmemcpy(pmci,
                    198:                     (LPSTR)((LPMDICREATESTRUCT)((LPCREATESTRUCT)lParam)->lpCreateParams)->lParam,
                    199:                     sizeof(MYCONVINFO));
                    200:             pmci->hwndXaction = 0;              /* no current transaction yet */
                    201:             pmci->x = pmci->y = 0;              /* new transaction windows start here */
                    202:             DdeKeepStringHandle(idInst, pmci->hszTopic);/* keep copies of the hszs for us */
                    203:             DdeKeepStringHandle(idInst, pmci->hszApp);
                    204: 
                    205:              // link hConv and hwnd together
                    206:             SetWindowLong(hwnd, 0, (DWORD)pmci);
                    207: 
                    208:             /*
                    209:              * non-list windows link the conversations to the windows via the
                    210:              * conversation user handle.
                    211:              */
                    212:             if (!pmci->fList)
                    213:                 DdeSetUserHandle(pmci->hConv, QID_SYNC, (DWORD)hwnd);
                    214:         }
                    215:         goto CallDCP;
                    216:         break;
                    217: 
                    218:     case UM_GETNEXTCHILDX:
                    219:     case UM_GETNEXTCHILDY:
                    220:         /*
                    221:          * Calculate the next place to put the next transaction window.
                    222:          */
                    223:         {
                    224:             pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    225:             GetClientRect(hwnd, &rc);
                    226:             if (msg == UM_GETNEXTCHILDX) {
                    227:                 pmci->x += 14;
                    228:                 if (pmci->x > (rc.right - 200 - rc.left))
                    229:                     pmci->x = 0;
                    230:                 return(pmci->x);
                    231:             } else {
                    232:                 pmci->y += 12;
                    233:                 if (pmci->y > (rc.bottom - 100 - rc.top))
                    234:                     pmci->y = 0;
                    235:                 return(pmci->y);
                    236:             }
                    237:         }
                    238:         break;
                    239: 
                    240:     case UM_DISCONNECTED:
                    241:         /*
                    242:          * Disconnected conversations can't have any transactions so we
                    243:          * remove all the transaction windows here to show whats up.
                    244:          */
                    245:         {
                    246:             HWND hwndT;
                    247:             while (hwndT = GetWindow(hwnd, GW_CHILD))
                    248:                 DestroyWindow(hwndT);
                    249:             InvalidateRect(hwnd, NULL, TRUE);
                    250:         }
                    251:         break;
                    252: 
                    253:     case WM_DESTROY:
                    254:         /*
                    255:          * Cleanup our conversation info structure, and disconnect all
                    256:          * conversations associated with this window.
                    257:          */
                    258:         pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    259:         pmci->hwndXaction = 0;      /* clear this to avoid focus problems */
                    260:         if (pmci->hConv) {
                    261:             if (pmci->fList) {
                    262:                 DdeDisconnectList((HCONVLIST)pmci->hConv);
                    263:             } else {
                    264:                 MyDisconnect(pmci->hConv);
                    265:             }
                    266:         }
                    267:         DdeFreeStringHandle(idInst, pmci->hszTopic);
                    268:         DdeFreeStringHandle(idInst, pmci->hszApp);
                    269:         MyFree(pmci);
                    270:         goto CallDCP;
                    271:         break;
                    272: 
                    273:     case WM_SETFOCUS:
                    274:         /*
                    275:          * This catches focus changes caused by dialogs.
                    276:          */
                    277:         lParam = (LPARAM)hwnd;
                    278:         // fall through
                    279: 
                    280:     case WM_MDIACTIVATE:
                    281:         hwndActive = GET_WM_MDIACTIVATE_HWNDACTIVATE(wParam, lParam);
                    282:         pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    283:         /*
                    284:          * pass the focus onto the current transaction window.
                    285:          */
                    286:         if (GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wParam, lParam) &&
                    287:                 IsWindow(pmci->hwndXaction))
                    288:             SetFocus(pmci->hwndXaction);
                    289:         break;
                    290: 
                    291:     case ICN_HASFOCUS:
                    292:         /*
                    293:          * update which transaction window is the main one.
                    294:          */
                    295:         pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    296:         pmci->hwndXaction = wParam ? (HWND)lParam : NULL;
                    297:         break;
                    298: 
                    299:     case ICN_BYEBYE:
                    300:         /*
                    301:          * Transaction window is closing...
                    302:          *
                    303:          * wParam = hwndXact
                    304:          * lParam = lpxact
                    305:          */
                    306:         pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    307:         if (pmci != NULL) {
                    308:             XACT *pxact;
                    309: 
                    310:             pxact = (XACT *)lParam;
                    311:             if (pxact != NULL) {
                    312:                 /*
                    313:                  * If this transaction is active, abandon it first.
                    314:                  */
                    315:                 if (pxact->fsOptions & XOPT_ASYNC &&
                    316:                         !(pxact->fsOptions & XOPT_COMPLETED)) {
                    317:                     DdeAbandonTransaction(idInst, pmci->hConv, pxact->Result);
                    318:                 }
                    319:                 /*
                    320:                  * release resources associated with transaction.
                    321:                  */
                    322:                 DdeFreeStringHandle(idInst, pxact->hszItem);
                    323:                 MyFree((PSTR)pxact);
                    324:                 /*
                    325:                  * Locate next apropriate transaction window to get focus.
                    326:                  */
                    327:                 if (!pmci->hwndXaction || pmci->hwndXaction == (HWND)wParam)
                    328:                     pmci->hwndXaction = GetWindow(hwnd, GW_CHILD);
                    329:                 if (pmci->hwndXaction == (HWND)wParam)
                    330:                     pmci->hwndXaction = GetWindow((HWND)wParam, GW_HWNDNEXT);
                    331:                 if (pmci->hwndXaction == (HWND)wParam ||
                    332:                         !IsWindow(pmci->hwndXaction) ||
                    333:                         !IsChild(hwnd, pmci->hwndXaction))
                    334:                     pmci->hwndXaction = NULL;
                    335:                 else
                    336:                     SetFocus(pmci->hwndXaction);
                    337:             }
                    338:         }
                    339:         break;
                    340: 
                    341:     case WM_PAINT:
                    342:         /*
                    343:          * Paint this conversation's related information.
                    344:          */
                    345:         pmci = (MYCONVINFO *)GetWindowLong(hwnd, 0);
                    346:         {
                    347:             PAINTSTRUCT ps;
                    348:             PSTR psz;
                    349: 
                    350:             BeginPaint(hwnd, &ps);
                    351:             SetBkMode(ps.hdc, TRANSPARENT);
                    352:             psz = pmci->fList ? GetConvListText(pmci->hConv) :
                    353:                     GetConvInfoText(pmci->hConv, &pmci->ci);
                    354:             if (psz) {
                    355:                 GetClientRect(hwnd, &rc);
                    356:                 DrawText(ps.hdc, psz, -1, &rc,
                    357:                         DT_WORDBREAK | DT_LEFT | DT_NOPREFIX | DT_TABSTOP);
                    358:                 MyFree(psz);
                    359:             }
                    360:             EndPaint(hwnd, &ps);
                    361:         }
                    362:         break;
                    363: 
                    364:     case WM_QUERYENDSESSION:
                    365:         return TRUE;
                    366: 
                    367:     default:
                    368: CallDCP:
                    369:         /* Again, since the MDI default behaviour is a little different,
                    370:          * call DefMDIChildProc instead of DefWindowProc()
                    371:          */
                    372:         return DefMDIChildProc (hwnd, msg, wParam, lParam);
                    373:     }
                    374:     return FALSE;
                    375: }
                    376: 
                    377: 
                    378: /****************************************************************************
                    379:  *                                                                          *
                    380:  *  FUNCTION   : Initializemenu ( hMenu )                                   *
                    381:  *                                                                          *
                    382:  *  PURPOSE    : Sets up greying, enabling and checking of main menu items  *
                    383:  *               based on the app's state.                                  *
                    384:  *                                                                          *
                    385:  ****************************************************************************/
                    386: VOID NEAR PASCAL InitializeMenu ( hmenu )
                    387: HANDLE hmenu;
                    388: {
                    389:     BOOL fLink      = FALSE; // set if Link format is on the clipboard;
                    390:     BOOL fAny       = FALSE; // set if hwndActive exists
                    391:     BOOL fList      = FALSE; // set if hwndActive is a list window
                    392:     BOOL fConnected = FALSE; // set if hwndActive is a connection conversation.
                    393:     BOOL fXaction   = FALSE; // set if hwndActive has a selected transaction window
                    394:     BOOL fXactions  = FALSE; // set if hwndActive contains transaction windows
                    395:     BOOL fBlocked   = FALSE; // set if hwndActive conversation is blocked.
                    396:     BOOL fBlockNext = FALSE; // set if handActive conversation is blockNext.
                    397:     MYCONVINFO *pmci = NULL;
                    398: 
                    399:     if (OpenClipboard(hwndFrame)) {
                    400:         fLink = (IsClipboardFormatAvailable(fmtLink));
                    401:         CloseClipboard();
                    402:     }
                    403: 
                    404:     if (fAny = (IsWindow(hwndActive) &&
                    405:             (pmci = (MYCONVINFO *)GetWindowLong(hwndActive, 0)))) {
                    406:         fXactions = (BOOL)GetWindow(hwndActive, GW_CHILD);
                    407:         if (!(fList = pmci->fList)) {
                    408:             CONVINFO ci;
                    409: 
                    410:             ci.cb = sizeof(CONVINFO);
                    411:             DdeQueryConvInfo(pmci->hConv, QID_SYNC, &ci);
                    412:             fConnected = ci.wStatus & ST_CONNECTED;
                    413:             fXaction = IsWindow(pmci->hwndXaction);
                    414:             fBlocked = ci.wStatus & ST_BLOCKED;
                    415:             fBlockNext = ci.wStatus & ST_BLOCKNEXT;
                    416:         }
                    417:     }
                    418: 
                    419:     EnableMenuItem(hmenu,   IDM_EDITPASTE,
                    420:             fLink           ? MF_ENABLED    : MF_GRAYED);
                    421: 
                    422:     // IDM_CONNECTED - always enabled.
                    423: 
                    424:     EnableMenuItem(hmenu,   IDM_RECONNECT,
                    425:             fList           ? MF_ENABLED    : MF_GRAYED);
                    426: 
                    427:     EnableMenuItem (hmenu,  IDM_DISCONNECT,
                    428:             fConnected      ? MF_ENABLED    : MF_GRAYED);
                    429: 
                    430:     EnableMenuItem (hmenu,  IDM_TRANSACT,
                    431:             fConnected      ? MF_ENABLED    : MF_GRAYED);
                    432: 
                    433:     EnableMenuItem(hmenu,   IDM_ABANDON,
                    434:             fXaction        ? MF_ENABLED    : MF_GRAYED);
                    435: 
                    436:     EnableMenuItem(hmenu,   IDM_ABANDONALL,
                    437:             fXactions ? MF_ENABLED : MF_GRAYED);
                    438: 
                    439: 
                    440:     EnableMenuItem (hmenu,  IDM_BLOCKCURRENT,
                    441:             fConnected && !fBlocked ? MF_ENABLED    : MF_GRAYED);
                    442:     CheckMenuItem(hmenu, IDM_BLOCKCURRENT,
                    443:             fBlocked        ? MF_CHECKED    : MF_UNCHECKED);
                    444: 
                    445:     EnableMenuItem (hmenu,  IDM_ENABLECURRENT,
                    446:             fConnected && (fBlocked || fBlockNext) ? MF_ENABLED : MF_GRAYED);
                    447:     CheckMenuItem(hmenu,    IDM_ENABLECURRENT,
                    448:             !fBlocked       ? MF_CHECKED    : MF_UNCHECKED);
                    449: 
                    450:     EnableMenuItem (hmenu,  IDM_ENABLEONECURRENT,
                    451:             fConnected && (fBlocked) ? MF_ENABLED : MF_GRAYED);
                    452:     CheckMenuItem(hmenu,    IDM_ENABLEONECURRENT,
                    453:             fBlockNext      ? MF_CHECKED    : MF_UNCHECKED);
                    454: 
                    455:     EnableMenuItem (hmenu,  IDM_BLOCKALLCBS,
                    456:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    457: 
                    458:     EnableMenuItem (hmenu,  IDM_ENABLEALLCBS,
                    459:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    460: 
                    461:     EnableMenuItem (hmenu,  IDM_ENABLEONECB,
                    462:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    463: 
                    464:     EnableMenuItem(hmenu,   IDM_BLOCKNEXTCB,
                    465:             fAny || fBlockNextCB ? MF_ENABLED    : MF_GRAYED);
                    466:     CheckMenuItem(hmenu,    IDM_BLOCKNEXTCB,
                    467:             fBlockNextCB    ? MF_CHECKED    : MF_UNCHECKED);
                    468: 
                    469:     EnableMenuItem(hmenu,   IDM_TERMNEXTCB,
                    470:             fAny || fTermNextCB ? MF_ENABLED    : MF_GRAYED);
                    471:     CheckMenuItem(hmenu,    IDM_TERMNEXTCB,
                    472:             fTermNextCB     ? MF_CHECKED    : MF_UNCHECKED);
                    473: 
                    474:     // IDM_DELAY - always enabled.
                    475: 
                    476:     // IDM_TIMEOUT - alwasy enabled.
                    477: 
                    478:     EnableMenuItem (hmenu,  IDM_WINDOWTILE,
                    479:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    480: 
                    481:     EnableMenuItem (hmenu,  IDM_WINDOWCASCADE,
                    482:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    483: 
                    484:     EnableMenuItem (hmenu,  IDM_WINDOWICONS,
                    485:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    486: 
                    487:     EnableMenuItem (hmenu,  IDM_WINDOWCLOSEALL,
                    488:             fAny            ? MF_ENABLED    : MF_GRAYED);
                    489: 
                    490:     EnableMenuItem (hmenu,  IDM_XACTTILE,
                    491:             fXactions       ? MF_ENABLED    : MF_GRAYED);
                    492: 
                    493:     EnableMenuItem (hmenu,  IDM_XACTCASCADE,
                    494:             fXactions       ? MF_ENABLED    : MF_GRAYED);
                    495: 
                    496:     CheckMenuItem(hmenu,   IDM_AUTORECONNECT,
                    497:             fAutoReconnect  ? MF_CHECKED    : MF_UNCHECKED);
                    498: 
                    499:     // IDM_HELPABOUT - always enabled.
                    500: }
                    501: 
                    502: 
                    503: 
                    504: /****************************************************************************
                    505:  *                                                                          *
                    506:  *  FUNCTION   : CloseAllChildren ()                                        *
                    507:  *                                                                          *
                    508:  *  PURPOSE    : Destroys all MDI child windows.                            *
                    509:  *                                                                          *
                    510:  ****************************************************************************/
                    511: VOID NEAR PASCAL CloseAllChildren ()
                    512: {
                    513:     HWND hwndT;
                    514: 
                    515:     /* hide the MDI client window to avoid multiple repaints */
                    516:     ShowWindow(hwndMDIClient,SW_HIDE);
                    517: 
                    518:     /* As long as the MDI client has a child, destroy it */
                    519:     while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){
                    520: 
                    521:         /* Skip the icon title windows */
                    522:         while (hwndT && GetWindow (hwndT, GW_OWNER))
                    523:             hwndT = GetWindow (hwndT, GW_HWNDNEXT);
                    524: 
                    525:         if (!hwndT)
                    526:             break;
                    527: 
                    528:         SendMessage(hwndMDIClient, WM_MDIDESTROY, (DWORD)hwndT, 0L);
                    529:     }
                    530: 
                    531:     ShowWindow( hwndMDIClient, SW_SHOW);
                    532: }
                    533: 
                    534: /****************************************************************************
                    535:  *                                                                          *
                    536:  *  FUNCTION   : CommandHandler ()                                          *
                    537:  *                                                                          *
                    538:  *  PURPOSE    : Processes all "frame" WM_COMMAND messages.                 *
                    539:  *                                                                          *
                    540:  ****************************************************************************/
                    541: VOID NEAR PASCAL CommandHandler (
                    542: HWND hwnd,
                    543: DWORD id)
                    544: 
                    545: {
                    546:     MYCONVINFO *pmci = NULL;
                    547: 
                    548:     if (hwndActive)
                    549:         pmci = (MYCONVINFO *)GetWindowLong(hwndActive, 0);
                    550: 
                    551:     switch (id){
                    552:         case IDM_EDITPASTE:
                    553:             {
                    554:                 HANDLE hClipData;
                    555:                 LPSTR psz;
                    556:                 XACT xact;
                    557: 
                    558:                 if (OpenClipboard(hwnd)) {
                    559:                     if (hClipData = GetClipboardData(fmtLink)) {
                    560:                         if (psz = GlobalLock(hClipData)) {
                    561:                             /*
                    562:                              * Create a conversation with the link app and
                    563:                              * begin a request and advise start transaction.
                    564:                              */
                    565:                             xact.hConv = CreateConv(DdeCreateStringHandle(idInst, psz, NULL),
                    566:                                     DdeCreateStringHandle(idInst, &psz[_fstrlen(psz) + 1], NULL),
                    567:                                     FALSE);
                    568:                             if (xact.hConv) {
                    569:                                 psz += _fstrlen(psz) + 1;
                    570:                                 psz += _fstrlen(psz) + 1;
                    571:                                 xact.ulTimeout = DefTimeout;
                    572:                                 xact.wType = XTYP_ADVSTART;
                    573:                                 xact.hDdeData = 0;
                    574:                                 xact.wFmt = CF_TEXT;
                    575:                                 xact.hszItem = DdeCreateStringHandle(idInst, psz, NULL);
                    576:                                 xact.fsOptions = 0;
                    577:                                 ProcessTransaction(&xact);
                    578:                                 xact.wType = XTYP_REQUEST;
                    579:                                 ProcessTransaction(&xact);
                    580:                             }
                    581:                             GlobalUnlock(hClipData);
                    582:                         }
                    583:                     }
                    584:                     CloseClipboard();
                    585:                 }
                    586:             }
                    587:             break;
                    588: 
                    589:         case IDM_CONNECT:
                    590:         case IDM_RECONNECT:
                    591:             DoDialog(MAKEINTRESOURCE(IDD_CONNECT), (WNDPROC)ConnectDlgProc,
                    592:                     id == IDM_RECONNECT, FALSE);
                    593:             break;
                    594: 
                    595:         case IDM_DISCONNECT:
                    596:             if (hwndActive) {
                    597:                 SendMessage(hwndMDIClient, WM_MDIDESTROY, (DWORD)hwndActive, 0L);
                    598:             }
                    599:             break;
                    600: 
                    601:         case IDM_TRANSACT:
                    602:             if (DoDialog(MAKEINTRESOURCE(IDD_TRANSACT), (WNDPROC)TransactDlgProc,
                    603:                     (DWORD)(LPSTR)pmci->hConv, FALSE))
                    604:                 SetFocus(GetWindow(hwndActive, GW_CHILD));
                    605:             break;
                    606: 
                    607:         case IDM_ABANDON:
                    608:             if (pmci != NULL && IsWindow(pmci->hwndXaction)) {
                    609:                 DestroyWindow(pmci->hwndXaction);
                    610:             }
                    611:             break;
                    612: 
                    613:         case IDM_ABANDONALL:
                    614:             DdeAbandonTransaction(idInst, pmci->hConv, NULL);
                    615:             {
                    616:                 HWND hwndXaction;
                    617: 
                    618:                 hwndXaction = GetWindow(hwndActive, GW_CHILD);
                    619:                 while (hwndXaction) {
                    620:                     DestroyWindow(hwndXaction);
                    621:                     hwndXaction = GetWindow(hwndActive, GW_CHILD);
                    622:                 }
                    623:             }
                    624:             break;
                    625: 
                    626:         case IDM_BLOCKCURRENT:
                    627:             DdeEnableCallback(idInst, pmci->hConv, EC_DISABLE);
                    628:             InvalidateRect(hwndActive, NULL, TRUE);
                    629:             break;
                    630: 
                    631:         case IDM_ENABLECURRENT:
                    632:             DdeEnableCallback(idInst, pmci->hConv, EC_ENABLEALL);
                    633:             InvalidateRect(hwndActive, NULL, TRUE);
                    634:             break;
                    635: 
                    636:         case IDM_ENABLEONECURRENT:
                    637:             DdeEnableCallback(idInst, pmci->hConv, EC_ENABLEONE);
                    638:             InvalidateRect(hwndActive, NULL, TRUE);
                    639:             break;
                    640: 
                    641:         case IDM_BLOCKALLCBS:
                    642:             DdeEnableCallback(idInst, NULL, EC_DISABLE);
                    643:             InvalidateRect(hwndMDIClient, NULL, TRUE);
                    644:             break;
                    645: 
                    646:         case IDM_ENABLEALLCBS:
                    647:             DdeEnableCallback(idInst, NULL, EC_ENABLEALL);
                    648:             InvalidateRect(hwndMDIClient, NULL, TRUE);
                    649:             break;
                    650: 
                    651:         case IDM_ENABLEONECB:
                    652:             DdeEnableCallback(idInst, NULL, EC_ENABLEONE);
                    653:             InvalidateRect(hwndMDIClient, NULL, TRUE);
                    654:             break;
                    655: 
                    656:         case IDM_BLOCKNEXTCB:
                    657:             fBlockNextCB = !fBlockNextCB;
                    658:             break;
                    659: 
                    660:         case IDM_TERMNEXTCB:
                    661:             fTermNextCB = !fTermNextCB;
                    662:             break;
                    663: 
                    664:         case IDM_DELAY:
                    665:             DoDialog(MAKEINTRESOURCE(IDD_VALUEENTRY), (WNDPROC)DelayDlgProc, NULL,
                    666:                     TRUE);
                    667:             break;
                    668: 
                    669:         case IDM_TIMEOUT:
                    670:             DoDialog(MAKEINTRESOURCE(IDD_VALUEENTRY), (WNDPROC)TimeoutDlgProc, NULL,
                    671:                     TRUE);
                    672:             break;
                    673: 
                    674:         case IDM_CONTEXT:
                    675:             DoDialog(MAKEINTRESOURCE(IDD_CONTEXT), (WNDPROC)ContextDlgProc, NULL, TRUE);
                    676:             break;
                    677: 
                    678:         case IDM_AUTORECONNECT:
                    679:             fAutoReconnect = !fAutoReconnect;
                    680:             break;
                    681: 
                    682:         /* The following are window commands - these are handled by the
                    683:          * MDI Client.
                    684:          */
                    685:         case IDM_WINDOWTILE:
                    686:             /* Tile MDI windows */
                    687:             SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L);
                    688:             break;
                    689: 
                    690:         case IDM_WINDOWCASCADE:
                    691:             /* Cascade MDI windows */
                    692:             SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
                    693:             break;
                    694: 
                    695:         case IDM_WINDOWICONS:
                    696:             /* Auto - arrange MDI icons */
                    697:             SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
                    698:             break;
                    699: 
                    700:         case IDM_WINDOWCLOSEALL:
                    701:             CloseAllChildren();
                    702:             break;
                    703: 
                    704:         case IDM_XACTTILE:
                    705:             TileChildWindows(hwndActive);
                    706:             break;
                    707: 
                    708:         case IDM_XACTCASCADE:
                    709:             MyCascadeChildWindows(hwndActive);
                    710:             break;
                    711: 
                    712:         case IDM_HELPABOUT:{
                    713:             DoDialog(MAKEINTRESOURCE(IDD_ABOUT), (WNDPROC)AboutDlgProc, NULL, TRUE);
                    714:             break;
                    715:         }
                    716: 
                    717:         default:
                    718:            /*
                    719:             * This is essential, since there are frame WM_COMMANDS generated
                    720:             * by the MDI system for activating child windows via the
                    721:             * window menu.
                    722:             */
                    723:             DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND,
                    724:                     GET_WM_COMMAND_MPS(id, 0, 0));
                    725:     }
                    726: }
                    727: 
                    728: 
                    729: /****************************************************************************
                    730:  *                                                                          *
                    731:  *  FUNCTION   : MPError (flags, id, ...)                            *
                    732:  *                                                                          *
                    733:  *  PURPOSE    : Flashes a Message Box to the user. The format string is    *
                    734:  *               taken from the STRINGTABLE.                                *
                    735:  *                                                                          *
                    736:  *  RETURNS    : Returns value returned by MessageBox() to the caller.      *
                    737:  *                                                                          *
                    738:  ****************************************************************************/
                    739: INT FAR cdecl MPError(
                    740: DWORD bFlags,
                    741: DWORD id,
                    742: ...)
                    743: {
                    744:     CHAR sz[160];
                    745:     CHAR szFmt[128];
                    746: 
                    747:     LoadString (hInst, id, szFmt, sizeof (szFmt));
                    748:     wvsprintf (sz, szFmt, (LPSTR)(&id + 1));
                    749:     LoadString (hInst, IDS_APPNAME, szFmt, sizeof (szFmt));
                    750:     return MessageBox (hwndFrame, sz, szFmt, bFlags);
                    751: }
                    752: 
                    753: 
                    754: 
                    755: /****************************************************************************
                    756:  *                                                                          *
                    757:  *  FUNCTION   : CreateConv()                                               *
                    758:  *                                                                          *
                    759:  *  PURPOSE    :                                                            *
                    760:  *                                                                          *
                    761:  *  RETURNS    :                                                            *
                    762:  *                                                                          *
                    763:  ****************************************************************************/
                    764: HCONV CreateConv(
                    765: HSZ hszApp,
                    766: HSZ hszTopic,
                    767: BOOL fList)
                    768: {
                    769:     HCONV hConv;
                    770:     HWND hwndConv = 0;
                    771:     CONVINFO ci;
                    772: 
                    773:     if (fList) {
                    774:         hConv = (HCONV)DdeConnectList(idInst, hszApp, hszTopic, NULL, &CCFilter);
                    775:     } else {
                    776:         hConv = DdeConnect(idInst, hszApp, hszTopic, &CCFilter);
                    777:     }
                    778:     if (hConv) {
                    779:         if (fList) {
                    780:             ci.hszSvcPartner = hszApp;
                    781:             ci.hszTopic = hszTopic;
                    782:         } else {
                    783:             ci.cb = sizeof(CONVINFO);
                    784:             DdeQueryConvInfo(hConv, QID_SYNC, &ci);
                    785:         }
                    786:         hwndConv = AddConv(ci.hszSvcPartner, ci.hszTopic, hConv, fList);
                    787:         // HSZs get freed when window dies.
                    788:     }
                    789:     if (!hwndConv) {
                    790:         DdeFreeStringHandle(idInst, hszApp);
                    791:         DdeFreeStringHandle(idInst, hszTopic);
                    792:     }
                    793:     return(hConv);
                    794: }
                    795: 
                    796: 
                    797: 
                    798: 
                    799: 
                    800: 
                    801: /****************************************************************************
                    802:  *                                                                          *
                    803:  *  FUNCTION   : AddConv()                                                  *
                    804:  *                                                                          *
                    805:  *  PURPOSE    : Creates an MDI window representing a conversation          *
                    806:  *               (fList = FALSE) or a set of MID windows for the list of    *
                    807:  *               conversations (fList = TRUE).                              *
                    808:  *                                                                          *
                    809:  *  EFFECTS    : Sets the hUser for the conversation to the created MDI     *
                    810:  *               child hwnd.  Keeps the hszs if successful.                 *
                    811:  *                                                                          *
                    812:  *  RETURNS    : created MDI window handle.                                 *
                    813:  *                                                                          *
                    814:  ****************************************************************************/
                    815: HWND  APIENTRY AddConv(
                    816: HSZ hszApp,
                    817: HSZ hszTopic,
                    818: HCONV hConv,
                    819: BOOL fList)
                    820: {
                    821:     HWND hwnd;
                    822:     MDICREATESTRUCT mcs;
                    823:     MYCONVINFO mci;
                    824: 
                    825:     if (fList) {
                    826:         /*
                    827:          * Create all child windows FIRST so we have info for list window.
                    828:          */
                    829:         CONVINFO ci;
                    830:         HCONV hConvChild = 0;
                    831: 
                    832:         ci.cb = sizeof(CONVINFO);
                    833:         while (hConvChild = DdeQueryNextServer((HCONVLIST)hConv, hConvChild)) {
                    834:             if (DdeQueryConvInfo(hConvChild, QID_SYNC, &ci)) {
                    835:                 AddConv(ci.hszSvcPartner, ci.hszTopic, hConvChild, FALSE);
                    836:             }
                    837:         }
                    838:     }
                    839: 
                    840:     mcs.szTitle = GetConvTitleText(hConv, hszApp, hszTopic, fList);
                    841: 
                    842:     mcs.szClass = fList ? szList : szChild;
                    843:     mcs.hOwner  = hInst;
                    844:     mcs.x = mcs.cx = CW_USEDEFAULT;
                    845:     mcs.y = mcs.cy = CW_USEDEFAULT;
                    846:     mcs.style = GetWindow(hwndMDIClient, GW_CHILD) ? 0L : WS_MAXIMIZE;
                    847: 
                    848:     // mci.hwndXaction =
                    849:     mci.fList = fList;
                    850:     mci.hConv = hConv;
                    851:     mci.hszTopic = hszTopic;
                    852:     mci.hszApp = hszApp;
                    853:     // mci.x =
                    854:     // mci.y =
                    855:     // mci.ci =
                    856:     mcs.lParam = (DWORD)(LPSTR)&mci;
                    857: 
                    858:     hwnd = (HWND)SendMessage (hwndMDIClient, WM_MDICREATE, 0,
                    859:              (LONG)(LPMDICREATESTRUCT)&mcs);
                    860: 
                    861:     MyFree((PSTR)(DWORD)mcs.szTitle);
                    862: 
                    863:     return hwnd;
                    864: }
                    865: 
                    866: 
                    867: 
                    868: 
                    869: 
                    870: /****************************************************************************
                    871:  *                                                                          *
                    872:  *  FUNCTION   : GetConvListText()                                          *
                    873:  *                                                                          *
                    874:  *  RETURN     : Returns a ponter to a string containing a list of          *
                    875:  *               conversations contained in the given hConvList freeable    *
                    876:  *               by MyFree();                                               *
                    877:  *                                                                          *
                    878:  ****************************************************************************/
                    879: PSTR GetConvListText(
                    880: HCONVLIST hConvList)
                    881: {
                    882:     HCONV hConv = 0;
                    883:     DWORD cConv = 0;
                    884:     CONVINFO ci;
                    885:     DWORD cb = 0;
                    886:     CHAR *psz, *pszStart;
                    887: 
                    888:     ci.cb = sizeof(CONVINFO);
                    889: 
                    890:     // find out size needed.
                    891: 
                    892:     while (hConv = DdeQueryNextServer(hConvList, hConv)) {
                    893:         if (DdeQueryConvInfo(hConv, QID_SYNC, &ci)) {
                    894:             if (!IsWindow((HWND)ci.hUser)) {
                    895:                 if (ci.wStatus & ST_CONNECTED) {
                    896:                     /*
                    897:                      * This conversation doesn't have a corresponding
                    898:                      * MDI window.  This is probably due to a reconnection.
                    899:                      */
                    900:                     ci.hUser = (DWORD)AddConv(ci.hszSvcPartner, ci.hszTopic, hConv, FALSE);
                    901:                 } else {
                    902:                     continue;   // skip this guy - he was closed locally.
                    903:                 }
                    904:             }
                    905:             cb += GetWindowTextLength((HWND)ci.hUser);
                    906:             if (cConv++)
                    907:                 cb += 2;        // room for CRLF
                    908:         }
                    909:     }
                    910:     cb++;                       // for terminator.
                    911: 
                    912:     // allocate and fill
                    913: 
                    914:     if (pszStart = psz = MyAlloc(cb)) {
                    915:         *psz = '\0';
                    916:         hConv = 0;
                    917:         while (hConv = DdeQueryNextServer(hConvList, hConv)) {
                    918:             if (DdeQueryConvInfo(hConv, QID_SYNC, &ci) &&
                    919:                     IsWindow((HWND)ci.hUser)) {
                    920:                 psz += GetWindowText((HWND)ci.hUser, psz, cb);
                    921:                 if (--cConv) {
                    922:                     *psz++ = '\r';
                    923:                     *psz++ = '\n';
                    924:                 }
                    925:             }
                    926:         }
                    927:     }
                    928:     return(pszStart);
                    929: }
                    930: 
                    931: 
                    932: /****************************************************************************
                    933:  *                                                                          *
                    934:  *  FUNCTION   : GetConvInfoText()                                          *
                    935:  *                                                                          *
                    936:  *  PURPOSE    : Returns a pointer to a string that reflects a              *
                    937:  *               conversation's information.  Freeable by MyFree();         *
                    938:  *                                                                          *
                    939:  ****************************************************************************/
                    940: PSTR GetConvInfoText(
                    941: HCONV hConv,
                    942: CONVINFO *pci)
                    943: {
                    944:     PSTR psz;
                    945:     PSTR szApp;
                    946: 
                    947:     psz = MyAlloc(300);
                    948:     pci->cb = sizeof(CONVINFO);
                    949:     if (hConv) {
                    950:         if (!DdeQueryConvInfo(hConv, QID_SYNC, (PCONVINFO)pci)) {
                    951:             strcpy(psz, "State=Disconnected");
                    952:             return(psz);
                    953:         }
                    954:         szApp = GetHSZName(pci->hszServiceReq);
                    955:         wsprintf(psz,
                    956:                 "hUser=0x%lx\r\nhConvPartner=0x%lx\r\nhszServiceReq=%s\r\nStatus=%s\r\nState=%s\r\nLastError=%s",
                    957:                 pci->hUser, pci->hConvPartner, (LPSTR)szApp,
                    958:                 (LPSTR)Status2String(pci->wStatus),
                    959:                 (LPSTR)State2String(pci->wConvst),
                    960:                 (LPSTR)Error2String(pci->wLastError));
                    961:         MyFree(szApp);
                    962:     } else {
                    963:         strcpy(psz, Error2String(DdeGetLastError(idInst)));
                    964:     }
                    965:     return(psz);
                    966: }
                    967: 
                    968: 
                    969: 
                    970: /****************************************************************************
                    971:  *                                                                          *
                    972:  *  FUNCTION   : GetConvTitleText()                                         *
                    973:  *                                                                          *
                    974:  *  PURPOSE    : Creates standard window title text based on parameters.    *
                    975:  *                                                                          *
                    976:  *  RETURNS    : psz freeable by MyFree()                                   *
                    977:  *                                                                          *
                    978:  ****************************************************************************/
                    979: PSTR GetConvTitleText(
                    980: HCONV hConv,
                    981: HSZ hszApp,
                    982: HSZ hszTopic,
                    983: BOOL fList)
                    984: {
                    985:     DWORD cb;
                    986:     PSTR psz;
                    987: 
                    988:     cb = (DWORD)DdeQueryString(idInst, hszApp, NULL, 0, 0) +
                    989:             (DWORD)DdeQueryString(idInst, hszTopic, (LPSTR)NULL, 0, 0) +
                    990:             (fList ? 30 : 20);
                    991: 
                    992:     if (psz = MyAlloc(cb)) {
                    993:         DdeQueryString(idInst, hszApp, psz, cb, 0);
                    994:         strcat(psz, "|");
                    995:         DdeQueryString(idInst, hszTopic, &psz[strlen(psz)], cb, 0);
                    996:         if (fList)
                    997:             strcat(psz, " - LIST");
                    998:         wsprintf(&psz[strlen(psz)], " - (%lx)", hConv);
                    999:     }
                   1000:     return(psz);
                   1001: }
                   1002: 
                   1003: 
                   1004: 
                   1005: /****************************************************************************
                   1006:  *                                                                          *
                   1007:  *  FUNCTION   : Status2String()                                            *
                   1008:  *                                                                          *
                   1009:  *  PURPOSE    : Converts a conversation status word to a string and        *
                   1010:  *               returns a pointer to that string.  The string is valid     *
                   1011:  *               till the next call to this function.                       *
                   1012:  *                                                                          *
                   1013:  ****************************************************************************/
                   1014: PSTR Status2String(
                   1015: DWORD status)
                   1016: {
                   1017:     DWORD c, i;
                   1018:     static CHAR szStatus[6 * 18];
                   1019:     static struct {
                   1020:         CHAR *szStatus;
                   1021:         DWORD status;
                   1022:     } s2s[] = {
                   1023:         { "Connected"    ,   ST_CONNECTED },
                   1024:         { "Advise"       ,   ST_ADVISE },
                   1025:         { "IsLocal"      ,   ST_ISLOCAL },
                   1026:         { "Blocked"      ,   ST_BLOCKED },
                   1027:         { "Client"       ,   ST_CLIENT },
                   1028:         { "Disconnected" ,   ST_TERMINATED },
                   1029:         { "BlockNext"    ,   ST_BLOCKNEXT },
                   1030:     };
                   1031: #define CFLAGS 7
                   1032:     szStatus[0] = '\0';
                   1033:     c = 0;
                   1034:     for (i = 0; i < CFLAGS; i++) {
                   1035:         if (status & s2s[i].status) {
                   1036:             if (c++)
                   1037:                 strcat(szStatus, " | ");
                   1038:             strcat(szStatus, s2s[i].szStatus);
                   1039:         }
                   1040:     }
                   1041:     return szStatus;
                   1042: #undef CFLAGS
                   1043: }
                   1044: 
                   1045: 
                   1046: 
                   1047: 
                   1048: /****************************************************************************
                   1049:  *                                                                          *
                   1050:  *  FUNCTION   : State2String()                                             *
                   1051:  *                                                                          *
                   1052:  *  PURPOSE    : converts a conversation state word to a string and         *
                   1053:  *               returns a pointer to that string.  The string is valid     *
                   1054:  *               till the next call to this routine.                        *
                   1055:  *                                                                          *
                   1056:  ****************************************************************************/
                   1057: PSTR State2String(
                   1058: DWORD state)
                   1059: {
                   1060:     static CHAR *s2s[] = {
                   1061:         "NULL"             ,
                   1062:         "Incomplete"       ,
                   1063:         "Standby"          ,
                   1064:         "Initiating"       ,
                   1065:         "ReqSent"          ,
                   1066:         "DataRcvd"         ,
                   1067:         "PokeSent"         ,
                   1068:         "PokeAckRcvd"      ,
                   1069:         "ExecSent"         ,
                   1070:         "ExecAckRcvd"      ,
                   1071:         "AdvSent"          ,
                   1072:         "UnadvSent"        ,
                   1073:         "AdvAckRcvd"       ,
                   1074:         "UnadvAckRcvd"     ,
                   1075:         "AdvDataSent"      ,
                   1076:         "AdvDataAckRcvd"   ,
                   1077:         "?"                ,    // 16
                   1078:     };
                   1079: 
                   1080:     if (state >= 17)
                   1081:         return s2s[17];
                   1082:     else
                   1083:         return s2s[state];
                   1084: }
                   1085: 
                   1086: /****************************************************************************
                   1087:  *                                                                          *
                   1088:  *  FUNCTION   : Error2String()                                             *
                   1089:  *                                                                          *
                   1090:  *  PURPOSE    : Converts an error code to a string and returns a pointer   *
                   1091:  *               to that string.  The string is valid until the next call   *
                   1092:  *               to this function.                                          *
                   1093:  *                                                                          *
                   1094:  ****************************************************************************/
                   1095: PSTR Error2String(
                   1096: DWORD error)
                   1097: {
                   1098:     static CHAR szErr[23];
                   1099:     static CHAR *e2s[] = {
                   1100:         "Advacktimeout"              ,
                   1101:         "Busy"                       ,
                   1102:         "Dataacktimeout"             ,
                   1103:         "Dll_not_initialized"        ,
                   1104:         "Dll_usage"                  ,
                   1105:         "Execacktimeout"             ,
                   1106:         "Invalidparameter"           ,
                   1107:         "Low Memory warning"         ,
                   1108:         "Memory_error"               ,
                   1109:         "Notprocessed"               ,
                   1110:         "No_conv_established"        ,
                   1111:         "Pokeacktimeout"             ,
                   1112:         "Postmsg_failed"             ,
                   1113:         "Reentrancy"                 ,
                   1114:         "Server_died"                ,
                   1115:         "Sys_error"                  ,
                   1116:         "Unadvacktimeout"            ,
                   1117:         "Unfound_queue_id"           ,
                   1118:     };
                   1119:     if (!error) {
                   1120:         strcpy(szErr, "0");
                   1121:     } else if (error > DMLERR_LAST || error < DMLERR_FIRST) {
                   1122:         strcpy(szErr, "???");
                   1123:     } else {
                   1124:         strcpy(szErr, e2s[error - DMLERR_FIRST]);
                   1125:     }
                   1126:     return(szErr);
                   1127: }
                   1128: 
                   1129: 
                   1130: 
                   1131: 
                   1132: 
                   1133: /****************************************************************************
                   1134:  *                                                                          *
                   1135:  *  FUNCTION   : Type2String()                                              *
                   1136:  *                                                                          *
                   1137:  *  PURPOSE    : Converts a wType word and fsOption flags to a string and   *
                   1138:  *               returns a pointer to that string.  the string is valid     *
                   1139:  *               until the next call to this function.                      *
                   1140:  *                                                                          *
                   1141:  ****************************************************************************/
                   1142: PSTR Type2String(
                   1143: DWORD wType,
                   1144: DWORD fsOptions)
                   1145: {
                   1146:     static CHAR sz[30];
                   1147:     static CHAR o2s[] = "^!#$X*<?";
                   1148:     static CHAR *t2s[] = {
                   1149:         ""                 ,
                   1150:         "AdvData"          ,
                   1151:         "AdvReq"           ,
                   1152:         "AdvStart"         ,
                   1153:         "AdvStop"          ,
                   1154:         "Execute"          ,
                   1155:         "Connect"          ,
                   1156:         "ConnectConfirm"   ,
                   1157:         "XactComplete"    ,
                   1158:         "Poke"             ,
                   1159:         "Register"         ,
                   1160:         "Request"          ,
                   1161:         "Term"             ,
                   1162:         "Unregister"       ,
                   1163:         "WildConnect"      ,
                   1164:         ""                 ,
                   1165:     };
                   1166:     DWORD bit, c, i;
                   1167: 
                   1168:     strcpy(sz, t2s[((wType & XTYP_MASK) >> XTYP_SHIFT)]);
                   1169:     c = strlen(sz);
                   1170:     sz[c++] = ' ';
                   1171:     for (i = 0, bit = 1; i < 7; bit = bit << 1, i++) {
                   1172:         if (fsOptions & bit)
                   1173:             sz[c++] = o2s[i];
                   1174:     }
                   1175:     sz[c] = '\0';
                   1176:     return(sz);
                   1177: }
                   1178: 
                   1179: 
                   1180: 
                   1181: 
                   1182: /****************************************************************************
                   1183:  *                                                                          *
                   1184:  *  FUNCTION   : GetHSZName()                                               *
                   1185:  *                                                                          *
                   1186:  *  PURPOSE    : Allocates local memory for and retrieves the string form   *
                   1187:  *               of an HSZ.  Returns a pointer to the local memory or NULL  *
                   1188:  *               if failure.  The string must be freed via MyFree().        *
                   1189:  *                                                                          *
                   1190:  ****************************************************************************/
                   1191: PSTR GetHSZName(
                   1192: HSZ hsz)
                   1193: {
                   1194:     PSTR psz;
                   1195:     DWORD cb;
                   1196: 
                   1197:     cb = (DWORD)DdeQueryString(idInst, hsz, NULL, 0, 0) + 1;
                   1198:     psz = MyAlloc(cb);
                   1199:     DdeQueryString(idInst, hsz, psz, cb, 0);
                   1200:     return(psz);
                   1201: }
                   1202: 
                   1203: 
                   1204: /****************************************************************************
                   1205:  *
                   1206:  *  FUNCTION   : MyMsgFilterProc
                   1207:  *
                   1208:  *  PURPOSE    : This filter proc gets called for each message we handle.
                   1209:  *               This allows our application to properly dispatch messages
                   1210:  *               that we might not otherwise see because of DDEMLs modal
                   1211:  *               loop that is used while processing synchronous transactions.
                   1212:  *
                   1213:  *               Generally, applications that only do synchronous transactions
                   1214:  *               in response to user input (as this app does) does not need
                   1215:  *               to install such a filter proc because it would be very rare
                   1216:  *               that a user could command the app fast enough to cause
                   1217:  *               problems.  However, this is included as an example.
                   1218:  *
                   1219:  ****************************************************************************/
                   1220: DWORD  APIENTRY MyMsgFilterProc(
                   1221: INT nCode,
                   1222: WPARAM wParam,
                   1223: DWORD lParam)
                   1224: {
                   1225:     wParam; // not used
                   1226: 
                   1227: #define lpmsg ((LPMSG)lParam)
                   1228:     if (nCode == MSGF_DDEMGR) {
                   1229: 
                   1230:         /* If a keyboard message is for the MDI , let the MDI client
                   1231:          * take care of it.  Otherwise, check to see if it's a normal
                   1232:          * accelerator key.  Otherwise, just handle the message as usual.
                   1233:          */
                   1234: 
                   1235:         if ( !TranslateMDISysAccel (hwndMDIClient, lpmsg) &&
                   1236:              !TranslateAccelerator (hwndFrame, hAccel, lpmsg)){
                   1237:             TranslateMessage (lpmsg);
                   1238:             DispatchMessage (lpmsg);
                   1239:         }
                   1240:         return(1);
                   1241:     }
                   1242:     return(0);
                   1243: #undef lpmsg
                   1244: }
                   1245: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.