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

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

unix.superglobalmegacorp.com

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