InPlaceEdit.cpp
上传用户:zdjx198
上传日期:2007-01-02
资源大小:95k
文件大小:5k
源码类别:

ListView/ListBox

开发平台:

Visual C++

  1. // InPlaceEdit.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "InPlaceEdit.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CInPlaceEdit
  12. CInPlaceEdit::CInPlaceEdit(int iItem, int iSubItem, CString sInitText)
  13. :m_sInitText( sInitText )
  14. {
  15. m_iItem = iItem;
  16. m_iSubItem = iSubItem;
  17. m_bESC = FALSE;
  18. }
  19. CInPlaceEdit::~CInPlaceEdit()
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
  23.         //{{AFX_MSG_MAP(CInPlaceEdit)
  24.         ON_WM_KILLFOCUS()
  25.         ON_WM_CHAR()
  26.         ON_WM_CREATE()
  27.         //}}AFX_MSG_MAP
  28. END_MESSAGE_MAP()
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CInPlaceEdit message handlers
  31. BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
  32. {
  33. if( pMsg->message == WM_KEYDOWN )
  34.         {
  35. SHORT sKey = GetKeyState( VK_CONTROL);
  36. if(pMsg->wParam == VK_RETURN
  37. || pMsg->wParam == VK_DELETE
  38. || pMsg->wParam == VK_ESCAPE
  39. || sKey
  40. )
  41. {
  42. ::TranslateMessage(pMsg);
  43. /* Strange but true:
  44. If the edit control has ES_MULTILINE and ESC
  45. is pressed the parent is destroyed if the 
  46. message is dispatched.  In this 
  47. case the parent is the list control. */
  48. if( !(GetStyle() & ES_MULTILINE) || pMsg->wParam != VK_ESCAPE )
  49. {
  50. ::DispatchMessage(pMsg);
  51. }
  52. return TRUE;                    // DO NOT process further
  53. }
  54.         }
  55. return CEdit::PreTranslateMessage(pMsg);
  56. }
  57. void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
  58. {
  59. CEdit::OnKillFocus(pNewWnd);
  60. CString str;
  61. GetWindowText(str);
  62. // Send Notification to parent of ListView ctrl
  63. LV_DISPINFO dispinfo;
  64. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  65. dispinfo.hdr.idFrom = GetDlgCtrlID();
  66. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  67. dispinfo.item.mask = LVIF_TEXT;
  68. dispinfo.item.iItem = m_iItem;
  69. dispinfo.item.iSubItem = m_iSubItem;
  70. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  71. dispinfo.item.cchTextMax = m_bESC ? 0 : str.GetLength();
  72. GetParent()->GetParent()->SendMessage( WM_NOTIFY, GetParent()->GetDlgCtrlID(), 
  73. (LPARAM)&dispinfo );
  74. }
  75. void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  76. {
  77. if( nChar == VK_ESCAPE || nChar == VK_RETURN)
  78.         {
  79. if( nChar == VK_ESCAPE )
  80. m_bESC = TRUE;
  81. GetParent()->SetFocus();
  82. return;
  83.         }
  84. CEdit::OnChar(nChar, nRepCnt, nFlags);
  85. // Resize edit control if needed
  86. CalculateSize();
  87. }
  88. int CInPlaceEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
  89. {
  90. if (CEdit::OnCreate(lpCreateStruct) == -1)
  91. return -1;
  92. // Set the proper font
  93. CFont* font = GetParent()->GetFont();
  94. SetFont(font);
  95. SetWindowText( m_sInitText );
  96. SetFocus();
  97. CalculateSize();
  98. SetSel( 0, -1 );
  99. return 0;
  100. }
  101. void CInPlaceEdit::CalculateSize()
  102. {
  103. // Get text extent
  104. CString str;
  105. GetWindowText( str );
  106. CWindowDC dc(this);
  107. CFont *pFont = GetParent()->GetFont();
  108. CFont *pFontDC = dc.SelectObject( pFont );
  109. CSize size;
  110. // Get client rect
  111. CRect rect, parentrect;
  112. GetClientRect( &rect );
  113. GetParent()->GetClientRect( &parentrect );
  114. // Transform rect to parent coordinates
  115. ClientToScreen( &rect );
  116. GetParent()->ScreenToClient( &rect );
  117. if( !(GetStyle() & ES_MULTILINE ) )
  118. {
  119. size = dc.GetTextExtent( str );
  120. dc.SelectObject( pFontDC );
  121. size.cx += 5;                           // add some extra buffer
  122. }
  123. else
  124. {
  125. CRect thinrect( rect );  // To measure the skinniest text box
  126. CRect widerect( rect );  // To measure the wides text box
  127. widerect.right = parentrect.right;
  128. // Use the shortest of the two box sizes.
  129. int thinheight = dc.DrawText( str, &thinrect, DT_CALCRECT|DT_NOPREFIX|DT_LEFT|DT_EXPANDTABS|DT_WORDBREAK );
  130. int wideheight = dc.DrawText( str, &widerect, DT_CALCRECT|DT_NOPREFIX|DT_LEFT|DT_EXPANDTABS|DT_WORDBREAK );
  131. if( thinheight >= wideheight )
  132. {
  133. size.cy = wideheight + 5;
  134. size.cx = widerect.right - widerect.left + 5;
  135. }
  136. else
  137. {
  138. size.cy = thinheight + 5;
  139. size.cx = thinrect.right - thinrect.left + 5;
  140. }
  141. }
  142. // Check whether control needs to be resized
  143. // and whether there is space to grow
  144. int changed = 0;
  145. if( size.cx > rect.Width() )
  146. {
  147. if( size.cx + rect.left < parentrect.right-2 )
  148. rect.right = rect.left + size.cx;
  149. else
  150. rect.right = parentrect.right-2;
  151. changed = 1;
  152. }
  153. if( size.cy > rect.Height() )
  154. {
  155. if( size.cy + rect.top < parentrect.bottom-2 )
  156. rect.bottom = rect.top + size.cy;
  157. else
  158. {
  159. rect.bottom = parentrect.bottom-2;
  160. ShowScrollBar( SB_VERT );
  161. }
  162. changed = 1;
  163. }
  164. // If the size became larger rposition the window.
  165. if( changed )
  166. MoveWindow( &rect );
  167. }