home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / win_lrn / dde / ddespy / dspydll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-12  |  34.9 KB  |  1,067 lines

  1. #include "windows.h" 
  2. #include "winexp.h" 
  3. #include "ddespy.h" 
  4. #include "dde.h" 
  5.  
  6. #define MENU
  7.  
  8. /*----------------------------------------------------------------------------*\
  9. |                                                                              |
  10. |   g l o b a l   v a r i a b l e s                                            |
  11. |                                                                              |
  12. \*----------------------------------------------------------------------------*/
  13. /* NOTICE: The message structure for WH_CALLWNDPROC is "upside down"
  14.            compared to the normal MSG structure. */
  15. typedef struct mymsg {
  16.     LONG lParam;
  17.     WORD wParam;
  18.     WORD message;
  19.     HWND hwnd;
  20. } MYMSG;
  21. typedef MYMSG FAR *LPMYMSG;
  22.  
  23. /* Static definitions */
  24. static  FARPROC fpxMsgHook1;
  25. static  FARPROC fpxMsgHook2;
  26. static  FARPROC fpxOldHook1;
  27. static  FARPROC fpxOldHook2;
  28.  
  29. FARPROC lplpfnNextHook1;
  30. FARPROC lplpfnNextHook2;
  31. HWND    hSpyChild;
  32. char    szTemp[30];
  33. char    szTemphWnd[30];
  34. static  int Tdx = 0;        /* Text font size */
  35. static  int Tdy = 0;
  36.  
  37. struct TEXT_STRUCT {
  38.     int  iFirst;                  /* First line in que */
  39.     int  iCount;                  /* Number of lines in que */
  40.     int  iTop;                    /* Line at top of window */
  41.     int  iLeft;                   /* X offset of the window */
  42.     char *Text[MAXLINES];         /* Que of Text in window */
  43.     int  Len[MAXLINES];           /* String Length of text */
  44.     int  MaxLen;                  /* Max String Length */
  45. };
  46.  
  47. typedef struct TEXT_STRUCT *PTXT; /* pointer to a text struct */
  48. typedef PTXT               *HTXT; /* Handle to a text struct */
  49.  
  50. #define ihqelMax 256
  51. #define RADIX    16
  52.  
  53. HWND    hGParent;
  54. HWND    hGMenu;
  55. HANDLE  rghqel[ihqelMax];
  56. int     ihqelHead;
  57. int     ihqelTail;
  58.  
  59. int  iLen;
  60. char pchFoo[MAXFOOLEN];    /* Buffer */
  61.  
  62. char szMessages[10][12];   /* messages */
  63.  
  64. HWND hWndMenu[10];
  65. HWND hSpyWndMenu;  /* this is so we can attach the
  66.                       windows text to the menu bar */
  67.  
  68. int  dllgfhFile;   /* handle to the file, if open */
  69.  
  70. /******************************************/
  71.  
  72. /* Handle to the DLL instance from Libinit.asm */
  73. extern HANDLE LIBINST;
  74.  
  75. /*----------------------------------------------------------------------------*\
  76. |                                                                              |
  77. |   f u n c t i o n   d e f i n i t i o n s                                    |
  78. |                                                                              |
  79. \*----------------------------------------------------------------------------*/
  80. void  FAR PASCAL InitHook( HWND );
  81. BOOL  FAR PASCAL KillHook();
  82. DWORD FAR PASCAL MsgHook1( WORD, WORD, LPMSG );
  83. DWORD FAR PASCAL MsgHook2( WORD, WORD, LPMSG );
  84. void  FAR PASCAL DebugPaint(HWND, HDC);
  85. HWND  FAR PASCAL CreateDebugWin(HANDLE, HWND);
  86.  
  87. void  FAR PASCAL PassFileToDLL(int);
  88. void  WriteitToFile( LPSTR , int);
  89. void  FormatString(void);
  90.  
  91. void DebugHScroll (HWND, PTXT, int);
  92. void DebugVScroll (HWND, PTXT, int);
  93. void Error (char *);
  94.  
  95. char   *WM_MessageText(WORD);
  96. HANDLE HqelGet();
  97. void   HqelPut(HANDLE);
  98.  
  99.  
  100. void FAR PASCAL PassFileToDLL(int gfhFile)
  101. {
  102.    dllgfhFile = gfhFile;
  103. }
  104.  
  105.  
  106. /* ------------------- Set the HOOKs ---------------- */
  107. void FAR PASCAL InitHook( hWnd )
  108. HWND hWnd;
  109. {
  110.  
  111.    hSpyChild = hWnd;  /* handle to child window */
  112.  
  113.    fpxMsgHook1 = MakeProcInstance((FARPROC)MsgHook1,LIBINST);
  114.    fpxMsgHook2 = MakeProcInstance((FARPROC)MsgHook2,LIBINST);
  115.  
  116.    fpxOldHook1 = SetWindowsHook(WH_GETMESSAGE, fpxMsgHook1);
  117.    fpxOldHook2 = SetWindowsHook(WH_CALLWNDPROC,fpxMsgHook2);
  118.  
  119.    strcpy(szMessages[0], "INITIATE  ");
  120.    strcpy(szMessages[1], "TERMINATE ");
  121.    strcpy(szMessages[2], "ADVISE    ");
  122.    strcpy(szMessages[3], "UNADVISE  ");
  123.    strcpy(szMessages[4], "ACK       ");
  124.    strcpy(szMessages[5], "DATA      ");
  125.    strcpy(szMessages[6], "REQUEST   ");
  126.    strcpy(szMessages[7], "POKE      ");
  127.    strcpy(szMessages[8], "EXECUTE   ");
  128.  
  129. return;
  130. }
  131.  
  132. /* ------------------- Remove the HOOKs ---------------- */
  133. BOOL FAR PASCAL KillHook()
  134. {
  135.    BOOL fSuccess;
  136.  
  137.    fSuccess = UnhookWindowsHook( WH_GETMESSAGE,  fpxMsgHook1 );
  138.    fSuccess = UnhookWindowsHook( WH_CALLWNDPROC, fpxMsgHook2 );
  139.  
  140.    FreeProcInstance( fpxMsgHook1 );
  141.    FreeProcInstance( fpxMsgHook2 );
  142.  
  143.    return fSuccess;
  144. }
  145.  
  146.  
  147.  
  148. /*----------------------------------------------------------------------------*\
  149. |  CreateDebugWin (hParent, lpchName, dwStyle, x, y, dx, dy)                   |
  150. |                                                                              |
  151. |   Description:                                                               |
  152. |     Creates a window for the depositing of debuging messages.                |
  153. |                                                                              |
  154. |   Arguments:                                                                 |
  155. |     hWnd   - Window handle of the parent window.                             |
  156. |     pcName - String to appear in the caption bar of the debuging window      |
  157. |     dwStyle- Window style                                                    |
  158. |     x,y    - Location of window                                              |
  159. |     dx,dy  - Size of the window                                              |
  160. |                                                                              |
  161. |   Returns:                                                                   |
  162. |     A window handle of the debuging window, or NULL if a error occured.      |
  163. |                                                                              |
  164. \*----------------------------------------------------------------------------*/
  165.  
  166. HWND FAR PASCAL CreateDebugWin (hInstance, hParent)
  167. HANDLE  hInstance;
  168. HWND    hParent;
  169. {
  170.     static BOOL bFirst = TRUE;   /* Is this the first call */
  171.  
  172.     HWND   hWnd;
  173.     PTXT   pTxt;      /* pointer to a debuging window struct */
  174.  
  175.     TEXTMETRIC tm;    /* Used to find out the size of a char */
  176.     RECT       rRect;
  177.     HDC        hDC;
  178.     int        i;
  179.  
  180.     if (bFirst) {
  181.         /* Find out the size of a Char in the system font */
  182.         hDC = GetDC(hParent);
  183.         GetTextMetrics (hDC,(LPTEXTMETRIC)&tm);
  184.         Tdy = tm.tmHeight;
  185.         Tdx = tm.tmAveCharWidth;
  186.         ReleaseDC (hParent,hDC);
  187.         SetDebugClass(hInstance);
  188.         hGParent = hParent;
  189.         hGMenu = GetMenu(hParent);
  190.         hSpyWndMenu = GetSubMenu( hGMenu ,4 );
  191.  
  192.         for (i=0 ; i<10 ; i++)         /* clear menu handles */
  193.            hWndMenu[i] = NULL;
  194.  
  195.         bFirst = FALSE;
  196.     }
  197.  
  198.     hInstance = GetWindowWord(hParent, GWW_HINSTANCE);
  199.     GetClientRect (hParent,(LPRECT)&rRect);
  200.  
  201.     hWnd = CreateWindow((LPSTR)"DEBUG"
  202.                         ,(LPSTR)"DDE SPY"
  203.                         ,WS_CHILD | WS_VSCROLL | WS_HSCROLL
  204.                         ,0,0
  205.                         ,rRect.right
  206.                         ,rRect.bottom
  207.                         ,(HWND)hParent      /* parent window */
  208.                         ,(HMENU)NULL        /* use class menu */
  209.                         ,(HANDLE)hInstance  /* handle to window instance */
  210.                         ,(LPSTR)NULL        /* no params to pass on */
  211.                        );
  212.  
  213.     pTxt = (PTXT)LocalAlloc(LPTR,sizeof(struct TEXT_STRUCT));
  214.     if (!pTxt || !hWnd) {
  215.         Error ("CreateDebugWindow Failed.....");
  216.         return NULL;
  217.     }
  218.     SetWindowWord (hWnd,0,(WORD)pTxt); /* Store the structure pointer with the
  219.                                           window handle */
  220.  
  221.     pTxt->iFirst = 0;               /* Set the que up to have 1 NULL line */
  222.     pTxt->iCount = 1;
  223.     pTxt->iTop   = 0;
  224.     pTxt->iLeft  = 0;
  225.     pTxt->Text[0]= NULL;
  226.     pTxt->Len[0] = 0;
  227.     pTxt->MaxLen = 0;
  228.  
  229.     SetScrollRange (hWnd,SB_VERT,0,0,FALSE);
  230.     SetScrollRange (hWnd,SB_HORZ,0,0,FALSE);
  231.     /* Make window visible */
  232.     ShowWindow(hWnd,SHOW_OPENWINDOW);
  233.  
  234.     return hWnd;
  235. }
  236.  
  237.  
  238. /*----------------------------------------------------------------------------*\
  239. |   SetDebugClass(hInstance)                                                   |
  240. |                                                                              |
  241. |   Description:                                                               |
  242. |     Registers a class for a DEBUG window.                                    |
  243. |                                                                              |
  244. |   Arguments:                                                                 |
  245. |       hInstance       instance handle of current instance                    |
  246. |                                                                              |
  247. |   Returns:                                                                   |
  248. |       TRUE if successful, FALSE if not                                       |
  249. |                                                                              |
  250. \*----------------------------------------------------------------------------*/
  251.  
  252. static BOOL SetDebugClass(hInstance)
  253.   HANDLE hInstance;
  254. {
  255.     WNDCLASS rClass;
  256.  
  257.     rClass.hCursor        = LoadCursor(NULL,IDC_ARROW);
  258.     rClass.hIcon          = (HICON)NULL;
  259.     rClass.lpszMenuName   = (LPSTR)NULL;
  260.     rClass.lpszClassName  = (LPSTR)"DEBUG";
  261.     rClass.hbrBackground  = (HBRUSH)COLOR_WINDOW + 1;
  262.     rClass.hInstance      = hInstance;
  263.     rClass.style          = CS_HREDRAW | CS_VREDRAW;
  264.     rClass.lpfnWndProc    = DebugWndProc;
  265.     rClass.cbWndExtra     = sizeof (HANDLE);
  266.     rClass.cbClsExtra     = 0;
  267.  
  268.     return RegisterClass((LPWNDCLASS)&rClass);
  269. }
  270.  
  271.  
  272.  
  273. /*----------------------------------------------------------------------------*\
  274. |   MsgHook1 (wToast,pMsg,nCode)                                                |
  275. |                                                                              |
  276. |   Description:                                                               |
  277. |       The Message Hook1 to process all messages...                            |
  278. |                                                                              |
  279. |   Arguments:                                                                 |
  280. |       wToast          integer (0-100) for darkness of toast in morning       |
  281. |       pMsg            Pointer to message                                     |
  282. |       nCode           Message context                                        |
  283. |                                                                              |
  284. |   Returns:                                                                   |
  285. |       FALSE to let windows process, TRUE to ignore                           |
  286. |                                                                              |
  287. \*----------------------------------------------------------------------------*/
  288. DWORD FAR PASCAL MsgHook1(code, wToast, lpmsg)
  289. WORD     code;
  290. WORD     wToast;
  291. LPMSG    lpmsg;
  292. {
  293.    HANDLE hData;
  294.    HANDLE hqel;
  295.    QEL *pqel;
  296.    char rgch[65];
  297.  
  298.    if (code == HC_ACTION &&
  299.        lpmsg->message >= WM_DDE_FIRST &&
  300.        lpmsg->message <= WM_DDE_LAST)
  301.    {
  302.       hqel=LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof(QEL));
  303.       pqel=(QEL *)LocalLock(hqel);
  304.       pqel->msg=*lpmsg;
  305.       switch(lpmsg->message)
  306.       {
  307.       case WM_DDE_TERMINATE:
  308.               break;
  309.  
  310.       case WM_DDE_ACK:
  311.               if ((unsigned)HIWORD(lpmsg->lParam)>=(unsigned)0xc000)
  312.                       {
  313.                       pqel->un.type=1;
  314.                       goto OneAtom;
  315.                       }
  316.               pqel->un.type=2;
  317.               /* fall thru... */
  318.       case WM_DDE_EXECUTE:
  319.               break;
  320.       case WM_DDE_ADVISE:
  321.               hData=(HANDLE)LOWORD(lpmsg->lParam);
  322.               pqel->un.cf=((DDELN far *)GlobalLock(hData))->cf;
  323.               GlobalUnlock(hData);
  324.               goto OneAtom;
  325.       case WM_DDE_REQUEST:
  326.               pqel->un.cf=LOWORD(lpmsg->lParam);
  327.               goto OneAtom;
  328.       case WM_DDE_DATA:
  329.       case WM_DDE_POKE:
  330.               hData=(HANDLE)LOWORD(lpmsg->lParam);
  331.               pqel->un.cf=((DDEUP far *)GlobalLock(hData))->cf;
  332.               GlobalUnlock(hData);
  333.               /* fall thru... */
  334.       case WM_DDE_UNADVISE:
  335. OneAtom:
  336.               rgch[GlobalGetAtomName(HIWORD(lpmsg->lParam), rgch, 64)]='\0';
  337.               pqel->atom1=AddAtom(rgch);
  338.               break;
  339.       }
  340.       LocalUnlock(hqel);
  341.       HqelPut(hqel);
  342.       /* alert window that new queue data is available */
  343.       FormatString();
  344.       /* PostMessage(hSpyApp, WM_USER, 0, 0L); */
  345.    }
  346.    /* do default message handling */
  347.    return(DefHookProc(code, wToast, (DWORD)lpmsg, (FARPROC FAR *)&fpxOldHook1));
  348. }
  349.  
  350. /* ----------------------------------------------------- */
  351. DWORD FAR PASCAL MsgHook2(code, wToast, lpmsgr)
  352. WORD   code;
  353. WORD   wToast;
  354. LPMSGR lpmsgr;
  355. {
  356.    HANDLE hqel;
  357.    QEL *pqel;
  358.    char rgch[65];
  359.  
  360.    if (code == HC_ACTION &&
  361.        lpmsgr->message >= WM_DDE_FIRST && 
  362.        lpmsgr->message <= WM_DDE_LAST)
  363.    {
  364.        hqel=LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof(QEL));
  365.        pqel=(QEL *)LocalLock(hqel);
  366.        pqel->msg.message =lpmsgr->message;
  367.        pqel->msg.wParam  =lpmsgr->wParam;
  368.        pqel->msg.lParam  =lpmsgr->lParam;
  369.        pqel->msg.hwnd    =lpmsgr->hwnd;
  370.        pqel->un.type     =0;
  371.        rgch[GlobalGetAtomName(LOWORD(lpmsgr->lParam), rgch, 64)]='\0';
  372.        pqel->atom1=AddAtom(rgch);
  373.        rgch[GlobalGetAtomName(HIWORD(lpmsgr->lParam), rgch, 64)]='\0';
  374.        pqel->atom2=AddAtom(rgch);
  375.        LocalUnlock(hqel);
  376.        HqelPut(hqel);
  377.        /* alert window that new queue data is available */
  378.        FormatString();
  379.        /* PostMessage(hSpyApp, WM_USER, 0, 0L); */
  380.    }
  381.    /* do default message handling */
  382.    return(DefHookProc(code, wToast, (DWORD)lpmsgr, (FARPROC FAR *)&fpxOldHook2));
  383. }
  384.  
  385. /* -------------------- FormatString ------------- */
  386. void  FormatString()
  387. {
  388.  
  389.   HANDLE hqel;
  390.   QEL *pqel;
  391.   HMENU hMenu;
  392.   RECT  rRect;
  393.   char rgch[32];
  394.   char rgch2[32];
  395.   int i;
  396.  
  397.   /*
  398.    *  if the message is greater than WM_USER then it is a message to
  399.    *  be printed in the window
  400.    */
  401.  
  402.    while ((hqel=HqelGet())!=NULL)
  403.    {
  404.         pqel=(QEL *)LocalLock(hqel);
  405.  
  406. #ifdef OLD
  407.         DebugPrintf(hSpyChild,"%-10s %4.4X %4.4X %4.4X,%4.4X ",
  408.                 WM_messageText(pqel->msg.message),
  409.                 pqel->msg.wParam,
  410.                 pqel->msg.hwnd,
  411.                 LOWORD(pqel->msg.lParam),
  412.                 HIWORD(pqel->msg.lParam));
  413. #else
  414.         lstrcpy( pchFoo, szMessages[(pqel->msg.message)-WM_DDE_FIRST] );
  415.         lstrcat( pchFoo, "  " );
  416.         ultoa ((DWORD)pqel->msg.wParam, szTemp, 16);
  417.         lstrcat( pchFoo, szTemp );
  418.         lstrcat( pchFoo, "  " );
  419.         ultoa ((DWORD)pqel->msg.hwnd, szTemphWnd, 16);
  420.         lstrcat( pchFoo, szTemphWnd );
  421.         if ( strlen(szTemphWnd) < 4)
  422.           lstrcat( pchFoo, " " );
  423.         lstrcat( pchFoo, "  " );
  424.         ultoa ((DWORD)LOWORD(pqel->msg.lParam), szTemp, 16);
  425.         lstrcat( pchFoo, szTemp );
  426.         if ( strlen(szTemp) < 3)
  427.           lstrcat( pchFoo, "  " );
  428.         if ( strlen(szTemp) < 4)
  429.           lstrcat( pchFoo, " " );
  430.         lstrcat( pchFoo, "  " );
  431.         ultoa ((DWORD)HIWORD(pqel->msg.lParam), szTemp, 16);
  432.         lstrcat( pchFoo, szTemp );
  433.  
  434.         iLen = 0;
  435.         DebugPrintf(hSpyChild, pchFoo, iLen);
  436.  
  437.  
  438. #endif
  439.  
  440. #ifdef MENU
  441.         if ( pqel->msg.message == WM_DDE_INITIATE &&
  442.              pqel->msg.hwnd    != NULL )
  443.         {
  444.           for (i=0 ; i<10 ; i++) {
  445.              if (hWndMenu[i] == NULL ) {
  446.                  hWndMenu[i] = pqel->msg.hwnd;
  447.                  GetWindowText ( pqel->msg.hwnd, szTemp,25 );
  448.                  lstrcat ( szTemphWnd, ":" );
  449.                  lstrcat ( szTemphWnd, szTemp );
  450.                  ChangeMenu(hSpyWndMenu, 153, (LPSTR)szTemphWnd,153, 
  451.                             i ? MF_APPEND : MF_CHANGE );
  452.                  if (i == 0) {
  453.                    EnableMenuItem(hGMenu, 152, MF_ENABLED );
  454.                    DrawMenuBar(hGParent);
  455.                  }
  456.                  break;
  457.              }
  458.              else {
  459.                if ( hWndMenu[i] == pqel->msg.hwnd )
  460.                  break;
  461.              }
  462.           }
  463.         }
  464. #endif
  465.         switch(pqel->msg.message)
  466.         {
  467.           case WM_DDE_ACK:
  468.                 switch (pqel->un.type)
  469.                         {
  470.                 case 1:
  471.                         goto OneAtom;
  472.                 case 2:
  473.                         goto Execute;
  474.                         }
  475.                 /* fall thru... */
  476.           case WM_DDE_INITIATE:
  477.                 rgch[GetAtomName(pqel->atom1, (LPSTR)rgch, 32)]='\0';
  478.                 rgch2[GetAtomName(pqel->atom2, (LPSTR)rgch2, 32)]='\0';
  479. #ifdef OLD
  480.                 DebugPrintf(hSpyChild,"(App:%s, Topic:%s)",rgch, rgch2);
  481. #else
  482.                 lstrcpy( pchFoo, " (App:"                     );
  483.                 lstrcat( pchFoo,       rgch                  );
  484.                 lstrcat( pchFoo,           ", Topic:"        );
  485.                 lstrcat( pchFoo,                    rgch2    );
  486.                 lstrcat( pchFoo,                         ")" );
  487.                 DebugPrintf(hSpyChild, pchFoo, iLen);
  488. #endif
  489.                 DeleteAtom(pqel->atom1);
  490.                 DeleteAtom(pqel->atom2);
  491.                 break;
  492.           case WM_DDE_TERMINATE:
  493.                 break;
  494.           case WM_DDE_UNADVISE:
  495. OneAtom:
  496.                 rgch[GetAtomName(pqel->atom1, (LPSTR)rgch, 32)]='\0';
  497. #ifdef OLD
  498.                 DebugPrintf(hSpyChild,"(Item:%s)",rgch);
  499. #else
  500.                 lstrcpy( pchFoo, " (Items:"      );
  501.                 lstrcat( pchFoo,         rgch   );
  502.                 lstrcat( pchFoo,            ")" );
  503.                 DebugPrintf(hSpyChild, pchFoo, iLen);
  504. #endif
  505.                 DeleteAtom(pqel->atom1);
  506.  
  507.                 break;
  508.           case WM_DDE_ADVISE:
  509.           case WM_DDE_DATA:
  510.           case WM_DDE_POKE:
  511.           case WM_DDE_REQUEST:
  512.                 rgch[MyGetClipboardFormatName(pqel->un.cf, (LPSTR)rgch, 32)]='\0';
  513.                 rgch2[GetAtomName(pqel->atom1, (LPSTR)rgch2, 32)]='\0';
  514. #ifdef OLD
  515.                 DebugPrintf(hSpyChild,"(Format:%s, Item:%s)",rgch, rgch2);
  516. #else
  517.                 lstrcpy( pchFoo, " (Format:"                    );
  518.                 lstrcat( pchFoo,         rgch                  );
  519.                 lstrcat( pchFoo,             ", Items:"        );
  520.                 lstrcat( pchFoo,                      rgch2    );
  521.                 lstrcat( pchFoo,                           ")" );
  522.                 DebugPrintf(hSpyChild, pchFoo, iLen);
  523. #endif
  524.                 DeleteAtom(pqel->atom1);
  525.                 break;
  526.           case WM_DDE_EXECUTE:
  527. Execute:
  528.                 break;
  529.         }
  530. #ifdef OLD
  531.         DebugPrintf(hSpyChild,"\n");
  532. #else
  533.         lstrcpy( pchFoo, "\n" );
  534.         DebugPrintf(hSpyChild, pchFoo, iLen);
  535. #endif
  536.  
  537.         LocalUnlock(hqel);
  538.         LocalFree(hqel);
  539.    }
  540.    /* return(0L); */
  541. }
  542.  
  543. /*----------------------------------------------------------------------------*\
  544. |   DebugPrintf (hWnd,str,...)                                                 |
  545. |                                                                              |
  546. |   Description:                                                               |
  547. |       Writes data into the window hWnd (hWnd must be created with            |
  548. |       CreateDebugWindow ())                                                  |
  549. |       follows the normal C printf definition.                                |
  550. |                                                                              |
  551. |   Arguments:                                                                 |
  552. |       hWnd            window handle for the Degubing window                  |
  553. |       str             printf control string                                  |
  554. |       ...             extra parameters as required by the contol string      |
  555. |                                                                              |
  556. |   NOTE: if hWnd == NULL text will be printed in the window used in the last  |
  557. |         call to DebugPrintf.                                                 |
  558. \*----------------------------------------------------------------------------*/
  559.  
  560. int  DebugPrintf (hWnd,format,i)
  561. HWND hWnd;
  562. char *format;
  563. int  i;
  564. {
  565. #ifdef OLD
  566.   return vDebugPrintf (hWnd,format,&i);
  567. #else
  568.   return vDebugPrintf (hWnd,format,i);
  569. #endif
  570. }
  571.  
  572. #ifdef OLD
  573. int  vDebugPrintf (hWnd,format,pi)
  574. HWND hWnd;
  575. char *format;
  576. int  *pi;
  577. #else
  578. int  vDebugPrintf (hWnd,format,pi)
  579. HWND hWnd;
  580. char *format;
  581. int  pi;
  582. #endif
  583.  
  584. {
  585.   static HWND hWndLast = NULL;
  586.   RECT  rect;
  587.   int   iFree;
  588.   int   iRet;
  589.   int   iLine;
  590.   int   cLine;
  591.   int   cScroll;
  592.   PTXT  pTxt;
  593.   MSG   rMsg;
  594.   POINT rPoint;
  595. /*
  596.   if (!SSEqualToDS()) {
  597.     Error ("WARNING: SS != DS,  Can't printf to window");
  598.     return 0;
  599.   }
  600.  */
  601.   if (hWnd == NULL) hWnd = hWndLast;
  602.  
  603.   if (hWnd == NULL || !IsWindow (hWnd)) {
  604.      Error ("WARNING: bad window handle,  Can't printf to window");
  605.      return 0;  /* exit if bad window handle */
  606.   }
  607.   pTxt = (PTXT)GetWindowWord (hWnd,0);
  608.   hWndLast = hWnd;
  609. #ifdef OLD
  610.   iRet = vsprintf(pchFoo,format,pi);
  611. #endif
  612.  
  613.   iLine   = pTxt->iCount - pTxt->iTop;
  614.   cLine   = LinesInDebugWindow(hWnd);
  615.   iFree   = pTxt->iTop;
  616.   cScroll = InsertString (pTxt,pchFoo);  /* Insert text in the que */
  617.  
  618.   /* Scroll the window if Que overflowed */
  619.   if (pTxt->iCount == MAXLINES && pTxt->iTop == 0) {
  620.     iFree = cScroll - iFree;
  621.     pTxt->iTop = -iFree;
  622.     DebugVScroll (hWnd,pTxt,iFree);
  623.   }
  624.  
  625.   if (iLine == cLine) {                  /* Scroll the window if last line */
  626.      DebugVScroll (hWnd,pTxt,cScroll);   /* is allso last line in window */
  627.      iLine -= cScroll;
  628.   }
  629.  
  630.   /* Update the scroll bars */
  631.   SetScrollRange (hWnd,SB_VERT,0,pTxt->iCount-2,FALSE);
  632.   SetScrollRange (hWnd,SB_HORZ,0,pTxt->MaxLen,FALSE);
  633.   SetScrollPos   (hWnd,SB_VERT,pTxt->iTop,FALSE);
  634.   SetScrollPos   (hWnd,SB_HORZ,pTxt->iLeft,FALSE);
  635.  
  636.   /* Now make sure the new text is painted only if visable */
  637.   GetClientRect(hWnd,(LPRECT)&rect);
  638.   rect.top += (iLine-1) * Tdy;
  639.   InvalidateRect (hWnd,(LPRECT)&rect,FALSE);
  640.   UpdateWindow (hWnd);
  641.  
  642.   return(iRet);       /* return the count of arguments printed */
  643. }
  644.  
  645. /*----------------------------------------------------------------------------*\
  646. |                                                                              |
  647. \*----------------------------------------------------------------------------*/
  648.  
  649. static void NewLine (pTxt)
  650. PTXT pTxt;
  651. {
  652.   int iLast = LAST(pTxt);
  653.   int iLine,cLine;
  654.  
  655.   if (pTxt->iCount == MAXLINES) {
  656.     LocalFree ((HANDLE)pTxt->Text[pTxt->iFirst]);
  657.     INC (pTxt->iFirst);
  658.     if (pTxt->iTop > 0) pTxt->iTop--;
  659.   }
  660.   else {
  661.     pTxt->iCount++;
  662.   }
  663.   iLast = LAST(pTxt);
  664.   pTxt->Text[iLast] = NULL;
  665.   pTxt->Len[iLast]  = 0;
  666. }
  667.  
  668. /*----------------------------------------------------------------------------*\
  669. |                                                                              |
  670. \*----------------------------------------------------------------------------*/
  671.  
  672. static int InsertString (pTxt,str)
  673.   PTXT pTxt;
  674.   char *str;
  675. {
  676.   static char   buffer[MAXFOOLEN];               /* intermediate buffer */
  677.   int    iBuf;
  678.   int    iLast = LAST(pTxt);
  679.   int    cLine = 0;
  680.  
  681.   for (iBuf=0; iBuf < pTxt->Len[iLast]; iBuf++)
  682.     buffer[iBuf] = pTxt->Text[iLast][iBuf];
  683.  
  684.   if (pTxt->Text[iLast] != NULL)
  685.     LocalFree ((HANDLE)pTxt->Text[iLast]);
  686.  
  687.   while (*str != '\0') {
  688.     while ((*str != '\n') && (*str != '\0'))
  689.       buffer[iBuf++] = *str++;
  690.  
  691.     /* Test for the case of a zero length line, Only brian would do this */
  692.  
  693.     if (iBuf == 0)
  694.        pTxt->Text[iLast] == NULL;
  695.     else {
  696.       if ((pTxt->Text[iLast] = (char *)LocalAlloc (LPTR,iBuf)) == NULL)
  697.          Error ("Local alloc failed in Insert string.....");
  698.     }
  699.  
  700.     pTxt->Len[iLast] = iBuf;
  701.     if (iBuf > pTxt->MaxLen) pTxt->MaxLen = iBuf;
  702.     while (--iBuf >= 0 )
  703.       pTxt->Text[iLast][iBuf] = buffer[iBuf];
  704.  
  705.     if (*str == '\n') {   /* Now do the next string after the \n */
  706.        str++;
  707.        iBuf = 0;
  708.        cLine++;
  709.        NewLine (pTxt);
  710.        INC(iLast);
  711.     }
  712.   }
  713.   return cLine;
  714. }
  715.  
  716.  
  717. /*----------------------------------------------------------------------------*\
  718. |   DebugWndProc( hWnd, uiMessage, wParam, lParam )                               |
  719. |                                                                              |
  720. |   Description:                                                               |
  721. |       The window proc for the debuging window.  This processes all           |
  722. |       of the window's messages.                                              |
  723. |                                                                              |
  724. |   Arguments:                                                                 |
  725. |       hWnd            window handle for the parent window                    |
  726. |       uiMessage       message number                                         |
  727. |       wParam          message-dependent                                      |
  728. |       lParam          message-dependent                                      |
  729. |                                                                              |
  730. |   Returns:                                                                   |
  731. |       0 if processed, nonzero if ignored                                     |
  732. |                                                                              |
  733. \*----------------------------------------------------------------------------*/
  734.  
  735. long FAR PASCAL DebugWndProc( hWnd, uiMessage, wParam, lParam )
  736. HWND     hWnd;
  737. unsigned uiMessage;
  738. WORD     wParam;
  739. long     lParam;
  740. {
  741.     PAINTSTRUCT rPS;
  742.     PTXT        pTxt  = (PTXT)GetWindowWord(hWnd,0);
  743.     RECT        CRect;
  744.     static WORD wScroll;
  745.  
  746.     switch (uiMessage) {
  747.        /*
  748.         * This tries to go around a BUG in 1.03 about scroll bars being confused
  749.         */
  750.         case WM_SYSCOMMAND:
  751.             switch (wParam & 0xFFF0) {
  752.                 case SC_VSCROLL:
  753.                 case SC_HSCROLL:
  754.                      wScroll = wParam & 0xFFF0;
  755.                 default:
  756.                    return DefWindowProc(hWnd,uiMessage,wParam,lParam);
  757.             }
  758.             break;
  759.  
  760.         case WM_DESTROY: {
  761.             int i,iQue;
  762.  
  763.             iQue = TOP(pTxt);
  764.             for (i=0; i < pTxt->iCount; i++,INC(iQue))
  765.               if (pTxt->Text[iQue] != NULL)
  766.                  LocalFree ((HANDLE)pTxt->Text[iQue]);
  767.  
  768.             LocalFree ((HANDLE)pTxt);
  769.             break;
  770.         }
  771.  
  772.         case WM_VSCROLL:
  773.             if (wScroll == SC_VSCROLL) {
  774.                switch (wParam) {
  775.                   case SB_LINEDOWN:
  776.                      DebugVScroll (hWnd,pTxt,1);
  777.                      break;
  778.                   case SB_LINEUP:
  779.                      DebugVScroll (hWnd,pTxt,-1);
  780.                      break;
  781.                   case SB_PAGEUP:
  782.                      DebugVScroll (hWnd,pTxt,-PAGE);
  783.                      break;
  784.                   case SB_PAGEDOWN:
  785.                      DebugVScroll (hWnd,pTxt,PAGE);
  786.                      break;
  787.                   case SB_THUMBPOSITION:
  788.                      DebugVScroll (hWnd,pTxt,LOWORD(lParam)-pTxt->iTop);
  789.                      break;
  790.                }
  791.              }
  792.              break;
  793.  
  794.         case WM_HSCROLL:
  795.             if (wScroll == SC_HSCROLL) {
  796.                switch (wParam) {
  797.                   case SB_LINEDOWN:
  798.                      DebugHScroll (hWnd,pTxt,1);
  799.                      break;
  800.                   case SB_LINEUP:
  801.                      DebugHScroll (hWnd,pTxt,-1);
  802.                      break;
  803.                   case SB_PAGEUP:
  804.                      DebugHScroll (hWnd,pTxt,-PAGE);
  805.                      break;
  806.                   case SB_PAGEDOWN:
  807.                      DebugHScroll (hWnd,pTxt,PAGE);
  808.                      break;
  809.                   case SB_THUMBPOSITION:
  810.                      DebugHScroll (hWnd,pTxt,LOWORD(lParam)-pTxt->iLeft);
  811.                      break;
  812.                }
  813.             }
  814.             break;
  815.  
  816.         case WM_PAINT:
  817.             BeginPaint(hWnd,(LPPAINTSTRUCT)&rPS);
  818.             DebugPaint (hWnd,rPS.hdc);
  819.             EndPaint(hWnd,(LPPAINTSTRUCT)&rPS);
  820.             break;
  821.  
  822.         default:
  823.            return DefWindowProc(hWnd,uiMessage,wParam,lParam);
  824.     }
  825.     return 0L;
  826. }
  827.  
  828.  
  829. /*----------------------------------------------------------------------------*\
  830. |   DebugPaint(hWnd, hDC )                                                     |
  831. |                                                                              |
  832. |   Description:                                                               |
  833. |       The paint function.                                                    |
  834. |                                                                              |
  835. |   Arguments:                                                                 |
  836. |       hWnd            Window to paint to.                                    |
  837. |       hDC             handle to update region's display context              |
  838. |                                                                              |
  839. |   Returns:                                                                   |
  840. |       nothing                                                                |
  841. |                                                                              |
  842. \*----------------------------------------------------------------------------*/
  843.  
  844. void FAR PASCAL DebugPaint(hWnd, hDC)
  845. HWND hWnd;
  846. HDC  hDC;
  847. {
  848.   PTXT pTxt;
  849.   int  i;
  850.   int  iQue;
  851.   int  xco;
  852.   int  yco;
  853.   char iFoo = 0;
  854.   int  iLast;
  855.   int  Wdy;
  856.   RECT CRect;
  857.  
  858.   pTxt = (PTXT)GetWindowWord(hWnd,0);
  859.  
  860.   GetClientRect(hWnd,(LPRECT)&CRect);
  861.   Wdy = CRect.bottom-CRect.top;
  862.  
  863.   iLast = LAST(pTxt);
  864.   iQue  = TOP(pTxt);
  865.   xco   = OFFSETX;
  866.   yco   = OFFSETY;
  867.   for (;;) {
  868.     if (pTxt->Len[iQue] > pTxt->iLeft)
  869.        TextOut (hDC,xco,yco,(LPSTR)pTxt->Text[iQue] + pTxt->iLeft,
  870.                                    pTxt->Len[iQue]  - pTxt->iLeft
  871.                );
  872.     if (iQue == iLast) break;
  873.     INC(iQue);
  874.     yco += Tdy;
  875.     if (yco > Wdy) break;
  876.   }
  877. }
  878.  
  879.  
  880. /*----------------------------------------------------------------------------*\
  881. |                                                                              |
  882. \*----------------------------------------------------------------------------*/
  883.  
  884. void DebugVScroll (hWnd,pTxt,n)
  885. HWND hWnd;
  886. PTXT pTxt;
  887. int  n;
  888. {
  889.   int  delta;
  890.   RECT rect;
  891.  
  892.   GetClientRect (hWnd,(LPRECT)&rect);
  893.   rect.left += OFFSETX;
  894.   rect.top  += OFFSETY;
  895.  
  896.   if (n > 0) {
  897.      delta = pTxt->iCount - pTxt->iTop - 2;
  898.      if (n > delta) n = delta;
  899.      pTxt->iTop += n;
  900.      ScrollWindow (hWnd,0,-n*Tdy,(LPRECT)&rect,(LPRECT)&rect);
  901.   }
  902.   else {
  903.      n *= -1;
  904.      delta = pTxt->iTop;
  905.      if (n > delta) n = delta;
  906.      pTxt->iTop -= n;
  907.      ScrollWindow (hWnd,0,n*Tdy,(LPRECT)&rect,(LPRECT)&rect);
  908.   }
  909.   SetScrollPos (hWnd,SB_VERT,pTxt->iTop,TRUE);
  910. }
  911.  
  912. /*----------------------------------------------------------------------------*\
  913. |                                                                              |
  914. \*----------------------------------------------------------------------------*/
  915.  
  916. void DebugHScroll (hWnd,pTxt,n)
  917. HWND hWnd;
  918. PTXT pTxt;
  919. int  n;
  920. {
  921.   int delta;
  922.   RECT rect;
  923.  
  924.   GetClientRect (hWnd,(LPRECT)&rect);
  925.   rect.left += OFFSETX;
  926.   rect.top  += OFFSETY;
  927.  
  928.   if (n > 0) {
  929.      delta = pTxt->MaxLen - pTxt->iLeft;
  930.      if (n > delta) n = delta;
  931.      pTxt->iLeft += n;
  932.      ScrollWindow (hWnd,-n*Tdx,0,(LPRECT)&rect,(LPRECT)&rect);
  933.   }
  934.   else {
  935.      n *= -1;
  936.      delta = pTxt->iLeft;
  937.      if (n > delta) n = delta;
  938.      pTxt->iLeft -= n;
  939.      ScrollWindow (hWnd,n*Tdx,0,(LPRECT)&rect,(LPRECT)&rect);
  940.   }
  941.   SetScrollPos (hWnd,SB_HORZ,pTxt->iLeft,TRUE);
  942. }
  943.  
  944. /*----------------------------------------------------------------------------*\
  945. |                                                                              |
  946. \*----------------------------------------------------------------------------*/
  947.  
  948. static
  949. int LinesInDebugWindow (hWnd)
  950.     HWND hWnd;
  951. {
  952.     RECT CRect;
  953.  
  954.     GetClientRect(hWnd,(LPRECT)&CRect);
  955.     return (CRect.bottom-CRect.top) / Tdy + 1;
  956. }
  957.  
  958.  
  959. /*----------------------------------------------------------------------------*\
  960. | Error routine, brings up a message box with a error message                  |
  961. \*----------------------------------------------------------------------------*/
  962.  
  963. static void Error (str)
  964. char *str;
  965. {
  966.   int a = MessageBox (GetFocus(),(LPSTR)str,(LPSTR)NULL,MB_OKCANCEL);
  967.   if (a == IDCANCEL) PostQuitMessage(0);
  968. }
  969.  
  970. /*----------------------------------------------------------------------------*\
  971. | routine to verify that SS == DS                                              |
  972. \*----------------------------------------------------------------------------*/
  973.  
  974. static BOOL SSEqualToDS () {
  975.   int a = (int)&a;
  976.   return (int far *)&a == (int far *)(int near *)a;
  977. }
  978.  
  979.  
  980. int MyGetClipboardFormatName(cf, lpch, cchMac)
  981. int cf;
  982. LPSTR lpch;
  983. int cchMac;
  984. {
  985.         switch(cf)
  986.                 {
  987.         case CF_TEXT:
  988.                 lstrcpy(lpch,"TEXT");
  989.                 return(4);
  990.         case CF_BITMAP:
  991.                 lstrcpy(lpch,"BITMAP");
  992.                 return(6);
  993.         case CF_METAFILEPICT:
  994.                 lstrcpy(lpch,"METAFILEPICT");
  995.                 return(12);
  996.         case CF_SYLK:
  997.                 lstrcpy(lpch,"SYLK");
  998.                 return(4);
  999.         case CF_DIF:
  1000.                 lstrcpy(lpch,"DIF");
  1001.                 return(3);
  1002.         default:
  1003.                 return(GetClipboardFormatName(cf, lpch, cchMac));
  1004.                 }
  1005. }
  1006.  
  1007.  
  1008. /* add an element to the queue */
  1009. void HqelPut(hqel)
  1010. HANDLE hqel;
  1011. {
  1012.  
  1013.   rghqel[ihqelHead++]=hqel;
  1014.   if (ihqelHead==ihqelMax)
  1015.     ihqelHead=0;
  1016.   if (ihqelHead==ihqelTail)
  1017.     MessageBox(GetFocus(), "Queue overflow", NULL, MB_OK|MB_SYSTEMMODAL);
  1018. }
  1019.  
  1020. /* delete an element from the queue */
  1021. HANDLE HqelGet()
  1022. {
  1023.   HANDLE hqel;
  1024.  
  1025.   if (ihqelTail==ihqelHead)
  1026.     return(NULL);
  1027.   hqel=rghqel[ihqelTail++];
  1028.  
  1029.   if (ihqelTail==ihqelMax)
  1030.     ihqelTail=0;
  1031.  
  1032.   return(hqel);
  1033. }
  1034.  
  1035. #ifdef OLD
  1036.  char *WM_MessageText (uiMsg)
  1037.  WORD uiMsg;
  1038.  {
  1039.    switch (uiMsg)
  1040.    {
  1041.      case WM_DDE_INITIATE:  return("INITIATE");
  1042.      case WM_DDE_TERMINATE: return("TERMINATE");
  1043.      case WM_DDE_ADVISE:    return("ADVISE");
  1044.      case WM_DDE_UNADVISE:  return("UNADVISE");
  1045.      case WM_DDE_ACK:       return("ACK");
  1046.      case WM_DDE_DATA:      return("DATA");
  1047.      case WM_DDE_REQUEST:   return("REQUEST");
  1048.      case WM_DDE_POKE:      return("POKE");
  1049.      case WM_DDE_EXECUTE:   return("EXECUTE");
  1050.    }
  1051.    return(NULL);
  1052.  }
  1053. #endif
  1054.  
  1055. #ifdef OLD
  1056.  void WriteitToFile( LPSTR lpString, int iLen )
  1057.  {
  1058.    if (dllgfhFile > 0) {
  1059.      _lwrite (dllgfhFile," ",1);
  1060.      _lwrite (dllgfhFile,lpString,iLen);
  1061.    }
  1062.    return;
  1063.  
  1064.  }
  1065. #endif
  1066.  
  1067.