It looks like:
ViewCallback::SetMotionFunction(ViewMotionCallback);
may be the solution...
It looks like:
ViewCallback::SetMotionFunction(ViewMotionCallback);
may be the solution...
If I've got a IViewMonitor set up, does the ViewportP or ViewportP::ViewInfo contain any information about the current cursor location that I can retrieve. I'm attempting to monitor new elements being created with SystemCallback::SetElmDscrToFileFunction(), and I'd like to know the cursor location for some view decorations. I guess I might be able to grab the cursor location (somehow) inside the SetElmDscrToFileFunction() callback, but was wondering if that information is already available to me as part of the IViewMonitor/Viewport/ViewInfo structs. I'm not inside a tool, so I don't have access to a Motion/NoMotion function.
Bruce
Ido,
My thoughts are you have a new (product based) question related to loss of information during a conversion that would be best asked to the appropriate product support team community first as a new post. If, the question is not able to be addressed and you are able to program to work-around/work past an issue providing a sample of what you currently have (dgn file, screen capt) showing what is expected and what is wrong (dgn and/or screen capt) we will be glad to provide any programming input and guidance we can.
HTH,
Bob
Since LoadSpriteFromRsrc() isn't yet available (as of Update 4), I thought I would try to defined a class that would let me load an Icon and use it for view decoration purposes. The Help File states that one can implement the ISprite interface:
"applications can implement this interface on other objects that are able to supply an icon resource."
So I came up with the following class:
struct MySprite : public ISprite { DEFINE_BENTLEY_REF_COUNTED_MEMBERS private: HICON m_oIcon {0}; public: MySprite() { DEFINE_BENTLEY_REF_COUNTED_MEMBER_INIT int iconID = 10003; /* IDI_ICON2; */ HINSTANCE myDll = GetModuleHandleW(L"srs_featureOperations"); m_oIcon = (HICON)LoadImage(myDll, MAKEINTRESOURCE(iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); // } ~MySprite() { // release memory form LoadImage() DeleteObject(m_oIcon); } void MakeClassAbstract() { } void GetHotSpot(Point2dP hotspot) { ICONINFO ii; GetIconInfo( m_oIcon, &ii ); hotspot->x = ii.xHotspot; hotspot->y = ii.yHotspot; return; } void GetSize(Point2dP size) { ICONINFO ii {0}; BITMAPINFO bmInf; if ( GetIconInfo( m_oIcon, &ii ) ) { if (ii.hbmColor) // ' Icon has color plane { if (GetObject(ii.hbmColor, sizeof(BITMAPINFO), &bmInf)) { size->x = bmInf.bmiHeader.biWidth; size->y = bmInf.bmiHeader.biHeight; //BitDepth = BMInf.bmBitsPixel } DeleteObject(ii.hbmColor); } else // ' Icon has no colour plane, image data stored in mask { if (GetObject(ii.hbmMask, sizeof(BITMAPINFO), &bmInf)) { size->x = bmInf.bmiHeader.biWidth; size->y = bmInf.bmiHeader.biHeight / 2; // monochrome icon contains image and XOR mask in the hbmMask //BitDepth = 1 } DeleteObject(ii.hbmMask); } } return; } bool GetUseAlpha() { return false; } }; MySprite m_oSprite;
So, when I try to use my "sprite" (m_oSprite) in my IViewDecoration::_DrawDecoration(), MicroStation immediately crashes. This leads me to believe that I have not correctly implemented ISprite class. I tested my class by calling m_oSprite.GetSize() and returned values that were correct, so I know the icon was successfully read from the DLL. Are there other requirements?
Bruce
Public Const Tag_Set_Name = "testTagSetName" Public Function GetTagSet(ByVal TagName As String) As TagSet Dim strName As String Dim oTagSets As TagSets strName = Tag_Set_Name Set oTagSets = ActiveDesignFile.TagSets On Error Resume Next Set GetTagSet = oTagSets(strName) If GetTagSet Is Nothing Then Dim td As TagDefinition Set GetTagSet = oTagSets.Add(strName) Set td = GetTagSet.TagDefinitions.Add(TagName, msdTagTypeCharacter) td.IsConstant = True End If End Function Public Sub TagMyElement(oElement As Element, ByVal TagName As String, ByVal TagValue As String) 'TAG THE ELEMENT'GET TAG SET, ADD TO TAG SET IF NOT THERE Dim ts As TagSet Set ts = GetTagSet(TagName)'GET THE TAG DEFS IN THE TAG SET Dim tagDefs As TagDefinitions Set tagDefs = ts.TagDefinitions'LOOK FOR OUR TAG NAME Dim tagDef As TagDefinition Set tagDef = tagDefs.Find(TagName)'CREATE IT IF IT DOES NOT EXIST If tagDef Is Nothing Then Set tagDef = tagDefs.Add(TagName, msdTagTypeCharacter) tagDef.IsConstant = True End If'CREATE A TAG ELEMENT Dim eleTag As TagElement Set eleTag = oElement.AddTag(tagDef)'SET ITS VALUE eleTag.Value = TagValue'MAKES SURE IT'S HIDDEN eleTag.IsHidden = True'MAKE SURE IT GOT WRITTEN eleTag.Rewrite End Sub
[View:/cfs-file/__key/communityserver-discussions-components-files/343173/Default.mvba:940:0]
[View:/cfs-file/__key/communityserver-discussions-components-files/343173/tagtest.dgn:940:0]
I see two problems...
[quote user="minion"]
Set td = GetTagSet.TagDefinitions.Add(TagName, msdTagTypeCharacter) td.IsConstant = True
[/quote]
You've defined a tag as constant, but without giving it a default value. The tag value is empty.
[quote user="minion"]
TagMyElement someline, "testTagName", "TestTagValue"
[/quote]
Does the NamedView class help?
#include <DgnPlatform/NamedView.h>
Jon,
You are looking at the published API, which as you know hides more that it exposes.
Rest assured the actual implementation of PersistentElementRef does all sorts of important, persistent-element-specific stuff.
MakeClassAbstract() is inserted by the tools which generate the published API in order to prevent users from accidentally instantiating objects of classes which should not be trivially instantiated.
Regards,
Paul
Hi Jon,
Since Transient was already an established item/term; PeristentElementRefs are used for specific cases where an ElementRef is highly likely to incur some remaining changes. e.g. _OnElementAdded (linkage and or dependency changes may still occur) or certain Transaction specific operations are in process where performing otherwise normal ElementRef operations at that point it time would not be desired.
HTH,
Bob
Here's the definition of class PersistentElementRef, found in DgnModel.h...
struct PersistentElementRef : public ElementRefBase { private: virtual void MakeClassAbstract() = 0; public: };
It's an abstract class that is otherwise identical to ElementRefBase. What is its purpose? Why not just use ElementRef?
[quote user="HDR_Coder"]I am wanting to iterate through all the models in my active design file in C++. Note that I am using V8i[/quote]
#include <msdgnmodelref.fdf> DgnFileObjP oDgnFile = mdlModelRef_getDgnFile (mdlModelRef_getActive ());
However, when you want to enumerate the models contained in a DGN file, you should take another approach. Read about that on our web site.
I am wanting to iterate through all the models in my active design file in C++. Note that I am using V8i.
The "MDL Function Reference" says I need a DgnFileP in order to create this iterator. Is there a simple way to obtain a pointer to this file object?
Something like
DgnModelRefP model = mdlModelRef_getActive();
But for the active design file.
Thank you for your help,
I'm porting some C++ drawing creation code where one of the usual operations is to create named views in model and then those views are attached into separate drawing file. One option is to have setting to specify that views is hidden line view, where instead of using the saved views directly from the model, the views are processed to hidden line files and those are used with drawing. The old hidden line removal code uses mdlView_findNamedElmdscr, which is removed from CONNECT. How can this be converted to CONNECT? The CE version needs to behave exactly like V8i version.
Below is simplified version of V8i code to provide idea what the code is doing.
int view_number = 7, buffer_size; ULong buffer[50]; UShort typemask[8], levelmask[8]; MSElementDescr *eldP; UInt32 filePos; DgnModelRefP hln_file; mdlView_findNamedElmdscr(&eldP, &filePos, viewName, NULL, mdlModelRef_getActive()); // Attach named view to viewport 8 if (!mdlView_isActive(view_number)) mdlView_turnOn(view_number); mdlView_attachNamed(viewName, NULL, view_number); mdlWorkDgn_createFile(&hln_file, fileName, DGNFILE_FORMAT_V8, ACTIVEMODEL, SEED_CopyDefaultData, NULL, NULL, TRUE); // Scan design file header information, to be copied into the memset(typemask, 0, sizeof(typemask)); typemask[0] = TMSK0_DGNFIL_HEADER; typemask[4] = TMSK4_MICROSTATION_ELM; memset(levelmask, 0xffff, sizeof(levelmask)); buffer_size = sizeof(buffer) / sizeof(ULong); // Returns a buffer of filePositions of elements that are // of type defined in the typemask buffer and are on a level // defined in the levelmask buffer. dppDrawing_findElementsOfTypeOnLevel(typemask, levelmask, buffer, buffer_size, &nr_found); // Write design file header information into hidden line output file for (i = 0; i < nr_found; i++) { mdlElmdscr_read(&eldP, buffer[i], MASTERFILE, FALSE, NULL); mdlWorkDgn_write(eldP, -1, hln_file); mdlElmdscr_freeAll(&eldP); } // Write saved view information mdlElmdscr_read(&eldP, filePos, MASTERFILE, FALSE, NULL); mdlWorkDgn_write(eldP, -1, hln_file); mdlElmdscr_freeAll(&eldP); // Start hidden line removal // Filemask is set to include master file and all reference files mdlView_hiddenLineRemoval3(preFunction, visibleFunction, invisibleFunction, view_number, modelRefListP, 0.0, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE); // Close hidden line file mdlWorkDgn_saveChanges(hln_file); mdlWorkDgn_closeFile(hln_file); // Close view 8 mdlView_turnOff(view_number);
DgnFileP dgnFile = mdlModelRef_getDgnFile (mdlModelRef_getActive()); NamedViewCollectionCR namedViewCollection = dgnFile->GetNamedViews(); for each (NamedViewPtr namedView in namedViewCollection) { // do something with the namedView here. } NamedViewPtr namedView = namedViewCollection.FindByName (L"Kari Heinola", false);
The problem is not about finding named view, but writing the saved view to hidden line file. That is, replacing code like below where removed function mdlView_findNamedElmdscr is used to get saved view filePos and mdlElmdscr_read and
mdlWorkDgn_write are used to save it to work file.
UInt32 filePos; MSElementDescr *eldP; mdlView_findNamedElmdscr(&eldP, &filePos, viewName, NULL, mdlModelRef_getActive()); mdlElmdscr_read(&eldP, filePos, MASTERFILE, FALSE, NULL); mdlWorkDgn_write(eldP, -1, hln_file);