home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / superpad / padview.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  18KB  |  641 lines

  1. // padview.cpp : implementation of the CPadView class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "superpad.h"
  15. #include "padview.h"
  16. #include "paditem.h"
  17. #include "linkitem.h"
  18. #include "tabstop.h"
  19. #include <afxpriv.h>
  20. #include <stdlib.h>
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CPadView
  29.  
  30. IMPLEMENT_DYNCREATE(CPadView, CEditView)
  31.  
  32. BEGIN_MESSAGE_MAP(CPadView, CEditView)
  33.     //{{AFX_MSG_MAP(CPadView)
  34.     ON_WM_CREATE()
  35.     ON_COMMAND(ID_CHOOSE_FONT, OnChooseFont)
  36.     ON_COMMAND(ID_WORD_WRAP, OnWordWrap)
  37.     ON_UPDATE_COMMAND_UI(ID_WORD_WRAP, OnUpdateWordWrap)
  38.     ON_WM_RBUTTONDOWN()
  39.     ON_COMMAND(ID_CHOOSE_PRINT_FONT, OnChoosePrintFont)
  40.     ON_COMMAND(ID_MIRROR_DISPLAY_FONT, OnMirrorDisplayFont)
  41.     ON_UPDATE_COMMAND_UI(ID_MIRROR_DISPLAY_FONT, OnUpdateMirrorDisplayFont)
  42.     ON_UPDATE_COMMAND_UI(ID_CHOOSE_PRINT_FONT, OnUpdateChoosePrintFont)
  43.     ON_WM_SIZE()
  44.     ON_CONTROL_REFLECT(EN_CHANGE, OnEditChange)
  45.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  46.     ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  47.     ON_WM_TIMER()
  48.     //}}AFX_MSG_MAP
  49.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  50.     ON_COMMAND(ID_SET_TABSTOPS, OnSetTabStops)
  51. END_MESSAGE_MAP()
  52.  
  53. UINT CPadView::m_nDefTabStops;
  54. UINT CPadView::m_nDefTabStopsOld;
  55. BOOL CPadView::m_bDefWordWrap;
  56. BOOL CPadView::m_bDefWordWrapOld;
  57. LOGFONT NEAR CPadView::m_lfDefFont;
  58. LOGFONT NEAR CPadView::m_lfDefFontOld;
  59. LOGFONT NEAR CPadView::m_lfDefPrintFont;
  60. LOGFONT NEAR CPadView::m_lfDefPrintFontOld;
  61.  
  62. /////////////////////////////////////////////////////////////////////////////
  63. // Static initialization/termination
  64.  
  65. static TCHAR BASED_CODE szSettings[] = _T("Settings");
  66. static TCHAR BASED_CODE szTabStops[] = _T("TabStops");
  67. static TCHAR BASED_CODE szFont[] = _T("Font");
  68. static TCHAR BASED_CODE szPrintFont[] = _T("PrintFont");
  69. static TCHAR BASED_CODE szHeight[] = _T("Height");
  70. static TCHAR BASED_CODE szWeight[] = _T("Weight");
  71. static TCHAR BASED_CODE szItalic[] = _T("Italic");
  72. static TCHAR BASED_CODE szUnderline[] = _T("Underline");
  73. static TCHAR BASED_CODE szPitchAndFamily[] = _T("PitchAndFamily");
  74. static TCHAR BASED_CODE szCharSet[] = _T("CharSet");
  75. static TCHAR BASED_CODE szFaceName[] = _T("FaceName");
  76. static TCHAR BASED_CODE szSystem[] = _T("System");
  77. static TCHAR BASED_CODE szWordWrap[] = _T("WordWrap");
  78.  
  79. static void GetProfileFont(LPCTSTR szSec, LOGFONT* plf)
  80. {
  81.     CWinApp* pApp = AfxGetApp();
  82.     plf->lfHeight = pApp->GetProfileInt(szSec, szHeight, 0);
  83.     if (plf->lfHeight != 0)
  84.     {
  85.         plf->lfWeight = pApp->GetProfileInt(szSec, szWeight, 0);
  86.         plf->lfItalic = (BYTE)pApp->GetProfileInt(szSec, szItalic, 0);
  87.         plf->lfUnderline = (BYTE)pApp->GetProfileInt(szSec, szUnderline, 0);
  88.         plf->lfPitchAndFamily = (BYTE)pApp->GetProfileInt(szSec, szPitchAndFamily, 0);
  89.         plf->lfCharSet = (BYTE)pApp->GetProfileInt(szSec, szCharSet, DEFAULT_CHARSET);
  90.         CString strFont = pApp->GetProfileString(szSec, szFaceName, szSystem);
  91.         lstrcpyn((TCHAR*)plf->lfFaceName, strFont, sizeof plf->lfFaceName);
  92.         plf->lfFaceName[sizeof plf->lfFaceName-1] = 0;
  93.     }
  94. }
  95.  
  96. static void WriteProfileFont(LPCTSTR szSec, const LOGFONT* plf, LOGFONT* plfOld)
  97. {
  98.     CWinApp* pApp = AfxGetApp();
  99.  
  100.     if (plf->lfHeight != plfOld->lfHeight)
  101.         pApp->WriteProfileInt(szSec, szHeight, plf->lfHeight);
  102.     if (plf->lfHeight != 0)
  103.     {
  104.         if (plf->lfHeight != plfOld->lfHeight)
  105.             pApp->WriteProfileInt(szSec, szHeight, plf->lfHeight);
  106.         if (plf->lfWeight != plfOld->lfWeight)
  107.             pApp->WriteProfileInt(szSec, szWeight, plf->lfWeight);
  108.         if (plf->lfItalic != plfOld->lfItalic)
  109.             pApp->WriteProfileInt(szSec, szItalic, plf->lfItalic);
  110.         if (plf->lfUnderline != plfOld->lfUnderline)
  111.             pApp->WriteProfileInt(szSec, szUnderline, plf->lfUnderline);
  112.         if (plf->lfPitchAndFamily != plfOld->lfPitchAndFamily)
  113.             pApp->WriteProfileInt(szSec, szPitchAndFamily, plf->lfPitchAndFamily);
  114.         if (plf->lfCharSet != plfOld->lfCharSet)
  115.             pApp->WriteProfileInt(szSec, szCharSet, plf->lfCharSet);
  116.         if (_tcscmp(plf->lfFaceName, plfOld->lfFaceName) != 0)
  117.             pApp->WriteProfileString(szSec, szFaceName, (LPCTSTR)plf->lfFaceName);
  118.     }
  119.     *plfOld = *plf;
  120. }
  121.  
  122. void CPadView::Initialize()
  123. {
  124.     CWinApp* pApp = AfxGetApp();
  125.     m_bDefWordWrap = pApp->GetProfileInt(szSettings, szWordWrap, 0);
  126.     m_bDefWordWrapOld = m_bDefWordWrap;
  127.     m_nDefTabStops = pApp->GetProfileInt(szSettings, szTabStops, 8*4);
  128.     m_nDefTabStopsOld = m_nDefTabStops;
  129.     GetProfileFont(szFont, &m_lfDefFont);
  130.     m_lfDefFontOld = m_lfDefFont;
  131.     GetProfileFont(szPrintFont, &m_lfDefPrintFont);
  132.     m_lfDefPrintFontOld = m_lfDefPrintFont;
  133. }
  134.  
  135. void CPadView::Terminate()
  136. {
  137.     CWinApp* pApp = AfxGetApp();
  138.     if (m_nDefTabStops != m_nDefTabStopsOld)
  139.         pApp->WriteProfileInt(szSettings, szTabStops, m_nDefTabStops);
  140.     if (m_bDefWordWrap != m_bDefWordWrapOld)
  141.         pApp->WriteProfileInt(szSettings, szWordWrap, m_bDefWordWrap);
  142.     WriteProfileFont(szFont, &m_lfDefFont, &m_lfDefFontOld);
  143.     WriteProfileFont(szPrintFont, &m_lfDefPrintFont, &m_lfDefPrintFontOld);
  144. }
  145.  
  146. /////////////////////////////////////////////////////////////////////////////
  147. // CPadView construction/destruction
  148.  
  149. CPadView::CPadView()
  150. {
  151.     m_nTabStops = m_nDefTabStops;
  152.     m_uTimerID = 0;
  153. }
  154.  
  155. BOOL CPadView::PreCreateWindow(CREATESTRUCT& cs)
  156. {
  157.     if (!CEditView::PreCreateWindow(cs))
  158.         return FALSE;
  159.  
  160.     if (m_bDefWordWrap)
  161.         cs.style &= ~(WS_HSCROLL|ES_AUTOHSCROLL);
  162.  
  163.     return TRUE;
  164. }
  165.  
  166. int CPadView::OnCreate(LPCREATESTRUCT lpcs)
  167. {
  168.     if (CEditView::OnCreate(lpcs) != 0)
  169.         return -1;
  170.     if (m_lfDefFont.lfHeight != 0)
  171.     {
  172.         m_font.CreateFontIndirect(&m_lfDefFont);
  173.         SetFont(&m_font);
  174.     }
  175.     if (m_lfDefPrintFont.lfHeight != 0)
  176.     {
  177.         m_fontPrint.CreateFontIndirect(&m_lfDefPrintFont);
  178.         SetPrinterFont(&m_fontPrint);
  179.     }
  180.     return 0;
  181. }
  182.  
  183. /////////////////////////////////////////////////////////////////////////////
  184. // CPadView Word Wrap support
  185.  
  186. BOOL CPadView::IsWordWrap() const
  187. {
  188.     return (GetStyle() & ES_AUTOHSCROLL) == 0;
  189. }
  190.  
  191. BOOL CPadView::SetWordWrap(BOOL bWordWrap)
  192. {
  193.     bWordWrap = !!bWordWrap;    // make sure ==TRUE || ==FALSE
  194.     if (IsWordWrap() == bWordWrap)
  195.         return FALSE;
  196.  
  197.     // preserve original control's state.
  198.     CFont* pFont = GetFont();
  199.     int nLen = GetBufferLength();
  200.     TCHAR* pSaveText = new TCHAR[GetBufferLength()+1];
  201.     GetWindowText(pSaveText, nLen+1);
  202.  
  203.     // create new edit control with appropriate style and size.
  204.     DWORD dwStyle = dwStyleDefault & ~(ES_AUTOHSCROLL|WS_HSCROLL|WS_VISIBLE);
  205.     if (!bWordWrap)
  206.         dwStyle |= ES_AUTOHSCROLL|WS_HSCROLL;
  207.  
  208.     CWnd* pParent = GetParent();
  209.     CRect rect;
  210.     GetWindowRect(rect);
  211.     pParent->ScreenToClient(rect);
  212.     CWnd* pFocus = GetFocus();
  213.  
  214.     UINT nID = GetDlgCtrlID();
  215.  
  216.     HWND hWnd = ::CreateWindowEx(WS_EX_CLIENTEDGE, _T("edit"), NULL, dwStyle,
  217.         rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
  218.         pParent->m_hWnd, (HMENU)nID, AfxGetInstanceHandle(), NULL);
  219.  
  220.     if (hWnd == NULL)
  221.     {
  222.         delete[] pSaveText;
  223.         return FALSE;
  224.     }
  225.  
  226.     // set the window text to nothing to make sure following set doesn't fail
  227.     SetWindowText(NULL);
  228.  
  229.     // restore visual state
  230.     ::SetWindowText(hWnd, pSaveText);
  231.     delete[] pSaveText;
  232.     if (pFont != NULL)
  233.     {
  234.         ASSERT(pFont->m_hObject != NULL);
  235.         ::SendMessage(hWnd, WM_SETFONT, (WPARAM)pFont->m_hObject, 0);
  236.     }
  237.  
  238.     // detach old window, attach new
  239.     SetDlgCtrlID(nID+1);
  240.     HWND hWndOld = Detach();
  241.     ::SetWindowLong(hWndOld, GWL_WNDPROC, (LONG)*GetSuperWndProcAddr());
  242.     ASSERT(m_hWnd == NULL);
  243.     SubclassWindow(hWnd);
  244.     ASSERT(m_hWnd == hWnd);
  245.     GetParentFrame()->SendMessage(WM_RECALCPARENT);
  246.  
  247.     UINT nTabStops = m_nTabStops;
  248.     GetEditCtrl().SetTabStops(nTabStops);
  249.  
  250.     GetClientRect(&rect);
  251.     SetWindowPos(NULL, 0, 0, 0, 0,
  252.         SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW);
  253.     SetWindowPos(NULL, 0, 0, 0, 0,
  254.         SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_DRAWFRAME);
  255.     SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  256.     UpdateWindow();
  257.  
  258.     // destroy old
  259.     ::SetWindowPos(hWndOld, NULL, 0, 0, 0, 0,
  260.         SWP_HIDEWINDOW|SWP_NOREDRAW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
  261.         SWP_NOZORDER);
  262.     ::DestroyWindow(hWndOld);
  263.  
  264.     // restore rest of state...
  265.     GetEditCtrl().LimitText(nMaxSize);
  266.     if (pFocus == this)
  267.         SetFocus();
  268.  
  269.     // notify container that doc changed
  270.     GetDocument()->UpdateAllItems(NULL);
  271.  
  272.     ASSERT_VALID(this);
  273.     return TRUE;
  274. }
  275.  
  276. /////////////////////////////////////////////////////////////////////////////
  277. // CPadView Printing support
  278.  
  279. void CPadView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
  280. {
  281.     CEditView::OnBeginPrinting(pDC, pInfo);
  282.  
  283.     LPCTSTR pszFileName = GetDocument()->GetPathName();
  284.     BOOL bForceSysTime = _tcschr(pszFileName, '.') == NULL;
  285.     CTime timeSys = CTime::GetCurrentTime();
  286.     CFileStatus status;
  287.     CFile::GetStatus(pszFileName, status);
  288.  
  289.     if (dlgPageSetup.m_iHeaderTime != 0 || bForceSysTime)
  290.         m_timeHeader = timeSys;
  291.     else
  292.         m_timeHeader = status.m_mtime;
  293.  
  294.     if (dlgPageSetup.m_iFooterTime != 0 || bForceSysTime)
  295.         m_timeFooter = timeSys;
  296.     else
  297.         m_timeFooter = status.m_mtime;
  298.  
  299.     if (!pInfo->m_bPreview)
  300.         return;
  301.  
  302.     CWaitCursor wait;
  303.     pInfo->m_nCurPage = 0xFFFF;
  304.     OnPrepareDC(pDC, pInfo);
  305.  
  306.     UINT nIndex = LOWORD(GetEditCtrl().GetSel());
  307.     UINT nCurPage = 1;
  308.     while (nCurPage < (UINT)m_aPageStart.GetSize())
  309.     {
  310.         if (nIndex < m_aPageStart[nCurPage])
  311.             break;
  312.         nCurPage++;
  313.     }
  314.     pInfo->m_nCurPage = nCurPage;
  315.     pInfo->SetMaxPage(m_aPageStart.GetSize());
  316.     m_nPreviewPage = nCurPage;
  317. }
  318.  
  319. void CPadView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
  320. {
  321.     // get string to show as "filename" in header/footer
  322.     LPCTSTR pszFileName = GetDocument()->GetPathName();
  323.     if (pszFileName[0] == 0)
  324.         pszFileName = GetDocument()->GetTitle();
  325.  
  326.     // go thru global CPageSetupDlg to format the header and footer
  327.     CString strHeader;
  328.     dlgPageSetup.FormatHeader(strHeader, m_timeHeader, pszFileName,
  329.         pInfo->m_nCurPage);
  330.     CString strFooter;
  331.     dlgPageSetup.FormatFooter(strFooter, m_timeFooter, pszFileName,
  332.         pInfo->m_nCurPage);
  333.  
  334.     TEXTMETRIC tm;
  335.     pDC->GetTextMetrics(&tm);
  336.     int cyChar = tm.tmHeight;
  337.     CRect rectPage = pInfo->m_rectDraw;
  338.  
  339.     // draw and exclude space for header
  340.     if (!strHeader.IsEmpty())
  341.     {
  342.         pDC->TextOut(rectPage.left, rectPage.top, strHeader);
  343.         rectPage.top += cyChar + cyChar / 4;
  344.         pDC->MoveTo(rectPage.left, rectPage.top);
  345.         pDC->LineTo(rectPage.right, rectPage.top);
  346.         rectPage.top += cyChar / 4;
  347.     }
  348.  
  349.     // allow space for footer
  350.     pInfo->m_rectDraw = rectPage;
  351.     if (!strFooter.IsEmpty())
  352.         pInfo->m_rectDraw.bottom -= cyChar + cyChar/4 + cyChar/4;
  353.  
  354.     // draw body text
  355.     CEditView::OnPrint(pDC, pInfo);
  356.  
  357.     // draw footer
  358.     if (!strFooter.IsEmpty())
  359.     {
  360.         rectPage.bottom -= cyChar;
  361.         pDC->TextOut(rectPage.left, rectPage.bottom, strFooter);
  362.         rectPage.bottom -= cyChar / 4;
  363.         pDC->MoveTo(rectPage.left, rectPage.bottom);
  364.         pDC->LineTo(rectPage.right, rectPage.bottom);
  365.         rectPage.bottom -= cyChar / 4;
  366.     }
  367. }
  368.  
  369. void CPadView::OnScrollTo(CDC*, CPrintInfo* pInfo, POINT)
  370. {
  371.     UINT nPage = pInfo->m_nCurPage;
  372.     ASSERT(nPage < (UINT)m_aPageStart.GetSize());
  373.     if (nPage != m_nPreviewPage)
  374.     {
  375.         UINT nIndex = m_aPageStart[nPage];
  376.         GetEditCtrl().SetSel((int)nIndex, (int)nIndex);
  377.     }
  378. }
  379.  
  380. /////////////////////////////////////////////////////////////////////////////
  381. // CPadView Font Handling
  382.  
  383. void CPadView::OnChooseFont()
  384. {
  385.    // get current font description
  386.    CFont* pFont = GetFont();
  387.    LOGFONT lf;
  388.    if (pFont != NULL)
  389.        pFont->GetObject(sizeof(LOGFONT), &lf);
  390.    else
  391.        ::GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
  392.  
  393.     CFontDialog dlg(&lf, CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT);
  394.     if (dlg.DoModal() == IDOK)
  395.     {
  396.         // switch to new font.
  397.         m_font.DeleteObject();
  398.         if (m_font.CreateFontIndirect(&lf))
  399.         {
  400.             CWaitCursor wait;
  401.             SetFont(&m_font);
  402.             m_lfDefFont = lf;
  403.  
  404.             if (GetPrinterFont() == NULL)
  405.             {
  406.                 // notify container that content has changed
  407.                 GetDocument()->UpdateAllItems(NULL);
  408.             }
  409.         }
  410.     }
  411. }
  412.  
  413. static void ScaleLogFont(LPLOGFONT plf, const CDC& dcFrom, const CDC& dcTo)
  414.     // helper to scale log font member from one DC to another!
  415. {
  416.     plf->lfHeight = MulDiv(plf->lfHeight,
  417.         dcTo.GetDeviceCaps(LOGPIXELSY), dcFrom.GetDeviceCaps(LOGPIXELSY));
  418.     plf->lfWidth = MulDiv(plf->lfWidth,
  419.         dcTo.GetDeviceCaps(LOGPIXELSX), dcFrom.GetDeviceCaps(LOGPIXELSX));
  420. }
  421.  
  422. void CPadView::OnChoosePrintFont()
  423. {
  424.     CWaitCursor wait;
  425.     CFont* pFont = GetPrinterFont();
  426.     LOGFONT lf;
  427.     LPLOGFONT plf = NULL;
  428.     if (pFont != NULL)
  429.     {
  430.         pFont->GetObject(sizeof(LOGFONT), &lf);
  431.         plf = &lf;
  432.     }
  433.  
  434.     // magic to get printer dialog that would be used if we were printing!
  435.     CPrintDialog dlgPrint(FALSE);
  436.     if (!AfxGetApp()->GetPrinterDeviceDefaults(&dlgPrint.m_pd))
  437.     {
  438.         AfxMessageBox(IDP_ERR_GET_DEVICE_DEFAULTS);
  439.         return;
  440.     }
  441.     wait.Restore();
  442.     HDC hdcPrint = dlgPrint.CreatePrinterDC();
  443.     if (hdcPrint == NULL)
  444.     {
  445.         AfxMessageBox(IDP_ERR_GET_PRINTER_DC);
  446.         return;
  447.     }
  448.  
  449.     CDC dcScreen;
  450.     dcScreen.Attach(::GetDC(NULL));
  451.     CDC dcPrint;
  452.     dcPrint.Attach(hdcPrint);
  453.  
  454.     if (plf != NULL)
  455.     {
  456.         // need to map initial logfont to screen metrics.
  457.         ::ScaleLogFont(plf, dcPrint, dcScreen);
  458.     }
  459.  
  460.     // now bring up the dialog since we know the printer DC
  461.     CFontDialog dlg(plf, CF_PRINTERFONTS, &dcPrint);
  462.     if (dlg.DoModal() == IDOK)
  463.     {
  464.         // map the resulting logfont back to printer metrics.
  465.         lf = dlg.m_lf;
  466.         ::ScaleLogFont(&lf, dcScreen, dcPrint);
  467.  
  468.         SetPrinterFont(NULL);
  469.         m_fontPrint.DeleteObject();
  470.         if (m_fontPrint.CreateFontIndirect(&lf))
  471.         {
  472.             SetPrinterFont(&m_fontPrint);
  473.             m_lfDefPrintFont = lf;
  474.  
  475.             // notify container that content has changed
  476.             GetDocument()->UpdateAllItems(NULL);
  477.         }
  478.     }
  479.     //NOTE: destructor will call dcPrint.DeleteDC
  480.  
  481.     ::ReleaseDC(NULL, dcScreen.Detach());
  482. }
  483.  
  484. void CPadView::OnMirrorDisplayFont()
  485. {
  486.     if (GetPrinterFont() != NULL)
  487.     {
  488.         SetPrinterFont(NULL);
  489.         m_lfDefPrintFont.lfHeight = 0;
  490.  
  491.         // notify container that content changed
  492.         GetDocument()->UpdateAllItems(NULL);
  493.     }
  494. }
  495.  
  496. void CPadView::OnUpdateChoosePrintFont(CCmdUI* pCmdUI)
  497. {
  498.     pCmdUI->SetCheck(GetPrinterFont() != NULL);
  499. }
  500.  
  501. void CPadView::OnUpdateMirrorDisplayFont(CCmdUI* pCmdUI)
  502. {
  503.     pCmdUI->SetCheck(GetPrinterFont() == NULL);
  504. }
  505.  
  506. /////////////////////////////////////////////////////////////////////////////
  507. // CPadView Tab Stops
  508.  
  509. void CPadView::OnSetTabStops()
  510. {
  511.     CSetTabStops dlg;
  512.     dlg.m_nTabStops = m_nTabStops/4;
  513.     if (dlg.DoModal() == IDOK)
  514.     {
  515.         CWaitCursor wait;
  516.         SetTabStops(dlg.m_nTabStops*4);
  517.         m_nDefTabStops = m_nTabStops;
  518.  
  519.         // notify container that content changed
  520.         GetDocument()->UpdateAllItems(NULL);
  521.     }
  522. }
  523.  
  524. /////////////////////////////////////////////////////////////////////////////
  525. // CPadView Word Wrap
  526.  
  527. void CPadView::OnUpdateWordWrap(CCmdUI* pCmdUI)
  528. {
  529.     pCmdUI->SetCheck(IsWordWrap());
  530. }
  531.  
  532. void CPadView::OnWordWrap()
  533. {
  534.     CWaitCursor wait;
  535.     SetWordWrap(!IsWordWrap());
  536.     m_bDefWordWrap = IsWordWrap();
  537. }
  538.  
  539. /////////////////////////////////////////////////////////////////////////////
  540. // CPadView commands
  541.  
  542. void CPadView::OnRButtonDown(UINT, CPoint)
  543. {
  544.     GetParentFrame()->BringWindowToTop();
  545. }
  546.  
  547. void CPadView::OnSize(UINT nType, int cx, int cy)
  548. {
  549.     CWaitCursor wait;
  550.     CEditView::OnSize(nType, cx, cy);
  551.  
  552.     CFrameWnd* pFrameWnd = GetParentFrame();
  553.     ASSERT_VALID(pFrameWnd);
  554.  
  555.     if ((pFrameWnd->GetStyle() & WS_VISIBLE) &&
  556.         pFrameWnd->IsKindOf(RUNTIME_CLASS(COleIPFrameWnd)))
  557.     {
  558.         // update the cx part of the extent to the width of the control
  559.         COleServerItem* pItem = GetDocument()->GetEmbeddedItem();
  560.  
  561.         // only update if it has actually changed
  562.         if ((int)pItem->m_sizeExtent.cx != cx)
  563.         {
  564.             pItem->m_sizeExtent.cx = cx;
  565.             OnEditChange();
  566.         }
  567.     }
  568. }
  569.  
  570. /////////////////////////////////////////////////////////////////////////////
  571. // CPadView OLE support
  572.  
  573. void CPadView::OnEditChange()
  574. {
  575.     CEditView::OnEditChange();
  576.  
  577.     if (m_uTimerID != 0) // if outstanding timer kill it
  578.         KillTimer(m_uTimerID);
  579.     m_uTimerID = SetTimer(1, 200, NULL); //set a timer for 200 milliseconds
  580.     if (m_uTimerID == 0) // no timer available so force update now
  581.         GetDocument()->UpdateAllItems(NULL);
  582. }
  583.  
  584. void CPadView::OnEditCopy()
  585. {
  586.     CWaitCursor wait;
  587.  
  588.     // get the current selection
  589.     UINT nFrom, nTo;
  590.     GetEditCtrl().GetSel((int&)nFrom, (int&)nTo);
  591.  
  592.     // what gets copied depends on partial vs. full selection
  593.     if ((nFrom == 0 && nTo == (UINT)GetWindowTextLength()))
  594.     {
  595.         // copy entire document to the clipboard
  596.         GetDocument()->GetEmbeddedItem()->CopyToClipboard(TRUE);
  597.     }
  598.     else
  599.     {
  600.         // copy linked item to clipboard
  601.         CPadLinkItem item(GetDocument(), nFrom, nTo);
  602.         item.CopyToClipboard(TRUE);
  603.     }
  604. }
  605.  
  606. void CPadView::OnEditCut()
  607. {
  608.     OnEditCopy();
  609.     CEditView::OnEditCut();
  610. }
  611.  
  612. void CPadView::OnTimer(UINT nIDEvent)
  613. {
  614.     if (m_uTimerID != nIDEvent) // not our timer
  615.     {
  616.         CEditView::OnTimer(nIDEvent);
  617.         return;
  618.     }
  619.  
  620.     KillTimer(m_uTimerID); // kill one-shot timer
  621.     m_uTimerID = 0;
  622.     GetDocument()->UpdateAllItems(NULL);
  623. }
  624.  
  625. /////////////////////////////////////////////////////////////////////////////
  626. // CPadView diagnostics
  627.  
  628. #ifdef _DEBUG
  629. void CPadView::AssertValid() const
  630. {
  631.     CEditView::AssertValid();
  632. }
  633.  
  634. void CPadView::Dump(CDumpContext& dc) const
  635. {
  636.     CEditView::Dump(dc);
  637. }
  638. #endif //_DEBUG
  639.  
  640. /////////////////////////////////////////////////////////////////////////////
  641.