Without testing I guess that ConfigurationVariableValue method should be enough to obtain the path you mentioned.
With regards,
Jan
Hi Christmas,
[quote user="Christmas050873"]I would like to build an external .exe program to read some _ustn variables. Is this possible? [/quote]
In my opinion there are two solutions:
[quote user="Christmas050873"]If so, could I get a portion of code to accomplish this?[/quote]
My assumption is that to implement such parser is not easy task (a few weeks maybe?) to be sure it works fine and you will still use not certified not supported access to MicroStation configuration. If you prefer this option, I guess you have to invest your time (to write own parser) or money (to pay somebody else).
With regards,
Jan
Hi,
My system is windows 7, VS 2015
I find Text Style Height and Width behavior very strange and here is example.
I have created TextNode with multiline text. With each new line, font height and width is different.
Debug.Print Application.ActiveSettings.TextStyle.Width prints result zero when clearly width is 10
Then I change width and Height to 20 and result is strange as picture shows.
dgn file is attached.
VBA code:
Debug.Print Application.ActiveSettings.TextStyle.Name Debug.Print Application.ActiveSettings.TextStyle.Height Debug.Print Application.ActiveSettings.TextStyle.Width Application.ActiveSettings.TextStyle.Height = 20 Application.ActiveSettings.TextStyle.Width = 20 Dim nTxt As TextNodeElement Set nTxt = Application.CreateTextNodeElement2(Nothing, Point3dFromXYZ(0, 0, 0), Matrix3dIdentity) nTxt.AddTextLine ("test1") nTxt.AddTextLine ("test1") nTxt.AddTextLine ("test1") nTxt.AddTextLine ("test1") ActiveModelReference.AddElement nTxt Dim oPH As PropertyHandler Set oPH = Application.CreatePropertyHandler(nTxt) oPH.SelectByAccessString ("ViewDependent") oPH.SetValue (False)
[View:/cfs-file/__key/communityserver-discussions-components-files/343173/5344.test.dgn:940:0]
Any idea?
best regards
Nenad
My preferences are stored at
C:\Users\[username]\AppData\Local\Bentley\MicroStation\8.11\o_Dof88niaENmS1PChQ4Mg
Is there any way to determine this directory programmatically?
[quote user="Robert Hook"] I would start with reviewing all modules for calls to mdlResource_openFile to ensure all file requests are using RSC_READONLY[/quote]
There's just one call to open a resource file and it's RSC_READONLY. When I first encountered this problem, I added a call to the OnUnload event handler to explicitly close the resource file. However, that made no difference.
[quote user="Robert Hook"]You could or an additional lock flag of: RSC_READDENYWRITE or RSC_STRICT_LOCKING; which might flush out an offendingapplication[/quote]
When I add RSC_STRICT_LOCKING to the call to open the resource file, I find that the application unloads immediately after loading. Something doesn't like RSC_STRICT_LOCKING. When I remove that flag the app. behaves normally.
When MicroStation starts up it processes a number of configuration files. There are multiple levels of configuration, with one configuration file calling one or more other configuration files. Each configuration file defines a number of configuration variables, one of which is what you are after.
However, one variable may be defined in terms of another variable. There are conditional tests that affect how a variable ends up being defined. Because CAD Administrators can, and do, define their own configuration files, it's impossible to forecast what the eventual set of variables will be once MicroStation is initialised. Even on the same site, different projects will have different configurations.
You have two choices...
Take your pick! However, for quick initial development, I suggest that you choose no. 2. For lengthy unsupported development (there's no public information about MicroStation's configuration file processor), choose no. 1.
I would like to build an external .exe program to read some _ustn variables. Is this possible? Do I have to open an instance of uStation to accomplish it? (Ideally I woud NOT need to open an instance of uStation.) If so, could I get a portion of code to accomplish this? I don't care what language the external .exe program is written in (C, VB, etc.)
Thanks in advance,
Christmas May
Here's some more evidence. I loaded my app. in two different ways...
1 Manual Load: Note the resource file count == 1
2 Auto-Load from Custom Palette: Note the resource file count == 2
When an app. is auto-loaded from a custom tool palette, MicroStation opens the .ma resource and doesn't let go.
Hi Christmas,
[quote user="Christmas050873"]If I have to actually "kick off" an instance of uStation to accomplish this[/quote]
This is not "you have to"! As Jon wrote "Take your pick" ... you have a freedom to choose. Because nobody knows all details and conditions (should it be general or desinged for very fixed in-house installation, your knowledge of MicroStation development versus general development, how a solution maintenance is planned...), only you can do a qualified decision.
On a general level, it seems all responding people think to use MicroStation to access configuration is less risky and simpler way.
[quote user="Christmas050873"]I was hoping to write a standalone .exe file to read the _ustn_Localuserappdatapath variable.[/quote]
Create and analyze msdebug.txt file to check how this configuration variable is defined. It will provide you some extra information how complex the task can be.
From msdebug.txt it's clear _USTN_LOCALUSERTEMPPATH variable (don't write it as _ustn_Localuserappdatapath, by default MicroStation variables are named using capital letters, so other form can be confusing) is predefined variable, so it's not defined in any config file. And it's also not documented where predefined varaibles come from (where they are defined), I guess they are hardcoded or defined as runtime values.
[quote user="Christmas050873"]As for the second solution, where are these files located?[/quote]
There are spread over more folders, some are standard (config folder), others depend on workspace configuration. The whole system is described in MicroStation documentation.
[quote user="Christmas050873"]Are there any code examples to get me started?[/quote]
Use MicroStation VBA documentation, there is chapter describing how to access MicroStation from another process using COM Application object.
With regards,
Jan
I've created a text element and associated it with a target element using TextHandlerBase::SetupOffsetAssociation. That works fine.
Now, in a separate operation, I want to find an associated text element from that target. That is, I locate the target element, then I want to find its associated elements. Then sift those associated elements to find my text element.
How should I go about getting and following an associative trail?
Welcome!
Please follow the MicroStation Programming forum best practices.
Please identify the version of MicroStation, or other product such as PowerDraft, that you are using: MicroStation CONNECT or MicroStation V8i. What is the 8-digit version number (e.g. 10.xx.yy.zz) of MicroStation?
If you're using MicroStation in a ProjectWise (PW) managed environment, let us know that too.
The APIs supplied with MicroStation CONNECT are different to those supplied with MicroStation V8i. Consequently, our answers are likely to be different.
[quote user="Matt Spencer"]How do you do code blocks <code></code> on these forums?[/quote]
When you post code, use the Forum advanced editor's syntax highlighting tool. That's the icon that resembles a pencil:
[quote user="Matt Spencer"]I am trying to create a simple little MVBA application to return the 2D slope between 2 points[/quote]
A screenshot showing the last two would help.
Jon,
My Apologies for any misleading information and thanks for the response.
1. I am using Microstation v8i (SS4 08.11.09.832). I use Projectwise and a local workspace environment both, but they are the same setup.
2. I updated my previous post to show the code blocks. (I don't think the syntax highlighting works in chrome)
3. At this point I am only interested in finding slopes in 2D DGN's, but I don't think this should complicate matters much. The slope is just a matter of (y2-y1)(x2-x1) between the two data points that get selected. When I move forward I will have to do a select case to check to see if the Z elevation of my point3D matches the Z elevation of the active file origin. If they match then I will assume a 2D slope (y2-y1)/(x2-x1) and can place a slope label. If the Z elevations don't match then I will assume a 3D slope and use (z2-z1) / sqrt((x2-x1)^2 + (y2-y1)^2) and omit any labeling. I will just pass the 3D slope to the Dialog box and omit any labeling.
I hope this help! See the attached image for an idea of the labels I am interested in. Also please note that these are done by hand for staged construction. We are only using InRoads to create the initial cross section set.
Disclaimer: First Foray into using MVBA with the native Microstation Objects. Well versed in VB.NET though.
I am trying to create a simple little MVBA application to return the 2D slope between 2 points. This is what I have so far thanks to a previous post by Jan called MeasureLine.mvba.
Main entry point for the program
Option Explicit' --------------------------------------------------------------------- Private Const strMODULE_NAME As String = "modMain"' AnnotateSlope is a MicroStation VBA project. It enables a user to' identify (locate) a 2 points in a DGN file and get/annotate the slope,' and post the measurement in a UserForm.' ---------------------------------------------------------------------' To start this macro, use the following MicroStation keyin:' vba run [AnnotateSlope]modMain.Main' ---------------------------------------------------------------------' Main entry point' --------------------------------------------------------------------- Public Sub Main() On Error GoTo err_Main Debug.Print "VBA project location: " & Application.VBE.activevbproject.FileName frmLocator.Show vbModeless Exit Sub err_Main: ReportError strMODULE_NAME, "Main" End Sub' ---------------------------------------------------------------------' ReportError' Generic way to report an error' --------------------------------------------------------------------- Public Sub ReportError(ByVal modName As String, ByVal procName As String) Const strColon As String = ":" MsgBox "Error " & CStr(err.Number) & strColon & " " & err.Description & vbNewLine & _"Caused by " & err.Source, vbOKOnly Or vbCritical, "Error in " & modName & strColon & procName End Sub' ---------------------------------------------------------------------
Temporary code for userform (Everything is commented out except the call CommandState.SetLocate)
Option Explicit' --------------------------------------------------------------------- Private Const strMODULE_NAME As String = "frmLocator"' --------------------------------------------------------------------- Public Property Let ElementID(ByRef id As DLong)'txtID.Text = DLongToString(id) End Property' --------------------------------------------------------------------- Public Property Let Length(ByVal l As Double)'txtLength.Text = Format(l, "#0.00") End Property' --------------------------------------------------------------------- Private Sub commandButton_Click()' Start a new locate command by invoking our class clsLocator Dim oLocator As New clsLocator Set oLocator.Originator = Me CommandState.SetLocate oLocator End Sub' --------------------------------------------------------------------- Private Sub UserForm_Initialize() ' Initialise units Dim master As MeasurementUnit master = ActiveModelReference.MasterUnit'lblLength.Caption = "Length " & master.Label & ":"' Initialise ID ElementID = DLongFromLong(0)' Initialise length Length = 0# End Sub
Class Module implementing ILocateCommandEvents
Option Explicit' --------------------------------------------------------------------- Private Const strMODULE_NAME As String = "clsLocator"' --------------------------------------------------------------------- Implements ILocateCommandEvents' ---------------------------------------------------------------------' Member variable stores a reference to the UserForm that called this' locate class' --------------------------------------------------------------------- Private m_oOriginator As frmLocator' ---------------------------------------------------------------------' Property lets us assign our form to this variable' e.g. Set oLocator.Originator = Me' --------------------------------------------------------------------- Public Property Set Originator(ByRef oForm As frmLocator) Set m_oOriginator = oForm End Property' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_Accept(ByVal oElement As Element, point As Point3d, ByVal View As View)' Use originator variable to use properties of frmLocator m_oOriginator.ElementID = oElement.id m_oOriginator.Length = oElement.AsLineElement.Length End Sub' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_Cleanup() End Sub ' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_Dynamics(point As Point3d, ByVal View As View, ByVal drawMode As MsdDrawingMode)' Intentionally empty End Sub' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_LocateFailed() ShowStatus "Not a line element" End Sub' ---------------------------------------------------------------------' Reject elements that are not LineElements because we can't measure them' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_LocateFilter(ByVal oElement As Element, point As Point3d, accepted As Boolean)' Intentionally empty End Sub' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_LocateReset()' Intentionally empty End Sub' --------------------------------------------------------------------- Private Sub ILocateCommandEvents_Start() Dim ele As Element Dim eleComponent As Element Dim hitPoint As Point3d ShowCommand "Select 1st Data Point" ShowPrompt "Snap on your 1st point" hitPoint = CommandState.GetHitPoint Debug.Print " Point on Element " & Point3dToString(hitPoint) End Sub' --------------------------------------------------------------------- Function Point3dToString(pnt As Point3d) As String Point3dToString = "(" & pnt.X & ", " & pnt.Y & ", " & pnt.Z & ")" End Function
I am having difficulty finding a CommandState Object Method for prompting the user to send a snapped Point3d rather than an element of some sort. Do I need to be using IPrimitiveCommandEvents instead? It looks like the IPrimitiveCommandEvents_DataPoint Method does what I want, but I am having trouble calling it from a dialog box button.
[View:/cfs-file/__key/communityserver-discussions-components-files/343173/Using-Partial-Delete.pdf:940:0]
Thanks!
Matt
P.S. How do you do code blocks <code></code> on these forums?
_USTN_LOCALUSERAPPDATAPATH is one of MicroStation's predefined/built in runtime macro definitions and should equate to doing this in Windows Explorer:
%LOCALAPPDATA%\Bentley\MicroStation\
You can simply query for the subfolder versions (Major.Minor.Subminor directory name) installed and append the version number for the build required. For example, one of my installs is defined as:
_USTN_LOCALUSERAPPDATAPATH: predefined = C:\Users\robert.hook\AppData\Local\Bentley\MicroStation\10.0.0_3\ <Locked>
And can be opened in Explorer, via ShellExecute, etc. as:
%LOCALAPPDATA%\Bentley\MicroStation\10.0.0_3
If you needed to know what version is installed you could query the registry location HKEY_LOCAL_MACHINE\SOFTWARE\Bentley\MicroStation, for respective "Version" keys having a value like: 10.04.00.046 which you could parse and format to match an expected directory location like above.
HTH,
Bob