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

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

unix.superglobalmegacorp.com

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