00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #include "stdafx.h"
00033 #include "GridCellMultiLine.h"
00034
00035
00036 #ifdef _DEBUG
00037 #define new DEBUG_NEW
00038 #undef THIS_FILE
00039 static char THIS_FILE[] = __FILE__;
00040 #endif
00041
00042
00046
00047
00048 CInPlaceMultiLine::CInPlaceMultiLine(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
00049 int nRow, int nColumn, CString sInitText,
00050 UINT nFirstChar)
00051 {
00052 if (pParent->IsKindOf(RUNTIME_CLASS(CGridCtrl)))
00053 m_pParentGC = pParent;
00054 else
00055 m_pParentGC = NULL;
00056 m_sInitText = sInitText;
00057 m_nRow = nRow;
00058 m_nColumn = nColumn;
00059 m_nLastChar = 0;
00060 m_bExitOnArrows = (nFirstChar != VK_LBUTTON);
00061
00062
00063 m_bExitOnArrows = FALSE;
00064
00065 m_bInEditModus = FALSE;
00066
00067 m_Rect = rect;
00068
00069
00070 CWindowDC dc(this);
00071 CSize proper = GetTextExtentMultiLine(m_Rect.Width (), m_sInitText, &dc);
00072 m_Rect.right = m_Rect.left + proper.cx * 3 / 2;
00073 m_Rect.bottom = m_Rect.top + proper.cy;
00074
00075
00076 DWORD dwEditStyle = WS_THICKFRAME|WS_CHILD|WS_VISIBLE|WS_VSCROLL| WS_HSCROLL |
00077 ES_AUTOVSCROLL|ES_MULTILINE|ES_WANTRETURN|ES_LEFT|
00078 dwStyle;
00079 if (!Create(dwEditStyle, m_Rect, pParent, nID)) return;
00080
00081 SetFont(pParent->GetFont());
00082
00083 SetWindowText(m_sInitText);
00084 SetFocus();
00085
00086 switch (nFirstChar){
00087 case VK_LBUTTON:
00088 case VK_RETURN:
00089 case VK_BACK: SetSel((int)_tcslen(m_sInitText), -1); break;
00090 case VK_TAB:
00091 case VK_DOWN:
00092 case VK_UP:
00093 case VK_RIGHT:
00094 case VK_LEFT:
00095 case VK_NEXT:
00096 case VK_PRIOR:
00097 case VK_HOME:
00098 case VK_SPACE:
00099 case VK_END: SetSel(0,-1); return;
00100 default: SetSel(0,-1);
00101 }
00102
00103 SendMessage(WM_CHAR, nFirstChar);
00104 }
00105
00106 CInPlaceMultiLine::~CInPlaceMultiLine()
00107 {
00108 }
00109
00110 BEGIN_MESSAGE_MAP(CInPlaceMultiLine, CEdit)
00111
00112 ON_WM_KILLFOCUS()
00113 ON_WM_CHAR()
00114 ON_WM_KEYDOWN()
00115 ON_WM_GETDLGCODE()
00116 ON_WM_CREATE()
00117
00118 END_MESSAGE_MAP()
00119
00121
00122
00123
00124
00125
00126 void CInPlaceMultiLine::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00127 {
00128 m_bInEditModus = TRUE;
00129
00130 if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
00131 nChar == VK_DOWN || nChar == VK_UP ||
00132 nChar == VK_RIGHT || nChar == VK_LEFT) &&
00133 (m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
00134 {
00135 m_nLastChar = nChar;
00136 GetParent()->SetFocus();
00137 return;
00138 }
00139
00140 CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
00141 }
00142
00143
00144 void CInPlaceMultiLine::OnKillFocus(CWnd* pNewWnd)
00145 {
00146 CEdit::OnKillFocus(pNewWnd);
00147 EndEdit();
00148 }
00149
00150 void CInPlaceMultiLine::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
00151 {
00152 if (nChar == VK_TAB )
00153 {
00154 m_nLastChar = nChar;
00155 GetParent()->SetFocus();
00156 return;
00157 }
00158 if (nChar == VK_ESCAPE)
00159 {
00160 SetWindowText(m_sInitText);
00161 m_nLastChar = nChar;
00162 GetParent()->SetFocus();
00163 return;
00164 }
00165 if (nChar == VK_RETURN && !m_bInEditModus)
00166 {
00167 return;
00168 }
00169
00170 CEdit::OnChar(nChar, nRepCnt, nFlags);
00171
00172
00173
00174
00175 CString str;
00176 GetWindowText( str );
00177
00178
00179 str += _T(" ");
00180
00181 CWindowDC dc(this);
00182 CFont *pFontDC = dc.SelectObject(GetFont());
00183
00184 CSize size = GetTextExtentMultiLine(m_Rect.Width (), str, &dc);
00185
00186 dc.SelectObject( pFontDC );
00187
00188
00189 CRect ParentRect;
00190 GetParent()->GetClientRect( &ParentRect );
00191
00192
00193
00194 if (size.cx > m_Rect.Width())
00195 {
00196 if( size.cx + m_Rect.left < ParentRect.right )
00197 m_Rect.right = m_Rect.left + size.cx;
00198 else
00199 m_Rect.right = ParentRect.right;
00200 MoveWindow( &m_Rect );
00201 }
00202 }
00203
00204 UINT CInPlaceMultiLine::OnGetDlgCode()
00205 {
00206 return DLGC_WANTALLKEYS;
00207 }
00208
00210
00211
00212
00213 BOOL CInPlaceMultiLine::PreTranslateMessage(MSG* pMsg)
00214 {
00215
00216 if (pMsg->message == WM_SYSCHAR)
00217 return TRUE;
00218
00219 return CWnd::PreTranslateMessage(pMsg);
00220 }
00221
00222
00223 void CInPlaceMultiLine::PostNcDestroy()
00224 {
00225 CEdit::PostNcDestroy();
00226
00227 delete this;
00228 }
00229
00231
00232
00233 void CInPlaceMultiLine::EndEdit()
00234 {
00235 CString str;
00236
00237
00238
00239
00240 static BOOL bAlreadyEnding = FALSE;
00241
00242 if(bAlreadyEnding)
00243 return;
00244
00245 bAlreadyEnding = TRUE;
00246 GetWindowText(str);
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 GV_DISPINFO dispinfo;
00265
00266 dispinfo.hdr.hwndFrom = GetSafeHwnd();
00267 dispinfo.hdr.idFrom = GetDlgCtrlID();
00268 dispinfo.hdr.code = GVN_ENDLABELEDIT;
00269
00270 dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
00271 dispinfo.item.row = m_nRow;
00272 dispinfo.item.col = m_nColumn;
00273 dispinfo.item.strText = str;
00274 dispinfo.item.lParam = (LPARAM) m_nLastChar;
00275
00276 CWnd* pOwner = GetOwner();
00277 if (pOwner)
00278 pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
00279
00280
00281 if (IsWindow(GetSafeHwnd()))
00282 SendMessage(WM_CLOSE, 0, 0);
00283 bAlreadyEnding = FALSE;
00284 }
00285
00286 CSize CInPlaceMultiLine::GetTextExtentMultiLine(int width, LPCTSTR szText, CDC* pDC )
00287 {
00288
00289
00290
00291 int nFormat = 0;
00292 CSize sz;
00293 CRect rect;
00294
00295 nFormat = DT_LEFT|DT_WORDBREAK;
00296 sz.cx = sz.cy = 0;
00297 rect.SetRect(0, 0, width, 0);
00298
00299 pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT);
00300
00301 sz = rect.Size();
00302
00303 return sz;
00304 }
00305
00307
00309
00310
00311 IMPLEMENT_DYNCREATE(CGridCellMultiLine, CGridCell)
00312
00313 CGridCellMultiLine::CGridCellMultiLine() : CGridCell()
00314 {
00315 SetStyle(ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_WANTRETURN);
00316
00317 SetHoldWidth ( TRUE);
00318 }
00319
00320
00321 BOOL CGridCellMultiLine::Edit(int nRow, int nCol, CRect rect, CPoint , UINT nID, UINT nChar)
00322 {
00323 m_bEditing = TRUE;
00324
00325
00326 m_pEditWnd = new CInPlaceMultiLine (GetGrid(), rect, GetStyle(), nID, nRow, nCol, GetText(), nChar);
00327
00328 return TRUE;
00329 }
00330
00331
00332 void CGridCellMultiLine::EndEdit()
00333 {
00334 if (m_pEditWnd)
00335 ((CInPlaceMultiLine*)m_pEditWnd)->EndEdit();
00336 }
00337
00338
00339 BOOL CGridCellMultiLine::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd )
00340 {
00341 return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
00342 }
00343
00344
00345
00346 CSize CGridCellMultiLine::GetTextExtentEx(int width, LPCTSTR szText, CDC* pDC )
00347 {
00348 CGridCtrl* pGrid = GetGrid();
00349 ASSERT(pGrid);
00350
00351 BOOL bReleaseDC = FALSE;
00352 if (pDC == NULL)
00353 {
00354 pDC = pGrid->GetDC();
00355 if (!pDC)
00356 {
00357 CGridDefaultCell* pDefCell = (CGridDefaultCell*) GetDefaultCell();
00358 ASSERT(pDefCell);
00359 return CSize(pDefCell->GetWidth(), pDefCell->GetHeight());
00360 }
00361 bReleaseDC = TRUE;
00362 }
00363
00364 CFont *pOldFont = NULL,
00365 *pFont = GetFontObject();
00366 if (pFont)
00367 pOldFont = pDC->SelectObject(pFont);
00368
00369 CSize size;
00370 int nFormat = GetFormat();
00371 TEXTMETRIC tm;
00372 pDC->GetTextMetrics(&tm);
00373
00374 int textWidth = width - (4*GetMargin ());
00375
00376
00377 if (textWidth <= 0)
00378 {
00379 textWidth = 1;
00380 }
00381
00382
00383
00384 if ((nFormat & DT_WORDBREAK) && !(nFormat & DT_SINGLELINE))
00385 {
00386 CRect rect;
00387 rect.SetRect(0, 0, textWidth, 0);
00388 pDC->DrawText(szText, -1, rect, nFormat | DT_CALCRECT);
00389
00390 size.cx = rect.Width ();
00391 size.cy = rect.Height ();
00392 }
00393 else
00394 size = pDC->GetTextExtent(szText, _tcslen(szText));
00395
00396 size.cx += (tm.tmOverhang);
00397
00398 if (pOldFont)
00399 pDC->SelectObject(pOldFont);
00400
00401 size += CSize(4*GetMargin(), 2*GetMargin());
00402
00403
00404 LOGFONT *pLF = GetFont();
00405 if (pLF->lfEscapement == 900 || pLF->lfEscapement == -900)
00406 {
00407 int nTemp = size.cx;
00408 size.cx = size.cy;
00409 size.cy = nTemp;
00410 size += CSize(0, 4*GetMargin());
00411 }
00412
00413 if (bReleaseDC)
00414 pGrid->ReleaseDC(pDC);
00415
00416 return size;
00417 }
00418
00419
00420 CSize CGridCellMultiLine::GetCellExtentEx(int width, CDC*pDC)
00421 {
00422 CSize ImageSize(0,0);
00423
00424 int nImage = GetImage();
00425 if (nImage >= 0)
00426 {
00427 CGridCtrl* pGrid = GetGrid();
00428 ASSERT(pGrid);
00429
00430 if (pGrid->GetImageList())
00431 {
00432 IMAGEINFO Info;
00433 if (pGrid->GetImageList()->GetImageInfo(nImage, &Info))
00434 ImageSize = CSize(Info.rcImage.right-Info.rcImage.left+1,
00435 Info.rcImage.bottom-Info.rcImage.top+1);
00436 }
00437 }
00438
00439
00440 CSize size = GetTextExtentEx(width - ImageSize.cx, GetText(), pDC);
00441
00442 CSize retSize(size.cx + ImageSize.cx, max(size.cy, ImageSize.cy));
00443
00444 return retSize;
00445 }
00446
00447