GME  13
SearchCtl.cpp
Go to the documentation of this file.
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 }