home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / DBWIN / DBWIN.C_ / DBWIN.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  14.4 KB  |  579 lines

  1. #include "dbwin.h"
  2.  
  3. // Max no. of lines allowed in edit control buffer
  4. // (this will hopefully keep us under the 64k buffer maximum)
  5. //
  6. #define CLINESMAX   500
  7.  
  8. // Globals
  9.  
  10. HINSTANCE   hinstDBWin = NULL;
  11.  
  12. char szDBWinClass[] = "DBWin";
  13.  
  14. HWND        hwndDBWin = NULL;
  15. HWND        hwndClient = NULL;
  16. HFONT       hfontClient = NULL;
  17. HACCEL      haccelDBWin = NULL;
  18.  
  19. BOOL        fTopmost = FALSE;       // Stay on top or not
  20.  
  21. BOOL DBWinInit(HINSTANCE hinst, HINSTANCE hinstPrev, int showCmd, LPSTR szCmdLine)
  22. {
  23.     WNDCLASS cls;
  24.     LOGFONT  lf;
  25.  
  26.     if (hinstPrev)
  27.     {
  28.         // Only one instance allowed.
  29.         //
  30.         // Find the first instance main window, and post a message
  31.         // to it to tell it to activate itself.
  32.         //
  33.         HWND hwnd = FindWindow(szDBWinClass, NULL);
  34.  
  35.         if (hwnd)
  36.         {
  37.             PostMessage(hwnd, WM_ACTIVATEFIRST, 0, 0L);
  38.             return FALSE;
  39.         }
  40.     }
  41.  
  42.     hinstDBWin = hinst;
  43.  
  44.     cls.hCursor        = LoadCursor(NULL, IDC_ARROW);
  45.     cls.hIcon          = LoadIcon(hinstDBWin, MAKEINTRESOURCE(IDR_MAINICON));
  46.     cls.lpszMenuName   = MAKEINTRESOURCE(IDR_MAINMENU);
  47.     cls.lpszClassName  = szDBWinClass;
  48.     cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  49.     cls.hInstance      = hinstDBWin;
  50.     cls.style          = CS_BYTEALIGNCLIENT;
  51.     cls.lpfnWndProc    = DBWinWndProc;
  52.     cls.cbWndExtra     = 0;
  53.     cls.cbClsExtra     = 0;
  54.  
  55.     if (!RegisterClass(&cls))
  56.         return FALSE;
  57.  
  58.     haccelDBWin = LoadAccelerators(hinstDBWin, MAKEINTRESOURCE(IDR_MAINACCEL));
  59.     if (!haccelDBWin)
  60.         return FALSE;
  61.  
  62.     if (!OutputInit())
  63.         return FALSE;
  64.  
  65.     // Create the main window
  66.  
  67.     hwndDBWin = CreateWindow(szDBWinClass,          // Class name
  68.                             "Debug Messages",       // Caption
  69.                             WS_OVERLAPPEDWINDOW,    // Style bits
  70.                             0, 0, 100, 100,
  71.                             (HWND)NULL,             // Parent window (no parent)
  72.                             (HMENU)NULL,            // use class menu
  73.                             (HINSTANCE)hinstDBWin,  // handle to window instance
  74.                             (LPSTR)NULL             // no params to pass on
  75.                            );
  76.     if (!hwndDBWin)
  77.         return FALSE;
  78.  
  79.     SetBufferNotify(hwndDBWin);
  80.  
  81.     hwndClient = CreateWindow("EDIT", NULL,
  82.             WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL |
  83.             ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE,
  84.             0, 0, 0, 0,
  85.             hwndDBWin, (HMENU)0, hinstDBWin, NULL);
  86.  
  87.     if (!hwndClient)
  88.         return FALSE;
  89.  
  90.     // Use the small icon title font
  91.     //
  92.     SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, FALSE);
  93.     hfontClient = CreateFontIndirect(&lf);
  94.     if (hfontClient)
  95.         SendMessage(hwndClient, WM_SETFONT, (WPARAM)(UINT)hfontClient, 1);
  96.  
  97.     ShowWindow(hwndClient, SW_SHOWNORMAL);
  98.  
  99.     ReadDBWinState(hwndDBWin);
  100.  
  101.     return TRUE;
  102. }
  103.  
  104. int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int showCmd)
  105. {
  106.     MSG msg;
  107.  
  108.     if (!DBWinInit(hinst, hinstPrev, showCmd, lpszCmdLine))
  109.         return FALSE;
  110.  
  111.     while (GetMessage(&msg, NULL, 0, 0)) 
  112.     {
  113.         if (!TranslateAccelerator(hwndDBWin, haccelDBWin, &msg))
  114.         {
  115.             TranslateMessage(&msg);
  116.             DispatchMessage(&msg);
  117.         }
  118.     }
  119.  
  120.     DBWinTerminate(FALSE);
  121.     return msg.wParam;
  122. }
  123.  
  124. void DBWinTerminate(BOOL fEndSession)
  125. {
  126.     // Write out the application state
  127.     //
  128.     WriteDBWinState(hwndDBWin);
  129.  
  130.     // Make sure our hook is unregistered...
  131.  
  132.     SetOutputMode(OMD_NONE);
  133.  
  134.     if (!fEndSession)
  135.     {
  136.         if (hwndDBWin)
  137.         {
  138.             DestroyWindow(hwndDBWin);
  139.             hwndDBWin = NULL;
  140.         }
  141.  
  142.         if (hfontClient)
  143.         {
  144.             DeleteObject(hfontClient);
  145.             hfontClient = NULL;
  146.         }
  147.     }
  148. }
  149.  
  150. LRESULT CALLBACK _export DBWinWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  151. {
  152.     switch (msg)
  153.     {
  154.     case WM_COMMAND:
  155.         DoCommand(hwnd, msg, wParam, lParam);
  156.         return 0L;
  157.  
  158.     case WM_CLOSE:
  159.         PostQuitMessage(0);
  160.         break;
  161.  
  162.     case WM_ENDSESSION:
  163.         DBWinTerminate(TRUE);
  164.         break;
  165.  
  166.     case WM_ACTIVATE:
  167.         if (wParam)
  168.             SetFocus(hwndClient);
  169.         break;
  170.  
  171.     case WM_SIZE:
  172.         /* Make sure the edit control always occupies the entire
  173.          * client area.
  174.          */
  175.         if (hwndClient)
  176.         {
  177.             RECT rc;
  178.  
  179.             GetClientRect(hwnd, &rc);
  180.             //
  181.             // Outset border
  182.             //
  183.             InflateRect(&rc, 1, 1);
  184.             MoveWindow(hwndClient, rc.top, rc.left, rc.right - rc.left, rc.bottom - rc.top, TRUE);
  185.         }
  186.         break;
  187.  
  188.     case WM_INITMENU:
  189.         DoInitMenu(hwnd);
  190.         break;
  191.  
  192.     case WM_BUFFERNOTEMPTY:
  193.         OnBufferNotEmpty();
  194.         return 0L;
  195.  
  196.     case WM_ACTIVATEFIRST:
  197.         // The user tried to run a second instance of this app.
  198.         // The second instance posted this message to us and exited.
  199.         //
  200.         // If we're iconic, restore ourself, otherwise just make
  201.         // ourself the active window.
  202.         //
  203.         if (IsIconic(hwnd))
  204.             ShowWindow(hwnd, SW_RESTORE);
  205.         else
  206.             SetActiveWindow(hwnd);
  207.         break;
  208.  
  209.     default:
  210.         return DefWindowProc(hwnd, msg, wParam, lParam);
  211.     }
  212.  
  213.     return 0L;
  214. }
  215.  
  216. void DoCommand(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  217. {
  218.     switch (wParam)
  219.     {
  220.     case CMD_HELPABOUT:
  221.         DoAbout(hwnd);
  222.         break;
  223.  
  224.     case CMD_FILEEXIT:
  225.         PostQuitMessage(0);
  226.         break;
  227.  
  228.     case CMD_EDITCOPY:
  229.         PostMessage(hwndClient, WM_COPY, 0, 0L);
  230.         break;
  231.  
  232.     case CMD_EDITCLEARBUFFER:
  233.         Edit_SetSel(hwndClient, 0, 32767);
  234.         Edit_ReplaceSel(hwndClient, "");
  235.         break;
  236.  
  237.     case CMD_EDITSELECTALL:
  238.         Edit_SetSel(hwndClient, 0, 32767);
  239.         break;
  240.  
  241.     case CMD_FILESAVEBUFFER:
  242.         SaveBuffer(hwnd);
  243.         break;
  244.  
  245.     case CMD_OPTIONSOUTWINDOW:
  246.     case CMD_OPTIONSOUTCOM1:
  247.     case CMD_OPTIONSOUTMONO:
  248.     case CMD_OPTIONSOUTNONE:
  249.         SetOutputMode(ModeFromCmd(wParam));
  250.         break;
  251.  
  252.     case CMD_OPTIONSTOPMOST:
  253.         SetTopmost(hwnd, !fTopmost);
  254.         break;
  255.  
  256.     case CMD_OPTIONSSETTINGS:
  257.         if (IsDebugSystem(hwnd))
  258.             DoDebugOptions(hwnd);
  259.         break;
  260.  
  261.     case CMD_FILESAVESETTINGS:
  262.         if (IsDebugSystem(hwnd))
  263.             DoSaveOptions(hwnd);
  264.         break;
  265.  
  266.     case CMD_OPTIONSALLOCBREAK:
  267.         if (IsDebugSystem(hwnd))
  268.             DoAllocBrk(hwnd);
  269.         break;
  270.     }
  271. }
  272.  
  273. BOOL IsDebugSystem(HWND hwnd)
  274. {
  275.     if (!GetSystemMetrics(SM_DEBUG))
  276.     {
  277.         MessageBox(hwnd,
  278.                 "This command requires the debugging Windows system binaries",
  279.                 NULL, MB_OK | MB_ICONSTOP);
  280.  
  281.         return FALSE;
  282.     }
  283.     return TRUE;
  284. }
  285.  
  286. void OnBufferNotEmpty(void)
  287. {
  288.     OUTBUFINFO obi;
  289.     int cLines;
  290.  
  291.     if (!GetOutputBufferInfo(&obi) || obi.cch == 0)
  292.         return;
  293.  
  294.     // First see if we will exceed our line maximum
  295.     //
  296.     cLines = Edit_GetLineCount(hwndClient) + obi.cLines;
  297.     if (cLines > CLINESMAX)
  298.     {
  299.         Edit_SetSel(hwndClient, 0, Edit_LineIndex(hwndClient, cLines - CLINESMAX));
  300.         Edit_ReplaceSel(hwndClient, "");
  301.     }
  302.  
  303.     // Append to the end of the buffer.
  304.     //
  305.     Edit_SetSel(hwndClient, 32767, 32767);
  306.     Edit_ReplaceSel(hwndClient, obi.lpch);
  307.     Edit_SetSel(hwndClient, 32767, 32767);
  308.  
  309.     // Clear the buffer
  310.     //
  311.     ResetBuffer();
  312. }
  313.  
  314. UINT CmdFromMode(UINT mode)
  315. {
  316.     static UINT mpModeCmd[] =
  317.     {
  318.         CMD_OPTIONSOUTNONE,     // OMD_NONE
  319.         CMD_OPTIONSOUTWINDOW,   // OMD_BUFFER
  320.         CMD_OPTIONSOUTCOM1,     // OMD_COM1
  321.         CMD_OPTIONSOUTCOM2,     // OMD_COM2
  322.         CMD_OPTIONSOUTMONO      // OMD_MONO
  323.     };
  324.  
  325.     return mpModeCmd[mode - OMD_NONE];
  326. }
  327.  
  328. UINT ModeFromCmd(UINT cmd)
  329. {
  330.     static UINT mpCmdMode[] =
  331.     {
  332.         OMD_BUFFER,     // CMD_OPTIONSOUTWINDOW
  333.         OMD_COM1,       // CMD_OPTIONSOUTCOM1
  334.         OMD_COM2,       // CMD_OPTIONSOUTCOM2
  335.         OMD_MONO,       // CMD_OPTIONSOUTMONO
  336.         OMD_NONE        // CMD_OPTIONSOUTNONE
  337.     };
  338.  
  339.     return mpCmdMode[cmd - CMD_OPTIONSOUTWINDOW];
  340. }
  341.  
  342. void SetTopmost(HWND hwnd, BOOL fTopmostT)
  343. {
  344.     fTopmost = fTopmostT;
  345.  
  346.     SetWindowPos(hwnd, (fTopmostT ? HWND_TOPMOST : HWND_NOTOPMOST),
  347.             0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
  348. }
  349.  
  350. void DoInitMenu(HWND hwnd)
  351. {
  352.     UINT mode;
  353.     UINT flagsOutput;
  354.     HMENU hmenu = GetMenu(hwnd);
  355.     UINT modeCur = GetOutputMode();
  356.  
  357.     flagsOutput = GetOutputFlags();
  358.  
  359.     for (mode = OMD_NONE; mode <= OMD_MONO; mode++)
  360.     {
  361.         CheckMenuItem(hmenu, CmdFromMode(mode),
  362.             ((modeCur == mode) ? MF_CHECKED : MF_UNCHECKED));
  363.     }
  364.  
  365.     EnableMenuItem(hmenu, CMD_OPTIONSOUTMONO,
  366.             ((flagsOutput & DBOF_HASMONO) ? MF_ENABLED : MF_GRAYED));
  367.  
  368.     EnableMenuItem(hmenu, CMD_OPTIONSOUTCOM1,
  369.             ((flagsOutput & DBOF_HASCOM1) ? MF_ENABLED : MF_GRAYED));
  370.  
  371.     EnableMenuItem(hmenu, CMD_OPTIONSOUTCOM2,
  372.             ((flagsOutput & DBOF_HASCOM2) ? MF_ENABLED : MF_GRAYED));
  373.  
  374.     EnableMenuItem(hmenu, CMD_FILESAVEBUFFER,
  375.             ((modeCur == OMD_BUFFER) ? MF_ENABLED : MF_GRAYED));
  376.  
  377.     CheckMenuItem(hmenu, CMD_OPTIONSTOPMOST,
  378.             (fTopmost ? MF_CHECKED : MF_UNCHECKED));
  379. }
  380.  
  381. int IntFromString(LPSTR FAR* lplpsz)
  382. {
  383.     LPSTR lpsz = *lplpsz;
  384.     int i = 0;
  385.     char ch;
  386.     BOOL fNeg;
  387.  
  388.     while (*lpsz == ' ')
  389.         lpsz++;
  390.  
  391.     fNeg = FALSE;
  392.     while (ch = *lpsz++)
  393.     {
  394.         if (ch == '-')
  395.         {
  396.             fNeg = !fNeg;
  397.             continue;
  398.         }
  399.  
  400.         if (ch < '0' || ch > '9')
  401.             break;
  402.         i = (i * 10) + (ch - '0');
  403.     }
  404.     *lplpsz = lpsz;
  405.  
  406.     return (fNeg ? -i : i);
  407. }
  408.  
  409. void ReadDBWinState(HWND hwndMain)
  410. {
  411.     WINDOWPLACEMENT wpl;
  412.     char ach[128];
  413.     LPSTR lpsz;
  414.     int cch;
  415.  
  416.     lpsz = ach;
  417.     cch = GetProfileString("DBWin", "State", "", ach, sizeof(ach));
  418.  
  419.     if (cch == 0 || IntFromString(&lpsz) != 12)
  420.     {
  421.         int cxScreen, cyScreen;
  422.         int x, y, cx, cy;
  423.  
  424.         // defaultly position window along right edge of screen
  425.         //
  426.         cxScreen = GetSystemMetrics(SM_CXSCREEN);
  427.         cyScreen = GetSystemMetrics(SM_CYSCREEN);
  428.  
  429.         cx = cxScreen / 2;
  430.         x = cxScreen - cx;
  431.         cy = cyScreen - GetSystemMetrics(SM_CYICONSPACING);
  432.         y = 0;
  433.  
  434.         wpl.length = sizeof(wpl);
  435.         GetWindowPlacement(hwndMain, &wpl);
  436.         wpl.rcNormalPosition.left = x;
  437.         wpl.rcNormalPosition.top = y;
  438.         wpl.rcNormalPosition.right = x + cx;
  439.         wpl.rcNormalPosition.bottom = y + cy;
  440.  
  441.         SetOutputMode(OMD_BUFFER);
  442.  
  443.         SetTopmost(hwndMain, FALSE);
  444.  
  445.         SetWindowPlacement(hwndMain, &wpl);
  446.         ShowWindow(hwndMain, SW_SHOW);
  447.     }
  448.     else
  449.     {
  450.         wpl.length = sizeof(wpl);
  451.         wpl.flags = (UINT)IntFromString(&lpsz);
  452.         wpl.showCmd = (UINT)IntFromString(&lpsz);
  453.         wpl.ptMinPosition.x = IntFromString(&lpsz);
  454.         wpl.ptMinPosition.y = IntFromString(&lpsz);
  455.         wpl.ptMaxPosition.x = IntFromString(&lpsz);
  456.         wpl.ptMaxPosition.y = IntFromString(&lpsz);
  457.         wpl.rcNormalPosition.left = IntFromString(&lpsz);
  458.         wpl.rcNormalPosition.top = IntFromString(&lpsz);
  459.         wpl.rcNormalPosition.right = IntFromString(&lpsz);
  460.         wpl.rcNormalPosition.bottom = IntFromString(&lpsz);
  461.  
  462.         SetOutputMode((UINT)IntFromString(&lpsz));
  463.  
  464.         SetTopmost(hwndMain, (BOOL)IntFromString(&lpsz));
  465.  
  466.         SetWindowPlacement(hwndMain, &wpl);
  467.     }
  468. }
  469.  
  470. void WriteDBWinState(HWND hwndMain)
  471. {
  472.     WINDOWPLACEMENT wpl;
  473.  
  474.     char ach[128];
  475.  
  476.     wpl.length = sizeof(wpl);
  477.     GetWindowPlacement(hwndMain, &wpl);
  478.  
  479.     wsprintf(ach, "%d %d %d %d %d %d %d %d %d %d %d %d %d",
  480.         12,
  481.         wpl.flags,
  482.         wpl.showCmd,
  483.         wpl.ptMinPosition.x,
  484.         wpl.ptMinPosition.y,
  485.         wpl.ptMaxPosition.x,
  486.         wpl.ptMaxPosition.y,
  487.         wpl.rcNormalPosition.left,
  488.         wpl.rcNormalPosition.top,
  489.         wpl.rcNormalPosition.right,
  490.         wpl.rcNormalPosition.bottom,
  491.         GetOutputMode(),
  492.         fTopmost);
  493.  
  494.     WriteProfileString("DBWin", "State", ach);
  495. }
  496.  
  497. BOOL SaveBuffer(HWND hwnd)
  498. {
  499.     char szFilename[256];
  500.     OPENFILENAME ofn;           /* passed to the File Open/save APIs */
  501.     BOOL fSuccess = FALSE;
  502.  
  503.     szFilename[0] = 0;
  504.     ofn.lStructSize = sizeof(OPENFILENAME);
  505.     ofn.hwndOwner = hwnd;
  506.     ofn.hInstance = hinstDBWin;
  507.     ofn.lpstrFilter = (LPSTR)"All\0*.*\0";
  508.     ofn.lpstrCustomFilter = NULL;
  509.     ofn.nMaxCustFilter = 0;
  510.     ofn.nFilterIndex = 1;
  511.     ofn.lpstrFile = (LPSTR)szFilename;
  512.     ofn.nMaxFile = sizeof(szFilename);
  513.     ofn.lpstrFileTitle = NULL;
  514.     ofn.nMaxFileTitle = 0;
  515.     ofn.lpstrInitialDir = NULL;
  516.     ofn.lpstrTitle = NULL;
  517.     ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  518.     ofn.nFileOffset = 0;
  519.     ofn.nFileExtension = 0;
  520.     ofn.lpstrDefExt = (LPSTR)"";
  521.     ofn.lCustData = 0L;
  522.     ofn.lpfnHook = NULL;
  523.     ofn.lpTemplateName = NULL;
  524.  
  525.     if (GetSaveFileName(&ofn))
  526.     {
  527.         OFSTRUCT of;
  528.         int cch;
  529.         char* pch;
  530.         HFILE hfile;
  531.         HLOCAL h;
  532.  
  533.         hfile = OpenFile(szFilename, &of, OF_CREATE | OF_WRITE);
  534.  
  535.         if (hfile != HFILE_ERROR)
  536.         {
  537.             h = Edit_GetHandle(hwndClient);
  538.             cch = Edit_GetTextLength(hwndClient);
  539.             pch = LocalLock(h);
  540.             if ((int)_lwrite(hfile, pch, cch) == cch)
  541.                 fSuccess = TRUE;
  542.  
  543.             LocalUnlock(h);
  544.             _lclose(hfile);
  545.         }
  546.         return fSuccess;
  547.     }
  548. }
  549.  
  550. void DoAbout(HWND hwnd)
  551. {
  552.     DLGPROC lpfndp;
  553.  
  554.     lpfndp = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, hinstDBWin);
  555.  
  556.     if (!lpfndp)
  557.         return;
  558.  
  559.     DialogBoxParam(hinstDBWin, MAKEINTRESOURCE(IDR_ABOUTDLG), hwnd, lpfndp, 0L);
  560.  
  561.     FreeProcInstance((FARPROC)lpfndp);
  562. }
  563.  
  564. BOOL CALLBACK _export AboutDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  565. {
  566.     switch (msg)
  567.     {
  568.     case WM_COMMAND:
  569.         if (wParam == CTL_OK || wParam == CTL_CANCEL)
  570.             EndDialog(hwndDlg, TRUE);
  571.         return TRUE;
  572.         break;
  573.  
  574.     case WM_INITDIALOG:
  575.         return TRUE;
  576.     }
  577.     return FALSE;
  578. }
  579.