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
*************************************************************************