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

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

unix.superglobalmegacorp.com

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