GME
13
|
00001 // InPlaceManager.cpp: implementation of the CInPlaceManager class. 00002 // 00004 00005 #include "stdafx.h" 00006 #include "InspectorList.h" 00007 #include "objectinspector.h" 00008 #include "InPlaceManager.h" 00009 #include "CompassCheckDlg.h" 00010 #include "CompassOptDlg.h" 00011 #include "ComboBoxSelectDlg.h" 00012 #include "ColourPopup.h" 00013 #include "MgaUtil.h" 00014 00015 #ifdef _DEBUG 00016 #undef THIS_FILE 00017 static char THIS_FILE[]=__FILE__; 00018 #define new DEBUG_NEW 00019 #endif 00020 00022 // Construction/Destruction 00024 00025 CInPlaceManager::CInPlaceManager(CInspectorList* pInspectorList) 00026 { 00027 m_pInspectorList=pInspectorList; 00028 } 00029 00030 CInPlaceManager::~CInPlaceManager() 00031 { 00032 00033 } 00034 00035 void CInPlaceManager::ShowInPlace(CRect rectInPlace, int nIndex) 00036 { 00037 00038 HideAllInPlace(); 00039 int nSelCount=m_pInspectorList->GetSelCount(); 00040 if(nSelCount!=1) 00041 { 00042 return; 00043 } 00044 00045 m_nCurrentIndex=nIndex; 00046 00047 CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(nIndex); 00048 00049 ListItem.Value.toString(); 00050 switch(ListItem.Value.dataType) 00051 { 00052 case ITEMDATA_NULL: 00053 { 00054 00055 }break; 00056 00057 case ITEMDATA_STRING: 00058 { 00059 if(ListItem.Value.cLineNum>1) 00060 { 00061 if(!ListItem.bIsReadOnly) { 00062 DisplayEditorButton(rectInPlace); 00063 } 00064 00065 DisplayMultilineEdit(rectInPlace, ListItem.bIsReadOnly); 00066 CString strText; // zolmol modification 00067 int uLim = ListItem.Value.stringVal.GetUpperBound(); // if empty uLim == -1 00068 for(int i=0;i<=uLim;i++) 00069 { 00070 strText+=ListItem.Value.stringVal[i]; 00071 if( i != uLim) 00072 strText+=_T("\r\n"); 00073 } 00074 // there is no newline at the end of the last line 00075 m_MultiEditCtrl.SetWindowText(strText);//WAS: strText.Left(strText.GetLength()-2) 00076 m_MultiEditCtrl.SetFocus(); 00077 00078 } 00079 else 00080 { 00081 DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly); 00082 00083 m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]); 00084 00085 int nLength=ListItem.Value.stringVal[0].GetLength(); 00086 m_SingleEditCtrl.SetSel(nLength,nLength); 00087 } 00088 00089 }break; 00090 00091 00092 case ITEMDATA_FIXED_LIST: 00093 { 00094 if(!ListItem.bIsReadOnly) { 00095 DisplayArrowButton(rectInPlace); 00096 } 00097 00098 }break; 00099 00100 00101 case ITEMDATA_INTEGER: 00102 { 00103 DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly); 00104 00105 m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]); 00106 int nLength=ListItem.Value.stringVal[0].GetLength(); 00107 m_SingleEditCtrl.SetSel(nLength,nLength); 00108 00109 00110 }break; 00111 case ITEMDATA_DOUBLE: 00112 { 00113 DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly); 00114 00115 m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]); 00116 int nLength=ListItem.Value.stringVal[0].GetLength(); 00117 m_SingleEditCtrl.SetSel(nLength,nLength); 00118 00119 00120 }break; 00121 case ITEMDATA_BOOLEAN: 00122 { 00123 if(!ListItem.bIsReadOnly) { 00124 DisplayArrowButton(rectInPlace); 00125 } 00126 }break; 00127 00128 case ITEMDATA_COLOR : 00129 { 00130 if(!ListItem.bIsReadOnly) { 00131 DisplayArrowButton(rectInPlace); 00132 } 00133 }break; 00134 00135 case ITEMDATA_COMPASS: 00136 { 00137 if(!ListItem.bIsReadOnly) { 00138 DisplayArrowButton(rectInPlace); 00139 } 00140 }break; 00141 00142 case ITEMDATA_COMPASS_EXCL: 00143 { 00144 if(!ListItem.bIsReadOnly) { 00145 DisplayArrowButton(rectInPlace); 00146 } 00147 }break; 00148 } 00149 } 00150 00151 void CInPlaceManager::DisplayMultilineEdit(CRect rectBound, bool readOnly) 00152 { 00153 00154 rectBound.bottom--; 00155 rectBound.bottom--; 00156 00157 if(!::IsWindow(m_MultiEditCtrl.GetSafeHwnd())) 00158 { 00159 m_MultiEditCtrl.Create(ES_WANTRETURN|ES_AUTOVSCROLL |WS_VSCROLL|ES_MULTILINE | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE |ES_LEFT,rectBound,m_pInspectorList,IDC_EDITBOX_MULTILINE); 00160 00161 00162 m_MultiEditCtrl.SetFont(&m_pInspectorList->m_entryFont); 00163 m_MultiEditCtrl.SetFocus(); 00164 } 00165 else 00166 { 00167 if(!m_MultiEditCtrl.IsWindowVisible()) 00168 { 00169 m_MultiEditCtrl.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height()); 00170 m_MultiEditCtrl.ShowWindow(SW_SHOW); 00171 // m_MultiEditCtrl.SetFocus(); 00172 } 00173 else 00174 { 00175 m_MultiEditCtrl.SetFocus(); 00176 m_MultiEditCtrl.Invalidate(); 00177 } 00178 } 00179 m_MultiEditCtrl.SetReadOnly(readOnly ? TRUE : FALSE); 00180 } 00181 00182 00183 void CInPlaceManager::DisplaySingleLineEdit(CRect rectBound, bool readOnly) 00184 { 00185 00186 rectBound.bottom--; 00187 rectBound.bottom--; 00188 00189 if(!::IsWindow(m_SingleEditCtrl.GetSafeHwnd())) 00190 { 00191 m_SingleEditCtrl.Create(WS_CHILD| WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT,rectBound,m_pInspectorList,IDC_EDITBOX_SINGLELINE); 00192 00193 00194 m_SingleEditCtrl.SetFont(&m_pInspectorList->m_entryFont); 00195 m_SingleEditCtrl.SetFocus(); 00196 00197 } 00198 else 00199 { 00200 if(!m_SingleEditCtrl.IsWindowVisible()) 00201 { 00202 m_SingleEditCtrl.SetWindowText(_T("")); 00203 m_SingleEditCtrl.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height()); 00204 m_SingleEditCtrl.ShowWindow(SW_SHOW); 00205 m_SingleEditCtrl.SetFocus(); 00206 } 00207 else 00208 { 00209 m_SingleEditCtrl.SetFocus(); 00210 m_SingleEditCtrl.Invalidate(); 00211 } 00212 } 00213 m_SingleEditCtrl.SetReadOnly(readOnly ? TRUE : FALSE); 00214 } 00215 00216 void CInPlaceManager::DisplayColorCombo(CRect rectBound, bool rightSideClick) 00217 { 00218 m_pInspectorList->ClientToScreen(rectBound); 00219 00220 CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00221 00222 CColourPopup dlg(m_pInspectorList); 00223 dlg.SetParameters(rectBound, // rect to display popup 00224 ListItem.Value.colorVal, // Selected colour 00225 rightSideClick, // summoned by arrow button click or right side click 00226 _T("Default"), // "Default" text area 00227 _T("More Colors..")); // Custom Text 00228 00229 if(dlg.DoModal()==IDOK) 00230 { 00231 if (dlg.m_nCurrentSel == DEFAULT_BOX_VALUE) 00232 { 00233 ListItem.RestoreDefault(); 00234 } 00235 else 00236 { 00237 ListItem.Value.SetColorValue(dlg.GetSelectedColor()); 00238 ListItem.SetDirty(); 00239 } 00240 00241 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00242 00243 m_pInspectorList->Invalidate(); 00244 } 00245 00246 m_pInspectorList->SetFocus(); 00247 } 00248 00249 00250 00251 00252 00253 void CInPlaceManager::HideAllInPlace() 00254 { 00255 HideEdit(); 00256 HideArrowButton(); 00257 HideEditorButton(); 00258 } 00259 00260 00261 void CInPlaceManager::HideEdit() 00262 { 00263 if(::IsWindow(m_SingleEditCtrl.GetSafeHwnd())) 00264 { 00265 m_SingleEditCtrl.ShowWindow(SW_HIDE); 00266 } 00267 00268 if(::IsWindow(m_MultiEditCtrl.GetSafeHwnd())) 00269 { 00270 m_MultiEditCtrl.ShowWindow(SW_HIDE); 00271 } 00272 } 00273 00274 00275 void CInPlaceManager::DisplayArrowButton(CRect rectBound) 00276 { 00277 rectBound.top--; 00278 rectBound.bottom--; 00279 rectBound.top--; 00280 rectBound.bottom--; 00281 00282 rectBound.left=rectBound.right-rectBound.Height(); 00283 if(!::IsWindow(m_ArrowButton.GetSafeHwnd()) ) 00284 { 00285 m_ArrowButton.Create(_T("ArrowButton"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,rectBound,m_pInspectorList,IDC_ARROW_BUTTON); 00286 } 00287 else 00288 { 00289 m_ArrowButton.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height()); 00290 m_ArrowButton.ShowWindow(SW_SHOW); 00291 } 00292 00293 m_ArrowButton.Invalidate(); 00294 } 00295 00296 void CInPlaceManager::DisplayEditorButton(CRect rectBound) 00297 { 00298 // Get External Editor prefs and display editor button if needed 00299 CComPtr<IMgaRegistrar> registrar; 00300 try { 00301 COMTHROW( registrar.CoCreateInstance(OLESTR("MGA.MgaRegistrar")) ); 00302 ASSERT( registrar != NULL ); 00303 00304 VARIANT_BOOL extenable; 00305 COMTHROW( registrar->get_ExternalEditorEnabled(REGACCESS_USER, &extenable) ); 00306 if (extenable == VARIANT_FALSE) { 00307 return; 00308 } 00309 } 00310 catch (hresult_exception &) { 00311 return; 00312 } 00313 00314 00315 CBitmap bm; 00316 bm.LoadMappedBitmap(IDB_BITMAP_EDITOR); 00317 00318 CSize bmSize; 00319 BITMAP bmStruct; 00320 if (bm.GetBitmap(&bmStruct)) { 00321 bmSize.cx = bmStruct.bmWidth; 00322 bmSize.cy = bmStruct.bmHeight; 00323 } 00324 00325 CRect rect; 00326 rect.top = rectBound.top; 00327 rect.bottom = rect.top + bmSize.cy; 00328 rect.right = rectBound.left - 2; // Shift it 00329 rect.left = rect.right - bmSize.cx; 00330 00331 if(!::IsWindow(m_EditorButton.GetSafeHwnd()) ) 00332 { 00333 m_EditorButton.Create(_T("EditorButton"),WS_CHILD|WS_VISIBLE|BS_BITMAP,rect,m_pInspectorList,IDC_EDITOR_BUTTON); 00334 m_EditorButton.SetBitmap(bm); 00335 bm.Detach(); 00336 00337 } 00338 else 00339 { 00340 m_EditorButton.MoveWindow(rect.left,rect.top,rect.Width(),rect.Height()); 00341 m_EditorButton.ShowWindow(SW_SHOW); 00342 } 00343 00344 m_EditorButton.Invalidate(); 00345 } 00346 00347 00348 void CInPlaceManager::HideArrowButton() 00349 { 00350 if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) ) 00351 { 00352 m_ArrowButton.ShowWindow(SW_HIDE); 00353 } 00354 } 00355 00356 void CInPlaceManager::HideEditorButton() 00357 { 00358 if(::IsWindowVisible(m_EditorButton.GetSafeHwnd()) ) 00359 { 00360 m_EditorButton.ShowWindow(SW_HIDE); 00361 } 00362 } 00363 00364 void CInPlaceManager::OnClickEditorButton() 00365 { 00366 CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00367 ASSERT(ListItem.Value.dataType == ITEMDATA_STRING); 00368 ASSERT(ListItem.Value.cLineNum > 1); 00369 00370 // Create temporary file 00371 TCHAR szTempPath[MAX_PATH]; 00372 if (::GetTempPath(MAX_PATH, szTempPath) == 0) { 00373 return; 00374 } 00375 00376 TCHAR szTempFileName[MAX_PATH]; 00377 if (::GetTempFileName(szTempPath, _T("GME"), 0, szTempFileName) == 0) { 00378 ASSERT(("Unable to get temporary filename.", false)); 00379 return; 00380 } 00381 00382 CString szAppPath; 00383 bool content_specific_editor = false; 00384 00385 if( !ListItem.strContentType.IsEmpty()) 00386 { 00387 CString extension; 00388 bool content_type_valid = true; 00389 if( ListItem.strContentType.GetAt(0) == _T('.')) // starts with '.' -> interpret it as extension 00390 extension = ListItem.strContentType; 00391 else // interpret it as MIME type (Content-Type), and lookup the extension corresponding to it 00392 content_type_valid = CInPlaceManager::findInfoInMimeDB( ListItem.strContentType, szAppPath, extension); 00393 00394 if( content_type_valid) // remove the file created above by GetTempFileName 00395 CFile::Remove( szTempFileName); 00396 00397 content_specific_editor = true; 00398 // if enough space, append the extension to the filename 00399 if( content_type_valid && _tcslen( szTempFileName) + extension.GetLength() <= MAX_PATH - 1) // there is enough room for appending the extension 00400 _tcscat( szTempFileName, extension); 00401 else if( content_type_valid && extension.GetLength() == 4) // replace tailing .tmp with extension 00402 _tcsncpy( szTempFileName + _tcslen( szTempFileName) - 4, extension, 4); 00403 else // can't use the content_specific_editor because the extension is not appended 00404 content_specific_editor = false; 00405 00406 // we could use findCommand (implemented at bottom of file) to locate the command 00407 // assigned for open/edit verbs, but we choose to rely on the ShellExecute call 00408 //if( content_type_valid) 00409 //{ 00410 // content_specific_editor = findCommand( extension, szAppPath); 00411 // if( szAppPath.Find( "%1") != -1) // if "%1" found in command string replace it with tempfilename 00412 // szAppPath.Replace( "%1", szTempFileName); 00413 //} 00414 } 00415 00416 CStdioFile tempFile; 00417 if (tempFile.Open(szTempFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText) == 0) { 00418 ASSERT(("Unable to create temporary file.", false)); 00419 return; 00420 } 00421 00422 // write attribute value to the temporary file 00423 for(int i=0;i<=ListItem.Value.stringVal.GetUpperBound();i++) 00424 { 00425 CString strLine = ListItem.Value.stringVal[i]; 00426 strLine.TrimRight(_T("\r\n")); 00427 tempFile.WriteString(strLine + _T("\n")); 00428 } 00429 00430 tempFile.Close(); 00431 00432 BOOL launched = FALSE; 00433 if( content_specific_editor) 00434 { 00435 if( !szAppPath.IsEmpty()) // GMEEditor value found in MimeDB 00436 { 00437 CString szCommandLine = _T(" "); 00438 szCommandLine += szTempFileName; 00439 int nCommandLineLength = szCommandLine.GetLength(); 00440 00441 // startup info for the redactor's process is taken similar to that 00442 // of invoking application 00443 STARTUPINFO startUpInfo; 00444 PROCESS_INFORMATION processInfo; 00445 ::GetStartupInfo(&startUpInfo); 00446 00447 // start pref'd editor with the file name as the command line parameter 00448 launched = ::CreateProcess(szAppPath,szCommandLine.GetBuffer(nCommandLineLength), 00449 NULL,NULL,FALSE,0,NULL,NULL,&startUpInfo,&processInfo); 00450 szCommandLine.ReleaseBuffer(); 00451 CloseHandle(processInfo.hProcess); 00452 CloseHandle(processInfo.hThread); 00453 } 00454 00455 if( !launched) 00456 { 00457 // success codes are strictly greater than 32 00458 int retcode = (int) ShellExecute( (HWND) m_EditorButton, _T("edit"), szTempFileName, 0, 0, SW_SHOWNORMAL); 00459 if( retcode == SE_ERR_NOASSOC) // failed because no such verb (edit) exists for this extension 00460 retcode = (int) ShellExecute( (HWND) m_EditorButton, _T("open"), szTempFileName, 0, 0, SW_SHOWNORMAL); 00461 00462 launched = retcode > 32; 00463 // if it was not launched successfully, use the specified editor 00464 } 00465 } 00466 00467 if( !launched) // if not found a content specific one, or if it failed to launch 00468 { 00469 // Get External Editor prefs and build command line for the editor application 00470 CComPtr<IMgaRegistrar> registrar; 00471 try { 00472 COMTHROW( registrar.CoCreateInstance(OLESTR("MGA.MgaRegistrar")) ); 00473 ASSERT( registrar != NULL ); 00474 COMTHROW( registrar->get_ExternalEditor(REGACCESS_USER, PutOut(szAppPath)) ); 00475 } 00476 catch (hresult_exception &) { 00477 } 00478 00479 CString szCommandLine = szAppPath + _T(" "); 00480 szCommandLine += szTempFileName; 00481 int nCommandLineLength = szCommandLine.GetLength(); 00482 00483 // startup info for the redactor's process is taken similar to that 00484 // of invoking application 00485 STARTUPINFO startUpInfo; 00486 PROCESS_INFORMATION processInfo; 00487 ::GetStartupInfo(&startUpInfo); 00488 00489 // start notepad.exe with the XML file name as the command line parameter 00490 00491 launched = ::CreateProcess(NULL, szCommandLine.GetBuffer(nCommandLineLength), 00492 NULL,NULL,FALSE,0,NULL,NULL,&startUpInfo,&processInfo); 00493 szCommandLine.ReleaseBuffer(); 00494 CloseHandle(processInfo.hProcess); 00495 CloseHandle(processInfo.hThread); 00496 } 00497 00498 // DWORD h = ::WaitForSingleObject(processInfo.hProcess, INFINITE); 00499 if (launched) 00500 { 00501 m_EditorButton.MessageBox(_T("Click OK to finish."), _T("Using External Text Editor"), MB_ICONINFORMATION); 00502 } 00503 00504 // open temporary file 00505 if (tempFile.Open(szTempFileName, CFile::modeRead | CFile::typeText) == 0) { 00506 ASSERT(("Unable to open temporary file.", false)); 00507 return; 00508 } 00509 00510 // read attribute value from the temporary file 00511 ListItem.Value.stringVal.RemoveAll(); 00512 CString strLine; 00513 while (tempFile.ReadString(strLine) == TRUE) { 00514 strLine.TrimRight(_T("\r\n")); 00515 ListItem.Value.stringVal.Add(strLine); 00516 } 00517 00518 tempFile.Close(); 00519 00520 ListItem.SetDirty(); 00521 00522 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00523 00524 m_pInspectorList->SetFocus(); 00525 00526 00527 00528 } 00529 00530 void CInPlaceManager::OnClickArrowButton(bool rightSideClick) 00531 { 00532 00533 CRect rectArrow; 00534 00535 m_ArrowButton.GetWindowRect(rectArrow); 00536 m_pInspectorList->ScreenToClient(rectArrow); 00537 CRect rectWnd(m_pInspectorList->m_Settings.m_nDivider,rectArrow.bottom-1,rectArrow.right,rectArrow.bottom-1); 00538 00539 CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00540 00541 00542 switch(ListItem.Value.dataType) 00543 { 00544 case ITEMDATA_COMPASS: 00545 { 00546 rectWnd.bottom+=100; 00547 DisplayCompassCheck(rectWnd); 00548 }break; 00549 00550 case ITEMDATA_COMPASS_EXCL: 00551 { 00552 rectWnd.bottom+=100; 00553 DisplayCompassOpt(rectWnd); 00554 }break; 00555 00556 case ITEMDATA_BOOLEAN: 00557 { 00558 rectWnd.bottom += 2 * m_pInspectorList->m_ComboboxLineHeight + 2; 00559 DisplayCombo(rectWnd); 00560 }break; 00561 case ITEMDATA_FIXED_LIST: 00562 { 00563 rectWnd.bottom += min(ListItem.Value.stringVal.GetSize(), 8) 00564 * m_pInspectorList->m_ComboboxLineHeight + 2; 00565 DisplayCombo(rectWnd); 00566 }break; 00567 00568 case ITEMDATA_COLOR: 00569 { 00570 DisplayColorCombo(rectWnd, rightSideClick); 00571 }break; 00572 00573 default: 00574 { 00575 // This should not happen here 00576 ASSERT(0); 00577 } 00578 } 00579 00580 if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) ) 00581 m_ArrowButton.Invalidate(); 00582 } 00583 00584 00585 void CInPlaceManager::DisplayCompassCheck(CRect rectBound) 00586 { 00587 CCompassCheckDlg dlg(m_pInspectorList); 00588 00589 CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00590 UINT uCompassVal=ListItem.Value.compassVal; 00591 CPoint ptDlgTopRight(rectBound.right,rectBound.top); 00592 m_pInspectorList->ClientToScreen(&ptDlgTopRight); 00593 dlg.SetParameters(ptDlgTopRight, uCompassVal); 00594 00595 if(dlg.DoModal()==IDOK) 00596 { 00597 ListItem.Value.SetCompassValue(dlg.GetCompassVal()); 00598 00599 ListItem.SetDirty(); 00600 00601 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00602 } 00603 00604 m_pInspectorList->SetFocus(); 00605 } 00606 00607 void CInPlaceManager::DisplayCompassOpt(CRect rectBound) 00608 { 00609 CCompassOptDlg dlg(m_pInspectorList); 00610 00611 CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00612 UINT uCompassVal=ListItem.Value.compassVal; 00613 CPoint ptDlgTopRight(rectBound.right,rectBound.top); 00614 m_pInspectorList->ClientToScreen(&ptDlgTopRight); 00615 dlg.SetParameters(ptDlgTopRight, uCompassVal); 00616 00617 if(dlg.DoModal()==IDOK) 00618 { 00619 ListItem.Value.SetCompassExclValue(dlg.GetCompassVal()); 00620 ListItem.SetDirty(); 00621 00622 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00623 } 00624 00625 m_pInspectorList->SetFocus(); 00626 } 00627 00628 00629 void CInPlaceManager::DisplayCombo(CRect rectBound) 00630 { 00631 CComboBoxSelectDlg dlg(m_pInspectorList, m_pInspectorList->m_ComboboxLineHeight); 00632 00633 CListItem& ListItem = m_pInspectorList->m_ListItemArray.ElementAt( m_nCurrentIndex ); 00634 m_pInspectorList->ClientToScreen( &rectBound ); 00635 dlg.SetParameters(rectBound, &ListItem, &m_pInspectorList->m_entryFont); 00636 00637 if ( dlg.DoModal() == IDOK ) { 00638 ListItem.SetDirty(); 00639 m_pInspectorList->NotifyParent( m_nCurrentIndex ); 00640 } 00641 00642 m_pInspectorList->SetFocus(); 00643 } 00644 00645 void CInPlaceManager::OnEditMultiLineEnd() 00646 { 00647 CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00648 00649 ASSERT(ListItem.Value.dataType==ITEMDATA_STRING); 00650 00651 ASSERT(ListItem.Value.cLineNum>1); 00652 00653 int nLines=m_MultiEditCtrl.GetLineCount(); 00654 ASSERT( nLines); // nLines >= 1 always 00655 00656 00657 CString strLine; 00658 ListItem.Value.stringVal.RemoveAll(); 00659 int nLineLength=m_MultiEditCtrl.GetWindowTextLength(); 00660 // To Zoltan's comment: 00661 // http://groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/f75d48b8655dde0e 00662 // There are two errors with CEdit GetLine 00663 // 1.: GetLine cannot return less than two characters, so if there's just one character, we should still supply 00664 // a buffer for two characters (in ANSI: two bytes) 00665 // 2.: If the edit control is empty, the GetLine call returns two null terminators 00666 // (this caused the phenomena Zoltan encountered) 00667 // **** 00668 // zolmol: avoid trimming in case when the field is cleared: nLineLength = 0 and nLines = 1 00669 // (corrupted strLine inserted into ListItem caused memory damage when released) 00670 if( nLineLength > 0 ) 00671 { 00672 for(int i=0;i<nLines;i++) 00673 { 00674 strLine = CEditGetLine(m_MultiEditCtrl, i); 00675 strLine.TrimRight(_T("\r\n")); 00676 ListItem.Value.stringVal.Add(strLine); 00677 } 00678 } 00679 00680 ListItem.SetDirty(); 00681 00682 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00683 00684 m_pInspectorList->Invalidate(); 00685 } 00686 00687 void CInPlaceManager::OnEditSingleLineEnd() 00688 { 00689 CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00690 00691 00692 CString strText; 00693 m_SingleEditCtrl.GetWindowText(strText); 00694 00695 switch(ListItem.Value.dataType) 00696 { 00697 case ITEMDATA_STRING: 00698 { 00699 ListItem.Value.SetStringValue(strText); 00700 00701 if(!ListItem.Value.Validate()) { 00702 m_pInspectorList->MessageBox(_T("Invalid (non ASCII) string data: ")+strText,_T("Object Inspector"),MB_ICONERROR); 00703 m_pInspectorList->SetFocus(); 00704 } 00705 else { 00706 ListItem.SetDirty(); 00707 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00708 00709 m_pInspectorList->Invalidate(); 00710 } 00711 }break; 00712 00713 case ITEMDATA_INTEGER: 00714 { 00715 ListItem.Value.stringVal[0]=strText; 00716 00717 if(!ListItem.Value.Validate()) 00718 { 00719 m_pInspectorList->MessageBox(_T("Invalid integer data: ")+strText,_T("Object Inspector"),MB_ICONERROR); 00720 // Restoring correct value 00721 ListItem.Value.toString(); 00722 m_pInspectorList->SetFocus(); 00723 } 00724 else 00725 { 00726 ListItem.SetDirty(); 00727 00728 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00729 } 00730 00731 }break; 00732 00733 case ITEMDATA_DOUBLE: 00734 { 00735 ListItem.Value.stringVal[0]=strText; 00736 00737 if(!ListItem.Value.Validate()) 00738 { 00739 m_pInspectorList->MessageBox(_T("Invalid floating point data: ")+strText,_T("Object Inspector"),MB_ICONERROR); 00740 // Restoring correct value 00741 ListItem.Value.toString(); 00742 m_pInspectorList->SetFocus(); 00743 } 00744 else 00745 { 00746 ListItem.SetDirty(); 00747 00748 m_pInspectorList->NotifyParent(m_nCurrentIndex); 00749 } 00750 00751 }break; 00752 00753 default: 00754 { 00755 ASSERT(0); // Should not happen 00756 } 00757 } 00758 00759 00760 } 00761 00762 00763 bool CInPlaceManager::OnRightItemClick(int nIndex, CRect rectInPlace) 00764 { 00765 // User request: color and direction selection popups and other popup should pop up not only by the 00766 // arrow click, but the right side line click too 00767 if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) ) 00768 { 00769 if (nIndex == m_nCurrentIndex) { 00770 OnClickArrowButton(true); 00771 return true; 00772 } 00773 } 00774 00775 return false; 00776 } 00777 00778 00779 void CInPlaceManager::OnEditEnd() 00780 { 00781 CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex); 00782 if(ListItem.Value.dataType==ITEMDATA_STRING&& ListItem.Value.cLineNum>1) 00783 { 00784 OnEditMultiLineEnd(); 00785 } 00786 else 00787 { 00788 OnEditSingleLineEnd(); 00789 } 00790 } 00791 00792 /*static*/ bool CInPlaceManager::findInfoInMimeDB( const CString& pContentType, CString& pPrefApp, CString& pExtension) 00793 { 00794 // mime types (content types) are enumerated under: 00795 const TCHAR MIME_DB[] = _T("MIME\\Database\\Content Type\\"); 00796 const TCHAR EXTENSION_VALUE[] = _T("Extension"); 00797 const TCHAR GMEEDITOR_VALUE[] = _T("GMEEditor"); // a developer might introduce here a GME specific value (by an installer) 00798 00799 CRegKey rk; 00800 LONG res = rk.Open( HKEY_CLASSES_ROOT, MIME_DB + pContentType, KEY_READ); 00801 00802 if( res != ERROR_SUCCESS) // such a mime type not found 00803 return false; 00804 00805 // an Extension value exists hopefully 00806 ULONG buff_len = 32; // we don't expect wider extensions than 32 00807 CString ext(_T(' '), buff_len); 00808 TCHAR* buff = ext.GetBufferSetLength( buff_len); 00809 res = rk.QueryStringValue( EXTENSION_VALUE, buff, &buff_len); 00810 ext.ReleaseBufferSetLength( buff_len); 00811 00812 if( res != ERROR_SUCCESS) 00813 ext.Empty(); // will not return succesfully 00814 00815 buff_len = MAX_PATH; 00816 CString pref_app(_T(' '), buff_len); 00817 buff = pref_app.GetBufferSetLength( buff_len); 00818 res = rk.QueryStringValue( GMEEDITOR_VALUE, buff, &buff_len); 00819 pref_app.ReleaseBufferSetLength( buff_len); 00820 rk.Close(); 00821 00822 if( res != ERROR_SUCCESS) 00823 pref_app.Empty(); // this is not an error 00824 00825 pPrefApp = pref_app; 00826 pExtension = ext; 00827 return !pExtension.IsEmpty(); 00828 } 00829 00830 // finds the Open/Edit verb defined for the file class (extension) 00831 // format of returned string pCommand 00832 // "C:\Program Files\Windows Media Player\wmplayer.exe" "%L" 00833 // "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" "%1" 00834 // "C:\Program Files\Opera8\Opera.exe" "%1" 00835 // "C:\Program Files\apps\Microsoft Office\Office10\msohtmed.exe" %1 00836 // 00838 //{ 00839 // if( pExtension.IsEmpty() || pExtension.GetAt(0) != '.') return false; 00840 // 00841 // CRegKey rk; 00842 // LONG res; 00843 // res = rk.Open( HKEY_CLASSES_ROOT, pExtension , KEY_READ); 00844 // if( res != ERROR_SUCCESS) // such an extension not found 00845 // return false; 00846 // 00847 // // for each extension a file class is created typically: .xls -> Excel.Sheet.8 00848 // ULONG buff_len = 256; // it is enough long for a file class name 00849 // CString file_class( ' ', buff_len); 00850 // TCHAR * buff = file_class.GetBufferSetLength( buff_len); 00851 // res = rk.QueryStringValue( 0, buff, &buff_len); 00852 // file_class.ReleaseBufferSetLength( buff_len); 00853 // 00854 // rk.Close(); 00855 // if( res != ERROR_SUCCESS) 00856 // return false; 00857 // 00858 // file_class = buff; 00859 // 00860 // res = rk.Open(HKEY_CLASSES_ROOT, file_class , KEY_READ); 00861 // if( res != ERROR_SUCCESS) return false; 00862 // 00863 // CRegKey sk; 00864 // const TCHAR SHELL_EDIT_COMMAND[] = _T("SHELL\\EDIT\\COMMAND"); 00865 // const TCHAR SHELL_OPEN_COMMAND[] = _T("SHELL\\OPEN\\COMMAND"); 00866 // 00867 // res = sk.Open( rk, SHELL_EDIT_COMMAND, KEY_READ); 00868 // if( res != ERROR_SUCCESS) 00869 // { 00870 // res = sk.Open( rk, SHELL_OPEN_COMMAND, KEY_READ); // this is the most common 00871 // if( res != ERROR_SUCCESS) 00872 // return false; 00873 // } 00874 // 00875 // 00876 // ULONG cmd_len = MAX_PATH; 00877 // TCHAR * cmd = pCommand.GetBufferSetLength( cmd_len); 00878 // res = sk.QueryStringValue( 0, cmd, &cmd_len); 00879 // pCommand.ReleaseBufferSetLength( cmd_len); 00880 // sk.Close(); 00881 // 00882 // if( res != ERROR_SUCCESS) 00883 // return false; 00884 // 00885 // return !pCommand.IsEmpty(); // return true only if something valuable found 00886 //}