home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / ddespy / ddespy.c next >
C/C++ Source or Header  |  1997-10-05  |  46KB  |  1,314 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /****************************************************************************
  13.  
  14.     PROGRAM: DdeSpy.c
  15.  
  16. ****************************************************************************/
  17.  
  18. #define UNICODE
  19. #include <windows.h>                /* required for all Windows applications */
  20. #include <windowsx.h>
  21. #include <shellapi.h>
  22. #include <dde.h>
  23. #include <stdio.h>
  24. #include <io.h>
  25. #include <errno.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <ctype.h>
  29. #include "ddespy.h"
  30. #include "lists.h"
  31.  
  32. /* GLOBAL Variables used for DDESPY */
  33.  
  34. UINT        idInst = 0;
  35. HINSTANCE   hInst;
  36. HICON       hIcon;
  37. HWND        hWndString = NULL;
  38. HWND        hwndSpy = NULL;
  39. HANDLE      fhOutput = NULL;
  40. OFSTRUCT    ofsOpen;
  41. TCHAR        OpenName[MAX_FNAME + 1];
  42. TCHAR        TBuf[BUFFER_SIZE];
  43. TCHAR        TBuf2[BUFFER_SIZE];
  44. TCHAR        szNULL[] = TEXT("");
  45. LPTSTR        apszResources[IDS_LAST + 1];
  46. PFNCALLBACK pfnDdeCallback = NULL;
  47. HWND        hwndTrack[IT_COUNT] = { 0 };
  48. LPTSTR        TrackTitle[IT_COUNT];
  49. BOOL        fBlockMsg[WM_DDE_LAST - WM_DDE_FIRST + 1] = { 0 };
  50. BOOL        fBlockCb[15] = { 0 };
  51. LPTSTR        TrackHeading[IT_COUNT];
  52. struct {                           /* profile data */
  53.     BOOL fOutput[IO_COUNT];
  54.     BOOL fFilter[IF_COUNT];
  55.     BOOL fTrack[IT_COUNT];
  56.     BOOL fTerse;
  57. } pro;
  58.  
  59.  
  60.  
  61. BOOL LoadResourceStrings()
  62. {
  63.     int i, cbLeft, cbRes;
  64.     LPTSTR psz;
  65.  
  66.     cbLeft = 0x1000;
  67.     psz = LocalAlloc(LPTR, sizeof(TCHAR) * cbLeft);
  68.     for (i = 0; i <= IDS_LAST; i++) {
  69.         apszResources[i] = psz;
  70.         cbRes = LoadString(hInst, i, psz, cbLeft) + 1;
  71.         cbLeft -= cbRes;
  72.         psz += cbRes;
  73.     }
  74.     for (i = 0; i < IT_COUNT; i++) {
  75.         TrackTitle[i] = RefString(IDS_TRACKTITLE_1 + i);
  76.         TrackHeading[i] = RefString(IDS_TRACKHEADING_1 + i);
  77.     }
  78.     lstrcpy(TBuf, RefString(IDS_DEFAULT_OUTPUT_FNAME));
  79.     GetFullPathName(TBuf, sizeof(OpenName) / sizeof(TCHAR),
  80.         OpenName, (LPTSTR *)TBuf2);
  81.     return(TRUE);
  82. }
  83.  
  84.  
  85.  
  86. int WINAPI WinMain(
  87.         HINSTANCE hInstance,
  88.         HINSTANCE hPrevInstance,
  89.         LPSTR lpCmdLine,
  90.         int nCmdShow)
  91. {
  92.     MSG msg;
  93.  
  94.     UNREFERENCED_PARAMETER(lpCmdLine);
  95.  
  96.     hInst = hInstance;
  97.  
  98.     if (!LoadResourceStrings()) {
  99.         return (FALSE);
  100.     }
  101.  
  102.     if (!hPrevInstance)
  103.         if (!InitApplication(hInstance)) /* Initialize shared things */
  104.             return (FALSE);              /* Exits if unable to initialize    */
  105.  
  106.     /* Perform initializations that apply to a specific instance */
  107.  
  108.     if (!InitInstance(hInstance, nCmdShow)) {
  109.         CloseApp();
  110.         return (FALSE);
  111.     }
  112.  
  113.     /* Acquire and dispatch messages until a WM_QUIT message is received. */
  114.  
  115.     while (GetMessage(&msg,        /* message structure                      */
  116.             NULL,                  /* handle of window receiving the message */
  117.             0,                     /* lowest message to examine              */
  118.             0))                    /* highest message to examine             */
  119.         {
  120.         TranslateMessage(&msg);    /* Translates virtual key codes           */
  121.         DispatchMessage(&msg);     /* Dispatches message to window           */
  122.     }
  123.     CloseApp();
  124.     return (msg.wParam);           /* Returns the value from PostQuitMessage */
  125. }
  126.  
  127.  
  128.  
  129. BOOL InitApplication(HINSTANCE hInstance)
  130. {
  131.     WNDCLASS  wc;
  132.  
  133.     if (!InitTestSubs())
  134.         return(FALSE);
  135.  
  136.     /* Fill in window class structure with parameters that describe the       */
  137.     /* main window.                                                           */
  138.  
  139.     wc.style = 0;                    /* Class style(s).                    */
  140.     wc.lpfnWndProc = (WNDPROC)MainWndProc;       /* Function to retrieve messages for  */
  141.                                         /* windows of this class.             */
  142.     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
  143.     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
  144.     wc.hInstance = hInstance;           /* Application that owns the class.   */
  145.     hIcon = wc.hIcon = LoadIcon(hInstance, TEXT("DDESpy"));
  146.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  147.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  148.     wc.lpszMenuName =  MAKEINTRESOURCE(IDR_MENU);   /* Name of menu resource in .RC file. */
  149.     wc.lpszClassName = RefString(IDS_CLASS);
  150.  
  151.     /* Register the window class and return success/failure code. */
  152.  
  153.     return (RegisterClass(&wc));
  154. }
  155.  
  156.  
  157. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  158. {
  159.     RECT            Rect;
  160.     INT             i;
  161.  
  162.     /* Save the instance handle in static variable, which will be used in  */
  163.     /* many subsequence calls from this application to Windows.            */
  164.  
  165.     pfnDdeCallback = (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback,
  166.             hInstance);
  167.  
  168.     GetProfile();
  169.  
  170.     /* Create a main window for this application instance.  */
  171.  
  172.     hwndSpy = CreateWindow(
  173.         RefString(IDS_CLASS),
  174.         RefString(IDS_TITLE),
  175.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  176.         CW_USEDEFAULT,                  /* Default horizontal position.       */
  177.         CW_USEDEFAULT,                  /* Default vertical position.         */
  178.         CW_USEDEFAULT,                  /* Default width.                     */
  179.         CW_USEDEFAULT,                  /* Default height.                    */
  180.         NULL,                           /* Overlapped windows have no parent. */
  181.         NULL,                           /* Use the window class menu.         */
  182.         hInstance,                      /* This instance owns this window.    */
  183.         NULL                            /* Pointer not needed.                */
  184.     );
  185.  
  186.  
  187.     GetClientRect(hwndSpy, (LPRECT) &Rect);
  188.  
  189.     hWndString = CreateWindow(          /* String Window (class Registered in Teststubs)*/
  190.         RefString(IDS_STRINGCLASS),
  191.         szNULL,
  192.         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
  193.         0,
  194.         0,
  195.         Rect.right - Rect.left,
  196.         Rect.bottom - Rect.top,
  197.         hwndSpy,
  198.         NULL,
  199.         hInst,
  200.         (LPTSTR)MAKELONG(CCHARS, CLINES));
  201.  
  202.     for (i = 0; i < IT_COUNT; i++) {
  203.         if (pro.fTrack[i]) {
  204.             pro.fTrack[i] = FALSE;
  205.             SendMessage(hwndSpy, WM_COMMAND,
  206.                     GET_WM_COMMAND_MPS(IDM_TRACK_FIRST + i, 0, 0));
  207.         }
  208.     }
  209.  
  210.     if (!hwndSpy || !hWndString) {
  211.         CloseApp();
  212.         return (FALSE);
  213.     }
  214.  
  215.     /* Make the window visible; update its client area; and return "success" */
  216.  
  217.     ShowWindow(hwndSpy, nCmdShow);  /* Show the window                        */
  218.     UpdateWindow(hwndSpy);          /* Sends WM_PAINT message                 */
  219.  
  220.     if (SetFilters()) {
  221.         return(FALSE);
  222.     }
  223.  
  224.     return(TRUE);
  225. }
  226.  
  227.  
  228. VOID CloseApp()
  229. {
  230.     DdeUninitialize(idInst);        /* perform cleanup and store profile */
  231.     SaveProfile();
  232.     if (fhOutput != NULL)
  233.         CloseHandle(fhOutput);
  234.     UnregisterClass(RefString(IDS_CLASS), hInst);
  235.     CloseTestSubs(hInst);
  236. }
  237.  
  238.  
  239.  
  240. LONG  CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  241. {
  242.     int i;
  243.  
  244.     switch (message) {
  245.     case WM_CREATE:
  246.         LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCEL));
  247.         if (pro.fOutput[IO_FILE])
  248.             fhOutput = (HANDLE)DoDialog(
  249.                     MAKEINTRESOURCE(IDD_OPEN),
  250.                     (DLGPROC)OpenDlg,
  251.                     0,
  252.                     TRUE,
  253.                     hWnd,
  254.                     hInst);
  255.             pro.fOutput[IO_FILE] = (fhOutput != NULL);
  256.         break;
  257.  
  258.     case WM_INITMENU:
  259.         if (GetMenu(hWnd) != (HMENU)wParam)
  260.             break;
  261.  
  262.         for (i = 0; i < IO_COUNT; i++) {
  263.         CheckMenuItem((HMENU)wParam, IDM_OUTPUT_FIRST + i,
  264.                 pro.fOutput[i] ? MF_CHECKED : MF_UNCHECKED);
  265.         }
  266.  
  267.         for (i = 0; i < IF_COUNT; i++) {
  268.             CheckMenuItem((HMENU)wParam, IDM_FILTER_FIRST + i,
  269.                 pro.fFilter[i] ? MF_CHECKED : MF_UNCHECKED);
  270.         }
  271.  
  272.         for (i = 0; i < IT_COUNT; i++) {
  273.             CheckMenuItem((HMENU)wParam, IDM_TRACK_FIRST + i,
  274.                 pro.fTrack[i] ? MF_CHECKED : MF_UNCHECKED);
  275.         }
  276.         break;
  277.  
  278.     case WM_COMMAND:           /* message: command from application menu */
  279.         switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  280.         case IDM_OUTPUT_FILE:
  281.         case IDM_OUTPUT_DEBUG:
  282.         case IDM_OUTPUT_SCREEN:
  283.             switch (wParam) {
  284.             case IDM_OUTPUT_FILE:
  285.                 if (fhOutput != NULL) {
  286.                     wsprintf(TBuf, RefString(IDS_QCLOSEFILE_TEXT), OpenName);
  287.                     if (IDYES != MessageBox(hWnd,
  288.                             TBuf, RefString(IDS_QCLOSEFILE_CAPTION),
  289.                             MB_YESNO | MB_ICONQUESTION)) {
  290.                         break;
  291.                     }
  292.                     CloseHandle(fhOutput);
  293.                 }
  294.                 fhOutput = (HANDLE)DoDialog(
  295.                         MAKEINTRESOURCE(IDD_OPEN),
  296.                         (DLGPROC)OpenDlg,
  297.                         0,
  298.                         TRUE,
  299.                         hWnd,
  300.                         hInst);
  301.                 pro.fOutput[IO_FILE] = (fhOutput != NULL);
  302.                 break;
  303.  
  304.             case IDM_OUTPUT_DEBUG:
  305.                 pro.fOutput[IO_DEBUG] = !pro.fOutput[IO_DEBUG];
  306.                 break;
  307.  
  308.             case IDM_OUTPUT_SCREEN:
  309.                 pro.fOutput[IO_SCREEN] = !pro.fOutput[IO_SCREEN];
  310.                 break;
  311.  
  312.             }
  313.             break;
  314.  
  315.         case IDM_CLEARSCREEN:
  316.             if (hWndString) {
  317.                 HANDLE hpsw;
  318.                 STRWND *psw;
  319.  
  320.                 hpsw = (HANDLE)GetWindowLong(hWndString, 0);
  321.                 psw = (STRWND *)LocalLock(hpsw);
  322.                 ClearScreen(psw);
  323.                 LocalUnlock(hpsw);
  324.                 InvalidateRect(hWndString, NULL, TRUE);
  325.             }
  326.             break;
  327.  
  328.         case IDM_MARK:
  329.             DoDialog(MAKEINTRESOURCE(IDD_VALUEENTRY), (DLGPROC)MarkDlgProc, 0, TRUE, hWnd, hInst);
  330.             break;
  331.  
  332.         case IDM_FILTER_HSZINFO:
  333.         case IDM_FILTER_INIT_TERM:
  334.         case IDM_FILTER_DDEMSGS:
  335.         case IDM_FILTER_CALLBACKS:
  336.         case IDM_FILTER_ERRORS:
  337.             pro.fFilter[wParam - IDM_FILTER_FIRST] =
  338.                     !pro.fFilter[wParam - IDM_FILTER_FIRST];
  339.             SetFilters();
  340.             break;
  341.  
  342.         case IDM_FILTER_DIALOG:
  343.             DoDialog(MAKEINTRESOURCE(IDD_MSGFILTERS), (DLGPROC)FilterDlgProc, 0, TRUE, hWnd, hInst);
  344.             break;
  345.  
  346.         case IDM_TRACK_HSZS:
  347.         case IDM_TRACK_CONVS:
  348.         case IDM_TRACK_LINKS:
  349.         case IDM_TRACK_SVRS:
  350.             pro.fTrack[wParam - IDM_TRACK_FIRST] =
  351.                     !pro.fTrack[wParam - IDM_TRACK_FIRST];
  352.             if (pro.fTrack[wParam - IDM_TRACK_FIRST]) {
  353.                 hwndTrack[wParam - IDM_TRACK_FIRST] = CreateMCLBFrame(
  354.                         NULL,
  355.                         TrackTitle[wParam - IDM_TRACK_FIRST],
  356.                         WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MINIMIZE,
  357.                         hIcon, (HBRUSH)(COLOR_APPWORKSPACE + 1),
  358.                         TrackHeading[wParam - IDM_TRACK_FIRST]);
  359.             } else {
  360.                 DestroyWindow(hwndTrack[wParam - IDM_TRACK_FIRST]);
  361.                 hwndTrack[wParam - IDM_TRACK_FIRST] = 0;
  362.             }
  363.             SetFilters();
  364.             break;
  365.  
  366.         case IDM_ABOUT:
  367.             DoDialog(MAKEINTRESOURCE(IDD_ABOUTBOX), (DLGPROC)About, 0, TRUE, hWnd, hInst);
  368.             break;
  369.  
  370.         default:
  371.             return (DefWindowProc(hWnd, message, wParam, lParam));
  372.         }
  373.         break;
  374.  
  375.     case WM_DESTROY:                  /* message: window being destroyed */
  376.         for (i = IDM_TRACK_FIRST; i <= IDM_TRACK_LAST; i++) {
  377.             if (pro.fTrack[i - IDM_TRACK_FIRST]) {
  378.                 DestroyWindow(hwndTrack[i - IDM_TRACK_FIRST]);
  379.                 hwndTrack[i - IDM_TRACK_FIRST] = 0;
  380.             }
  381.         }
  382.         PostQuitMessage(0);
  383.         break;
  384.  
  385.     case WM_SIZE:
  386.         if (hWndString) {
  387.             RECT rc;
  388.  
  389.             GetClientRect(hWnd, &rc);
  390.             MoveWindow(hWndString, 0, 0, rc.right, rc.bottom, TRUE);
  391.         }
  392.         // fall through
  393.     default:
  394.         return (DefWindowProc(hWnd, message, wParam, lParam));
  395.     }
  396.     return (0);
  397. }
  398.  
  399.  
  400.  
  401.  
  402.  
  403. BOOL  CALLBACK About(
  404.                     HWND hDlg,
  405.                     UINT message,
  406.                     WPARAM wParam,
  407.                     LPARAM lParam)
  408. {
  409.     switch (message) {
  410.         case WM_INITDIALOG:                /* message: initialize dialog box */
  411.             return (TRUE);
  412.  
  413.         case WM_COMMAND:                      /* message: received a command */
  414.             if (GET_WM_COMMAND_ID(wParam, lParam) == IDOK
  415.                 || GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL) {
  416.                 EndDialog(hDlg, TRUE);        /* Exits the dialog box        */
  417.                 return (TRUE);
  418.             }
  419.             break;
  420.     }
  421.     return (FALSE);                           /* Didn't process a message    */
  422. }
  423.  
  424.  
  425. HDDEDATA CALLBACK DdeCallback(
  426.                             UINT wType,
  427.                             UINT wFmt,
  428.                             HCONV hConv,
  429.                             HSZ hsz1,
  430.                             HSZ hsz2,
  431.                             HDDEDATA hData,
  432.                             UINT dwData1,
  433.                             UINT dwData2)
  434. {
  435.     LPVOID pData;
  436.     UINT cb;
  437.     TCHAR *psz1, *psz2, *psz3;
  438.     TCHAR *szAction;
  439.     INT i;
  440.     BOOL fInt = FALSE;
  441.     wFmt;
  442.     hConv;
  443.     dwData1;
  444.  
  445.     switch (wType) {
  446.     case XTYP_MONITOR:
  447.     if (pData = DdeAccessData(hData, (LPDWORD)&cb)) {
  448.         switch (dwData2) {
  449.         case MF_HSZ_INFO:
  450.             if (pro.fTrack[IT_HSZS]) {
  451.                 switch (((MONHSZSTRUCT FAR *)pData)->fsAction) {
  452.                 case MH_DELETE:
  453.                     wsprintf(TBuf, fInt ? TEXT("0x%lx\t*\t%s(int)")
  454.                 : TEXT("0x%lx\t*\t%s"),
  455.                             ((MONHSZSTRUCT FAR *)pData)->hsz,
  456.                             (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  457.                     i = GetMCLBColValue(TBuf, hwndTrack[IT_HSZS], 2);
  458.                     if (i > 1) {
  459.                         wsprintf(TBuf2, fInt ? TEXT("0x%lx\t%d\t%s(int)")
  460.                 : TEXT("0x%lx\t%d\t%s"),
  461.                                 ((MONHSZSTRUCT FAR *)pData)->hsz,
  462.                                  i - 1,
  463.                                  (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  464.                         AddMCLBText(TBuf, TBuf2, hwndTrack[IT_HSZS]);
  465.                     } else if (i == 1) {
  466.                         DeleteMCLBText(TBuf, hwndTrack[IT_HSZS]);
  467.                     }
  468.                     break;
  469.  
  470.                 case MH_KEEP:
  471.                 case MH_CREATE:
  472.                     wsprintf(TBuf, fInt ? TEXT("0x%lx\t*\t%s(int)")
  473.                 : TEXT("0x%lx\t*\t%s"),
  474.                             ((MONHSZSTRUCT FAR *)pData)->hsz,
  475.                             (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  476.                     i = GetMCLBColValue(TBuf, hwndTrack[IT_HSZS], 2) + 1;
  477.                     wsprintf(TBuf2, fInt ? TEXT("0x%lx\t%d\t%s(int)")
  478.                 : TEXT("0x%lx\t%d\t%s"),
  479.                             ((MONHSZSTRUCT FAR *)pData)->hsz,
  480.                              i,
  481.                              (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  482.                     AddMCLBText(TBuf, TBuf2, hwndTrack[IT_HSZS]);
  483.                 }
  484.             }
  485.  
  486.             if (!pro.fFilter[IF_HSZ]) {
  487.                 return(0);
  488.             }
  489.  
  490.             switch (((MONHSZSTRUCT FAR *)pData)->fsAction) {
  491.             case MH_CLEANUP:
  492.                 szAction = RefString(IDS_ACTION_CLEANEDUP);
  493.                 break;
  494.  
  495.             case MH_DELETE:
  496.                 szAction = RefString(IDS_ACTION_DESTROYED);
  497.                 break;
  498.  
  499.             case MH_KEEP:
  500.                 szAction = RefString(IDS_ACTION_INCREMENTED);
  501.                 break;
  502.  
  503.             case MH_CREATE:
  504.                 szAction = RefString(IDS_ACTION_CREATED);
  505.                 break;
  506.  
  507.             default:
  508.                 DdeUnaccessData(hData);
  509.                 return(0);
  510.             }
  511.             if (pro.fTerse) {
  512.                 wsprintf(TBuf, TEXT("[%x:%ld] HSZ %s: %lx(%s)"),
  513.                         ((MONHSZSTRUCT FAR *)pData)->hTask,
  514.                         ((MONHSZSTRUCT FAR *)pData)->dwTime,
  515.                         (LPTSTR)szAction,
  516.                         ((MONHSZSTRUCT FAR *)pData)->hsz,
  517.                         (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  518.             } else {
  519.                 wsprintf(TBuf,
  520.                         RefString(IDS_FMT_SH_MSG1),
  521.                         ((MONHSZSTRUCT FAR *)pData)->hTask,
  522.                         ((MONHSZSTRUCT FAR *)pData)->dwTime,
  523.                         (LPTSTR)szAction,
  524.                         ((MONHSZSTRUCT FAR *)pData)->hsz,
  525.                         (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
  526.             }
  527.             break;
  528.  
  529.  
  530.         case MF_SENDMSGS:
  531.         case MF_POSTMSGS:
  532.             if (fBlockMsg[((MONMSGSTRUCT FAR *)pData)->wMsg - WM_DDE_FIRST]) {
  533.                 return(0);
  534.             }
  535.             if (pro.fTerse) {
  536.                 wsprintf(TBuf, RefString(IDS_FMT_TRS_MSG1),
  537.                         ((MONMSGSTRUCT FAR *)pData)->hTask,
  538.                         ((MONMSGSTRUCT FAR *)pData)->dwTime,
  539.                         ((MONMSGSTRUCT FAR *)pData)->wParam,
  540.                         ((MONMSGSTRUCT FAR *)pData)->hwndTo,
  541.                         (dwData2 == MF_SENDMSGS) ? RefString(IDS_SENT) : RefString(IDS_POSTED),
  542.                         (LPTSTR)DdeMsg2String(((MONMSGSTRUCT FAR *)pData)->wMsg));
  543.             } else {
  544.                 wsprintf(TBuf, RefString(IDS_FMT_MSG1),
  545.                         ((MONMSGSTRUCT FAR *)pData)->hTask,
  546.                         ((MONMSGSTRUCT FAR *)pData)->dwTime,
  547.                         ((MONMSGSTRUCT FAR *)pData)->hwndTo,
  548.                         (dwData2 == MF_SENDMSGS) ? RefString(IDS_SENT) : RefString(IDS_POSTED),
  549.                         (LPTSTR)DdeMsg2String(((MONMSGSTRUCT FAR *)pData)->wMsg));
  550.             }
  551.             OutputString(TBuf);
  552.             wsprintf(TBuf, pro.fTerse ? RefString(IDS_FMT_TRS_MSG2) : RefString(IDS_FMT_MSG2),
  553.                         ((MONMSGSTRUCT FAR *)pData)->wParam);
  554.             DisectMsgLP(((MONMSGSTRUCT FAR *)pData)->wMsg,
  555.                         ((MONMSGSTRUCT FAR *)pData),
  556.                         &TBuf[lstrlen(TBuf)]);
  557.             break;
  558.  
  559.  
  560.         case MF_CALLBACKS:
  561.             if (fBlockCb[(((MONCBSTRUCT FAR *)pData)->wType & XTYP_MASK) >> XTYP_SHIFT]) {
  562.                 return(0);
  563.             }
  564.             wsprintf(TBuf,
  565.                     pro.fTerse ? RefString(IDS_FMT_TRS_CB1) : RefString(IDS_FMT_CB1),
  566.                     ((MONCBSTRUCT FAR *)pData)->hTask,
  567.                     ((MONCBSTRUCT FAR *)pData)->dwTime,
  568.                     (LPTSTR)Type2String(((MONCBSTRUCT FAR *)pData)->wType));
  569.             wsprintf(DumpFormat(((MONCBSTRUCT FAR *)pData)->wFmt, &TBuf[lstrlen(TBuf)]),
  570.                     pro.fTerse ? RefString(IDS_FMT_TRS_CB2) : RefString(IDS_FMT_CB2),
  571.                     (UINT)((MONCBSTRUCT FAR *)pData)->hConv,
  572.                     ((MONCBSTRUCT FAR *)pData)->hsz1,
  573.                     (LPTSTR)(psz1 = GetHszName(((MONCBSTRUCT FAR *)pData)->hsz1)),
  574.                     ((MONCBSTRUCT FAR *)pData)->hsz2,
  575.                     (LPTSTR)(psz2 = GetHszName(((MONCBSTRUCT FAR *)pData)->hsz2)),
  576.                     ((MONCBSTRUCT FAR *)pData)->hData,
  577.                     ((MONCBSTRUCT FAR *)pData)->dwData1,
  578.                     ((MONCBSTRUCT FAR *)pData)->dwData2,
  579.                     ((MONCBSTRUCT FAR *)pData)->dwRet);
  580.             MyFree(psz1);
  581.             MyFree(psz2);
  582.             OutputString(TBuf);
  583.             if (((MONCBSTRUCT FAR *)pData)->dwData1 &&
  584.                (((MONCBSTRUCT FAR *)pData)->wType == XTYP_CONNECT ||
  585.                ((MONCBSTRUCT FAR *)pData)->wType == XTYP_WILDCONNECT)) {
  586.                 // display proposed context
  587.                 wsprintf(TBuf,
  588.                     pro.fTerse ? RefString(IDS_FMT_TRS_CTXT1) : RefString(IDS_FMT_CTXT1),
  589.                     ((MONCBSTRUCT FAR *)pData)->cc.wFlags,
  590.                     ((MONCBSTRUCT FAR *)pData)->cc.wCountryID,
  591.                     ((MONCBSTRUCT FAR *)pData)->cc.iCodePage,
  592.                     ((MONCBSTRUCT FAR *)pData)->cc.dwLangID,
  593.                     ((MONCBSTRUCT FAR *)pData)->cc.dwSecurity,
  594.                     ((MONCBSTRUCT FAR *)pData)->cc.qos.ImpersonationLevel,
  595.                     ((MONCBSTRUCT FAR *)pData)->cc.qos.ContextTrackingMode,
  596.                     ((MONCBSTRUCT FAR *)pData)->cc.qos.EffectiveOnly);
  597.                 OutputString(TBuf);
  598.             }
  599.             if (((MONCBSTRUCT FAR *)pData)->hData && ((MONCBSTRUCT FAR *)pData)->cbData) {
  600.                 wsprintf(TBuf, RefString(IDS_INPUT_DATA));
  601.                 OutputString(TBuf);
  602.                 DumpData((LPBYTE)((MONCBSTRUCT FAR *)pData)->Data,
  603.                                  ((MONCBSTRUCT FAR *)pData)->cbData,
  604.                                  TBuf,
  605.                                  ((MONCBSTRUCT FAR *)pData)->wFmt);
  606.                 OutputString(TBuf);
  607.                 if (cb > MAX_DISPDATA)
  608.                     OutputString(RefString(IDS_TABDDD));
  609.                 DdeUnaccessData(((MONCBSTRUCT FAR *)pData)->hData);
  610.             }
  611.             if ((((MONCBSTRUCT FAR *)pData)->wType & XCLASS_DATA) &&
  612.                  ((MONCBSTRUCT FAR *)pData)->dwRet &&
  613.                  ((MONCBSTRUCT FAR *)pData)->cbData) {
  614.                 wsprintf(TBuf, RefString(IDS_OUTPUT_DATA));
  615.                 OutputString(TBuf);
  616.                 DumpData((LPBYTE)((MONCBSTRUCT FAR *)pData)->Data,
  617.                                  ((MONCBSTRUCT FAR *)pData)->cbData,
  618.                                  TBuf,
  619.                                  ((MONCBSTRUCT FAR *)pData)->wFmt);
  620.                 OutputString(TBuf);
  621.                 if (cb > MAX_DISPDATA)
  622.                     OutputString(RefString(IDS_TABDDD));
  623.                 DdeUnaccessData((HDDEDATA)((MONCBSTRUCT FAR *)pData)->dwRet);
  624.             }
  625.             DdeUnaccessData(hData);
  626.             return(0);
  627.             break;
  628.  
  629.         case MF_ERRORS:
  630.             wsprintf(TBuf, pro.fTerse ? RefString(IDS_FMT_TRS_ER1) : RefString(IDS_FMT_ER1),
  631.                     ((MONERRSTRUCT FAR *)pData)->hTask,
  632.                     ((MONERRSTRUCT FAR *)pData)->dwTime,
  633.                     ((MONERRSTRUCT FAR *)pData)->wLastError,
  634.                     (LPTSTR)Error2String(((MONERRSTRUCT FAR *)pData)->wLastError));
  635.             break;
  636.  
  637.  
  638.         case MF_LINKS:
  639.             psz1 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszSvc);
  640.             psz2 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszTopic);
  641.             psz3 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszItem);
  642.             if (!GetClipboardFormatName(((MONLINKSTRUCT FAR *)pData)->wFmt, TBuf2, BUFFER_SIZE))
  643.                 lstrcpy(TBuf2, pdf(((MONLINKSTRUCT FAR *)pData)->wFmt));
  644.             if (!lstrcmp(RefString(IDS_HUH), TBuf2)) {
  645.                 wsprintf(TBuf2, TEXT("%d"), ((MONLINKSTRUCT FAR *)pData)->wFmt);
  646.             }
  647.  
  648.             wsprintf(TBuf, TEXT("%s\t%s\t%s\t%s\t%s\t%lx\t%lx"),
  649.                     (LPTSTR)psz1, (LPTSTR)psz2, (LPTSTR)psz3,
  650.                     (LPTSTR)TBuf2,
  651.                     ((MONLINKSTRUCT FAR *)pData)->fNoData ?
  652.                      RefString(IDS_WARM) : RefString(IDS_HOT),
  653.                     ((MONLINKSTRUCT FAR *)pData)->hConvClient,
  654.                     ((MONLINKSTRUCT FAR *)pData)->hConvServer);
  655.  
  656.             if (((MONLINKSTRUCT FAR *)pData)->fEstablished) {
  657.                 AddMCLBText(TBuf, TBuf, hwndTrack[IT_LINKS]);
  658.             } else {
  659.                 DeleteMCLBText(TBuf, hwndTrack[IT_LINKS]);
  660.             }
  661.  
  662.             MyFree(psz1);
  663.             MyFree(psz2);
  664.             MyFree(psz3);
  665.             DdeUnaccessData(hData);
  666.             return(0);
  667.  
  668.  
  669.         case MF_CONV:
  670.             psz1 = GetHszName(((MONCONVSTRUCT FAR *)pData)->hszSvc);
  671.             psz2 = GetHszName(((MONCONVSTRUCT FAR *)pData)->hszTopic);
  672.  
  673.             wsprintf(TBuf, TEXT("%s\t%s\t%lx\t%lx"),
  674.                     (LPTSTR)psz1, (LPTSTR)psz2,
  675.                     ((MONCONVSTRUCT FAR *)pData)->hConvClient,
  676.                     ((MONCONVSTRUCT FAR *)pData)->hConvServer);
  677.  
  678.             if (((MONCONVSTRUCT FAR *)pData)->fConnect) {
  679.                 AddMCLBText(TBuf, TBuf, hwndTrack[IT_CONVS]);
  680.             } else {
  681.                 DeleteMCLBText(TBuf, hwndTrack[IT_CONVS]);
  682.             }
  683.  
  684.             MyFree(psz1);
  685.             MyFree(psz2);
  686.             DdeUnaccessData(hData);
  687.             return(0);
  688.  
  689.  
  690.         default:
  691.             lstrcpy(TBuf, RefString(IDS_UNKNOWN_CALLBACK));
  692.         }
  693.         DdeUnaccessData(hData);
  694.         OutputString(TBuf);
  695.     }
  696.     break;
  697.  
  698.     case XTYP_REGISTER:
  699.     case XTYP_UNREGISTER:
  700.         if (!pro.fTrack[IT_SVRS]) {
  701.             return(0);
  702.         }
  703.         psz1 = GetHszName(hsz1);
  704.         psz2 = GetHszName(hsz2);
  705.         wsprintf(TBuf, TEXT("%s\t%s"), (LPTSTR)psz1, (LPTSTR)psz2);
  706.         if (wType == XTYP_REGISTER) {
  707.             AddMCLBText(NULL, TBuf, hwndTrack[IT_SVRS]);
  708.         } else {
  709.             DeleteMCLBText(TBuf, hwndTrack[IT_SVRS]);
  710.         }
  711.         MyFree(psz1);
  712.         MyFree(psz2);
  713.         break;
  714.     }
  715.     return(0);
  716. }
  717.  
  718.  
  719. LPTSTR DisectMsgLP(UINT msg, MONMSGSTRUCT *pmms,  LPTSTR pszBuf)
  720. {
  721.     static LONG m2t[] = {
  722.  
  723.     /*              LOW                       HIGH */
  724.  
  725.         MAKELONG(T_APP | T_ATOM,        T_TOPIC | T_ATOM),  // WM_DDE_INITIATE
  726.         0,                                                  // WM_DDE_TERMINATE
  727.         MAKELONG(T_OPTIONHANDLE,        T_ITEM | T_ATOM),   // WM_DDE_ADVISE
  728.         MAKELONG(T_FORMAT,              T_ITEM | T_ATOM),   // WM_DDE_UNADVISE
  729.         MAKELONG(T_APP | T_ATOM | T_OR | T_STATUS,
  730.                                         T_TOPIC | T_ITEM | T_ATOM | T_OR | T_STRINGHANDLE),
  731.                                                             // WM_DDE_ACK
  732.         MAKELONG(T_DATAHANDLE,          T_ITEM | T_ATOM),   // WM_DDE_DATA
  733.         MAKELONG(T_FORMAT,              T_ITEM | T_ATOM),   // WM_DDE_REQUEST
  734.         MAKELONG(T_DATAHANDLE,          T_ITEM | T_ATOM),   // WM_DDE_POKE
  735.         MAKELONG(0,                     T_STRINGHANDLE),    // WM_DDE_EXECUTE
  736.     };
  737.  
  738.     // ASSUMED: msg is a valid DDE message!!!
  739.  
  740.     pszBuf = DisectWord(LOWORD(m2t[msg - WM_DDE_FIRST]),
  741.                         pmms->dmhd.uiLo, &pmms->dmhd, pszBuf);
  742.     *pszBuf++ = TEXT('\r');
  743.     *pszBuf++ = TEXT('\n');
  744.     *pszBuf++ = TEXT('\t');
  745.     return(DisectWord(HIWORD(m2t[msg - WM_DDE_FIRST]),
  746.                         pmms->dmhd.uiHi, &pmms->dmhd, pszBuf));
  747. }
  748.  
  749.  
  750.  
  751.  
  752. /*
  753.  * Allocates local memory for and retrieves the string form of an HSZ.
  754.  * Returns a pointer to the local memory or NULL if failure.
  755.  * The string must be freed via MyFree().
  756.  */
  757. LPTSTR GetHszName(HSZ hsz)
  758. {
  759.     LPTSTR psz;
  760.     UINT cb;
  761.  
  762.     cb = (UINT)DdeQueryString(idInst, hsz, NULL, 0, 0) + 1;
  763.     psz = LocalAlloc (LPTR, sizeof(TCHAR) * cb);
  764.     DdeQueryString(idInst, hsz, psz, cb, 0);
  765.     return(psz);
  766. }
  767.  
  768.  
  769.  
  770.  
  771. LPTSTR DisectWord( UINT type,
  772. UINT data,
  773. DDEML_MSG_HOOK_DATA *pdmhd,
  774. LPTSTR pstr)
  775. {
  776.     UINT wT;
  777.  
  778.     *pstr = TEXT('\0');   // in case we do nothing.
  779.  
  780.     if (type & T_ATOM) {
  781.         wT = GlobalGetAtomName((ATOM)data, (LPTSTR)pstr, 25);
  782.         if (wT || data == 0) {
  783.             if (type & T_APP) {
  784.                 lstrcpy(pstr, RefString(IDS_APPIS));
  785.                 pstr += lstrlen(pstr);
  786.             }
  787.  
  788.             if (type & T_TOPIC) {
  789.                 lstrcpy(pstr, RefString(IDS_TOPICIS));
  790.                 pstr += lstrlen(pstr);
  791.             }
  792.  
  793.             if (type & T_ITEM) {
  794.                 lstrcpy(pstr, RefString(IDS_ITEMIS));
  795.                 pstr += lstrlen(pstr);
  796.             }
  797.         }
  798.         if (wT) {
  799.             wsprintf(pstr, TEXT("0x%x(\""), data);
  800.             pstr += lstrlen(pstr);
  801.             GlobalGetAtomName((ATOM)data, (LPTSTR)pstr, 25);
  802.             pstr += wT;
  803.             if (wT == 25) {
  804.                 *pstr++ = TEXT('.');
  805.                 *pstr++ = TEXT('.');
  806.                 *pstr++ = TEXT('.');
  807.             }
  808.             *pstr++ = TEXT('\"');
  809.             *pstr++ = TEXT(')');
  810.             *pstr = TEXT('\0');
  811.             type &= ~(T_OR | T_STRINGHANDLE);  // its an atom, so its not an object!
  812.         } else if (data == 0) {     // could be a wild atom
  813.             *pstr++ = TEXT('*');
  814.             *pstr = TEXT('\0');
  815.         } else if (type & T_OR) {
  816.             type &= ~T_OR;   // not an atom, must be somthin else.
  817.         } else {
  818.             wsprintf(pstr, RefString(IDS_FMT_BADATOM), data);
  819.             pstr += lstrlen(pstr);
  820.         }
  821.     }
  822.  
  823.     if (type & T_OR) {
  824.         lstrcpy(pstr, RefString(IDS_OR));
  825.         pstr += lstrlen(pstr);
  826.     }
  827.  
  828.  
  829.     if (type & T_OPTIONHANDLE) {
  830.         if (pdmhd->cbData >= 4) {
  831.             wsprintf(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS), LOWORD(pdmhd->Data[0]));
  832.             pstr += lstrlen(pstr);
  833.             if (LOWORD(pdmhd->Data[0]) & DDE_FACKREQ) {
  834.                 lstrcpy(pstr, RefString(IDS_FACKREQ));
  835.                 pstr += lstrlen(pstr);
  836.             }
  837.             if (LOWORD(pdmhd->Data[0]) & DDE_FDEFERUPD) {
  838.                 lstrcpy(pstr, RefString(IDS_DEFERUPD));
  839.                 pstr += lstrlen(pstr);
  840.             }
  841.             *pstr++ = TEXT(')');
  842.             *pstr++ = TEXT(' ');
  843.             pstr = DumpFormat((UINT)HIWORD(pdmhd->Data[0]), pstr);
  844.         }
  845.     }
  846.  
  847.     if (type & T_FORMAT) {
  848.         pstr = DumpFormat(data, pstr);
  849.     }
  850.  
  851.     if (type & T_STATUS) {
  852.         wsprintf(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS), LOWORD(data));
  853.         pstr += lstrlen(pstr);
  854.         if (data & DDE_FACK) {
  855.             lstrcpy(pstr, RefString(IDS_FACK));
  856.             pstr += lstrlen(pstr);
  857.         }
  858.         if (data & DDE_FBUSY) {
  859.             lstrcpy(pstr, RefString(IDS_FBUSY));
  860.             pstr += lstrlen(pstr);
  861.         }
  862.         *pstr++ = TEXT(')');
  863.         *pstr = TEXT('\0');
  864.     }
  865.  
  866.     if (type & T_STRINGHANDLE && pdmhd->cbData) {
  867.         WCHAR szData[16];
  868.  
  869.         memset(szData, '\0', 16 * sizeof(WCHAR));
  870.         memcpy(szData, pdmhd->Data, min(16 * sizeof(WCHAR), pdmhd->cbData));
  871.         szData[15] = L'\0';
  872.         wsprintf(pstr, pro.fTerse ?
  873.                     RefString(IDS_FMT_TRS_EXEC1) : RefString(IDS_FMT_EXEC1), (LPWSTR)szData);
  874.         pstr += lstrlen(pstr);
  875.         *pstr = TEXT('\0');
  876.     }
  877.  
  878.     if (type & T_DATAHANDLE && pdmhd->cbData) {
  879.         wsprintf(pstr, pro.fTerse ?
  880.                     RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS),
  881.                     LOWORD(pdmhd->Data[0]));
  882.         pstr += lstrlen(pstr);
  883.         if (LOWORD(pdmhd->Data[0]) & DDE_FRELEASE) {
  884.             lstrcpy(pstr, RefString(IDS_FRELEASE));
  885.             pstr += lstrlen(pstr);
  886.         }
  887.         if (LOWORD(pdmhd->Data[0]) & DDE_FREQUESTED) {
  888.             lstrcpy(pstr, RefString(IDS_FREQUESTED));
  889.             pstr += lstrlen(pstr);
  890.         }
  891.         *pstr++ = TEXT(')');
  892.         *pstr++ = TEXT(' ');
  893.         pstr = DumpFormat(HIWORD(pdmhd->Data[0]), pstr);
  894.         lstrcpy(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_DATAIS1) : RefString(IDS_FMT_DATAIS1));
  895.         pstr += lstrlen(pstr);
  896.         pstr = DumpData((LPBYTE)&pdmhd->Data[1], min(28, pdmhd->cbData - 4),
  897.                 pstr, HIWORD(pdmhd->Data[0]));
  898.     }
  899.     return(pstr);
  900. }
  901.  
  902.  
  903. LPTSTR pdf(UINT fmt)
  904. {
  905.     INT i;
  906.     static struct {
  907.         UINT fmt;
  908.         LPTSTR psz;
  909.     } fmts[] = {
  910.         { CF_TEXT             ,     TEXT("CF_TEXT")           }   ,
  911.         { CF_UNICODETEXT      ,     TEXT("CF_UNICODETEXT")    }   ,
  912.         { CF_BITMAP           ,     TEXT("CF_BITMAP")         }   ,
  913.         { CF_METAFILEPICT     ,     TEXT("CF_METAFILEPICT")   }   ,
  914.         { CF_ENHMETAFILE      ,     TEXT("CF_ENHMETAFILE")    }   ,
  915.         { CF_SYLK             ,     TEXT("CF_SYLK")           }   ,
  916.         { CF_DIF              ,     TEXT("CF_DIF")            }   ,
  917.         { CF_TIFF             ,     TEXT("CF_TIFF")           }   ,
  918.         { CF_OEMTEXT          ,     TEXT("CF_OEMTEXT")        }   ,
  919.         { CF_DIB              ,     TEXT("CF_DIB")            }   ,
  920.         { CF_PALETTE          ,     TEXT("CF_PALETTE")        }   ,
  921.     };
  922.     for (i = 0; i < 10; i++)
  923.         if (fmts[i].fmt == fmt)
  924.             return(fmts[i].psz);
  925.     return(RefString(IDS_HUH));
  926. }
  927.  
  928.  
  929.  
  930. LPTSTR DumpFormat(UINT fmt, LPTSTR pstr)
  931. {
  932.     UINT cb;
  933.  
  934.     wsprintf(pstr, TEXT("fmt=0x%x(\""), (WORD)fmt);
  935.     pstr += lstrlen(pstr);
  936.     if (cb = GetClipboardFormatName(fmt, pstr, 25)) {
  937.         pstr += cb;
  938.         *pstr++ = TEXT('\"');
  939.         *pstr++ = TEXT(')');
  940.     } else {
  941.         wsprintf(pstr, TEXT("%s\")"), (LPTSTR)pdf(fmt));
  942.         pstr += lstrlen(pstr);
  943.     }
  944.     return(pstr);
  945. }
  946.  
  947.  
  948.  
  949. LPTSTR DumpData(LPBYTE pData, UINT cb, TCHAR *szBuf, UINT fmt)
  950. {
  951.     register INT i;
  952.     LPTSTR psz = szBuf;
  953.  
  954.  
  955.     while (cb) {
  956.         if (fmt == CF_TEXT || fmt == CF_UNICODETEXT) {
  957.             *szBuf++ = TEXT('\t');
  958.             if (fmt == CF_UNICODETEXT) {
  959.                 *szBuf++ = TEXT('U');
  960.             }
  961.             *szBuf++ = TEXT('\"');
  962.             if (fmt == CF_UNICODETEXT) {
  963.                 memcpy(szBuf, pData, cb);
  964.             } else {
  965.                 MultiByteToWideChar(CP_ACP, 0, pData, cb, szBuf, cb / sizeof(TCHAR));
  966.             }
  967.             szBuf[cb - 2] = TEXT('\0');
  968.             lstrcat(szBuf, TEXT("\""));
  969.             cb = 0;
  970.         } else {
  971.             for (i = 0; i < 80 ; i++) {
  972.                 szBuf[i] = TEXT(' ');
  973.             }
  974.             szBuf[0] = TEXT('\t');
  975.             i = 0;
  976.             while (cb && (i < 16)) {
  977.                 wsprintf(&szBuf[i * 3 + 1], TEXT("%02x "), pData[0]);
  978.                 wsprintf(&szBuf[17 * 3 + i + 1], TEXT("%c"), MPRT(pData[0]));
  979.                 pData++;
  980.                 cb--;
  981.                 i++;
  982.             }
  983.             szBuf[i * 3 + 1] = TEXT(' ');
  984.             szBuf[17 * 3 + i + 1] = TEXT(' ');
  985.             szBuf[68] = TEXT('\0');
  986.         }
  987.         szBuf += lstrlen(szBuf);
  988.     }
  989.     return(szBuf);
  990. }
  991.  
  992.  
  993.  
  994. LPTSTR Error2String(UINT error)
  995. {
  996.     static TCHAR szErr[23];
  997.  
  998.     if (error == 0) {
  999.         lstrcpy(szErr, RefString(IDS_ZERO));
  1000.     } else if (error > DMLERR_LAST || error < DMLERR_FIRST) {
  1001.         lstrcpy(szErr, RefString(IDS_HUH));
  1002.     } else {
  1003.         lstrcpy(szErr, apszResources[IDS_ERRST0 + error - DMLERR_FIRST]);
  1004.     }
  1005.     return(szErr);
  1006. }
  1007.  
  1008.  
  1009.  
  1010. LPTSTR DdeMsg2String(UINT msg)
  1011. {
  1012.     static TCHAR szBadMsg[10];
  1013.  
  1014.     if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST) {
  1015.        wsprintf (szBadMsg, TEXT("%ld"), szBadMsg);
  1016.        return (szBadMsg);
  1017. //        return((LPTSTR)itoa(msg, szBadMsg, 10));
  1018.     } else {
  1019.         return(apszResources[IDS_MSG0 + msg - WM_DDE_FIRST]);
  1020.     }
  1021. }
  1022.  
  1023.  
  1024.  
  1025. VOID OutputString(LPTSTR pstr)
  1026. {
  1027.     DWORD cbWritten;
  1028.  
  1029.     if (pro.fOutput[IO_FILE] && fhOutput != NULL) {
  1030.         static CHAR szT[200];
  1031.  
  1032.         WideCharToMultiByte(
  1033.                 CP_ACP,
  1034.                 0,
  1035.                 pstr,
  1036.                 -1,
  1037.                 szT,
  1038.                 200,
  1039.                 NULL,
  1040.                 NULL);
  1041.         WriteFile(fhOutput, (LPCSTR) szT, lstrlenA(szT), &cbWritten, NULL);
  1042.         WriteFile(fhOutput, (LPCSTR) "\r\n", 2, &cbWritten, NULL);
  1043.         FlushFileBuffers(fhOutput);
  1044.     }
  1045.     if (pro.fOutput[IO_DEBUG]) {
  1046.         OutputDebugString((LPTSTR)pstr);
  1047.         OutputDebugString(RefString(IDS_CRLF));
  1048.     }
  1049.     if (pro.fOutput[IO_SCREEN]) {
  1050.         if (IsWindow(hWndString))
  1051.             DrawString(hWndString, pstr);
  1052.     }
  1053. }
  1054.  
  1055.  
  1056.  
  1057. BOOL SetFilters()
  1058. {
  1059.     UINT cbf;
  1060.  
  1061.     cbf = 0;
  1062.     if (pro.fTrack[IT_HSZS] || pro.fFilter[IF_HSZ])
  1063.         cbf |= MF_HSZ_INFO;
  1064.     if (pro.fTrack[IT_LINKS])
  1065.         cbf |= MF_LINKS;
  1066.     if (pro.fTrack[IT_CONVS])
  1067.         cbf |= MF_CONV;
  1068.     if (pro.fFilter[IF_SEND])
  1069.         cbf |= MF_SENDMSGS;
  1070.     if (pro.fFilter[IF_POST])
  1071.         cbf |= MF_POSTMSGS;
  1072.     if (pro.fFilter[IF_CB])
  1073.         cbf |= MF_CALLBACKS;
  1074.     if (pro.fFilter[IF_ERR])
  1075.         cbf |= MF_ERRORS;
  1076.     return((BOOL)DdeInitialize(&idInst, pfnDdeCallback, APPCLASS_MONITOR | cbf, 0));
  1077. }
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083. /*
  1084.  * This dialog returns a file handle to the opened file name given or NULL
  1085.  * if cancel.
  1086.  */
  1087.  
  1088. BOOL CALLBACK OpenDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1089. {
  1090.     HANDLE fh;
  1091.     lParam;
  1092.  
  1093.     switch (message) {
  1094.         case WM_INITDIALOG:
  1095.             SetDlgItemText(hDlg, IDC_EDIT, (LPTSTR)OpenName);
  1096.             SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL,
  1097.                     GET_EM_SETSEL_MPS(0, 0x7fff));
  1098.             SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  1099.             return (FALSE); /* Indicates the focus is set to a control */
  1100.             break;
  1101.  
  1102.         case WM_COMMAND:
  1103.             switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  1104.                 case IDOK:
  1105.                     GetDlgItemText(hDlg, IDC_EDIT, TBuf, MAX_FNAME);
  1106.                     GetFullPathName(TBuf, sizeof(OpenName), OpenName, (LPTSTR *)TBuf2);
  1107.                     fh = CreateFile(
  1108.                             OpenName,
  1109.                             GENERIC_WRITE,
  1110.                             FILE_SHARE_READ,
  1111.                             (PSECURITY_ATTRIBUTES)NULL,
  1112.                             CREATE_ALWAYS,
  1113.                             FILE_ATTRIBUTE_NORMAL,
  1114.                             NULL);
  1115.                     if (fh == INVALID_HANDLE_VALUE) {
  1116.                         MessageBox(hDlg, RefString(IDS_INVALID_FNAME),
  1117.                             NULL, MB_OK | MB_ICONHAND);
  1118.                         return (TRUE);
  1119.                     }
  1120.  
  1121.                     EndDialog(hDlg, (INT)fh);
  1122.                     return (TRUE);
  1123.  
  1124.                 case IDCANCEL:
  1125.                     EndDialog(hDlg, 0);
  1126.                     return (FALSE);
  1127.             }
  1128.             break;
  1129.     }
  1130.     return FALSE;
  1131. }
  1132.  
  1133. BOOL CALLBACK FilterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1134. {
  1135.     int i;
  1136.     lParam;
  1137.  
  1138.     switch (message) {
  1139.     case WM_INITDIALOG:
  1140.             for (i = IDRB_WM_DDE_INITIATE; i <= IDRB_WM_DDE_EXECUTE; i++) {
  1141.                 CheckDlgButton(hDlg, i, !fBlockMsg[i - IDRB_WM_DDE_INITIATE]);
  1142.             }
  1143.             for (i = IDRB_XTYP_ERROR; i <= IDRB_XTYP_WILDCONNECT; i++) {
  1144.                 CheckDlgButton(hDlg, i, !fBlockCb[i - IDRB_XTYP_ERROR]);
  1145.             }
  1146.             CheckDlgButton(hDlg, IDRB_TERSE, pro.fTerse);
  1147.             return TRUE;
  1148.  
  1149.         case WM_COMMAND:
  1150.             switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  1151.                 case IDOK:
  1152.                     for (i = IDRB_WM_DDE_INITIATE; i <= IDRB_WM_DDE_EXECUTE; i++) {
  1153.                         fBlockMsg[i - IDRB_WM_DDE_INITIATE] = !IsDlgButtonChecked(hDlg, i);
  1154.                     }
  1155.                     for (i = IDRB_XTYP_ERROR; i <= IDRB_XTYP_WILDCONNECT; i++) {
  1156.                         fBlockCb[i - IDRB_XTYP_ERROR] = !IsDlgButtonChecked(hDlg, i);
  1157.                     }
  1158.                     pro.fTerse = IsDlgButtonChecked(hDlg, IDRB_TERSE);
  1159.                     EndDialog(hDlg, TRUE);
  1160.                     break;
  1161.  
  1162.                 case IDCANCEL:
  1163.                     EndDialog(hDlg, 0);
  1164.                     break;
  1165.             }
  1166.             break;
  1167.     }
  1168.     return FALSE;
  1169. }
  1170.  
  1171.  
  1172.  
  1173.  
  1174. VOID GetProfile()
  1175. {
  1176.     pro.fOutput[IO_FILE]    = GetProfileBoolean(RefString(IDS_PROF_OUT_FILE),FALSE);
  1177.     pro.fOutput[IO_DEBUG]   = GetProfileBoolean(RefString(IDS_PROF_OUT_DEBUG),FALSE);
  1178.     pro.fOutput[IO_SCREEN]  = GetProfileBoolean(RefString(IDS_PROF_OUT_SCREEN),FALSE);
  1179.  
  1180.     pro.fFilter[IF_HSZ]     = GetProfileBoolean(RefString(IDS_PROF_MONITOR_STRINGHANDLES),FALSE);
  1181.     pro.fFilter[IF_SEND]    = GetProfileBoolean(RefString(IDS_PROF_MONITOR_INITIATES), FALSE);
  1182.     pro.fFilter[IF_POST]    = GetProfileBoolean(RefString(IDS_PROF_MONITOR_DDE_MESSAGES), FALSE);
  1183.     pro.fFilter[IF_CB]      = GetProfileBoolean(RefString(IDS_PROF_MONITOR_CALLBACKS), FALSE);
  1184.     pro.fFilter[IF_ERR]     = GetProfileBoolean(RefString(IDS_PROF_MONITOR_ERRORS),FALSE);
  1185.  
  1186.     pro.fTrack[IT_HSZS]     = GetProfileBoolean(RefString(IDS_PROF_TRACK_STRINGHANDLES), FALSE);
  1187.     pro.fTrack[IT_LINKS]    = GetProfileBoolean(RefString(IDS_PROF_TRACK_LINKS), FALSE);
  1188.     pro.fTrack[IT_CONVS]    = GetProfileBoolean(RefString(IDS_PROF_TRACK_CONVERSATIONS), FALSE);
  1189.     pro.fTrack[IT_SVRS]     = GetProfileBoolean(RefString(IDS_PROF_TRACK_SERVICES), FALSE);
  1190.  
  1191.     pro.fTerse              = GetProfileBoolean(RefString(IDS_PROF_TERSE), FALSE);
  1192. }
  1193.  
  1194.  
  1195.  
  1196. VOID SaveProfile()
  1197. {
  1198.     SetProfileBoolean(RefString(IDS_PROF_OUT_FILE), pro.fOutput[IO_FILE]  );
  1199.     SetProfileBoolean(RefString(IDS_PROF_OUT_DEBUG), pro.fOutput[IO_DEBUG] );
  1200.     SetProfileBoolean(RefString(IDS_PROF_OUT_SCREEN), pro.fOutput[IO_SCREEN]);
  1201.  
  1202.     SetProfileBoolean(RefString(IDS_PROF_MONITOR_STRINGHANDLES), pro.fFilter[IF_HSZ]   );
  1203.     SetProfileBoolean(RefString(IDS_PROF_MONITOR_INITIATES), pro.fFilter[IF_SEND]  );
  1204.     SetProfileBoolean(RefString(IDS_PROF_MONITOR_DDE_MESSAGES), pro.fFilter[IF_POST]  );
  1205.     SetProfileBoolean(RefString(IDS_PROF_MONITOR_CALLBACKS), pro.fFilter[IF_CB]    );
  1206.     SetProfileBoolean(RefString(IDS_PROF_MONITOR_ERRORS), pro.fFilter[IF_ERR]   );
  1207.  
  1208.     SetProfileBoolean(RefString(IDS_PROF_TRACK_STRINGHANDLES), pro.fTrack[IT_HSZS]   );
  1209.     SetProfileBoolean(RefString(IDS_PROF_TRACK_LINKS), pro.fTrack[IT_LINKS]  );
  1210.     SetProfileBoolean(RefString(IDS_PROF_TRACK_CONVERSATIONS), pro.fTrack[IT_CONVS]  );
  1211.     SetProfileBoolean(RefString(IDS_PROF_TRACK_SERVICES), pro.fTrack[IT_SVRS]   );
  1212.  
  1213.     SetProfileBoolean(RefString(IDS_PROF_TERSE), pro.fTerse   );
  1214. }
  1215.  
  1216.  
  1217.  
  1218.  
  1219. BOOL GetProfileBoolean(LPTSTR pszKey, BOOL fDefault)
  1220. {
  1221.     GetPrivateProfileString(RefString(IDS_TITLE), pszKey,
  1222.                     fDefault ? RefString(IDS_YES) : RefString(IDS_NO), TBuf,
  1223.                     sizeof(TBuf), RefString(IDS_INIFNAME));
  1224.     return(lstrcmpi(RefString(IDS_NO), TBuf));
  1225. }
  1226.  
  1227.  
  1228.  
  1229. VOID SetProfileBoolean(LPTSTR pszKey, BOOL fSet)
  1230. {
  1231.     WritePrivateProfileString(RefString(IDS_TITLE), pszKey,
  1232.                     fSet ? RefString(IDS_YES) : RefString(IDS_NO),
  1233.                     RefString(IDS_INIFNAME));
  1234. }
  1235.  
  1236. /*
  1237.  * Generic dialog invocation routine.  Handles procInstance stuff and param
  1238.  * passing.
  1239.  */
  1240. INT FAR DoDialog(
  1241.                 LPTSTR lpTemplateName,
  1242.                 DLGPROC lpDlgProc,
  1243.                 UINT param,
  1244.                 BOOL fRememberFocus,
  1245.                 HWND hwndParent,
  1246.                 HANDLE hInst)
  1247. {
  1248.     UINT wRet;
  1249.     HWND hwndFocus;
  1250.  
  1251.     if (fRememberFocus)
  1252.         hwndFocus = GetFocus();
  1253.     lpDlgProc = (DLGPROC)MakeProcInstance(lpDlgProc, hInst);
  1254.     wRet = DialogBoxParam(hInst, (LPCTSTR)lpTemplateName, hwndParent,
  1255.             lpDlgProc, param);
  1256.     FreeProcInstance((FARPROC)lpDlgProc);
  1257.     if (fRememberFocus)
  1258.         SetFocus(hwndFocus);
  1259.     return wRet;
  1260. }
  1261.  
  1262.  
  1263. BOOL CALLBACK MarkDlgProc(
  1264.                         HWND hwnd,
  1265.                         UINT msg,
  1266.                         WPARAM wParam,
  1267.                         LPARAM lParam)
  1268. {
  1269.     TCHAR szT[MAX_MARK + 1];
  1270.     lParam;
  1271.  
  1272.     switch (msg){
  1273.     case WM_INITDIALOG:
  1274.         SetWindowText(hwnd, RefString(IDS_MARKDLGTITLE));
  1275.         SendDlgItemMessage(hwnd, IDEF_VALUE, EM_LIMITTEXT, MAX_MARK, 0);
  1276.         SetDlgItemText(hwnd, IDEF_VALUE, RefString(IDS_SEPERATOR));
  1277.         SetDlgItemText(hwnd, IDTX_VALUE, RefString(IDS_MARKTEXT));
  1278.         return(1);
  1279.         break;
  1280.  
  1281.     case WM_COMMAND:
  1282.         switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  1283.         case IDOK:
  1284.             GetDlgItemText(hwnd, IDEF_VALUE, szT, MAX_MARK);
  1285.             OutputString(szT);
  1286.             // fall through
  1287.         case IDCANCEL:
  1288.             EndDialog(hwnd, 0);
  1289.             break;
  1290.  
  1291.         default:
  1292.             return(FALSE);
  1293.         }
  1294.         break;
  1295.     }
  1296.     return(FALSE);
  1297. }
  1298.  
  1299. /****************************************************************************
  1300.     My_mbschr:  strchr() DBCS version
  1301. ****************************************************************************/
  1302. LPTSTR _CRTAPI1 My_mbschr(
  1303.     LPTSTR psz, unsigned short uiSep)
  1304. {
  1305.     while (*psz != '\0' && *psz != uiSep) {
  1306.         psz = CharNext(psz);
  1307.     }
  1308.     if (*psz == '\0' && uiSep != '\0') {
  1309.         return NULL;
  1310.     } else {
  1311.         return psz;
  1312.     }
  1313. }
  1314.