Yes you can use C++, but lots more work. For example here is a sample program that start Rose from a C++ application,
loads a model, and generates (C++) code for a component in the model. Below you will find a .cpp file that shows how that is done is C++. You will note that the CPP code includes comments indicating how that was done in Visual Basic. Also copied below is the equivalent VBCode file that shows how that would normall be done in Visual Basic. Note: this uses stdafx, but you can use to OLEAUTO.H, OBJBASE.H and the regular COM SDK stuff. //////////////////////////////////////////////////////////////////////// CPPCodeGen.cpp //////////////////////////////////////////////////////////////////////// #include <stdafx.h> HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...); void CPPCodeGen(); void CPPCodeGen() { VARIANT root[64] = {0}; // Generic IDispatchs VARIANT parm[64] = {0}; // Generic Parameters VARIANT rVal = {0}; // Temporary result holder int level=0; // Current index into root[] // Initialize the OLE Library... OleInitialize(NULL); // Line 1: Dim roseApp As RoseApplication VARIANT roseApp = {0}; // Line 2: Dim CPPCodeGenObject As Object VARIANT CPPCodeGenObject = {0}; // Line 3: Dim theModel As RoseModel VARIANT theModel = {0}; // Line 4: Dim theDiag As RoseModuleDiagram VARIANT theDiag = {0}; // Line 5: Dim theSubSys As RoseSubsystem VARIANT theSubSys = {0}; // Line 6: Dim theModule As RoseModule VARIANT theModule = {0}; // Line 7: Dim theComponentView As RoseComponentView VARIANT theComponentView = {0}; // Line 8: Dim I As Integer VARIANT I = {0}; // Line 9: Dim K As Integer VARIANT K = {0}; // Line 10: Dim bDone As Boolean VARIANT bDone = {0}; // Line 11: // Line 12: Set roseApp = GetObject , Rose.Application { CLSID clsid; IUnknown *pUnk; CLSIDFromProgID(L"Rose.Application", &clsid); HRESULT hr = GetActiveObject(clsid, NULL, (LPUNKNOWN *)&pUnk); if(FAILED(hr)) { char buf[256]; sprintf(buf, "GetActiveObject() for \"Rose.Application\" failed. Err=%08lx", hr); ::MessageBox(NULL, buf, "Error", 0x10010); _exit(0); } rVal.vt = VT_DISPATCH; pUnk->QueryInterface(IID_IDispatch, (void **)&rVal.pdispVal); pUnk->Release(); } VariantCopy(&roseApp, &rVal); VariantClear(&rVal); // Line 13: Set CPPCodeGenObject = CreateObject Rose.CPPAddIn { CLSID clsid; CLSIDFromProgID(L"Rose.CPPAddIn", &clsid); HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER, IID_IDispatch, (void **)&rVal.pdispVal); if(FAILED(hr)) { char buf[256]; sprintf(buf, "CoCreateInstance() for \"Rose.CPPAddIn\" failed. Err=%08lx", hr); ::MessageBox(NULL, buf, "Error", 0x10010); _exit(0); } rVal.vt = VT_DISPATCH; } VariantCopy(&CPPCodeGenObject, &rVal); VariantClear(&rVal); // Line 14: Set theModel = roseApp . OpenModel d:\\test\\test.mdl VariantCopy(&root[++level], &roseApp); parm[0].vt = VT_BSTR; parm[0].bstrVal = ::SysAllocString(L"d:\\test\\test.mdl"); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"OpenModel", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantCopy(&theModel, &rVal); VariantClear(&rVal); // Line 15: Set theSubSys = theModel . RootSubsystem VariantCopy(&root[++level], &theModel); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"RootSubsystem", 0); VariantClear(&root[level--]); VariantCopy(&theSubSys, &rVal); VariantClear(&rVal); // Line 16: Set theDiag = theSubSys . AddModuleDiagram TEMP VariantCopy(&root[++level], &theSubSys); parm[0].vt = VT_BSTR; parm[0].bstrVal = ::SysAllocString(L"TEMP"); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"AddModuleDiagram", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantCopy(&theDiag, &rVal); VariantClear(&rVal); // Line 17: // Line 18: // Line 19: For I = 1 To theDiag . ComponentViews . Count { VariantCopy(&root[++level], &theDiag); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"ComponentViews", 0); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"Count", 0); VariantClear(&root[level--]); VariantClear(&root[level--]); long endValI = rVal.lVal; I.vt = VT_I4; for(I.lVal=1; I.lVal<=endValI; I.lVal++) { // Line 20: bDone = theDiag . RemoveComponentView theDiag . ComponentViews . GetAt I VariantCopy(&root[++level], &theDiag); VariantCopy(&parm[0], &theDiag); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"RemoveComponentView", 1, parm[0]); VariantClear(&parm[0]); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"ComponentViews", 0); VariantCopy(&parm[0], &I); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"GetAt", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantClear(&root[level--]); VariantClear(&root[level--]); VariantCopy(&bDone, &rVal); VariantClear(&rVal); // Line 21: Next I } } // Line 22: // Line 23: For I = 1 To theModel . GetAllSubsystems . Count { VariantCopy(&root[++level], &theModel); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"GetAllSubsystems", 0); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"Count", 0); VariantClear(&root[level--]); VariantClear(&root[level--]); long endValI = rVal.lVal; I.vt = VT_I4; for(I.lVal=1; I.lVal<=endValI; I.lVal++) { // Line 24: Set theSubSys = theModel . GetAllSubsystems . GetAt I VariantCopy(&root[++level], &theModel); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"GetAllSubsystems", 0); VariantCopy(&parm[0], &I); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"GetAt", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantClear(&root[level--]); VariantCopy(&theSubSys, &rVal); VariantClear(&rVal); // Line 25: For K = 1 To theSubSys . Modules . Count { VariantCopy(&root[++level], &theSubSys); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"Modules", 0); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"Count", 0); VariantClear(&root[level--]); VariantClear(&root[level--]); long endValK = rVal.lVal; K.vt = VT_I4; for(K.lVal=1; K.lVal<=endValK; K.lVal++) { // Line 26: Set theModule = theSubSys . Modules . GetAt I VariantCopy(&root[++level], &theSubSys); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"Modules", 0); VariantCopy(&parm[0], &I); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"GetAt", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantClear(&root[level--]); VariantCopy(&theModule, &rVal); VariantClear(&rVal); // Line 27: If theModule . GetAssignedClasses . Count > 0 And { VariantCopy(&root[++level], &theModule); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &root[level+1], root[level++].pdispVal, L"GetAssignedClasses", 0); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"Count", 0); VariantClear(&root[level--]); VariantClear(&root[level--]); VARIANT tmp = {0}; VariantCopy(&tmp, &rVal); VariantClear(&rVal); rVal.vt = VT_I4; rVal.lVal = 0; VariantChangeType(&tmp, &tmp, 0, VT_R8); VariantChangeType(&rVal, &rVal, 0, VT_R8); int exp = tmp.dblVal > rVal.dblVal; if(exp) { VariantClear(&rVal); // Line 28: theModule . AssignedLanguage = C++ Then rVal.vt = VT_BSTR; rVal.bstrVal = ::SysAllocString(L"C++"); VariantCopy(&root[++level], &theModule); AutoWrap(DISPATCH_PROPERTYPUT, NULL, root[level].pdispVal, L"AssignedLanguage", 1, rVal); VariantClear(&root[level--]); VariantClear(&rVal); // Line 29: Set theComponentView = theDiag . AddComponentView theModule VariantCopy(&root[++level], &theDiag); VariantCopy(&parm[0], &theModule); AutoWrap(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &rVal, root[level].pdispVal, L"AddComponentView", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); VariantCopy(&theComponentView, &rVal); VariantClear(&rVal); // Line 30: theComponentView . SetSelected 1 VariantCopy(&root[++level], &theComponentView); parm[0].vt = VT_I4; parm[0].lVal = 1; AutoWrap(DISPATCH_METHOD, NULL, root[level].pdispVal, L"SetSelected", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); // Line 31: End If } } // Line 32: Next K } } // Line 33: Next I } } // Line 34: // Line 35: theDiag . Activate VariantCopy(&root[++level], &theDiag); AutoWrap(DISPATCH_METHOD, NULL, root[level].pdispVal, L"Activate", 0); VariantClear(&root[level--]); // Line 36: // Line 37: CPPCodeGenObject . OnActivate roseApp VariantCopy(&root[++level], &CPPCodeGenObject); VariantCopy(&parm[0], &roseApp); AutoWrap(DISPATCH_METHOD, NULL, root[level].pdispVal, L"OnActivate", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); // Line 38: CPPCodeGenObject . OnGenerateCode roseApp VariantCopy(&root[++level], &CPPCodeGenObject); VariantCopy(&parm[0], &roseApp); AutoWrap(DISPATCH_METHOD, NULL, root[level].pdispVal, L"OnGenerateCode", 1, parm[0]); VariantClear(&parm[0]); VariantClear(&root[level--]); // Clearing variables VariantClear(&roseApp); VariantClear(&CPPCodeGenObject); VariantClear(&theModel); VariantClear(&theDiag); VariantClear(&theSubSys); VariantClear(&theModule); VariantClear(&theComponentView); VariantClear(&I); VariantClear(&K); VariantClear(&bDone); // Close the OLE Library... OleUninitialize(); } HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) { // Begin variable-argument list... va_list marker; va_start(marker, cArgs); if(!pDisp) { MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010); _exit(0); } // Variables used... DISPPARAMS dp = { NULL, NULL, 0, 0 }; DISPID dispidNamed = DISPID_PROPERTYPUT; DISPID dispID; HRESULT hr; char buf[200]; char szName[200]; // Convert down to ANSI WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL); // Get DISPID for name passed... hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID); if(FAILED(hr)) { sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // Allocate memory for arguments... VARIANT *pArgs = new VARIANT[cArgs+1]; // Extract arguments... for(int i=0; i<cArgs; i++) { pArgs[i] = va_arg(marker, VARIANT); } // Build DISPPARAMS dp.cArgs = cArgs; dp.rgvarg = pArgs; // Handle special-case for property-puts! if(autoType & DISPATCH_PROPERTYPUT) { dp.cNamedArgs = 1; dp.rgdispidNamedArgs = &dispidNamed; } // Make the call! hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL); if(FAILED(hr)) { sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // End variable-argument section... va_end(marker); delete [] pArgs; return hr; } /////////////////////////////////////////////////////////////////////////// equilevent VB code /////////////////////////////////////////////////////////////////////////// Dim roseApp As RoseApplication Dim CPPCodeGenObject As Object Dim theModel As RoseModel Dim theDiag As RoseModuleDiagram Dim theSubSys As RoseSubsystem Dim theModule As RoseModule Dim theComponentView As RoseComponentView Dim I As Integer Dim K As Integer Dim bDone As Boolean Set roseApp = GetObject(, "Rose.Application") Set CPPCodeGenObject = CreateObject("Rose.CPPAddIn") Set theModel = roseApp.OpenModel("d:\test\test.mdl") Set theSubSys = theModel.RootSubsystem Set theDiag = theSubSys.AddModuleDiagram("TEMP") For I = 1 To theDiag.ComponentViews.Count bDone = theDiag.RemoveComponentView(theDiag.ComponentViews.GetAt(I)) Next I For I = 1 To theModel.GetAllSubsystems.Count Set theSubSys = theModel.GetAllSubsystems.GetAt(I) For K = 1 To theSubSys.Modules.Count Set theModule = theSubSys.Modules.GetAt(I) If theModule.GetAssignedClasses().Count > 0 And _ theModule.AssignedLanguage = "C++" Then Set theComponentView = theDiag.AddComponentView(theModule) theComponentView.SetSelected True End If Next K Next I theDiag.Activate CPPCodeGenObject.OnActivate roseApp CPPCodeGenObject.OnGenerateCode roseApp ###################################################### Patrick Kennedy Rational Support -----Original Message----- From: Nea Suciu [mailto:[EMAIL PROTECTED]] Sent: Wednesday, February 19, 2003 1:52 PM To: [EMAIL PROTECTED]; [EMAIL PROTECTED] Subject: RE: (ROSE) Add-in functionality Thanks for the info. I was actually planning on writing my add-in in c++. Does rose provide a set of c++ class declarations that represent rose model elements (such as sequence diagrams, class diagrams, etc)? ----Original Message Follows---- From: "Kennedy, Patrick" <[EMAIL PROTECTED]> Reply-To: "Kennedy, Patrick" <[EMAIL PROTECTED]> To: "'Nea Suciu'" <[EMAIL PROTECTED]>, [EMAIL PROTECTED] Subject: RE: (ROSE) Add-in functionality Date: Wed, 19 Feb 2003 13:40:39 -0800 Yes you can create diagram via Rose script. Here is an example: 'automatically make main diagrams for each category 'with all the category's classes in them sub fillmeup(cat as category, diag as classdiagram) dim cc as classcollection set cc = cat.classes dim cold as classcollection set cold = diag.getclasses ' ' ' for i% = cold.count to 1 step -1 xxx = diag.removeClass(cold.getat(i)) next i ' ' ' for i% = 1 to cc.count added = diag.addclass(cc.getat(i)) next i diag.layout end sub Sub Main dim cc as categoryCollection set cc = roseapp.currentmodel.getAllCategories dim kitty as category dim maindiag as classdiagram dim diag as classdiagram print cc.getat(1).name set maindiag = cc.getat(1).classdiagrams.getat(1) maindiag.visible = true set cc=roseapp.currentmodel.categories for i% = 1 to cc.count set kitty = cc.getat(i) maduga = maindiag.addcategory (kitty) jj% = kitty.classdiagrams.findfirst("Main") if jj = 0 then set diag = kitty.addClassDiagram ("Main") else set diag = kitty.classdiagrams.getat(jj) end if fillmeup kitty,diag next i fillmeup maindiag.parentcategory, maindiag maindiag.layout End Sub For more on Rose script, please see http://solutions.rational.com/solutions/display.jsp?solutionId=7953 Subject: WINDOWS/UNIX:Scripting Help - Learning RoseScript and REI Solution Id: 7953 Patrick Kennedy Rational Support -----Original Message----- From: Nea Suciu [mailto:[EMAIL PROTECTED]] Sent: Wednesday, February 19, 2003 1:02 PM To: [EMAIL PROTECTED] Subject: (ROSE) Add-in functionality Hi, I'm thinking about writing an add-in to rational rose that would basically create a class diagram from a java source file. I'm pretty new to RR and the add-in API's in particular. Does RR provide any hooks for creating diagrams? Thanks a lot Nea _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 ************************************************************************ * Rose Forum is a public venue for ideas and discussions. * For technical support, visit http://www.rational.com/support * Only plain-text messages are supported. * HTML or Rich-Text messages may be rejected. * * Post or Reply to: [EMAIL PROTECTED] * Subscription Requests: [EMAIL PROTECTED] * Archive of messages: * http://www.rational.com/support/usergroups/rose/rose_forum.jsp * Other Requests: [EMAIL PROTECTED] * * To unsubscribe from the list, please send email * To: [EMAIL PROTECTED] * Subject: <BLANK> * Body: unsubscribe rose_forum ************************************************************************* ************************************************************************ * Rose Forum is a public venue for ideas and discussions. * For technical support, visit http://www.rational.com/support * Only plain-text messages are supported. * HTML or Rich-Text messages may be rejected. * * Post or Reply to: [EMAIL PROTECTED] * Subscription Requests: [EMAIL PROTECTED] * Archive of messages: * http://www.rational.com/support/usergroups/rose/rose_forum.jsp * Other Requests: [EMAIL PROTECTED] * * To unsubscribe from the list, please send email * To: [EMAIL PROTECTED] * Subject: <BLANK> * Body: unsubscribe rose_forum ************************************************************************* _________________________________________________________________ STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail ************************************************************************ * Rose Forum is a public venue for ideas and discussions. * For technical support, visit http://www.rational.com/support * Only plain-text messages are supported. * HTML or Rich-Text messages may be rejected. * * Post or Reply to: [EMAIL PROTECTED] * Subscription Requests: [EMAIL PROTECTED] * Archive of messages: * http://www.rational.com/support/usergroups/rose/rose_forum.jsp * Other Requests: [EMAIL PROTECTED] * * To unsubscribe from the list, please send email * To: [EMAIL PROTECTED] * Subject: <BLANK> * Body: unsubscribe rose_forum *************************************************************************