Hi friends,
I am trying to create a Pattern Area with an MDL function and it is not possible for me, it always returns the error -131 (MDLERR_CELLNOTFOUND) and I do not understand why
I'm working with MicroStation v8i (SELECT series 3) v08.11.09.578, with VBA
1. FIRST, I HAVE THE CELL "MYPATTERN" CREATED IN MY LIBRARY OF CELLS
2. THIS IS MY CODE
DECLARATION OF THE MDL FUNCTION
Declare Function mdlPattern_area Lib "stdmdlbltin.dll" _ (ByRef patternEdPP As Long, ByVal solid As Long, ByVal holes As Long, _ ByVal cell As Long, ByVal cellName As String, ByVal roscale As Double, _ ByVal angle As Double, ByVal rowSpacing As Double, ByVal colSpacing As Double, _ ByVal view As Integer, ByVal SearchForHoles As Boolean, ByRef originPoint As Point3d) As Long
IMPLEMENTATION
Const SUCCESS As Long = 0 Const MDLERR_CELLNOTFOUND As Long = -131 Const MDLERR_NONCLOSEDPATELM As Long = -745 Const MDLERR_NONSOLIDPATELM As Long = -746 Const MDLERR_INVALIDPATSPACE As Long = -744 '***************************************************** 'GENERATE A SHAPE ELEMENT '***************************************************** Dim points(0 To 4) As Point3d points(0).X = 440453.86 points(0).Y = 4639314.61 points(0).Z = 297.66 points(1).X = points(0).X + 20 points(1).Y = points(0).Y points(1).Z = 297.66 points(2).X = points(0).X + 20 points(2).Y = points(0).Y + 20 points(2).Z = 297.66 points(3).X = points(0).X points(3).Y = points(0).Y + 20 points(3).Z = 297.66 points(4).X = points(0).X points(4).Y = points(0).Y points(4).Z = 297.66 Dim myShape1 As ShapeElement Set myShape1 = CreateShapeElement1(Nothing, points) '***************************************************** Dim pHatch As Long Dim status As Long status = mdlPattern_area(pHatch, myShape1.MdlElementDescrP, 0, 0, "MYPATTERN", 1, 0, 0, 0, 0, False, points(0)) If SUCCESS <> status Then Dim msg As String Select Case status Case MDLERR_CELLNOTFOUND msg = "Pattern cell not found" Case MDLERR_NONCLOSEDPATELM msg = "Element is not closed" Case MDLERR_NONSOLIDPATELM msg = "Shape element has hole bit set" Case MDLERR_INVALIDPATSPACE msg = "Invalid pattern spacing and/or cell size" End Select MsgBox msg, vbCritical Or vbOKOnly, "Pattern Grouped Hole" End If
3. AND RESULT IS ALWAYS -131
Please, any idea ?
Thanks in advance
Kala
Hi Kala,
kala mit tat said:Please, any idea ?
I assume the problem is how you pass the cell name to the function. If I remember right (have not enough time to consult VBA documentation now), you cannot pass string directly to MDL function when MSWchar* is expected.
Check VBA documentation, there is chapter dedicated to how functions from externall DLL can be used from VBA. There is a description for every data type (including string) with explanation how it should be passed to C MDL and retrieved as a result.
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
kala mit tat said:DECLARATION OF THE MDL FUNCTION
Your MDL declaration differs from the declaration in the MDL documentation …
Declare Function mdlPattern_area Lib "stdmdlbltin.dll" ( _ ByRef patternEdPP As Long , _ ByVal shape As Long , _ ByVal holes As Long , _ ByVal cell As Long , _ ByVal cellName As Long , _ ByVal scale As Double , _ ByVal angle As Double , _ ByVal rowSpacing As Double , _ ByVal columnSpacing As Double , _ ByVal view As Long , _ ByVal searchForHoles As Long , _ ByRef originPoint As Point3d ) As Long
cellName should be Long (meaning a C-style pointer to a string buffer) and searchForHoles should be Long, not Boolean. Use 0 for False and -1 for True.
cellName
Long
searchForHoles
Boolean
0
False
-1
True
As Jan notes, Unicode strings such as a cell name have to be treated carefully when calling MDL from VBA. Read the section in VBA help Calling DLL functions from VBA, then use VBA function StrPtr to wrap your cell name.
StrPtr
Regards, Jon Summers LA Solutions
Thanks Jan & Jon,
it's work, converting cell name (string) to StrPtr (long) and change function parameter cellName to "Long". This function returned SUCCESS and pattern element correctly
Now, I try to apply this solution in my C# code, ¿ you know how is the equivalent of StrPtr in C# ?
Thanks another time
kala mit tat said:¿ you know how is the equivalent of StrPtr in C# ?
That is Microsoft technology. Consult web sites that deal with VBA and C#.
kala mit tat said:I try to apply this solution in my C# code
Your app. is written in C# but calls the VBA COM server via an InterOp. For MDL functions you can call the function directly from C# using P/Invoke. Look on Microsoft sites for more info about that technology.
Please start a new thread if you need help on P/Invoke.
kala mit tat said:Now, I try to apply this solution in my C# code, ¿ you know how is the equivalent of StrPtr in C# ?
Marshalling data types from native types to managed ones is different than in VBA.
See Microsoft documentation how types are marshalled, I guess MSWchar is equal String with CharSet = CharSet.Unicode attribute. More information about marshalling String is here.
Thanks, Jan but dont work with attribute "CharSet = CharSet.Unicode"
kala mit tat said:but dont work with attribute "CharSet = CharSet.Unicode"
A question is whether the problem is in this attribute or somewhere else. I think you should share you DllImport in C# to ensure other parameters are correct (because they possible can also be different than in VBA).
Regards,
Ok,
thats is my declaration in C#
[DllImport("stdmdlbltin.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int mdlPattern_area(ref long patternEdPP, long solid, long holes, long cell, long cellName, double scale, double angle, double rowSpacing, double columnSpacing, int view, long searchForHoles, ref BCOM.Point3d originPoint);
The problem is in the string pointer value.When in VBA I use strPtr ("MYPATTERN") it works fine, but I can not find the equivalent in C #
I've tried this, but nothing
[DllImport("stdmdlbltin.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern int mdlPattern_area(....);
Is it possible to import the strPtr function in C # ?, something like this
[DllImport("VBA.dll", CallingConvention = CallingConvention.Cdecl)] public static extern long strPtr(string myString);
kala mit tat said:Is it possible to import the strPtr function in C # ?, something like this
No, StrPtr is solely VBA feature and makes no sense in other environments.
Hi,
kala mit tat said:thats is my declaration in C#
it seems you did not bother to check marshalling documentation I linked in my earlier answer and it confirms my thought the problem is probably somewhere else:
When P/Invoke is used with 32bit dlls, pointer is int and native int stay also int (precisely System.Int32). So your DllImport is wrong (where long is used, should be int), so it cannot work regardless String is marshalled correctly or not.
Answer Verified By: Robert Hook