GME
13
|
00001 // SearchCtl.cpp : Implementation of the CSearchCtrl ActiveX Control class. 00002 00003 #include "stdafx.h" 00004 #include "Search.h" 00005 #include "SearchCtl.h" 00006 #include "SearchPpg.h" 00007 #include "Mga_i.c" 00008 00009 00010 #ifdef _DEBUG 00011 #define new DEBUG_NEW 00012 #undef THIS_FILE 00013 static char THIS_FILE[] = __FILE__; 00014 #endif 00015 00016 IMPLEMENT_DYNCREATE(CSearchCtrl, COleControl) 00017 00018 00019 00020 // Message map 00021 00022 BEGIN_MESSAGE_MAP(CSearchCtrl, COleControl) 00023 //{{AFX_MSG_MAP(CSearchCtrl) 00024 ON_WM_CREATE() 00025 //}}AFX_MSG_MAP 00026 ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) 00027 END_MESSAGE_MAP() 00028 00029 00031 // Dispatch map 00032 00033 BEGIN_DISPATCH_MAP(CSearchCtrl, COleControl) 00034 //{{AFX_DISPATCH_MAP(CSearchCtrl) 00035 DISP_PROPERTY_EX(CSearchCtrl, "MgaProject", GetMgaProject, SetMgaProject, VT_UNKNOWN) 00036 DISP_FUNCTION(CSearchCtrl, "OpenProject", OpenProject, VT_EMPTY, VTS_BSTR) 00037 //}}AFX_DISPATCH_MAP 00038 DISP_FUNCTION_ID(CSearchCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE) 00039 DISP_FUNCTION_ID(CSearchCtrl, "SelMgaObjects", dispidSelMgaObjects, SelMgaObjects, VT_EMPTY, VTS_UNKNOWN) 00040 END_DISPATCH_MAP() 00041 00042 00044 // Event map 00045 00046 BEGIN_EVENT_MAP(CSearchCtrl, COleControl) 00047 //{{AFX_EVENT_MAP(CSearchCtrl) 00048 EVENT_CUSTOM("ClickMgaObject", FireClickMgaObject, VTS_UNKNOWN) 00049 EVENT_CUSTOM("DblClickMgaObject", FireDblClickMgaObject, VTS_UNKNOWN) 00050 EVENT_CUSTOM("WantToBeClosed", FireWantToBeClosed, VTS_NONE) 00051 //}}AFX_EVENT_MAP 00052 EVENT_CUSTOM_ID("LocateMgaObject", eventidLocateMgaObject, FireLocateMgaObject, VTS_BSTR) 00053 END_EVENT_MAP() 00054 00056 // Native COM interface map - peter 00057 BEGIN_INTERFACE_MAP(CSearchCtrl, COleControl) 00058 INTERFACE_PART(CSearchCtrl, IID_IMgaEventSink, EventSink) 00059 END_INTERFACE_MAP() 00060 00061 00063 // Property pages 00064 00065 // TODO: Add more property pages as needed. Remember to increase the count! 00066 BEGIN_PROPPAGEIDS(CSearchCtrl, 1) 00067 PROPPAGEID(CSearchPropPage::guid) 00068 END_PROPPAGEIDS(CSearchCtrl) 00069 00070 00072 // Initialize class factory and guid 00073 00074 IMPLEMENT_OLECREATE_EX(CSearchCtrl, "GME.SearchCtrl.1", 00075 0xe5fe98f1, 0xb7ad, 0x4abe, 0x89, 0xdb, 0x87, 0xdd, 0xd9, 0xdb, 0x75, 0x3e) 00076 00077 00079 // Type library ID and version 00080 00081 IMPLEMENT_OLETYPELIB(CSearchCtrl, _tlid, _wVerMajor, _wVerMinor) 00082 00083 00085 // Interface IDs 00086 00087 const IID BASED_CODE IID_DSearch = 00088 { 0xb718ccf7, 0x5055, 0x40dd, { 0x9c, 0xbd, 0xab, 0x17, 0xf7, 0x2a, 0xb1, 0x13 } }; 00089 const IID BASED_CODE IID_DSearchEvents = 00090 { 0xb240c566, 0xa493, 0x4529, { 0x8a, 0xd7, 0xb9, 0xb7, 0xb, 0x17, 0xbb, 0xa1 } }; 00091 00092 00094 // Control type information 00095 00096 static const DWORD BASED_CODE _dwSearchOleMisc = 00097 OLEMISC_ACTIVATEWHENVISIBLE | 00098 OLEMISC_SETCLIENTSITEFIRST | 00099 OLEMISC_INSIDEOUT | 00100 OLEMISC_CANTLINKINSIDE | 00101 OLEMISC_RECOMPOSEONRESIZE; 00102 00103 IMPLEMENT_OLECTLTYPE(CSearchCtrl, IDS_SEARCH, _dwSearchOleMisc) 00104 00105 00106 00107 // CSearchCtrl::CSearchCtrlFactory::UpdateRegistry - 00108 // Adds or removes system registry entries for CSearchCtrl 00109 00110 BOOL CSearchCtrl::CSearchCtrlFactory::UpdateRegistry(BOOL bRegister) 00111 { 00112 // TODO: Verify that your control follows apartment-model threading rules. 00113 // Refer to MFC TechNote 64 for more information. 00114 // If your control does not conform to the apartment-model rules, then 00115 // you must modify the code below, changing the 6th parameter from 00116 // afxRegApartmentThreading to 0. 00117 00118 if (bRegister) 00119 return AfxOleRegisterControlClass( 00120 AfxGetInstanceHandle(), 00121 m_clsid, 00122 m_lpszProgID, 00123 IDS_SEARCH, 00124 IDB_SEARCH, 00125 afxRegApartmentThreading, 00126 _dwSearchOleMisc, 00127 _tlid, 00128 _wVerMajor, 00129 _wVerMinor); 00130 else 00131 return AfxOleUnregisterClass(m_clsid, m_lpszProgID); 00132 } 00133 00134 00136 // CSearchCtrl::XEventSink - native COM interface - peter 00137 STDMETHODIMP_(ULONG) CSearchCtrl::XEventSink::AddRef() 00138 { 00139 METHOD_PROLOGUE(CSearchCtrl,EventSink) 00140 return pThis->ExternalAddRef(); 00141 } 00142 00143 STDMETHODIMP_(ULONG) CSearchCtrl::XEventSink::Release() 00144 { 00145 METHOD_PROLOGUE(CSearchCtrl,EventSink) 00146 return pThis->ExternalRelease(); 00147 } 00148 00149 STDMETHODIMP CSearchCtrl::XEventSink::QueryInterface(REFIID riid, void** ppv) 00150 { 00151 METHOD_PROLOGUE(CSearchCtrl,EventSink) 00152 return pThis->ExternalQueryInterface(&riid, ppv); 00153 } 00154 00155 STDMETHODIMP CSearchCtrl::XEventSink::GlobalEvent(globalevent_enum event) 00156 { 00157 METHOD_PROLOGUE(CSearchCtrl,EventSink) 00158 pThis->OnMgaGlobalEvent(event); 00159 return S_OK; 00160 } 00161 00162 STDMETHODIMP CSearchCtrl::XEventSink::ObjectEvent(IMgaObject * obj, unsigned long eventmask, VARIANT v) 00163 { 00164 METHOD_PROLOGUE(CSearchCtrl,EventSink) 00165 pThis->OnMgaObjectEvent(obj, eventmask); 00166 return S_OK; 00167 } 00168 00169 00170 00172 // CSearchCtrl::CSearchCtrl - Constructor 00173 00174 CSearchCtrl::CSearchCtrl() 00175 { 00176 InitializeIIDs(&IID_DSearch, &IID_DSearchEvents); 00177 00178 SetInitialSize(SEARCH_INITIAL_SIZEX, SEARCH_INITIAL_SIZEY); 00179 m_territory = NULL; 00180 m_project = NULL; 00181 m_MgaObjs=NULL; 00182 m_transactionCnt = 0; 00183 m_inEventTransactionMode = false; 00184 } 00185 00186 00188 // CSearchCtrl::~CSearchCtrl - Destructor 00189 00190 CSearchCtrl::~CSearchCtrl() 00191 { 00192 m_territory = NULL; 00193 m_project = NULL; 00194 m_MgaObjs=NULL; 00195 } 00196 00197 00199 // CSearchCtrl::OnDraw - Drawing function 00200 00201 void CSearchCtrl::OnDraw( 00202 CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) 00203 { 00204 if (m_searchDlg.GetSafeHwnd()) { 00205 m_searchDlg.MoveWindow(rcBounds, TRUE); 00206 } 00207 else { 00208 AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 00209 CBrush brush (RGB(255,255,255)); 00210 pdc->FillRect (rcBounds, &brush); 00211 00212 CRect edge(rcBounds); 00213 pdc->DrawEdge(&edge, EDGE_BUMP, BF_RECT); 00214 00215 CString label("GME Search OCX"); 00216 00217 BITMAP bm; 00218 CBitmap bitmap; 00219 bitmap.LoadBitmap(IDB_SEARCH); 00220 bitmap.GetBitmap(&bm); 00221 CSize size(bm.bmWidth, bm.bmHeight); 00222 pdc->DPtoLP(&size); 00223 CPoint org(0,0); 00224 pdc->DPtoLP(&org); 00225 CPoint pos(rcBounds.Width()/2, rcBounds.Height()/2 - (pdc->GetTextExtent(label).cy) ); 00226 CDC dcMem; 00227 dcMem.CreateCompatibleDC(pdc); 00228 CBitmap *oldbitmap = dcMem.SelectObject(&bitmap); 00229 dcMem.SetMapMode (pdc->GetMapMode()); 00230 pdc->BitBlt(pos.x, pos.y, size.cx, size.cy, &dcMem, org.x, org.y, SRCCOPY); 00231 dcMem.SelectObject(oldbitmap); 00232 00233 pdc->SetTextAlign(TA_CENTER); 00234 pdc->TextOut(rcBounds.Width()/2, rcBounds.Height()/2, CString("GME Search ActiveX Control")); 00235 } 00236 } 00237 00238 00240 // CSearchCtrl::DoPropExchange - Persistence support 00241 00242 void CSearchCtrl::DoPropExchange(CPropExchange* pPX) 00243 { 00244 ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); 00245 COleControl::DoPropExchange(pPX); 00246 00247 // TODO: Call PX_ functions for each persistent custom property. 00248 00249 } 00250 00251 00253 // CSearchCtrl::OnResetState - Reset control to default state 00254 00255 void CSearchCtrl::OnResetState() 00256 { 00257 COleControl::OnResetState(); // Resets defaults found in DoPropExchange 00258 00259 // TODO: Reset any other control state here. 00260 } 00261 00262 00264 // CSearchCtrl::AboutBox - Display an "About" box to the user 00265 00266 void CSearchCtrl::AboutBox() 00267 { 00268 CDialog dlgAbout(IDD_ABOUTBOX_SEARCH); 00269 dlgAbout.DoModal(); 00270 } 00271 00272 00274 // CSearchCtrl message handlers 00275 00276 int CSearchCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 00277 { 00278 if (COleControl::OnCreate(lpCreateStruct) == -1) 00279 return -1; 00280 00281 m_searchDlg.Create(IDD_SEARCH_DIALOG, this); 00282 00283 return 0; 00284 } 00285 00286 BOOL CSearchCtrl::PreCreateWindow(CREATESTRUCT& cs) 00287 { 00288 cs.dwExStyle |= WS_EX_CONTROLPARENT; 00289 return COleControl::PreCreateWindow(cs); 00290 } 00291 00292 00293 LPUNKNOWN CSearchCtrl::GetMgaProject() 00294 { 00295 CComPtr<IUnknown> unk; 00296 if (m_project != NULL) { 00297 if (FAILED(m_project.QueryInterface(&unk))) { 00298 ThrowError(CTL_E_INVALIDPROPERTYVALUE, _T("Unable to cast MgaProject.")); 00299 return NULL; 00300 } 00301 } 00302 return unk; 00303 } 00304 00305 void CSearchCtrl::SetMgaProject(LPUNKNOWN newValue) 00306 { 00307 if(m_project != NULL) 00308 { 00309 m_searchDlg.RemoveAll(); 00310 if(m_territory != NULL) 00311 { 00312 COMTHROW(m_territory->Destroy() ); 00313 } 00314 } 00315 00316 if (newValue != NULL) { 00317 CComQIPtr<IMgaProject> ccpMgaProject(newValue); 00318 if (ccpMgaProject == NULL) 00319 { 00320 ThrowError(CTL_E_INVALIDPROPERTYVALUE, _T("Unable to cast MgaProject.")); 00321 return; 00322 } 00323 00324 m_project = ccpMgaProject; 00325 00326 // Creating Territory 00327 m_territory = NULL; 00328 COMTHROW( m_project->CreateTerritory(&m_xEventSink,&m_territory,NULL) ); 00329 m_searchDlg.EnableSearch(); 00330 m_searchDlg.GetKinds(m_project); 00331 00332 } 00333 else { 00334 m_searchDlg.DisableSearch(); 00335 m_project = NULL; 00336 m_territory = NULL; 00337 m_MgaObjs.Release(); 00338 } 00339 } 00340 00341 void CSearchCtrl::OpenProject(LPCTSTR connStr) 00342 { 00343 CComPtr<IMgaProject> ccpMgaProject; 00344 try 00345 { 00346 COMTHROW(ccpMgaProject.CoCreateInstance(OLESTR("Mga.MgaProject"))); 00347 00348 VARIANT_BOOL vtbMode; 00349 CComBSTR bszProjectConnStr(connStr); 00350 00351 COMTHROW(ccpMgaProject->Open(bszProjectConnStr, &vtbMode)); 00352 SetMgaProject(ccpMgaProject); 00353 00354 } 00355 catch (hresult_exception &) 00356 { 00357 ThrowError(CTL_E_INVALIDPROPERTYVALUE, _T("Error opening project.")); 00358 return; 00359 } 00360 } 00361 00362 00364 // MGA Event handlers 00365 00366 void CSearchCtrl::OnMgaObjectEvent(IMgaObject *obj, unsigned long eventmask) 00367 { 00368 m_inEventTransactionMode = true; 00369 // We do not process individual object events 00370 m_inEventTransactionMode = false; 00371 return; 00372 } 00373 00374 void CSearchCtrl::OnMgaGlobalEvent(globalevent_enum event) 00375 { 00376 00377 m_inEventTransactionMode = true; 00378 00379 // Handling Global Events 00380 if(event==GLOBALEVENT_COMMIT_TRANSACTION) 00381 { 00382 m_searchDlg.RemoveZombies(); 00383 } 00384 else if(event==GLOBALEVENT_NOTIFICATION_READY) 00385 { 00386 m_searchDlg.RemoveZombies(); 00387 } 00388 00389 else if(event==GLOBALEVENT_ABORT_TRANSACTION) 00390 { 00391 m_searchDlg.RemoveAll(); 00392 } 00393 else if(event==GLOBALEVENT_UNDO) 00394 { 00395 m_searchDlg.RemoveZombies(); 00396 } 00397 else if(event==GLOBALEVENT_REDO) 00398 { 00399 m_searchDlg.RemoveZombies(); 00400 } 00401 m_inEventTransactionMode = false; 00402 } 00403 00405 // These functions can be used from the dialog 00406 00407 void CSearchCtrl::BeginTransaction(transactiontype_enum type) 00408 { 00409 // In the event handlers we are already in transaction 00410 if(m_inEventTransactionMode) { 00411 return; 00412 } 00413 00414 if(m_transactionCnt == 0) // Not in transactions 00415 { 00416 COMTHROW( 00417 m_project->BeginTransaction( 00418 m_territory, 00419 type 00420 ) 00421 ); 00422 } 00423 m_transactionCnt++; 00424 } 00425 00426 void CSearchCtrl::CommitTransaction() 00427 { 00428 // In the event handlers we are already in transaction 00429 if(m_inEventTransactionMode) { 00430 return; 00431 } 00432 00433 if(m_transactionCnt == 0) // We are not in transaction. What to commit? 00434 { 00435 return; 00436 } 00437 00438 if(m_transactionCnt == 1) 00439 { 00440 COMTHROW(m_project->CommitTransaction()); 00441 } 00442 m_transactionCnt--; 00443 } 00444 00445 void CSearchCtrl::AbortTransaction() 00446 { 00447 if(m_transactionCnt == 0) { 00448 return; 00449 } 00450 00451 COMTHROW(m_project->AbortTransaction()); 00452 m_transactionCnt = 0; 00453 m_inEventTransactionMode = false; 00454 00455 return; 00456 } 00457 00458 CComPtr<IMgaTerritory> CSearchCtrl::Terr() 00459 { 00460 return m_territory; 00461 } 00462 00463 // needs to be called in a transaction 00464 CComPtr<IMgaObjects> CSearchCtrl::PutInMyTerritory(CComPtr<IMgaObjects> &p_inColl) 00465 { 00466 CComPtr<IMgaObjects> coll_in_active_terr; 00467 coll_in_active_terr.CoCreateInstance( L"Mga.MgaObjects"); 00468 00469 long c = 0; 00470 if( p_inColl) 00471 COMTHROW(p_inColl->get_Count( &c)); 00472 00473 // nothing to copy? no territory? failed to create out coll? or no transaction active? 00474 if( c > 0 && m_territory && coll_in_active_terr && m_transactionCnt > 0) 00475 { 00476 for( long i = 1; i <= c; ++i) // for all items in coll 00477 { 00478 CComPtr<IMgaObject> obj, item; 00479 COMTHROW(p_inColl->get_Item( i, &item)); 00480 00481 COMTHROW(m_territory->OpenObj( item, &obj)); // puts in our territory 00482 COMTHROW(coll_in_active_terr->Append( obj)); 00483 } 00484 } 00485 00486 return coll_in_active_terr; 00487 } 00488 00489 void CSearchCtrl::ClickOnObject(CComPtr<IMgaObject> object) 00490 { 00491 CComPtr<IUnknown> unk; 00492 COMTHROW(object.QueryInterface(&unk)); 00493 FireClickMgaObject(unk); 00494 } 00495 00496 void CSearchCtrl::ClickOnObject(CComPtr<IMgaObjects> object) 00497 { 00498 CComPtr<IUnknown> unk; 00499 COMTHROW(object.QueryInterface(&unk)); 00500 FireClickMgaObject(unk); 00501 } 00502 00503 00504 void CSearchCtrl::DblClickOnObject(CComPtr<IMgaObject> object) 00505 { 00506 CComPtr<IUnknown> unk; 00507 COMTHROW(object.QueryInterface(&unk)); 00508 FireDblClickMgaObject(unk); 00509 } 00510 00511 void CSearchCtrl::WantToBeClosed() 00512 { 00513 FireWantToBeClosed(); 00514 } 00515 00516 void CSearchCtrl::LocateMgaObject(CComPtr<IMgaObject> object) 00517 { 00518 try 00519 { 00520 // obtain object id 00521 BeginTransaction(); 00522 CBstr bstr_id; 00523 COMTHROW( object->get_ID( bstr_id)); 00524 CommitTransaction(); 00525 00526 // fire event 00527 FireLocateMgaObject( (LPCTSTR) (CString) bstr_id); 00528 00529 } catch( hresult_exception& ) { 00530 AbortTransaction(); 00531 } 00532 } 00533 00534 void CSearchCtrl::SelMgaObjects(IUnknown* p_selMgaObjs) 00535 { 00536 //if project is undefined no point in setting objects -kiran 00537 if(!m_project) 00538 { 00539 m_MgaObjs.Release(); 00540 return; 00541 } 00542 AFX_MANAGE_STATE(AfxGetStaticModuleState()); 00543 if (p_selMgaObjs != NULL) { 00544 CComQIPtr<IMgaObjects> ccpMgaObjects( p_selMgaObjs); 00545 if (ccpMgaObjects == NULL) 00546 { 00547 ThrowError(CTL_E_INVALIDPROPERTYVALUE, _T("Unable to cast MgaObjects.")); 00548 //m_searchDlg.EnableScoped( FALSE); 00549 return; 00550 } 00551 00552 m_MgaObjs = ccpMgaObjects; 00553 00554 } 00555 else { // called when Dlg is Hidden, in order to release the Mga ptrs 00556 m_MgaObjs.Release(); 00557 } 00558 } 00559 00560 //added to make enter key work in dialog 00561 //the message from the parent CGMESearch is transmitted to OLE control 00562 //which is this, after this message is obtained its forwarded to dialog 00563 //so that it is properly taken care of 00564 00565 BOOL CSearchCtrl::PreTranslateMessage(MSG *pMsg) 00566 { 00567 if( pMsg->message == WM_KEYDOWN ) 00568 { 00569 switch(pMsg->wParam) 00570 { 00571 case VK_RETURN: 00572 case VK_TAB: 00573 return this->m_searchDlg.PreTranslateMessage(pMsg); 00574 00575 } 00576 } 00577 return FALSE; 00578 }