GME  13
PartBrowserOLEData.cpp
Go to the documentation of this file.
00001 #include <stdafx.h>
00002 #include <afxadv.h>
00003 #include "afxcoll.h"
00004 #include "afxtempl.h"
00005 #include "..\Interfaces\meta.h"
00006 #include "..\Interfaces\mga.h"
00007 #include "..\Interfaces\parser.h"
00008 
00009 #include "..\GME\GMEstd.h"
00010 
00011 #include "PartBrowserOLEData.h"
00012 
00013 #include "PartBrowser_i.c"
00014 
00015 CLIPFORMAT CPartBrowserDataSource::cfGMEDesc =  (CLIPFORMAT)(RegisterClipboardFormat(_T("GME Descriptor")));
00016 int CPartBrowserDataSource::myData = 0;
00017 
00018 /* --------------------------- CPartBrowserDataDescriptor --------------------------- */
00019 //static // called externally, to destruct certain lists
00020 void CPartBrowserDataDescriptor::destructList(CTypedPtrList<CPtrList, CRect*>& pList)// it is a CRectList
00021 {
00022         POSITION pos = pList.GetHeadPosition();
00023         while (pos)
00024                 delete pList.GetNext(pos);
00025         pList.RemoveAll();
00026 }
00027 
00028 CPartBrowserDataDescriptor::CPartBrowserDataDescriptor(CTypedPtrList<CPtrList, CRect*> &list,
00029                                                                                                            CTypedPtrList<CPtrList, CRect*> &annList,
00030                                                                                                            CPoint dragPoint, CPoint offs)
00031 {
00032         POSITION pos = list.GetHeadPosition();
00033         while (pos) {
00034                 CRect *rect = new CRect(list.GetNext(pos));
00035                 rect->OffsetRect(-dragPoint.x,-dragPoint.y);
00036                 rects.AddTail(rect);
00037         }
00038 
00039         pos = annList.GetHeadPosition();
00040         while (pos) {
00041                 CRect* rect = new CRect(annList.GetNext(pos));
00042                 rect->OffsetRect(-dragPoint.x,-dragPoint.y);
00043                 annRects.AddTail(rect);
00044         }
00045 
00046         offset = offs;
00047         pFile = 0;
00048 }
00049 
00050 void CPartBrowserDataDescriptor::Reset()
00051 {
00052         POSITION pos = rects.GetHeadPosition();
00053         while (pos)
00054                 delete rects.GetNext(pos);
00055         rects.RemoveAll();
00056 
00057         pos = annRects.GetHeadPosition();
00058         while (pos)
00059                 delete annRects.GetNext(pos);
00060         annRects.RemoveAll();
00061 }
00062 
00063 void CPartBrowserDataDescriptor::Serialize(CArchive& ar)
00064 {
00065         if (ar.IsStoring()) {
00066                 ar << rects.GetCount();
00067                 POSITION pos = rects.GetHeadPosition();
00068                 while (pos)
00069                         ar << *(rects.GetNext(pos));
00070 
00071                 ar << annRects.GetCount();
00072                 pos = annRects.GetHeadPosition();
00073                 while (pos)
00074                         ar << *(annRects.GetNext(pos));
00075 
00076                 ar << offset;
00077         } else {
00078                 Reset();
00079                 int n;
00080                 ar >> n;
00081                 for(int i = 0; i < n; i++) {
00082                         CRect* rect = new CRect();
00083                         ar >> *rect;
00084                         rects.AddTail(rect);
00085                 }
00086 
00087                 ar >> n;
00088                 for(int j = 0; j < n; j++) {
00089                         CRect* rect = new CRect();
00090                         ar >> *rect;
00091                         annRects.AddTail(rect);
00092                 }
00093                 ar >> offset;
00094         }
00095 }
00096 
00097 bool CPartBrowserDataDescriptor::Load(COleDataObject* pDataObject)
00098 {
00099         ASSERT(pDataObject != NULL);
00100 
00101         if (pDataObject->IsDataAvailable(CPartBrowserDataSource::cfGMEDesc)) {
00102                 ASSERT(pFile == 0);
00103                 pFile = pDataObject->GetFileData(CPartBrowserDataSource::cfGMEDesc);
00104                 ASSERT(pFile != NULL);
00105                 CArchive ar(pFile, CArchive::load);
00106                 Serialize(ar);
00107                 return true;
00108         }
00109         return false;
00110 }
00111 
00112 int CPartBrowserDataDescriptor::GetCount()
00113 {
00114         /* return (rects.GetCount() + annRects.GetCount()); */
00115         return rects.GetCount(); 
00116 }
00117 
00118 void CPartBrowserDataDescriptor::Clean()
00119 {
00120         delete pFile;
00121         pFile = 0;
00122 }
00123 
00124 void CPartBrowserDataDescriptor::Draw(CDC *pDC,CPoint &pt)
00125 {
00126         POSITION pos = rects.GetHeadPosition();
00127         while (pos) {
00128                 CRect rect = *(rects.GetNext(pos));
00129 
00130                 rect.OffsetRect(pt);
00131                 CPoint align = rect.CenterPoint();
00132 
00133                 // Emulate the grid.
00134                 long gs = GME_GRID_SIZE;
00135                 align.x = (align.x % gs);
00136                 align.y = (align.y % gs);
00137 
00138                 
00139                 rect.OffsetRect(-align.x, -align.y);
00140                 // rect.OffsetRect(-offset.x, -offset.y);
00141                 pDC->DrawFocusRect(&rect);
00142 
00143         }
00144 
00145         pos = annRects.GetHeadPosition();
00146         while (pos) {
00147                 CRect rect = *(annRects.GetNext(pos));
00148 
00149                 rect.OffsetRect(pt);
00150                 pDC->DrawFocusRect(&rect);
00151         }
00152 }
00153 
00154 
00155 // This function has been simplified for GMEActiveBrowser
00156 // No annotations and grid alignment
00157 void CPartBrowserDataDescriptor::SimpleDraw(CDC *pDC, CPoint &pt)
00158 {
00159         POSITION pos = rects.GetHeadPosition();
00160         while (pos) {
00161                 CRect rect = *(rects.GetNext(pos));
00162 
00163                 rect.OffsetRect(pt);
00164 
00165                 pDC->DrawFocusRect(&rect);
00166 
00167         }
00168 }
00169 
00170 
00171 void CPartBrowserDataDescriptor::GetBoundingRect(CRect &rBoundingRect)
00172 {
00173         rBoundingRect = CRect(0, 0, 0, 0);
00174 
00175         CRect Rect;
00176         POSITION pos = rects.GetHeadPosition();
00177         
00178         while (pos) {
00179                 Rect = *(rects.GetNext(pos));
00180                 rBoundingRect.UnionRect(rBoundingRect, Rect);
00181         }
00182 }
00183 
00184 
00185 /* --------------------------- CPartBrowserDataSource ------------------------------- */
00186 
00187 bool CPartBrowserDataSource::IsGmeNativeDataAvailable(COleDataObject *pDataObject, IMgaProject *project)
00188 {
00189         ASSERT( project != NULL );
00190 
00191         CComPtr<IDataObject> p = pDataObject->GetIDataObject(FALSE);
00192         CComPtr<IPartBrowserDataSource> source;
00193         if (p!= NULL && p.QueryInterface(&source) == S_OK) {
00194                 CComPtr<IUnknown> unknown;
00195                 COMTHROW(source->get_Project(&unknown));
00196                 ASSERT(unknown != NULL);
00197 
00198                 CComPtr<IMgaProject> source_project;
00199                 COMTHROW(unknown.QueryInterface(&source_project));
00200                 ASSERT(source_project != NULL);
00201 
00202                 return source_project.IsEqualObject(project);
00203         }
00204         return false;
00205 }
00206 
00207 bool CPartBrowserDataSource::IsXMLDataAvailable(COleDataObject *pDataObject)
00208 {
00209         ASSERT(pDataObject != NULL);
00210 
00211         return pDataObject->IsDataAvailable(CF_TEXT) != FALSE;
00212 }
00213 
00214 bool CPartBrowserDataSource::ParseXMLData(COleDataObject *pDataObject, IMgaObject *target, bool merge = false)
00215 {
00216         ASSERT(pDataObject != NULL);
00217         ASSERT(target != NULL);
00218 
00219         // create a temporary filename
00220         char *fname = _tempnam("c:\\temp", "tmp");
00221         CString filename = fname;
00222         free(fname);
00223 
00224         try
00225         {
00226                 // get the memory file
00227                 CFile *memfile = pDataObject->GetFileData(CF_TEXT);
00228                 if (memfile == NULL)
00229                         return false;
00230                 memfile->SeekToBegin();
00231 
00232                 // copy
00233                 CFile file;
00234                 if(file.Open(filename, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary) == 0)
00235                         return false;
00236 
00237                 const int buffsize = 10240;
00238                 unsigned char buff[buffsize];
00239                 UINT c;
00240                 do
00241                 {
00242                         c = memfile->Read(buff, buffsize);
00243 
00244                         UINT new_c = 0; // addition by ZolMol
00245                         while (buff[new_c] != 0 && new_c < c) ++new_c;
00246                         c = new_c;              // end
00247 
00248                         file.Write(buff, c);
00249                 } while(c == buffsize);
00250                 file.Close();
00251 
00252                 // clear the memory file
00253                 delete memfile;
00254 
00255                 // parse
00256                 CComPtr<IMgaParser> parser;
00257                 COMTHROW(parser.CoCreateInstance(L"Mga.MgaParser"));
00258                 ASSERT(parser != NULL);
00259 
00260                 CComBstrObj acckind, version; 
00261                 VARIANT_BOOL is_acc_target;
00262                 COMTHROW(parser->GetClipXMLInfo(PutInBstr(filename), target, &is_acc_target, PutOut(acckind), PutOut( version)));
00263                 CString ver = "0"; // defval
00264                 if (version) // clipboard main token found, otherwise use defval
00265                         CopyTo(version, ver);
00266 
00267 
00268                 CComObjPtr<IMgaProject> t_project;
00269                 COMTHROW(target->get_Project(PutOut(t_project)));
00270                 CComPtr<IGMEOLEApp> t_GME = CPartBrowserDataSource::get_GME(t_project);
00271                 
00272                 CComBSTR msg, done;
00273                 done.Append("Done.");
00274                 if (ver == "0") {
00275                         msg.Append("Inserting XML data...");
00276                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO));
00277                         COMTHROW(parser->ParseFCOs(target, PutInBstr(filename)));
00278                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO));
00279                 } else if (ver == "4") {
00280                         msg.Append("Inserting XML SmartCopied data...");
00281                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO));
00282                         COMTHROW(parser->ParseClos4(target, PutInBstr(filename), merge ? MERGE:ADDITION));
00283                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO));
00284                 } else if (ver == "1" || ver == "") {
00285                         msg.Append("Inserting XML CopyClosured data...");
00286                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO));
00287                         COMTHROW(parser->ParseClos1(target, PutInBstr(filename)));
00288                         if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO));
00289                 } else {
00290                         msg.Append("Error: Unknown clipboard closure format");
00291                         if(t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO));
00292 
00293                         ASSERT(0);
00294                 }
00295 
00296 
00297                 CFile::Remove(filename);
00298 
00299                 return true;
00300         }
00301         catch(hresult_exception &e)
00302         {
00303                 CFile::Remove(filename);
00304 
00305                 try
00306                 {
00307                         CComObjPtr<IErrorInfo> errinfo;
00308                         COMTHROW(GetErrorInfo(0, PutOut(errinfo)));
00309                         ASSERT(errinfo != NULL);
00310 
00311                         CString desc;
00312                         COMTHROW(errinfo->GetDescription(PutOut(desc)));
00313 
00314                         AfxMessageBox(CString("Error while parsing XML file: ") + desc);
00315                 }
00316                 catch(hresult_exception &)
00317                 {
00318                         AfxMessageBox("Fatal error while parsing XML file!");
00319                 }
00320 
00321                 throw e;
00322         }
00323 
00324         return false;
00325 }
00326 
00327 void CPartBrowserDataSource::CacheDescriptor(CPartBrowserDataDescriptor* desc)
00328 {
00329         CacheGlobalData(cfGMEDesc, CreateDescriptor(desc));
00330         DelayXMLDump();
00331 }
00332 
00333 HGLOBAL CPartBrowserDataSource::CreateDescriptor(CPartBrowserDataDescriptor* desc)
00334 {
00335         ASSERT(desc);
00336 
00337         CSharedFile file;
00338         CArchive ar(&file, CArchive::store);
00339         desc->Serialize(ar);
00340         ar.Close();
00341         return file.Detach();
00342 }
00343 
00344 void CPartBrowserDataSource::DelayXMLDump()
00345 {
00346         FORMATETC fe = {
00347         CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM|TYMED_HGLOBAL
00348         };
00349 
00350         DelayRenderFileData(CF_TEXT, &fe);
00351 }
00352 
00353 BOOL CPartBrowserDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
00354 {
00355         if (lpFormatEtc->cfFormat == CF_TEXT) {
00356                 ASSERT(pFile != NULL);
00357 
00358                 // TODO: we have to dump it directly to the shared memory file
00359 
00360                 try
00361                 {
00362                         char *fname = _tempnam("c:\\temp", "tmp");
00363                         CString filename = fname;
00364                         free(fname);
00365                 
00366                         CComPtr<IMgaDumper> dumper;
00367                         COMTHROW(dumper.CoCreateInstance(L"Mga.MgaDumper"));
00368 
00369                         CComObjPtr<IMgaFCOs> fcos;
00370                         if (data) // check whether it is set
00371                                 COMTHROW(::QueryInterface(data, fcos));
00372 
00373                         CComObjPtr<IMgaFolders> folds;
00374                         if (folders) // check whether it is set
00375                                 COMTHROW(::QueryInterface(folders, folds));
00376 
00377                         CComObjPtr<IMgaRegNodes> regd;
00378                         if (regdata) // check whether it is set
00379                                 COMTHROW(::QueryInterface(regdata, regd));
00380 
00381                         COMTHROW(dumper->DumpFCOs(project, fcos, folds, regd, PutInBstr(filename)));
00382 
00383                         CFile file;
00384                         if(file.Open(filename, CFile::modeRead | CFile::typeBinary) == 0)
00385                                 return FALSE;
00386                         
00387                         const int buffsize = 10240;
00388                         unsigned char buff[buffsize];
00389                         UINT c;
00390                         do
00391                         {
00392                                 c = file.Read(buff, buffsize);
00393                                 pFile->Write(buff, c);
00394                         } while(c == buffsize);
00395 
00396                         buff[0] = 0;
00397                         pFile->Write(buff, 1);
00398 
00399                         file.Close();
00400                         CFile::Remove(filename);
00401                 }
00402                 catch(hresult_exception &)
00403                 {
00404                         return FALSE;
00405                 }
00406                 catch(CFileException *)
00407                 {
00408                         return FALSE;
00409                 }
00410 
00411                 return TRUE;
00412         }
00413 
00414         return FALSE;
00415 }
00416 
00417 // ****************************************************************************************************
00418 // *********************************   CPartBrowserClosureDataSource  *****************************************
00419 // ****************************************************************************************************
00420 BOOL CPartBrowserClosureDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
00421 {
00422         if (lpFormatEtc->cfFormat == CF_TEXT) {
00423                 ASSERT(pFile != NULL);
00424 
00425                 // TODO: we have to dump it directly to the shared memory file
00426 
00427                 try
00428                 {
00429                         char *fname = _tempnam("c:\\temp", "tmp");
00430                         CString filename = fname;
00431                         free(fname);
00432                 
00433                         CComPtr<IMgaDumper> dumper;
00434                         COMTHROW(dumper.CoCreateInstance(L"Mga.MgaDumper"));
00435 
00436                         CComObjPtr<IMgaFCOs> fcos;
00437                         if (data) // is it set?
00438                                 COMTHROW(::QueryInterface(data, fcos));
00439 
00440                         CComObjPtr<IMgaFolders> fols;
00441                         if (folders) // is it set?
00442                                 COMTHROW(::QueryInterface(folders, fols));
00443 
00444                         bool is_top_set = false;
00445                         CComObjPtr<IMgaFCOs> top_fcos;
00446                         CComObjPtr<IMgaFolders> top_folds;
00447 
00448                         if (m_topFcos) {
00449                                 COMTHROW(::QueryInterface( m_topFcos, top_fcos));
00450                                 is_top_set = true;
00451                         }
00452 
00453                         if (m_topFolders) {
00454                                 COMTHROW(::QueryInterface( m_topFolders, top_folds));
00455                                 is_top_set = true;
00456                         }
00457 
00458                         if (is_top_set)
00459                                 COMTHROW(dumper->DumpClosR(fcos, fols, PutInBstr(filename), top_fcos, top_folds, m_options, m_absPathPart, m_acceptingKinds));
00460                         else // if top objects are not set dump starting from RootFolder
00461                                 COMTHROW(dumper->DumpClos(fcos, fols, PutInBstr(filename), m_options));
00462 
00463                         CFile file;
00464                         if (file.Open(filename, CFile::modeRead | CFile::typeBinary) == 0)
00465                                 return FALSE;
00466 
00467                         const int buffsize = 10240;
00468                         unsigned char buff[buffsize];
00469                         UINT c;
00470                         do
00471                         {
00472                                 c = file.Read(buff, buffsize);
00473                                 pFile->Write(buff, c);
00474                         } while (c == buffsize);
00475 
00476                         buff[0] = 0;
00477                         pFile->Write(buff, 1);
00478 
00479                         file.Close();
00480                         CFile::Remove(filename);
00481                 }
00482                 catch(hresult_exception &)
00483                 {
00484                         return FALSE;
00485                 }
00486                 catch(CFileException *)
00487                 {
00488                         return FALSE;
00489                 }
00490 
00491                 return TRUE;
00492         }
00493 
00494         return FALSE;
00495 }
00496 
00497 BEGIN_MESSAGE_MAP(CPartBrowserDataSource, COleDataSource)
00498         //{{AFX_MSG_MAP(CPartBrowserDataSource)
00499                 // NOTE - the ClassWizard will add and remove mapping macros here.
00500         //}}AFX_MSG_MAP
00501 END_MESSAGE_MAP()
00502 
00503 // Interface Maps
00504 
00505 BEGIN_DISPATCH_MAP(CPartBrowserDataSource, COleDataSource)
00506         //{{AFX_DISPATCH_MAP(CPartBrowserDataSource)
00507         DISP_PROPERTY_EX(CPartBrowserDataSource, "Data", DispGetData, DispSetData, VT_DISPATCH)
00508         DISP_PROPERTY_EX(CPartBrowserDataSource, "Folders", DispGetFolders, DispSetFolders, VT_DISPATCH)
00509         DISP_PROPERTY_EX(CPartBrowserDataSource, "RegistryData", DispGetRegistryData, DispSetRegistryData, VT_DISPATCH)
00510         DISP_PROPERTY_EX(CPartBrowserDataSource, "Project", DispGetProject, DispSetProject, VT_DISPATCH)
00511         //}}AFX_DISPATCH_MAP
00512 END_DISPATCH_MAP()
00513 
00514 
00515 BEGIN_INTERFACE_MAP(CPartBrowserDataSource, COleDataSource)
00516         INTERFACE_PART(CPartBrowserDataSource, IID_IPartBrowserDataSource, PartBrowserDataSource)
00517         DUAL_ERRORINFO_PART(CPartBrowserDataSource)
00518 END_INTERFACE_MAP()
00519 
00520 DELEGATE_DUAL_INTERFACE(CPartBrowserDataSource, PartBrowserDataSource)
00521 
00522 // Implement ISupportErrorInfo to indicate we support the
00523 // OLE Automation error handler.
00524 IMPLEMENT_DUAL_ERRORINFO(CPartBrowserDataSource, IID_IPartBrowserDataSource)
00525 
00526 
00527 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Data(IUnknown **p)
00528 {
00529         METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource)
00530         CHECK_OUT(p);
00531 
00532         if (pThis->data != NULL)
00533                 return pThis->data.QueryInterface(p);
00534 
00535         return S_OK;
00536 }
00537 
00538 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Folders(IUnknown **p)
00539 {
00540         METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource)
00541         CHECK_OUT(p);
00542 
00543         if (pThis->folders != NULL)
00544                 return pThis->folders.QueryInterface(p);
00545 
00546         return S_OK;
00547 }
00548 
00549 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_RegistryData(IUnknown **p)
00550 {
00551         METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource)
00552         CHECK_OUT(p);
00553 
00554         if (pThis->regdata != NULL)
00555                 return pThis->regdata.QueryInterface(p);
00556 
00557         return S_OK;
00558 }
00559 
00560 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Project(IUnknown **p)
00561 {
00562         METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource)
00563         CHECK_OUT(p);
00564 
00565         return pThis->project.QueryInterface(p);
00566 }
00567 
00568 
00569 
00570 
00571 /*static*/ CComPtr<IGMEOLEApp> CPartBrowserDataSource::get_GME(CComObjPtr<IMgaProject> project)
00572 {
00573         CComPtr<IGMEOLEApp> gme;
00574         if ( (project != NULL)) {
00575                 CComBSTR bstrName("GME.Application");
00576                 CComPtr<IMgaClient> pClient;
00577                 HRESULT hr = project->GetClientByName(bstrName, &pClient);
00578                 if (SUCCEEDED(hr) && pClient) {
00579                         CComPtr<IDispatch> pDispatch;
00580                         hr = pClient->get_OLEServer(&pDispatch);
00581                         if (SUCCEEDED(hr) && pDispatch) {
00582                                 hr = pDispatch.QueryInterface(&gme);
00583                                 if (FAILED(hr)) {
00584                                         gme = NULL;
00585                                 }
00586                         }
00587                 }
00588         }
00589         return gme;
00590 }
00591 
00592 LPDISPATCH CPartBrowserDataSource::DispGetData() 
00593 {
00594         CComPtr<IDispatch> p;
00595         if (data != NULL) {
00596                 data.QueryInterface(&p);
00597         }
00598 
00599         return p.Detach();
00600 }
00601 
00602 void CPartBrowserDataSource::DispSetData(LPDISPATCH)
00603 {
00604         SetNotSupported();
00605 }
00606 
00607 LPDISPATCH CPartBrowserDataSource::DispGetFolders()
00608 {
00609         CComPtr<IDispatch> p;
00610         if (folders != NULL) {
00611                 folders.QueryInterface(&p);
00612         }
00613 
00614         return p.Detach();
00615 }
00616 
00617 void CPartBrowserDataSource::DispSetFolders(LPDISPATCH)
00618 {
00619         SetNotSupported();
00620 }
00621 
00622 LPDISPATCH CPartBrowserDataSource::DispGetRegistryData()
00623 {
00624         CComPtr<IDispatch> p;
00625         if (regdata != NULL) {
00626                 regdata.QueryInterface(&p);
00627         }
00628 
00629         return p.Detach();
00630 }
00631 
00632 void CPartBrowserDataSource::DispSetRegistryData(LPDISPATCH)
00633 {
00634         SetNotSupported();
00635 }
00636 
00637 LPDISPATCH CPartBrowserDataSource::DispGetProject()
00638 {
00639         CComPtr<IDispatch> p;
00640         if (project != NULL) {
00641                 project.QueryInterface(&p);
00642         }
00643 
00644         return p.Detach();
00645 }
00646 
00647 void CPartBrowserDataSource::DispSetProject(LPDISPATCH)
00648 {
00649         SetNotSupported();
00650 }
00651