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

Internet/IE编程

开发平台:

Visual C++

  1. // InPlaceList.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. // CInPlaceList from http://www.codeguru.com/listview
  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. // 6 Aug 1998 - Added CComboEdit to subclass the edit control - code provided by 
  28. //              Roelf Werkman <rdw@inn.nl>. Added nID to the constructor param list.
  29. // 29 Nov 1998 - bug fix in onkeydown (Markus Irtenkauf)
  30. //
  31. /////////////////////////////////////////////////////////////////////////////
  32. #include "stdafx.h"
  33. #include "InPlaceList.h"
  34. #include "GridCtrl.h"
  35. #ifdef _DEBUG
  36. #define new DEBUG_NEW
  37. #undef THIS_FILE
  38. static char THIS_FILE[] = __FILE__;
  39. #endif
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CComboEdit
  42. CComboEdit::CComboEdit()
  43. {
  44. }
  45. CComboEdit::~CComboEdit()
  46. {
  47. }
  48. // Stoopid win95 accelerator key problem workaround - Matt Weagle.
  49. BOOL CComboEdit::PreTranslateMessage(MSG* pMsg) 
  50. {
  51. // Make sure that the keystrokes continue to the appropriate handlers
  52. if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
  53. {
  54. ::TranslateMessage(pMsg);
  55. ::DispatchMessage(pMsg);
  56. return TRUE;
  57. }
  58. // Catch the Alt key so we don't choke if focus is going to an owner drawn button
  59. if (pMsg->message == WM_SYSCHAR)
  60. return TRUE;
  61. return CEdit::PreTranslateMessage(pMsg);
  62. }
  63. BEGIN_MESSAGE_MAP(CComboEdit, CEdit)
  64. //{{AFX_MSG_MAP(CComboEdit)
  65. ON_WM_KILLFOCUS()
  66. ON_WM_KEYDOWN()
  67. ON_WM_KEYUP()
  68. //}}AFX_MSG_MAP
  69. END_MESSAGE_MAP()
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CComboEdit message handlers
  72. void CComboEdit::OnKillFocus(CWnd* pNewWnd) 
  73. {
  74. CEdit::OnKillFocus(pNewWnd);
  75.     CInPlaceList* pOwner = (CInPlaceList*) GetOwner();  // This MUST be a CInPlaceList
  76.     if (pOwner)
  77.         pOwner->EndEdit();
  78. }
  79. void CComboEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  80. {
  81. if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
  82.  nChar == VK_DOWN  || nChar == VK_UP   ||
  83.  nChar == VK_RIGHT || nChar == VK_LEFT) &&
  84. (GetKeyState(VK_CONTROL) < 0 && GetDlgCtrlID() == IDC_COMBOEDIT))
  85.     {
  86.         CWnd* pOwner = GetOwner();
  87.         if (pOwner)
  88.             pOwner->SendMessage(WM_KEYDOWN, nChar, nRepCnt+ (((DWORD)nFlags)<<16));
  89.         return;
  90.     }
  91. CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  92. }
  93. void CComboEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  94. {
  95. if (nChar == VK_ESCAPE) 
  96. {
  97.         CWnd* pOwner = GetOwner();
  98.         if (pOwner)
  99.             pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
  100.         return;
  101.     }
  102. if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
  103.     {
  104.         CWnd* pOwner = GetOwner();
  105.         if (pOwner)
  106.             pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
  107.         return;
  108.     }
  109. CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. // CInPlaceList
  113. CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
  114.                            int nRow, int nColumn, 
  115.    CStringArray& Items, CString sInitText, 
  116.    UINT nFirstChar)
  117. {
  118. m_nNumLines = 4;
  119. m_sInitText = sInitText;
  120.   m_nRow = nRow;
  121.   m_nCol      = nColumn;
  122.   m_nLastChar = 0; 
  123. m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON); // If mouse click brought us here,
  124. // Create the combobox
  125.   DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL|
  126.        CBS_AUTOHSCROLL | dwStyle;
  127. int nHeight = rect.Height();
  128. rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL);
  129. if (!Create(dwComboStyle, rect, pParent, nID)) return;
  130. // Add the strings
  131. for (int i = 0; i < Items.GetSize(); i++) 
  132. AddString(Items[i]);
  133. // Get the maximum width of the text strings
  134. int nMaxLength = 0;
  135. CClientDC dc(GetParent());
  136. CFont* pOldFont = dc.SelectObject(pParent->GetFont());
  137. for (i = 0; i < Items.GetSize(); i++) 
  138. nMaxLength = max(nMaxLength, dc.GetTextExtent(Items[i]).cx);
  139. nMaxLength += (::GetSystemMetrics(SM_CXVSCROLL) + dc.GetTextExtent(_T(" ")).cx*2);
  140. dc.SelectObject(pOldFont);
  141.     if (nMaxLength > rect.Width())
  142.     rect.right = rect.left + nMaxLength;
  143. // Resize the edit window and the drop down window
  144. MoveWindow(rect);
  145. SetFont(pParent->GetFont());
  146. SetItemHeight(-1, nHeight);
  147. SetDroppedWidth(nMaxLength);
  148. SetHorizontalExtent(0); // no horz scrolling
  149. // Set the initial text to m_sInitText
  150. if (SelectString(-1, m_sInitText) == CB_ERR) 
  151. SetWindowText(m_sInitText); // No text selected, so restore what was there before
  152.     // Subclass the combobox edit control if style includes CBS_DROPDOWN
  153.     if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST)
  154.     {
  155.         m_edit.SubclassDlgItem(IDC_COMBOEDIT, this);
  156.       SetFocus();
  157.         switch (nFirstChar)
  158.         {
  159.             case VK_LBUTTON: 
  160.             case VK_RETURN:   m_edit.SetSel((int)_tcslen(m_sInitText), -1); return;
  161.             case VK_BACK:     m_edit.SetSel((int)_tcslen(m_sInitText), -1); break;
  162.             case VK_DOWN: 
  163.             case VK_UP:   
  164.             case VK_RIGHT:
  165.             case VK_LEFT:  
  166.             case VK_NEXT:  
  167.             case VK_PRIOR: 
  168.             case VK_HOME:  
  169.             case VK_END:      m_edit.SetSel(0,-1); return;
  170.             default:          m_edit.SetSel(0,-1);
  171.         }
  172.         SendMessage(WM_CHAR, nFirstChar);
  173.     }
  174.     else
  175.       SetFocus();
  176. }
  177. CInPlaceList::~CInPlaceList()
  178. {
  179. }
  180. void CInPlaceList::EndEdit()
  181. {
  182.     CString str;
  183.     GetWindowText(str);
  184.  
  185.     // Send Notification to parent
  186.     GV_DISPINFO dispinfo;
  187.     dispinfo.hdr.hwndFrom = GetSafeHwnd();
  188.     dispinfo.hdr.idFrom   = GetDlgCtrlID();
  189.     dispinfo.hdr.code     = GVN_ENDLABELEDIT;
  190.  
  191.     dispinfo.item.mask    = LVIF_TEXT|LVIF_PARAM;
  192.     dispinfo.item.row     = m_nRow;
  193.     dispinfo.item.col     = m_nCol;
  194.     dispinfo.item.szText  = str;
  195.     dispinfo.item.lParam  = (LPARAM) m_nLastChar; 
  196.  
  197.     CWnd* pOwner = GetOwner();
  198.     if (IsWindow(pOwner->GetSafeHwnd()))
  199.         pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
  200.  
  201.     // Close this window (PostNcDestroy will delete this)
  202.     PostMessage(WM_CLOSE, 0, 0);
  203. }
  204. void CInPlaceList::PostNcDestroy() 
  205. {
  206. CComboBox::PostNcDestroy();
  207. delete this;
  208. }
  209. BEGIN_MESSAGE_MAP(CInPlaceList, CComboBox)
  210. //{{AFX_MSG_MAP(CInPlaceList)
  211. ON_WM_KILLFOCUS()
  212. ON_WM_KEYDOWN()
  213. ON_WM_KEYUP()
  214. //}}AFX_MSG_MAP
  215. END_MESSAGE_MAP()
  216. /////////////////////////////////////////////////////////////////////////////
  217. // CInPlaceList message handlers
  218. void CInPlaceList::OnKillFocus(CWnd* pNewWnd) 
  219. {
  220. CComboBox::OnKillFocus(pNewWnd);
  221. if (GetSafeHwnd() == pNewWnd->GetSafeHwnd())
  222.         return;
  223.     // Only end editing on change of focus if we're using the CBS_DROPDOWNLIST style
  224.     if ((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
  225.         EndEdit();
  226. }
  227. // If an arrow key (or associated) is pressed, then exit if
  228. //  a) The Ctrl key was down, or
  229. //  b) m_bExitOnArrows == TRUE
  230. void CInPlaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  231. {
  232. if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
  233.  nChar == VK_DOWN  || nChar == VK_UP   ||
  234.  nChar == VK_RIGHT || nChar == VK_LEFT) &&
  235. (m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
  236. {
  237. m_nLastChar = nChar;
  238. GetParent()->SetFocus();
  239. return;
  240. }
  241. CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
  242. }
  243. // Need to keep a lookout for Tabs, Esc and Returns.
  244. void CInPlaceList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  245. {
  246. if (nChar == VK_ESCAPE) 
  247. SetWindowText(m_sInitText); // restore previous text
  248. if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
  249. {
  250. m_nLastChar = nChar;
  251. GetParent()->SetFocus(); // This will destroy this window
  252. return;
  253. }
  254. CComboBox::OnKeyUp(nChar, nRepCnt, nFlags);
  255. }