home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLCMD.PAK / OWLCMD.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  7.9 KB  |  297 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1993, 1995 by Borland International, All Rights Reserved
  4. //
  5. // This program demonstrates the use of TFloatingFrame.  It uses
  6. // a class derived from TComboBox that catches the <RETURN> key in an
  7. // edit field and executes the command which was typed.  If the command
  8. // executed sucessfully it is stored in the combo box's list box for
  9. // future retrieval.
  10. //
  11. // Commands supported:
  12. //  DOS     Executes command.com
  13. //  DIR     Launches WINFILE
  14. //  CD x$   Changes default directory (CD\  CD \)
  15. //  EXIT    Closes OWLCMD
  16. //  x$:     Changes default drive (D:)
  17. //  x$      Executes command x$
  18. //
  19. //----------------------------------------------------------------------------
  20. #include <owl/pch.h>
  21. #include <owl/applicat.h>
  22. #include <owl/edit.h>
  23. #include <owl/combobox.h>
  24. #include <owl/floatfra.h>
  25. #include <services/dir.h>
  26. #include <stdio.h>
  27. #include "string.h"
  28.  
  29. const int EditWidth  = 300;  // Width of the combo box
  30. const int CmdBufSize = 256;  // Max command size
  31. const int IDC_COMBO  = 1;
  32.  
  33. // For diagnostics
  34. DIAG_DEFINE_GROUP(OwlCmd,1,0);
  35.  
  36. //
  37. // A Combo box is actually made up of three windows, an edit
  38. // window, a list box window, and a parent window.  If we need to trap
  39. // an event on the edit or list box window, normal OWL event handlers
  40. // won't work.  These event handlers would trap events to the parent
  41. // window.
  42. //
  43. // TComboEdit is hard wired to the control ID that MS uses for the edit
  44. // window. This allows us to trap events, like CR.
  45. //
  46.  
  47. const int IDC_COMBO_LIST = 0x3e8;  // Window ID for list box component
  48. const int IDC_COMBO_EDIT = 0x3e9;  // Window ID for edit field component
  49.  
  50. class TComboEdit : public TEdit {
  51.   public:
  52.     TComboEdit(TComboBox* parent, uint textLen) :
  53.       TEdit(parent, IDC_COMBO_EDIT, textLen)
  54.       {
  55.         Combo = parent;
  56.       }
  57.  
  58.   private:
  59.     // This is where we'll look for c/r and special keys
  60.     void EvChar(uint key, uint repeatCount, uint flags);
  61.  
  62.     void ExecuteCmd(char* cmd);
  63.  
  64.     // We could also get Parent from TWindow and downcast it
  65.     TComboBox* Combo;
  66.  
  67.     char EditBuf[CmdBufSize];
  68.     char CmdBuf[CmdBufSize];
  69.  
  70.   DECLARE_RESPONSE_TABLE(TComboEdit);
  71. };
  72.  
  73. DEFINE_RESPONSE_TABLE1(TComboEdit,TEdit)
  74.   EV_WM_CHAR,
  75. END_RESPONSE_TABLE;
  76.  
  77. //
  78. // This is where we look for the <ENTER> key and execute commands
  79. //
  80. void
  81. TComboEdit::EvChar(uint key, uint /*repeatCount*/, uint /*flags*/)
  82. {
  83.   char*    ptr;
  84.   int      result;
  85.   TWindow* fw;
  86.  
  87.   if (key == VK_RETURN) {
  88.  
  89.     // Get Line into local buffer for parsing
  90.     //
  91.     GetText(EditBuf, sizeof(EditBuf));
  92.     if (!EditBuf[0]) // Ignore empty strings
  93.       return;
  94.  
  95.     strupr(EditBuf);
  96.  
  97.     // Brain dead parser
  98.     //
  99.     if (strcmp(EditBuf, "DIR") == 0) {
  100.       sprintf(CmdBuf,"winfile");
  101.       ExecuteCmd(CmdBuf);
  102.       return;
  103.     }
  104.     else if (strcmp(EditBuf,"DOS") == 0) {
  105.       sprintf(CmdBuf,"COMMAND.COM");
  106.       ExecuteCmd(CmdBuf);
  107.       return;
  108.     }
  109.     else if (strcmp(EditBuf,"EXIT") == 0) {
  110.       //Quit
  111.       PostQuitMessage(0);
  112.       return;
  113.     }
  114.     else if (strncmp(EditBuf,"CD",2) == 0 && strlen(EditBuf) > 2 ) {
  115.       if (EditBuf[2] == '\\')
  116.         result = chdir(EditBuf+2);
  117.       else if (EditBuf[2] == ' ') {
  118.         char* p = EditBuf+3;
  119.         for (; *p && *p == ' '; p++)
  120.           ;
  121.         result = chdir(p); // Point past space
  122.       }
  123.       else {
  124.         // Must be a program name starting with "cd"
  125.         //
  126.         ExecuteCmd(EditBuf);
  127.         return;
  128.       }
  129.       if (result) {
  130.         ptr = "Invalid directory";
  131.         MessageBox(ptr,"OWLCMD",MB_OK);
  132.         return;
  133.       }
  134.       else {
  135.         ExecuteCmd(0); //Just store result and clear edit field
  136.         ptr = getcwd(EditBuf,sizeof(EditBuf));
  137.         if (ptr) {
  138.           fw = GetApplication()->GetMainWindow();
  139.           fw->SetCaption(ptr);
  140.           fw->SetWindowPos(0, TRect(), SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
  141.         }
  142.         return;
  143.       }
  144.     }
  145.     else if (isalpha(EditBuf[0]) && EditBuf[1] == ':' && EditBuf[2] == 0) {
  146.       // Set drive
  147.       //
  148.       setdisk(toupper(EditBuf[0])-'A');
  149.       ptr = getcwd(EditBuf,sizeof(EditBuf));
  150.       if (ptr){
  151.         ExecuteCmd(0); // Store and clear
  152.         fw = GetApplication()->GetMainWindow();
  153.         fw->SetCaption(ptr);
  154.         fw->SetWindowPos(0, TRect(), SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
  155.       }
  156.     }
  157.     else {
  158.       ExecuteCmd(EditBuf);
  159.       return;
  160.     }
  161.   }
  162.   else
  163.     DefaultProcessing();
  164. }
  165.  
  166. void
  167. TComboEdit::ExecuteCmd(char* cmd)
  168. {
  169.   if (cmd) {
  170.     int result = WinExec(cmd, SW_SHOWNORMAL);
  171.     switch (result) {
  172.       case 0:  cmd = "Out of memory"; break;
  173.       case 2:  cmd = "File not found"; break;
  174.       case 3:  cmd = "Path not found"; break;
  175.       default: cmd = "Error in WinExec"; break;
  176.     }
  177.     if (result <= 32 ) {
  178.       MessageBox(cmd, "OWLCMD", MB_OK);
  179.       return;
  180.     }
  181.   }
  182.  
  183.   // If we got here, then command was sucessful
  184.   // Store command in pick list buffer, & clear edit control
  185.   //
  186.   Combo->InsertString(EditBuf,0);
  187.   Clear();
  188. }
  189.  
  190. //------------------------------------------------------------------------
  191.  
  192. class TLineEdit : public TComboBox {
  193.   public:
  194.     TLineEdit(TWindow* p,int w, int h);
  195.  
  196.     TComboEdit* Ed;
  197. };
  198.  
  199. TLineEdit::TLineEdit(TWindow* p, int w, int h)
  200. :
  201. //  TComboBox(p, IDC_COMBO, 0, 0, w, h, CBS_DROPDOWN, CmdBufSize-1)
  202.   TComboBox(p, IDC_COMBO, -1, -1, w, h, CBS_DROPDOWN, CmdBufSize-1)
  203. {
  204.   Ed = new TComboEdit(this, CmdBufSize-1);
  205.  
  206.   // We don't want a sorted list
  207.   //
  208.   Attr.Style &= ~CBS_SORT;
  209.  
  210. #if defined(BI_PLAT_WIN32)  
  211.   Attr.ExStyle &= ~WS_EX_CLIENTEDGE;  // DOnt want 3d sunken inside edge
  212. #endif
  213. }
  214.  
  215. //------------------------------------------------------------------------
  216.  
  217. class TMyFrame : public TFloatingFrame {
  218.   public:
  219.     TMyFrame(TWindow* client, char* title);
  220.  
  221.   private:
  222.     void    SetupWindow();
  223.  
  224.     TLineEdit* Cmd;
  225.  
  226.   DECLARE_RESPONSE_TABLE(TMyFrame);
  227. };
  228.  
  229. DEFINE_RESPONSE_TABLE1(TMyFrame, TFloatingFrame)
  230. END_RESPONSE_TABLE;
  231.  
  232. TMyFrame::TMyFrame(TWindow* client, char* title)
  233. :
  234.   TFloatingFrame(0, title, client)
  235. {
  236.   // We can set our own attributes, but must be before EnableTiny...
  237.   //
  238.   Attr.Style = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX;
  239.  
  240. #if defined(BI_PLAT_WIN32)         
  241.   Attr.ExStyle |= WS_EX_WINDOWEDGE;
  242. #endif
  243.  
  244.   // Or we can be specific, even make it BIGGER if we want
  245.   // If we set the option CloseBox flag to true, then clicking the box
  246.   // will close the window instead of displaying the system menu
  247.   //
  248.   EnableTinyCaption(58, false);
  249.  
  250.   // Create our combo box and size it for an edit line and 5 text items
  251.   // What's the correct way to get the height of an edit control?
  252.   //
  253.   int lineH = GetSystemMetrics(SM_CYCAPTION)+2; // 1pixel top & bottom border
  254.   Cmd = new TLineEdit(this, EditWidth, lineH*6);
  255.   Attr.X = (GetSystemMetrics(SM_CXSCREEN) - EditWidth)/2;
  256.   Attr.Y = (GetSystemMetrics(SM_CYSCREEN) - lineH*6)/2;
  257.   Attr.W = EditWidth;
  258.   Attr.H = 0;  // Resize ourselves later, when we know the actual size
  259. }
  260.  
  261. void
  262. TMyFrame::SetupWindow()
  263. {
  264.   TFloatingFrame::SetupWindow();
  265.  
  266.   // Resize window to actual combo box size
  267.   //
  268.   TRect cr = Cmd->GetWindowRect();
  269.   TRect newRect = GetWindowRect();
  270.   newRect.bottom = newRect.top + CaptionHeight + cr.Height() + 1;
  271. //  newRect.right += 2;
  272. //  newRect.bottom += 2;
  273.   MoveWindow(newRect, true);
  274.  
  275.   char buf[MAXDIR+1];
  276.   if (getcwd(buf, sizeof(buf))) {
  277. //    strlwr(buf);
  278.     SetCaption(buf);
  279.   }
  280. }
  281.  
  282. //------------------------------------------------------------------------
  283.  
  284. class TOwlCmd : public TApplication {
  285.   public:
  286.     TOwlCmd() : TApplication("Owl Command") {}
  287.  
  288.   protected:
  289.     void InitMainWindow() {MainWindow = new TMyFrame(0,"OwlCmd");}
  290. };
  291.  
  292. int
  293. OwlMain(int /*argc*/, char* /*argv*/ [])
  294. {
  295.   return TOwlCmd().Run();
  296. }
  297.