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
00030
00031
00032
00033
00035
00036 #include "stdafx.h"
00037 #include "../GridCtrl_src/GridCell.h"
00038 #include "../GridCtrl_src/GridCtrl.h"
00039
00040 #include "GridCellCombo.h"
00041
00042
00043 #ifdef _DEBUG
00044 #define new DEBUG_NEW
00045 #undef THIS_FILE
00046 static char THIS_FILE[] = __FILE__;
00047 #endif
00048
00049
00051
00052
00053 CComboEdit::CComboEdit()
00054 {
00055 }
00056
00057 CComboEdit::~CComboEdit()
00058 {
00059 }
00060
00061
00062 BOOL CComboEdit::PreTranslateMessage(MSG* pMsg)
00063 {
00064
00065 if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
00066 {
00067 ::TranslateMessage(pMsg);
00068 ::DispatchMessage(pMsg);
00069 return TRUE;
00070 }
00071
00072
00073 if (pMsg->message == WM_SYSCHAR)
00074 return TRUE;
00075
00076 return CEdit::PreTranslateMessage(pMsg);
00077 }
00078
00079 BEGIN_MESSAGE_MAP(CComboEdit, CEdit)
00080
00081 ON_WM_KILLFOCUS()
00082 ON_WM_KEYDOWN()
00083 ON_WM_KEYUP()
00084
00085 END_MESSAGE_MAP()
00086
00088
00089
00090 void CComboEdit::OnKillFocus(CWnd* pNewWnd)
00091 {
00092 CEdit::OnKillFocus(pNewWnd);
00093
00094 CInPlaceList* pOwner = (CInPlaceList*) GetOwner();
00095 if (pOwner)
00096 pOwner->EndEdit();
00097 }
00098
00099 void CComboEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00100 {
00101 if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
00102 nChar == VK_DOWN || nChar == VK_UP ||
00103 nChar == VK_RIGHT || nChar == VK_LEFT) &&
00104 (GetKeyState(VK_CONTROL) < 0 && GetDlgCtrlID() == IDC_COMBOEDIT))
00105 {
00106 CWnd* pOwner = GetOwner();
00107 if (pOwner)
00108 pOwner->SendMessage(WM_KEYDOWN, nChar, nRepCnt+ (((DWORD)nFlags)<<16));
00109 return;
00110 }
00111
00112 CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
00113 }
00114
00115 void CComboEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
00116 {
00117 if (nChar == VK_ESCAPE)
00118 {
00119 CWnd* pOwner = GetOwner();
00120 if (pOwner)
00121 pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
00122 return;
00123 }
00124
00125 if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
00126 {
00127 CWnd* pOwner = GetOwner();
00128 if (pOwner)
00129 pOwner->SendMessage(WM_KEYUP, nChar, nRepCnt + (((DWORD)nFlags)<<16));
00130 return;
00131 }
00132
00133 CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
00134 }
00135
00136
00138
00139
00140 CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
00141 int nRow, int nColumn,
00142 COLORREF crFore, COLORREF crBack,
00143 CStringArray& Items, CString sInitText,
00144 UINT nFirstChar)
00145 {
00146 m_crForeClr = crFore;
00147 m_crBackClr = crBack;
00148
00149 m_nNumLines = 4;
00150 m_sInitText = sInitText;
00151 m_nRow = nRow;
00152 m_nCol = nColumn;
00153 m_nLastChar = 0;
00154 m_bExitOnArrows = FALSE;
00155
00156
00157 DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL|
00158 CBS_AUTOHSCROLL | dwStyle;
00159 int nHeight = rect.Height();
00160 rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL);
00161 if (!Create(dwComboStyle, rect, pParent, nID)) return;
00162
00163
00164 for (int i = 0; i < Items.GetSize(); i++)
00165 AddString(Items[i]);
00166
00167 SetFont(pParent->GetFont());
00168 SetItemHeight(-1, nHeight);
00169
00170 int nMaxLength = GetCorrectDropWidth();
00171
00172
00173
00174
00175
00176
00177
00178 SetDroppedWidth(nMaxLength);
00179
00180 SetHorizontalExtent(0);
00181
00182
00183 if (::IsWindow(m_hWnd) && SelectString(-1, m_sInitText) == CB_ERR)
00184 SetWindowText(m_sInitText);
00185
00186 ShowDropDown();
00187
00188
00189 if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST)
00190 {
00191 m_edit.SubclassDlgItem(IDC_COMBOEDIT, this);
00192 SetFocus();
00193 switch (nFirstChar)
00194 {
00195 case VK_LBUTTON:
00196 case VK_RETURN: m_edit.SetSel((int)_tcslen(m_sInitText), -1); return;
00197 case VK_BACK: m_edit.SetSel((int)_tcslen(m_sInitText), -1); break;
00198 case VK_DOWN:
00199 case VK_UP:
00200 case VK_RIGHT:
00201 case VK_LEFT:
00202 case VK_NEXT:
00203 case VK_PRIOR:
00204 case VK_HOME:
00205 case VK_END: m_edit.SetSel(0,-1); return;
00206 default: m_edit.SetSel(0,-1);
00207 }
00208 SendMessage(WM_CHAR, nFirstChar);
00209 }
00210 else
00211 SetFocus();
00212 }
00213
00214 CInPlaceList::~CInPlaceList()
00215 {
00216 }
00217
00218 void CInPlaceList::EndEdit()
00219 {
00220 CString str;
00221 if (::IsWindow(m_hWnd))
00222 GetWindowText(str);
00223
00224
00225 GV_DISPINFO dispinfo;
00226
00227 dispinfo.hdr.hwndFrom = GetSafeHwnd();
00228 dispinfo.hdr.idFrom = GetDlgCtrlID();
00229 dispinfo.hdr.code = GVN_ENDLABELEDIT;
00230
00231 dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
00232 dispinfo.item.row = m_nRow;
00233 dispinfo.item.col = m_nCol;
00234 dispinfo.item.strText = str;
00235 dispinfo.item.lParam = (LPARAM) m_nLastChar;
00236
00237 CWnd* pOwner = GetOwner();
00238 if (IsWindow(pOwner->GetSafeHwnd()))
00239 pOwner->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
00240
00241
00242 if (::IsWindow(m_hWnd))
00243 PostMessage(WM_CLOSE, 0, 0);
00244 }
00245
00246 int CInPlaceList::GetCorrectDropWidth()
00247 {
00248 const int nMaxWidth = 200;
00249
00250
00251 int nNumEntries = GetCount();
00252 int nWidth = 0;
00253 CString str;
00254
00255 CClientDC dc(this);
00256 int nSave = dc.SaveDC();
00257 dc.SelectObject(GetFont());
00258
00259 int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
00260 for (int i = 0; i < nNumEntries; i++)
00261 {
00262 GetLBText(i, str);
00263 int nLength = dc.GetTextExtent(str).cx + nScrollWidth;
00264 nWidth = max(nWidth, nLength);
00265 }
00266
00267
00268 nWidth += dc.GetTextExtent("0").cx;
00269
00270 dc.RestoreDC(nSave);
00271
00272 nWidth = min(nWidth, nMaxWidth);
00273
00274 return nWidth;
00275
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 void CInPlaceList::PostNcDestroy()
00297 {
00298 CComboBox::PostNcDestroy();
00299
00300 delete this;
00301 }
00302
00303 BEGIN_MESSAGE_MAP(CInPlaceList, CComboBox)
00304
00305 ON_WM_KILLFOCUS()
00306 ON_WM_KEYDOWN()
00307 ON_WM_KEYUP()
00308 ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
00309 ON_WM_GETDLGCODE()
00310 ON_WM_CTLCOLOR_REFLECT()
00311
00312
00313 END_MESSAGE_MAP()
00314
00315
00317
00318
00319 UINT CInPlaceList::OnGetDlgCode()
00320 {
00321 return DLGC_WANTALLKEYS;
00322 }
00323
00324 void CInPlaceList::OnDropdown()
00325 {
00326 SetDroppedWidth(GetCorrectDropWidth());
00327 }
00328
00329 void CInPlaceList::OnKillFocus(CWnd* pNewWnd)
00330 {
00331 CComboBox::OnKillFocus(pNewWnd);
00332
00333 if (GetSafeHwnd() == pNewWnd->GetSafeHwnd())
00334 return;
00335
00336
00337 if ((GetStyle() & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
00338 EndEdit();
00339 }
00340
00341
00342
00343
00344 void CInPlaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00345 {
00346 if ((nChar == VK_PRIOR || nChar == VK_NEXT ||
00347 nChar == VK_DOWN || nChar == VK_UP ||
00348 nChar == VK_RIGHT || nChar == VK_LEFT) &&
00349 (m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0))
00350 {
00351 m_nLastChar = nChar;
00352 GetParent()->SetFocus();
00353 return;
00354 }
00355
00356 CComboBox::OnKeyDown(nChar, nRepCnt, nFlags);
00357 }
00358
00359
00360 void CInPlaceList::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
00361 {
00362 if (nChar == VK_ESCAPE)
00363 SetWindowText(m_sInitText);
00364
00365 if (nChar == VK_TAB || nChar == VK_RETURN || nChar == VK_ESCAPE)
00366 {
00367 m_nLastChar = nChar;
00368 GetParent()->SetFocus();
00369 return;
00370 }
00371
00372 CComboBox::OnKeyUp(nChar, nRepCnt, nFlags);
00373 }
00374
00375 HBRUSH CInPlaceList::CtlColor(CDC* , UINT )
00376 {
00377
00378
00379
00380
00381
00382
00383
00384
00385 return NULL;
00386 }
00387
00389
00391
00392
00393 IMPLEMENT_DYNCREATE(CGridCellCombo, CGridCell)
00394
00395 CGridCellCombo::CGridCellCombo() : CGridCell()
00396 {
00397 SetStyle(CBS_DROPDOWN);
00398 }
00399
00400
00401 BOOL CGridCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint , UINT nID, UINT nChar)
00402 {
00403 m_bEditing = TRUE;
00404
00405
00406 m_pEditWnd = new CInPlaceList(GetGrid(), rect, GetStyle(), nID, nRow, nCol,
00407 GetTextClr(), GetBackClr(), m_Strings, GetText(), nChar);
00408
00409 return TRUE;
00410 }
00411
00412 CWnd* CGridCellCombo::GetEditWnd() const
00413 {
00414 if (m_pEditWnd && (m_pEditWnd->GetStyle() & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST )
00415 return &(((CInPlaceList*)m_pEditWnd)->m_edit);
00416
00417 return NULL;
00418 }
00419
00420 CSize CGridCellCombo::GetCellExtent(CDC* pDC)
00421 {
00422 CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CYHSCROLL));
00423
00424 return CGridCell::GetCellExtent(pDC) + sizeScroll;
00425 }
00426
00427
00428 void CGridCellCombo::EndEdit()
00429 {
00430 if (m_pEditWnd)
00431 ((CInPlaceList*)m_pEditWnd)->EndEdit();
00432 }
00433
00434
00435 BOOL CGridCellCombo::Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd )
00436 {
00437 #ifdef _WIN32_WCE
00438 return CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
00439 #else
00440
00441
00442 if (GetGrid()->IsCellEditable(nRow, nCol) && !IsEditing())
00443 {
00444
00445 CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CYHSCROLL));
00446
00447
00448 if (sizeScroll.cy < rect.Width() && sizeScroll.cy < rect.Height())
00449 {
00450
00451 CRect ScrollRect = rect;
00452 ScrollRect.left = rect.right - sizeScroll.cx;
00453 ScrollRect.bottom = rect.top + sizeScroll.cy;
00454
00455
00456 pDC->DrawFrameControl(ScrollRect, DFC_SCROLL, DFCS_SCROLLDOWN);
00457
00458
00459 rect.right = ScrollRect.left;
00460 }
00461 }
00462
00463 CString strTempText = GetText();
00464 if (IsEditing())
00465 SetText(_T(""));
00466
00467
00468 BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect, bEraseBkgnd);
00469
00470 if (IsEditing())
00471 SetText(strTempText);
00472
00473 return bResult;
00474 #endif
00475 }
00476
00477
00478 void CGridCellCombo::SetOptions(CStringArray& ar)
00479 {
00480 m_Strings.RemoveAll();
00481 for (int i = 0; i < ar.GetSize(); i++)
00482 m_Strings.Add(ar[i]);
00483 }