INPLACEEDIT.CPP
上传用户:asikq0571
上传日期:2014-07-12
资源大小:528k
文件大小:8k
源码类别:

Internet/IE编程

开发平台:

Visual C++

  1. // InPlaceEdit.cpp : implementation file
  2. //
  3. // Written by Chris Maunder (chrismaunder@codeguru.com)
  4. // Copyright (c) 1998.
  5. //
  6. // The code contained in this file is based on the original
  7. // CInPlaceEdit from http://www.codeguru.com/listview/edit_subitems.shtml
  8. //
  9. // This code may be used in compiled form in any way you desire. This
  10. // file may be redistributed unmodified by any means PROVIDING it is 
  11. // not sold for profit without the authors written consent, and 
  12. // providing that this notice and the authors name is included. If 
  13. // the source code in  this file is used in any commercial application 
  14. // then acknowledgement must be made to the author of this file 
  15. // (in whatever form you wish).
  16. //
  17. // This file is provided "as is" with no expressed or implied warranty.
  18. // The author accepts no liability for any damage/loss of business that
  19. // this product may cause.
  20. //
  21. // Expect bugs!
  22. // 
  23. // Please use and enjoy. Please let me know of any bugs/mods/improvements 
  24. // that you have found/implemented and I will fix/incorporate them into this
  25. // file. 
  26. //
  27. // Modifed 10 May 1998  Uses GVN_ notifications instead of LVN_,
  28. //                      Sends notification messages to the parent, 
  29. //                      instead of the parent's parent.
  30. //
  31. //         15 May 1998  There was a problem when editing with the in-place editor, 
  32. //                      there arises a general protection fault in user.exe, with a 
  33. //                      few qualifications:
  34. //                         (1) This only happens with owner-drawn buttons;
  35. //                         (2) This only happens in Win95
  36. //                         (3) This only happens if the handler for the button does not 
  37. //                             create a new window (even an AfxMessageBox will avoid the 
  38. //                             crash)
  39. //                         (4) This will not happen if Spy++ is running.
  40. //                      PreTranslateMessage was added to route messages correctly.
  41. //                      (Matt Weagle found and fixed this problem)
  42. //         26 Jul 1998  Removed the ES_MULTILINE style - that fixed a few probs!
  43. //          6 Aug 1998  Added nID to the constructor param list
  44. //          6 Sep 1998  Space no longer clears selection when starting edit (Franco Bez)
  45. //
  46. /////////////////////////////////////////////////////////////////////////////
  47. #include "stdafx.h"
  48. #include "TCHAR.h"
  49. #include "InPlaceEdit.h"
  50. #include "GridCtrl.h"
  51.  
  52. #ifdef _DEBUG
  53. #define new DEBUG_NEW
  54. #undef THIS_FILE
  55. static char THIS_FILE[] = __FILE__;
  56. #endif
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CInPlaceEdit
  59. CInPlaceEdit::CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
  60.                            int nRow, int nColumn, CString sInitText, 
  61.                            UINT nFirstChar)
  62. {
  63.     m_sInitText     = sInitText;
  64.     m_nRow          = nRow;
  65.     m_nColumn       = nColumn;
  66.     m_nLastChar     = 0; 
  67.     m_bExitOnArrows = (nFirstChar != VK_LBUTTON);    // If mouse click brought us here,
  68.                                                      // then no exit on arrows
  69.     DWORD dwEditStyle = WS_BORDER|WS_CHILD|WS_VISIBLE| ES_AUTOHSCROLL //|ES_MULTILINE
  70.                        | dwStyle;
  71.     if (!Create(dwEditStyle, rect, pParent, nID)) return;
  72.     SetFont(pParent->GetFont());
  73.     SetWindowText(sInitText);
  74.     SetFocus();
  75.     switch (nFirstChar){
  76.         case VK_LBUTTON: 
  77.         case VK_RETURN:   SetSel((int)_tcslen(m_sInitText), -1); return;
  78.         case VK_BACK:     SetSel((int)_tcslen(m_sInitText), -1); break;
  79.         case VK_DOWN: 
  80.         case VK_UP:   
  81.         case VK_RIGHT:
  82.         case VK_LEFT:  
  83.         case VK_NEXT:  
  84.         case VK_PRIOR: 
  85.         case VK_HOME:
  86.         case VK_SPACE:
  87.         case VK_END:      SetSel(0,-1); return;
  88.         default:          SetSel(0,-1);
  89.     }
  90.     SendMessage(WM_CHAR, nFirstChar);
  91. }
  92. CInPlaceEdit::~CInPlaceEdit()
  93. {
  94. }
  95.  
  96. BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
  97.     //{{AFX_MSG_MAP(CInPlaceEdit)
  98.     ON_WM_KILLFOCUS()
  99.     ON_WM_CHAR()
  100.     ON_WM_KEYDOWN()
  101.     ON_WM_KEYUP()
  102.     ON_WM_CREATE()
  103. //}}AFX_MSG_MAP
  104. END_MESSAGE_MAP()
  105.  
  106. ////////////////////////////////////////////////////////////////////////////
  107. // CInPlaceEdit message handlers
  108. // If an arrow key (or associated) is pressed, then exit if
  109. //  a) The Ctrl key was down, or
  110. //  b) m_bExitOnArrows == TRUE
  111. void CInPlaceEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  112. {
  113.     if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
  114.          nChar == VK_DOWN  || nChar == VK_UP   ||
  115.          nChar == VK_RIGHT || nChar == VK_LEFT) &&
  116.         (m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
  117.     {
  118.         m_nLastChar = nChar;
  119.         GetParent()->SetFocus();
  120.         return;
  121.     }
  122.     if (nChar == VK_ESCAPE) 
  123.     {
  124.         SetWindowText(m_sInitText);    // restore previous text
  125.         m_nLastChar = nChar;
  126.         GetParent()->SetFocus();
  127.         return;
  128.     }
  129.     CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  130. }
  131. // Need to keep a lookout for Tabs, Esc and Returns. These send a 
  132. // "KeyUp" message, but no "KeyDown". That's why I didn't put their
  133. // code in OnKeyDown. (I will never understand windows...)
  134. void CInPlaceEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  135. {
  136.     if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
  137.     {
  138.         m_nLastChar = nChar;
  139.         GetParent()->SetFocus();    // This will destroy this window
  140.         return;
  141.     }
  142.     CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
  143. }
  144. // As soon as this edit loses focus, kill it.
  145. void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
  146. {
  147.     CEdit::OnKillFocus(pNewWnd);
  148.     EndEdit();
  149. }
  150. void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  151. {
  152.      CEdit::OnChar(nChar, nRepCnt, nFlags);
  153.  
  154.      // Resize edit control if needed
  155.  
  156.      // Get text extent
  157.      CString str;
  158.      GetWindowText( str );
  159.      CWindowDC dc(this);
  160.      CFont *pFontDC = dc.SelectObject(GetFont());
  161.      CSize size = dc.GetTextExtent( str );
  162.      dc.SelectObject( pFontDC );
  163.      size.cx += 5;                   // add some extra buffer
  164.  
  165.      // Get client rect
  166.      CRect rect, parentrect;
  167.      GetClientRect( &rect );
  168.      GetParent()->GetClientRect( &parentrect );
  169.  
  170.      // Transform rect to parent coordinates
  171.      ClientToScreen( &rect );
  172.      GetParent()->ScreenToClient( &rect );
  173.  
  174.      // Check whether control needs to be resized
  175.      // and whether there is space to grow
  176.      if (size.cx > rect.Width())
  177.      {
  178.          if( size.cx + rect.left < parentrect.right )
  179.              rect.right = rect.left + size.cx;
  180.          else
  181.              rect.right = parentrect.right;
  182.          MoveWindow( &rect );
  183.      }
  184. }
  185. ////////////////////////////////////////////////////////////////////////////
  186. // CInPlaceEdit overrides
  187. // Stoopid win95 accelerator key problem workaround - Matt Weagle.
  188. BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg) 
  189. {
  190. // Make sure that the keystrokes continue to the appropriate handlers
  191. if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
  192. {
  193. ::TranslateMessage(pMsg);
  194. ::DispatchMessage(pMsg);
  195. return TRUE;
  196. }
  197. // Catch the Alt key so we don't choke if focus is going to an owner drawn button
  198. if (pMsg->message == WM_SYSCHAR)
  199. return TRUE;
  200.     return CWnd::PreTranslateMessage(pMsg);
  201. }
  202. // Auto delete
  203. void CInPlaceEdit::PostNcDestroy() 
  204. {
  205. CEdit::PostNcDestroy();
  206.     delete this;
  207. }
  208. ////////////////////////////////////////////////////////////////////////////
  209. // CInPlaceEdit implementation
  210. void CInPlaceEdit::EndEdit()
  211. {
  212.     CString str;
  213.     GetWindowText(str);
  214.  
  215.     // Send Notification to parent
  216.     GV_DISPINFO dispinfo;
  217.     dispinfo.hdr.hwndFrom = GetSafeHwnd();
  218.     dispinfo.hdr.idFrom   = GetDlgCtrlID();
  219.     dispinfo.hdr.code     = GVN_ENDLABELEDIT;
  220.  
  221.     dispinfo.item.mask    = LVIF_TEXT|LVIF_PARAM;
  222.     dispinfo.item.row     = m_nRow;
  223.     dispinfo.item.col     = m_nColumn;
  224.     dispinfo.item.szText  = str;
  225.     dispinfo.item.lParam  = (LPARAM) m_nLastChar; 
  226.  
  227.     CWnd* pOwner = GetOwner();
  228.     if (pOwner)
  229.         pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
  230.  
  231.     // Close this window (PostNcDestroy will delete this)
  232.     PostMessage(WM_CLOSE, 0, 0);
  233. }
  234.