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

  1. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2.  
  3.   textview.cpp
  4.   Created: 10/24/95
  5.   Copyright (c) 1995, Borland International
  6.   $Revision:   1.16  $
  7.  
  8. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  9.  
  10. #ifndef __AOEXPCH_H
  11.   #include "aoexpch.h"
  12. #endif
  13. #pragma hdrstop
  14. #include <ideaddon\isbar.h>
  15. #include <windowsx.h>
  16.  
  17. #include "textview.h"
  18.  
  19. /******************************************************************************
  20. *
  21. *
  22. * TextViewClient
  23. *
  24. *
  25. ******************************************************************************/
  26.  struct IViewClientFile : IViewClient, IViewFile {};
  27.  
  28. class TextViewClient : public IUnknownImp<IViewClientFile> {
  29. public:
  30.   TextViewClient();
  31.   ~TextViewClient();
  32.  
  33.   //IUnknown members
  34.   STDMETHODIMP QueryInterface (THIS_ REFIID, LPVOID FAR *);
  35.  
  36.   virtual HWND  GetHwnd();
  37.   virtual long  GetRestoreDataLen();
  38.   virtual void* GetRestoreData();
  39.   virtual BOOL  CanClose();
  40.  
  41.   virtual unsigned CommandSupported( IPolyString* );
  42.   virtual void ExecuteCommand( IPolyString* );
  43.   virtual void PropertyChangeNotify();
  44.   HWND    Create(IViewParentWnd* wndServer, void * restoreData);
  45.  
  46.   //
  47.   // IViewFile
  48.   //
  49.   virtual BOOL IsDirty();
  50.   virtual BOOL Save();
  51.   virtual BOOL SaveAs(IPolyString* FileName);
  52.   virtual BOOL Close();
  53.   virtual BOOL Print(BOOL noDialogs);
  54.  
  55. protected:
  56.   HWND            d_hwnd;
  57.   IViewParentWnd* d_viewParent;
  58.   char d_textBuf[256];
  59. };
  60.  
  61. TextViewClient::TextViewClient()
  62.               : IUnknownImp<IViewClientFile>(IID_IUnknown) {
  63.   d_hwnd = 0;
  64.   d_viewParent = 0;
  65. };
  66.  
  67. TextViewClient::~TextViewClient() {
  68.   if (d_viewParent) {
  69.     d_viewParent->Release();
  70.   }
  71.   if ( IsWindow(d_hwnd) )
  72.     DestroyWindow(d_hwnd);
  73. };
  74.  
  75.  
  76. STDMETHODIMP
  77. TextViewClient::QueryInterface (REFIID riid, LPVOID FAR* ppobj)
  78. {
  79.   if ((riid == IID_IUnknown) || (riid == IID_Addon_IViewClient) ) {
  80.     IViewClient* vc = this;
  81.     *ppobj = vc;
  82.   } else if (riid == IID_Addon_IViewFile) {
  83.     IViewFile* vf = this;
  84.     *ppobj = vf;
  85.   } else {
  86.     *ppobj = NULL;
  87.     return ResultFromScode(E_NOINTERFACE);
  88.   }
  89.   AddRef();
  90.   return NOERROR;
  91. }
  92.  
  93. static WNDPROC OldViewParentWndProc;
  94.  
  95. LONG APIENTRY ViewParentWndProc(
  96.   HWND hWnd,                /* window handle                   */
  97.   UINT message,            /* type of message                */
  98.   UINT wParam,              /* additional information         */
  99.   LONG lParam)              /* additional information         */
  100. {
  101.   if (message == WM_COMMAND) {
  102.     WORD wNotifyCode = HIWORD(wParam);
  103.     //
  104.     // the edit control is modified, notify parent about the new modified state
  105.     //
  106.     if ( wNotifyCode == EN_CHANGE) {
  107.       HWND hwndChild = GetWindow(hWnd, GW_CHILD);
  108.       IViewParentWnd* wndServer =
  109.             (IViewParentWnd*)GetWindowLong(hwndChild, GWL_USERDATA);
  110.       if ( wndServer ) {
  111.         wndServer->UpdateModifyState();
  112.       }
  113.     }
  114.   };
  115.   return OldViewParentWndProc(hWnd, message, wParam, lParam);
  116. };
  117.  
  118. HWND TextViewClient::Create(IViewParentWnd* wndServer, void * restoreData) {
  119.  
  120.   d_viewParent = wndServer;
  121.   HWND parentHwnd = wndServer->GetHwnd();
  122.  
  123.   //
  124.   // just create a window edit control
  125.   //
  126.   d_hwnd = CreateWindowEx(  WS_EX_CLIENTEDGE,      /* extended styles            */
  127.                             "EDIT",                /* class name                  */
  128.                             "",                    /* window name                */
  129.                             WS_CHILDWINDOW |        /* overlapped window           */
  130.                             ES_MULTILINE|
  131.                             WS_VISIBLE  |
  132.                             WS_HSCROLL |            /* horizontal scroll bar       */
  133.                             WS_VSCROLL,            /* vertical scroll bar        */
  134.                             CW_USEDEFAULT,          /* default horizontal position */
  135.                             CW_USEDEFAULT,          /* default vertical position   */
  136.                             CW_USEDEFAULT,          /* default width               */
  137.                             CW_USEDEFAULT,          /* default height             */
  138.                             (HWND) parentHwnd,      /* parent or owner window     */
  139.                             (HMENU) NULL,          /* class menu used            */
  140.                             NULL/*hinstance*/,      /* instance handle             */
  141.                             NULL);                  /* no window creation data     */
  142.   //
  143.   // limit the number of characters allowed
  144.   //
  145.   Edit_LimitText(d_hwnd, sizeof(d_textBuf) - 1);
  146.  
  147.   //
  148.   // initialize the data with the data from desktop file
  149.   //
  150.   if (restoreData)
  151.     SetWindowText(d_hwnd, (char*)restoreData);
  152.  
  153.   Edit_SetModify(d_hwnd, FALSE);
  154.   SetWindowLong(d_hwnd, GWL_USERDATA, (LONG)wndServer);
  155.   OldViewParentWndProc = SubclassWindow(parentHwnd, ViewParentWndProc);
  156.   return d_hwnd;
  157.  
  158. };
  159.  
  160. HWND TextViewClient::GetHwnd()
  161. {
  162.   return d_hwnd;
  163. };
  164.  
  165. long  TextViewClient::GetRestoreDataLen()
  166. {
  167.   return GetWindowTextLength(d_hwnd) + /* plus \0 */1; 
  168. };
  169.  
  170. //
  171. // Save the data user entered to the destop file
  172. //
  173. void* TextViewClient::GetRestoreData()
  174. {
  175.  
  176.   //
  177.   // This is kind of the problem of the interface.  Client has to make sure the
  178.   //  pointer returned remain valid.
  179.   //
  180.   GetWindowText(
  181.                 d_hwnd,        // handle of window or control with text
  182.                 d_textBuf,          // address of buffer for text
  183.                 sizeof(d_textBuf)  // maximum number of characters to copy
  184.                ); 
  185.   return d_textBuf;
  186. };
  187.  
  188. BOOL  TextViewClient::CanClose()
  189. {
  190.   int l = GetWindowTextLength(d_hwnd);
  191.   if (l == 0) {
  192.     MessageBox(d_hwnd, "Window can not be closed. Please enter some text.","Addon Text View", MB_OK);
  193.     return 0;
  194.   };
  195.   return 1;
  196. };
  197.  
  198. unsigned TextViewClient::CommandSupported(IPolyString* cmdStr)
  199. {
  200.   char cmd[256];
  201.   strcpy(cmd, cmdStr->GetCstr());
  202.   cmdStr->Release();
  203.  
  204.   DWORD dw = Edit_GetSel(d_hwnd);
  205.   WORD start = LOWORD(dw);
  206.   WORD end = HIWORD(dw);
  207.  
  208.   if (stricmp(cmd, CMD_SELECTALL) == 0) {
  209.     //
  210.     // can not select all if there is no text
  211.     //
  212.     if (GetWindowTextLength(d_hwnd) == 0) {
  213.       return CMD_UNAVAILABLE;
  214.     }
  215.     return CMD_AVAILABLE;
  216.   } else if (stricmp(cmd, CMD_CUT) == 0) {
  217.     if ( start == end) {
  218.       return CMD_UNAVAILABLE;
  219.     }
  220.     return CMD_AVAILABLE;
  221.   } else if (stricmp(cmd, CMD_CLEAR) == 0) {
  222.     if ( start == end) {
  223.       return CMD_UNAVAILABLE;
  224.     }
  225.     return CMD_AVAILABLE;
  226.   } else if (stricmp(cmd, CMD_COPY) == 0) {
  227.     if ( start == end) {
  228.       return CMD_UNAVAILABLE;
  229.     }
  230.     return CMD_AVAILABLE;
  231.   } else if (stricmp(cmd, CMD_PASTE) == 0) {
  232.     //
  233.     // always available
  234.     //
  235.     return CMD_AVAILABLE;
  236.   } else if (stricmp(cmd, CMD_UNDO) == 0) {
  237.     if ( !Edit_CanUndo(d_hwnd) ) {
  238.       return CMD_UNAVAILABLE;
  239.     }
  240.     return CMD_AVAILABLE;
  241.   } else if (stricmp(cmd, CMD_FIND) == 0) {
  242.     //
  243.     // always available
  244.     //
  245.     return CMD_AVAILABLE;
  246.   } else if (stricmp(cmd, CMD_REPLACE) == 0) {
  247.     //
  248.     // always available
  249.     //
  250.     return CMD_AVAILABLE;
  251.   } else if (stricmp(cmd, CMD_SEARCHAGAIN) == 0) {
  252.     //
  253.     // always available
  254.     //
  255.     return CMD_AVAILABLE;
  256.   } else if (stricmp(cmd, CMD_CLOSE) == 0) {
  257.     //
  258.     // always available
  259.     //
  260.     return CMD_AVAILABLE;
  261.   } else if (stricmp(cmd, CMD_SAVE) == 0) {
  262.     //
  263.     // always available
  264.     //
  265.     return CMD_AVAILABLE;
  266.   } else if (stricmp(cmd, CMD_SAVEAS) == 0) {
  267.     //
  268.     // always available
  269.     //
  270.     return CMD_AVAILABLE;
  271.   } else if (stricmp(cmd, CMD_PRINT) == 0) {
  272.     //
  273.     // always available
  274.     //
  275.     return CMD_AVAILABLE;
  276.   }
  277.   return CMD_UNKNOWN;
  278. }
  279.  
  280.  
  281. void TextViewClient::ExecuteCommand(IPolyString* cmdStr)
  282. {
  283.  
  284.   char cmd[256];
  285.   strcpy(cmd, cmdStr->GetCstr());
  286.  
  287.   //
  288.   // Let's test status bar here
  289.   //
  290.   IStatusBar* statusBar = (IStatusBar*)GetInterface(IID_Addon_IStatusBar);
  291.   cmdStr->AddRef();
  292.   statusBar->Display(cmdStr);
  293.   statusBar->Release();
  294.  
  295.   cmdStr->Release();
  296.  
  297.   if (stricmp(cmd, CMD_SELECTALL) == 0) {
  298.     //
  299.     // select everything
  300.     //
  301.     Edit_SetSel(d_hwnd, 0, -1);
  302.   } else if (stricmp(cmd, CMD_CUT) == 0) {
  303.     SendMessage(d_hwnd, WM_CUT, 0, 0L);
  304.   } else if (stricmp(cmd, CMD_CLEAR) == 0) {
  305.     SendMessage(d_hwnd, WM_CLEAR, 0, 0L);
  306.   } else if (stricmp(cmd, CMD_COPY) == 0) {
  307.     SendMessage(d_hwnd, WM_COPY, 0, 0L);
  308.   } else if (stricmp(cmd, CMD_PASTE) == 0) {
  309.     SendMessage(d_hwnd, WM_PASTE, 0, 0L);
  310.   } else if (stricmp(cmd, CMD_UNDO) == 0) {
  311.     SendMessage(d_hwnd, WM_UNDO, 0, 0L);
  312.   }
  313. }
  314.  
  315. void TextViewClient::PropertyChangeNotify() {
  316. };
  317.  
  318. BOOL TextViewClient::IsDirty() {
  319.   return Edit_GetModify(d_hwnd);
  320. };
  321.  
  322. //
  323. // We are not doing any real file i/o here.
  324. //
  325. BOOL TextViewClient::Save() {
  326.   Edit_SetModify(d_hwnd, FALSE);
  327.   //
  328.   // notify parent that our dirty state has changed
  329.   //
  330.   d_viewParent->UpdateModifyState();
  331.   return TRUE;
  332. };
  333.  
  334. BOOL TextViewClient::SaveAs(IPolyString* FileName) {
  335.   if (FileName) {
  336.     if (FileName->GetCstr() && *(FileName->GetCstr()) == '\0') {
  337.       //
  338.       // no real file name, release it
  339.       //
  340.       FileName->Release();
  341.       FileName = 0;
  342.     }
  343.   }
  344.  
  345.   if (!FileName) {
  346.     //
  347.     // We don't have a file name yet. Display SaveAs dialog 
  348.     //  and prompt for file name
  349.     //
  350.  
  351.     //
  352.     // make up a dummy file name. one would display FileSaveAs dialog
  353.     // to get the filename from user 
  354.     //
  355.     FileName = MakePolyString("aFileName");
  356.   }
  357.   //
  358.   // save file code here
  359.   //
  360.  
  361.   FileName->Release();
  362.   //
  363.   // notify parent that our dirty state has changed
  364.   //
  365.   Edit_SetModify(d_hwnd, FALSE);
  366.   d_viewParent->UpdateModifyState();
  367.   return TRUE;
  368. };
  369.  
  370. BOOL TextViewClient::Close() {
  371.   return TRUE;
  372. };
  373.  
  374. BOOL TextViewClient::Print(BOOL /*noDialogs*/) {
  375.   return TRUE;
  376. }
  377.  
  378. /******************************************************************************
  379. *
  380. *
  381. * TextViewFactory
  382. *
  383. *
  384. ******************************************************************************/
  385.  
  386. TextViewFactory::TextViewFactory() {
  387.   m_RefCount = 1;
  388. };
  389.  
  390. STDMETHODIMP
  391. TextViewFactory::QueryInterface (REFIID riid, LPVOID FAR* ppobj)
  392. {
  393.   if ((riid == IID_IUnknown))
  394.   {
  395.     *ppobj = (LPVOID)this;
  396.     AddRef();
  397.     return NOERROR;
  398.   }
  399.  
  400.   *ppobj = NULL;
  401.   return ResultFromScode(E_NOINTERFACE);
  402. }
  403.  
  404. IViewClient* TextViewFactory::CreateView(IViewParentWnd* wndServer, void * restoreData) {
  405.   TextViewClient* viewClient = new TextViewClient;
  406.   viewClient->Create(wndServer, restoreData);
  407.   return viewClient;
  408. };
  409.  
  410. void TextViewFactory::InitializeProperty(IViewType* viewType) {
  411.  
  412.   viewType->Release();
  413. }
  414.  
  415. //.............................................................................
  416.