home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / DIAGXPRT.PAK / DIAGXPRT.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  14KB  |  558 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //----------------------------------------------------------------------------
  4. #include <owl\owlpch.h>
  5. #include "diagxprt.rh"
  6. #include  "diagxprt.h"
  7. #include  "setup.h"
  8.  
  9.  
  10. DEFINE_RESPONSE_TABLE1(TDiagClient, TEditFile)
  11.   EV_COMMAND(CM_FILENEW, CmFileNew),
  12.   EV_COMMAND(CM_FILEOPEN, CmFileOpen),
  13.   EV_COMMAND(CM_FILESAVE, CmFileSave),
  14.   EV_COMMAND(CM_FILESAVEAS, CmFileSaveAs),
  15.   EV_COMMAND(CM_SETUP, CmSetup),
  16.   EV_COMMAND(CM_START, CmStart),
  17.   EV_COMMAND(CM_STOP, CmStop),
  18.   EV_COMMAND(CM_MEM, CmMem),
  19.   EV_COMMAND(CM_HELP, CmHelp),
  20.   EV_COMMAND_ENABLE(CM_FILENEW, CmFileNewEnable),
  21.   EV_COMMAND_ENABLE(CM_FILEOPEN, CmFileOpenEnable),
  22.   EV_COMMAND_ENABLE(CM_FILESAVE, CmFileSaveEnable),
  23.   EV_COMMAND_ENABLE(CM_SETUP, CmSetupEnable),
  24.   EV_COMMAND_ENABLE(CM_START, CmStartEnable),
  25.   EV_COMMAND_ENABLE(CM_STOP, CmStopEnable),
  26.   EV_MESSAGE(CM_LOGPARAMERROR, CmLogParamError),
  27.   EV_MESSAGE(CM_LOGERROR, CmLogError),
  28.   EV_MESSAGE(CM_OUTSTR, CmOutStr),
  29. //  EV_MESSAGE(CM_DEFAULT, CmDefault),  // Will display unhandled toolhelp ids
  30. END_RESPONSE_TABLE;
  31.  
  32. //
  33. //  class TOwlDiagApp
  34. //
  35.  
  36. //
  37. // This defines the icons for the speedbar
  38. //
  39. int TOwlDiagApp::speedbar[] = {
  40.   CM_FILENEW, CM_FILENEW,
  41.   CM_FILEOPEN, CM_FILEOPEN,
  42.   CM_FILESAVE, CM_FILESAVE,
  43.   CM_FILESAVEAS, CM_FILESAVEAS,
  44.   -1, -1,
  45.   CM_EDITCOPY, CM_EDITCOPY,
  46.   CM_EDITCUT, CM_EDITCUT,
  47.   CM_EDITPASTE, CM_EDITPASTE,
  48.   -1, -1,
  49.   CM_EDITFIND, CM_EDITFIND,
  50.   CM_EDITREPLACE, CM_EDITREPLACE,
  51.   CM_EDITFINDNEXT, CM_EDITFINDNEXT,
  52.   -1, -1,
  53.   CM_SETUP, CM_SETUP,
  54.   -1, -1,
  55.   IDB_START, CM_START,
  56.   IDB_STOP, CM_STOP,
  57.   -1, -1,
  58.   IDB_MEM,  CM_MEM,
  59.   IDB_HELP, CM_HELP,
  60.   0, 0
  61. };
  62.  
  63. char *helpText[] = {
  64.   "DIAGXPRT displays diagnostic messages sent by OutputDebugString()",
  65.   "or by the RTL diagnostic macros, TRACEX & WARNX.",
  66.   "OWL diagnostics can be enabled or disabled by using the configure button.",
  67.   "There are two levels of diagnostics used in OWL, 0 and 1.  You can configure",
  68.   "this for each area.",
  69.   "You can also add your own diagnostic groups.  Each new group will be",
  70.   "written to the OWL.INI file and the declaration placed on the clipboard",
  71.   "for inclusion in your code.",
  72.   "The OWL.INI file is only read when your application loads.",
  73.   "Please see the RTL documentation and online help for a complete description",
  74.   "of the diagnostic macros and their use.  You may also look in OWL source",
  75.   "for additional examples.",
  76.   0
  77. };
  78.   
  79. void
  80. TOwlDiagApp::InitMainWindow()
  81. {
  82.   TDiagFrame *frame = new TDiagFrame(
  83.     string(*this, IDS_TITLE).c_str(), new TDiagClient);
  84.  
  85.   TControlBar* cb = new TControlBar(frame);
  86.  
  87.   for (int *pID = speedbar; *pID; pID += 2) {
  88.     if (pID[0] == -1)
  89.       cb->Insert(*new TSeparatorGadget(6));
  90.     else
  91.       cb->Insert(*new TButtonGadget(pID[0], pID[1]));
  92.   }
  93.   cb->Attr.Id = CM_TOOLBAR;
  94.  
  95.   //Turn on control bar hints.
  96.   cb->SetHintMode(TGadgetWindow::EnterHints); 
  97.  
  98.   frame->Insert(*cb, TDecoratedFrame::Top);
  99.  
  100.   MainWindow = frame;
  101.   MainWindow->SetIcon(this, IC_OWLDIAG);
  102.  
  103.   // Construct a status bar & insert it at the bottom
  104.   //
  105.   TStatusBar *pS = new TStatusBar(0, TGadget::Recessed,
  106.     TStatusBar::CapsLock | TStatusBar::NumLock | TStatusBar::ScrollLock);
  107. //  pS->Attr.Id = CM_STATUSBAR;
  108.   frame->Insert(*pS, TDecoratedFrame::Bottom);
  109.  
  110.   EnableCtl3d(TRUE);
  111. }
  112.  
  113. //
  114. //  class TDiagClient
  115. //
  116.  
  117. TDiagClient * TDiagClient::pThis;
  118. void
  119. TDiagClient::CmStart()
  120. {
  121.   nActive = 1;
  122. }
  123.  
  124. void
  125. TDiagClient::CmStop()
  126. {
  127.   nActive = 0;
  128. }
  129.  
  130. void
  131. TDiagClient::CmSetup()
  132. {
  133.   nActive--;
  134.   TSetupDialog(this).Execute();
  135.   nActive++;
  136. }
  137.  
  138.  
  139. void
  140. TDiagClient::CmHelp()
  141. {
  142.   int i = 0;
  143.  
  144.   SetSelection(-1, -1);
  145.  
  146.   while (helpText[i]) {
  147.     Insert(helpText[i++]);
  148.     Insert("\r\n");
  149.     }
  150. }
  151.  
  152. //
  153. //Dumps memory statistics into output window
  154. //
  155. void 
  156. TDiagClient::CmMem()
  157. {
  158.   static char buf[80];
  159.  
  160.   MEMMANINFO info;
  161.   info.dwSize=sizeof(info);
  162.  
  163.   SYSHEAPINFO sysInfo;
  164.   sysInfo.dwSize=sizeof(sysInfo);
  165.  
  166.   SetSelection(-1, -1);
  167.  
  168.   Insert("Compacting heap, please wait\r\n");
  169.  
  170.   DWORD freeMemEst = GlobalCompact(-1);
  171.   wsprintf(buf,"Estimated free memory = %lu\r\n",freeMemEst);
  172.   Insert(buf);
  173.  
  174.   if (MemManInfo(&info)) {
  175.     Insert("MemManInfo() reports...\r\n");
  176.     wsprintf(buf,"..Largest free block = %lu\r\n", info.dwLargestFreeBlock);
  177.     Insert(buf);
  178.     wsprintf(buf,"..Max pages available = %lu\r\n", info.dwMaxPagesAvailable);
  179.     Insert(buf);
  180.     wsprintf(buf,"..Max pages lockable = %lu\r\n", info.dwMaxPagesLockable);
  181.     Insert(buf);
  182.     wsprintf(buf,"..Total linear space = %lu\r\n", info.dwTotalLinearSpace);
  183.     Insert(buf);
  184.     wsprintf(buf,"..Total unlocked pages = %lu\r\n", info.dwTotalUnlockedPages);
  185.     Insert(buf);
  186.     wsprintf(buf,"..Free pages = %lu\r\n", info.dwFreePages);
  187.     Insert(buf);
  188.     wsprintf(buf,"..Total pages = %lu\r\n", info.dwTotalPages);
  189.     Insert(buf);
  190.     wsprintf(buf,"..Free linear space = %lu\r\n", info.dwFreeLinearSpace);
  191.     Insert(buf);
  192.     wsprintf(buf,"..Swap file pages = %lu\r\n", info.dwSwapFilePages);
  193.     Insert(buf);
  194.     wsprintf(buf,"..Page size = %u\r\n",  info.wPageSize);
  195.     Insert(buf);
  196.   }
  197.   else
  198.     Insert("MemManInfo() failed\r\n");
  199.  
  200.   if (SystemHeapInfo(&sysInfo)) {
  201.     Insert("SysHeapInfo() reports...\r\n");
  202.     wsprintf(buf,"..User free percent = %u\r\n", sysInfo.wUserFreePercent);
  203.     Insert(buf);
  204.     wsprintf(buf,"..GDI free percent = %u\r\n", sysInfo.wGDIFreePercent);
  205.     Insert(buf);
  206.   }
  207.   else
  208.     Insert("SysHeapInfo() failed\r\n");
  209. }
  210.  
  211. //
  212. // Override of TEditFile::CanClear()
  213. //
  214. BOOL
  215. TDiagClient::CanClear()
  216. {
  217.   // We don't want to be prompted all the time to see if we want to save the
  218.   // text
  219.   return TRUE;
  220. }
  221.  
  222. void
  223. TDiagClient::SetupWindow()
  224. {
  225.   extern BOOL FAR PASCAL Callback(WORD id, DWORD data);
  226.   TEditFile::SetupWindow();
  227.   nActive = 0;
  228.   pThis = this;
  229.   pThunk = MakeProcInstance((FARPROC)Callback, HINSTANCE(*GetModule()));
  230.   // Create 2 fonts: A big one and a small one. Names & sizes are loaded
  231.   // from resource file.
  232.   pFont0 = new TFont(
  233.     string(*GetModule(), IDS_FONT0_NAME).c_str(),
  234.     atoi(string(*GetModule(), IDS_FONT0_SIZE).c_str()));
  235.   pFont1 = new TFont(
  236.     string(*GetModule(), IDS_FONT1_NAME).c_str(),
  237.     atoi(string(*GetModule(), IDS_FONT1_SIZE).c_str()));
  238.   SetSize(bigSize);
  239.   LoadMode();
  240.   NotifyRegister(0, (LPFNNOTIFYCALLBACK)pThunk, NF_NORMAL);
  241. }
  242.  
  243. void
  244. TDiagClient::CleanupWindow()
  245. {
  246.   SaveMode();
  247.   // Un-register our callback by toolhelp
  248.   NotifyUnRegister(0);
  249.   FreeProcInstance(pThunk);
  250.   delete pFont0;
  251.   delete pFont1;
  252. }
  253.  
  254. void
  255. TDiagClient::SetSize(Size s)
  256. {
  257.   // Called when the frame window changes "size" (small or big). We make
  258.   // here the client window reflect the change by modifying some attributes
  259.   size = s;
  260.  
  261.   // Small font for smallSize, large font for bigSize
  262.   //
  263.   SetWindowFont(*(size == bigSize ? pFont0 : pFont1), TRUE);
  264.  
  265.   // No scroll bar for smallSize, scroll bars for largeSize
  266.   //
  267.   Attr.Style = GetWindowLong(GWL_STYLE);
  268.   if (size == bigSize)
  269.     Attr.Style |= (WS_VSCROLL+WS_HSCROLL);
  270.   else
  271.     Attr.Style &= ~(WS_VSCROLL+WS_HSCROLL);
  272.   SetWindowLong(GWL_STYLE, Attr.Style);
  273. }
  274.  
  275. void
  276. FixUpEOL(char *str)
  277. {
  278.     while (*str) {
  279.         // Normalize the \r\n ordering (edit doesn't tolerate \n\r)
  280.     if (str[0] == '\n') {
  281.           if (str[1] == '\r')
  282.         str[1] = '\n';
  283.       else
  284.         memmove(str+1,str,strlen(str)+1);
  285.       str[0] = '\r'; 
  286.       str += 2;
  287.     }
  288.     else
  289.           str++;
  290.     }
  291.  
  292. }
  293. LRESULT
  294. TDiagClient::CmDefault(WPARAM id, LPARAM /*data*/)
  295. {
  296.   if (!nActive)
  297.     return TRUE;
  298.  
  299.   char buf[128];
  300.   wsprintf(buf,"Toolhelp callback id: %u\r\n",id);
  301.  
  302.   // To avoid beeing overflown: passed 200 lines, keep deleting
  303.   // the first line so that the number of lines cannot grow
  304.   //
  305.   if (GetNumLines() >= 200)
  306.     DeleteLine(0);
  307.  
  308.   // Append the line to display to the end of the edit buffer
  309.   //
  310.   SetSelection(-1, -1);
  311.   Insert(buf);
  312.   SetSelection(-1, -1);
  313.  
  314.   return TRUE;
  315. }
  316.  
  317. //
  318. // This gets called as a result of a message post from the toolhelp
  319. // callback
  320. //
  321. LRESULT
  322. TDiagClient::CmOutStr(WPARAM /*id*/, LPARAM data)
  323. {
  324.   if (!nActive)
  325.     return TRUE;
  326.  
  327.   // To avoid beeing overflown: passed 200 lines, keep deleting
  328.   // the first line so that the number of lines cannot grow
  329.   //
  330.   if (GetNumLines() >= 200)
  331.     DeleteLine(0);
  332.  
  333.   // Append the line to display to the end of the edit buffer
  334.   //
  335.   TDispData far* d = (TDispData far *)data;
  336.   SetSelection(-1, -1);
  337.   FixUpEOL(d->ProcName);
  338.   Insert(d->ProcName); // Really message
  339.   // Assume that caller of OutputDebugString is responsible for \r\n
  340.   // Insert("\r\n");
  341.   SetSelection(-1, -1);
  342.  
  343.   // This was allocated in call back
  344.   //
  345.   delete d;
  346.   return TRUE;  
  347. }
  348.  
  349. LRESULT
  350. TDiagClient::CmLogParamError(WPARAM /*id*/, LPARAM data)
  351. {
  352.   if (!nActive)
  353.     return TRUE;
  354.  
  355.   TDispData far* d = (TDispData far *)data;
  356.   char buf[128];
  357.   FormatLogParamError(buf, sizeof(buf), d);
  358.  
  359.   // To avoid beeing overflown: passed 200 lines, keep deleting
  360.   // the first line so that the number of lines cannot grow
  361.   //
  362.   if (GetNumLines() >= 200)
  363.     DeleteLine(0);
  364.  
  365.   // Append the line to display to the end of the edit buffer
  366.   //
  367.   SetSelection(-1, -1);
  368.   Insert(buf);  
  369.   SetSelection(-1, -1);
  370.  
  371.   delete d;
  372.   return TRUE;
  373. }
  374.  
  375. LRESULT
  376. TDiagClient::CmLogError(WPARAM /*id*/, LPARAM data)
  377. {
  378.   if (!nActive)
  379.     return TRUE;
  380.  
  381.   TDispData far* d = (TDispData far*)data;
  382.   char buf[128];
  383.   FormatLogError(buf, sizeof(buf), d);
  384.  
  385.   // To avoid beeing overflown: passed 200 lines, keep deleting
  386.   // the first line so that the number of lines cannot grow
  387.   //
  388.   if (GetNumLines() >= 200)
  389.     DeleteLine(0);
  390.  
  391.   // Append the line to display to the end of the edit buffer
  392.   //
  393.   SetSelection(-1, -1);
  394.   Insert(buf);
  395.   SetSelection(-1, -1);
  396.  
  397.   delete d;
  398.   return TRUE;
  399. }
  400.  
  401. void
  402. TDiagClient::SaveMode()
  403. {
  404.   WritePrivateProfileString(DIAG_CLS, DIAG_MODE, nActive > 0 ? "1":"0", DIAG_INI);
  405. }
  406.  
  407. void
  408. TDiagClient::LoadMode()
  409. {
  410.   char b[4];
  411.   GetPrivateProfileString(DIAG_CLS, DIAG_MODE, "0", b, sizeof(b), DIAG_INI);
  412.   nActive = *b != '0';
  413. }
  414.  
  415. //
  416. //  class TDiagFrame
  417. //
  418.  
  419. DEFINE_RESPONSE_TABLE2(TDiagFrame, TTinyCaption, TDecoratedFrame)
  420.   EV_WM_SYSCOMMAND,
  421.   EV_WM_SIZE,
  422. END_RESPONSE_TABLE;
  423.  
  424. TDiagFrame::TDiagFrame(const char* t, TWindow* c)
  425.   : TDecoratedFrame(0, t, c, TRUE), TTinyCaption(), TWindow(0, t, 0)
  426. {
  427.   // This frame window is special. We start with a normal caption but are
  428.   // prepared to switch to a tiny caption...
  429.   //
  430.   Attr.Style = WS_OVERLAPPEDWINDOW & ~WS_VISIBLE;
  431.   EnableTinyCaption(44, FALSE);
  432.   TCEnabled = FALSE;
  433. }
  434.  
  435. void
  436. TDiagFrame::SetupWindow()
  437. {
  438.   TDecoratedFrame::SetupWindow();
  439.  
  440.   // Add to the system menu a menu-item which can be used to switch
  441.   // to a tiny-caption and back to normal:
  442.   //
  443.   TSystemMenu Menu(*this);
  444.   Menu.InsertMenu(SC_CLOSE, MF_BYCOMMAND|MF_CHECKED, SC_TOGGLE_SIZE,
  445.                   string(*GetModule(), IDS_DECORATED).c_str());
  446.   Menu.InsertMenu(SC_CLOSE, MF_BYCOMMAND|MF_SEPARATOR, -1, 0);
  447.  
  448.   // Restore the window to size it had at the last session:
  449.   //
  450.   char b[20];
  451.   if (GetPrivateProfileString(DIAG_CLS, DIAG_RECT, "", b, sizeof(b), OWL_INI)) {
  452.     sscanf(b, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
  453.     MoveWindow(rect, TRUE);
  454.   }
  455. }
  456.  
  457. void
  458. TDiagFrame::CleanupWindow()
  459. {
  460.   TDecoratedFrame::CleanupWindow();
  461.  
  462.   // Remember the size for the next time:
  463.   //
  464.   char b[20];
  465.   wsprintf(b, "%d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom);
  466.   WritePrivateProfileString(DIAG_CLS, DIAG_RECT, b, OWL_INI);
  467. }
  468.  
  469. void
  470. TDiagFrame::EvSize(UINT type, TSize &size)
  471. {
  472.   TDecoratedFrame::EvSize(type, size);
  473.  
  474.   // We remember the size of the frame window whenever it changes.
  475.   // Note however that we are only interested by 'normal' resizes,
  476.   // not resizes dued to maximized or minimized operations.
  477.   //
  478.   if (type == SIZE_RESTORED)
  479.     rect = GetWindowRect();
  480. }
  481.  
  482. LRESULT
  483. TDiagFrame::EvCommand(UINT id, HWND hWndCtl, UINT notifyCode)
  484. {
  485.   LRESULT er;
  486.  
  487.   // Give a chance to the TTinyCaption mixin to completely process the
  488.   // events it knows about:
  489.   //
  490.   if (TTinyCaption::DoCommand(id, hWndCtl, notifyCode, er) == esComplete)
  491.     return er;
  492.  
  493.   // Otherwise, forward to the frame window
  494.   //
  495.   return TFrameWindow::EvCommand(id, hWndCtl, notifyCode);
  496. }
  497.  
  498. void
  499. TDiagFrame::EvSysCommand(UINT id,TPoint& pt)
  500. {
  501.   switch (id) {
  502.     case SC_TOGGLE_SIZE:
  503.       // Here we are: the user selected the toggle menu-item
  504.       // from the system menu
  505.       CmToggleSize();
  506.       break;
  507.     default:
  508.       if (TTinyCaption::DoSysCommand(id, pt) == esPartial)
  509.         TFrameWindow::EvSysCommand(id, pt);
  510.   }
  511. }
  512.  
  513. void
  514. TDiagFrame::CmToggleSize()
  515. {
  516.   TCEnabled ^= TRUE;
  517.  
  518.   // Toggle the menu-item in the system menu
  519.   //
  520.   TSystemMenu Menu(*this);
  521.   UINT bCheck = TCEnabled ? MF_UNCHECKED:MF_CHECKED;
  522.   Menu.CheckMenuItem(SC_TOGGLE_SIZE, MF_BYCOMMAND | bCheck);
  523.  
  524.   // Toggle the toolbar visibility
  525.   //
  526.   TDecoratedFrame::EvCommand(CM_TOOLBAR, 0, 0);
  527.  
  528.   // Toggle the status bar visibility
  529.   //
  530.   TDecoratedFrame::EvCommand(CM_STATUSBAR, 0, 0);
  531.   
  532.   // Notify the client that we want to toggle the size
  533.   //
  534.   TDiagClient *pClient = TYPESAFE_DOWNCAST(ClientWnd, TDiagClient);
  535.   CHECK(pClient != 0);
  536.   pClient->SetSize(TCEnabled ? TDiagClient::smallSize:TDiagClient::bigSize);
  537.  
  538.   // Force a calcsize by simulating a window resize
  539.   //
  540.   TRect rect = GetWindowRect();
  541.   rect.right--;
  542.   MoveWindow(rect, FALSE);
  543.   rect.right++;
  544.   MoveWindow(rect, TRUE);
  545. }
  546.  
  547.  
  548. //
  549. //  Entry point
  550. //
  551.  
  552. int
  553. OwlMain(int /*argc*/, char* /*argv*/ [])
  554. {
  555.   ::SetMessageQueue(32);
  556.   return TOwlDiagApp().Run();
  557. }
  558.