I am trying to get a list of files to process on from the user but I have not been able to figure out how to do this. I can get one file fine via the mdlDialog_fileOpen inside the stdmdlbltin.dll, but as far as I can tell, there is no way to allow the user to select multiple files.
What I'm looking for is the dialog you get when you try to attach a reference to a file. It has a single "tab" at the top that says Select. Inside there, you can select multiple documents by hitting control or shift. Or alternatively, hitting the Add button, which adds to the bottom panel.
I've tried using the mdlFileList_Edit, but that appears to allow me to open a folder, which is not what I'm looking for.
My backup plan is to use the batch processor, but I'd prefer not to do that.
Any help would be greatly appreciated.
Thanks,
Please follow the Forum guidelines.
ProjectWise is a Document Management System (DMS). It uses an Oracle database (DB) to manage projects. Put simply, a project is a list of files. PW stores the files somewhere, usually on a server. Unless you're a PW administrator, you don't know where those files are stored, and don't need to know. When a user requests a file from PW, she's querying that DB. If she has permission and the file is available, PW copies the file to a local folder so she can work on it. The files on the PW server folder are protected, secure and probably not even visible to normal users, which is why I ask the question below.
PW handles any type of file, not just DGN files. It has a list of the app required to open each file type (e.g. MicroStation opens DGN files, Word opens .docx files, etc).
.docx
dkleinot said:I am trying to get a list of files from ProjectWise (PW). I can get one file fine via the mdlDialog_fileOpen
mdlDialog_fileOpen
I don't know that mdlDialog_fileOpen is the right function to open a PW file. How does that work?
The best way to interact with PW as a user is by installing PW Explorer, these days called PW Design Integration. The best way to interact with PW as a developer is to install the PW Design Integration SDK.
There's a dedicated ProjectWise Programming Forum.
Regards, Jon Summers LA Solutions
Jon,
[CONNECT Update 14 VBA] MSCE version 10.14.00.19
So the User will have the PW Explorer installed.
When I call the mdlDialog_fileOpen, it is like the user opening a file and getting the PW interface (not the local). It initializes the open file dialog, the user navigates to the file they need, select and open it. Unfortunately, it appears to only work on one file.
I am technically an Admin in PW, but I have others managing that, so I don't fully understand how it all works. Thanks for the explanation. So much to learn...
This project was supposed to be pretty basic, hence using VBA, so I don't know that I want to go through the PW SDK.
I also checked on the PW programming forum, but couldn't find much. I believe this is more a MicroStation issue, and I happen to be using PW.
So, after poking around more, it looks like the mdlFileList_edit command is the one i'm looking for! I found another post that detailed how to send the attributes in correctly. Turns out it defaults to folder mode if you don't pass the attributes in correctly. Here's where i'm at so far:
Declare PtrSafe Function mdlFileList_edit Lib "stdmdlbltin.dll" ( _ ByRef lastInfoP As FileListInfo, _ ByRef StringListP As String, _ ByVal attributes As Long, _ ByVal dialogTitle As String, _ ByVal listLabel As String, _ ByVal fileFilter As String, _ ByVal defaultDirectory As String) As Long Type FileListInfo lastAction As Long lastDirectory As String lastFilter As String End Type Sub MultipleFiles() Const FILELISTATTR_SORT = &H1 Const FILELISTATTR_MULTIPLE = &H8 Const FILELISTATTR_FILES = &H100 Dim sList As String Dim info As FileListInfo Dim attributes As Long Dim retVal As Long attributes = FILELISTATTR_FILES + FILELISTATTR_SORT + FILELISTATTR_MULTIPLE 'This opens the select dialog file box. I can select multiple files from PW and hit OK and it doesn't crash. retVal = mdlFileList_edit(info, sList, attributes, "This is the title", "This is the list label", "*.dgn", "") 'Need to figure out how to get the information out and do stuff with it. end sub
So if you look at the definition of mdlFileList_edit, it uses a structure called StringListP. I cannot find a way to use this structure, and I believe it's my problem. The function 'returns' a StringListP. I put return in quotes, because I'm not sure it actually returns anything or if it tries to write it directly to the first passed variable "info" (it lists "info" as [out]). I cannot get anything out of "info".
I tried setting the function declaration to return anything else (tried String, Object, 'nothing', etc...) but they all cause MSCE to crash with no error handling. If I set the function as Long, it 'works' but, I get nothing usable out of it. Or nothing I currently know how to use.
Thanks.
dkleinot said:When I call the mdlDialog_fileOpen, it is like the user opening a file and getting the PW interface
When PW Explorer is installed, it adds an app mcm to MicroStation's app folder (..\MicroStation\mdlapps). That app is automatically loaded when you start MicroStation. Amongst other things, it hijacks MicroStation's user interface.
mcm
..\MicroStation\mdlapps
mdlDialog_fileOpen is intended for the user to open a single DGN file.
dkleinot said:mdlFileList_edit uses a structure called StringListP. I cannot find a way to use this structure
A StringList dates from the earliest days of MDL, when VBA wasn't even a glint in Microsoft's eye. It uses dynamic memory allocation both for the list it manages and the strings contained in that list. VBA is bad at dynamic memory and doesn't understand C++ pointers. It would not be easy to attempt to use a StringList from VBA.
StringList
You get a MicroStation crash because you must deallocate memory used by the StringList. VBA has no way to deallocate memory.
PW lacks a VBA API.
You can write PW Explorer code using C++ or C#. Visit the PW Programming Forum I mentioned above.
I agree, the mdlDialog_fileOpen is not the way to go.
So after replying, I found a post from you on this a few years ago:
https://communities.bentley.com/products/programming/microstation_programming/f/microstation-programming---forum/125209/v8i-vba-mdl-is-it-possible-to-use-mdlstringlist_getmember-with-vba
Which you implemented in an example working with LineStyles:
http://www.la-solutions.co.uk/content/V8/MVBA/MVBA-LineStyles.htm
When trying to implement the code from the post or your article, I keep getting errors where it states that it can't find the function call in the MDL.
"Can't find DLL entry point mdlStringList_getMember in stdmdlbltin.dll"
I also get this error for mdlDialog_fileOpenExt. I mention this because both mdlDialog_fileOpen and mdlDialog_fileOpenExt say they require the mdlbltin.lib. One works but the other doesn't?
I don't understand how stdmdlbltin.dll relates to mdlbltin.lib.
StringList states that it requires "RmgrTools<ApiNumber>.lib i.e. RmgrTools3.lib" I found the lib, but I don't know how to load a lib.
I feel like I'm really close and if I can figure out why it can't find the DLL entry point, I might be able to get something working...
Thanks again for taking the time to help on this. I really appreciate this. I have a basic understanding of C++ but languages like C and Objective C escape me... I've gotten used to managed code.
dkleinot said: I found a post from you on this
I told you it wasn't easy!
dkleinot said:When trying to implement the code from the post or your article, I keep getting errors where it states that it can't find the function call
Here's an updated version of that article about StringLists. Note each function declaration where I've changed Long to LongPtr to match 64-bit VBA.
Long
LongPtr
dkleinot said:StringList states that it requires "RmgrTools<ApiNumber>.lib i.e. RmgrTools3.lib" I found the lib, but I don't know how to load a lib.
You don't have to load a library. Once you have the correct function declaration in VBA, the VBA run-time finds the library for you.
dkleinot said:I don't understand how stdmdlbltin.dll relates to mdlbltin.lib
The CONNECT SDK delivers mdlbltin.lib. The V8 SDK delivers stdmdlbltin.lib.
mdlbltin.lib
stdmdlbltin.lib
dkleinot said:I've gotten used to managed code
The MicroStation CONNECT SDK delivers a first-class .NET API. The PW SDK is C++, but MostOfDavesClasses.cs provides wrappers around the C functions.
I tried this one quick and noticed two things:
1) the Download link to get the mvba is broken on your site.
2) I copy and pasted the code from the example you posted, but it cannot find the dll file. I searched through the folder that contained the stdmdlbltin.dll and mdlbltin.dll is not there. I was able to find the mdlbltin.lib, but that does not help. I was looking through the SDK information to see if there was a way to create the dll from the lib but haven't seen anything yet.
I'll search around tomorrow morning, any idea why the mdlbltin.dll isn't in the same folder? Or where it is?
I'll dig in to this one tomorrow morning.
I'm not Jon, and I can't help overall, but I can answer one of your questions.
stdmdlbltin is part of the V8i SDK
mdlbltin is part of the CONNECT SDK
They are not the same because they are developed for different MicroStation versions. They are similar in that they are the same TYPE of file for their respective versions, but they are not directly related. You will use one or the other, depending on which MicroStation version your are writing for
MaryB
Power GeoPak 08.11.09.918Power InRoads 08.11.09.918OpenRoads Designer 2021 R2
dkleinot said:the Download link to get the mvba is broken on your site
I haven't had time to rewrite the VBA for CONNECT. Download the V8 version and modify it.
dkleinot said:I searched through the folder that contained the stdmdlbltin.dll and mdlbltin.dll is not there
Read the responses to your questions. Both MaryB and I have informed you about stdmdlbltin.lib and mdlbltin.lib. The library (*.lib) files are delivered with the MicroStation SDK for the use of native code (C++) developers. They are of no use with any other language.
*.lib
I can see stdmdlbltin.dll in the CONNECT ..\MicroStation folder. I mistakenly changed the DLL name in the function declarations, which I've corrected.
stdmdlbltin.dll
..\MicroStation
dkleinot said:I was looking through the SDK information to see if there was a way to create the dll from the lib but haven't seen anything
When Bentley Systems build MicroStation, the DLLs in the ..\MicroStation folder are created from those *.lib files.
Jon / MaryB,
I apologize for my ignorance and thank you for your patience!
Maybe I wasn't clear enough, but when I could not download the mvba, I tried editing the code manually.
Declare PtrSafe Function mdlStringList_getMember Lib "stdmdlbltin.dll" ( _ ByRef pString As LongPtr, _ ByRef pInfo As LongPtr, _ ByVal list As LongPtr, _ ByVal n As Long) As Long
The only difference from your code and mine for the function call is the PtrSafe, which VBA yells at me about. Throws a Compile error saying that the code must be updated for 64-bit systems.
When I run this, I get the error that it cannot find it:
This is why I thought I was missing the mdlbltin.dll, hence the other questions about the .lib files.
So, why is it saying that this function (and others) are not in the stdmdlbltin? I have checked the spelling multiple times.
Declare PtrSafe Function mdlFileList_edit Lib "stdmdlbltin.dll" ( _ ByRef lastInfoP As FileListInfo, _ ByRef StringListP As String, _ ByVal attributes As Long, _ ByVal dialogTitle As String, _ ByVal listLabel As String, _ ByVal fileFilter As String, _ ByVal defaultDirectory As String) As Long Declare PtrSafe Function mdlStringList_getMember Lib "stdmdlbltin.dll" ( _ ByRef pString As LongPtr, _ ByRef pInfo As LongPtr, _ ByVal list As LongPtr, _ ByVal n As Long) As Long Declare PtrSafe Function SysAllocString Lib "oleaut32" (ByVal CharPtr As Long) As String Function CharPtrToString(CharPtr As LongPtr) As String If CharPtr = 0 Then CharPtrToString = "" Else CharPtrToString = SysAllocString(CharPtr) End If End Function Sub MultipleFiles() Stop Const FILELISTATTR_SORT = &H1 Const FILELISTATTR_MULTIPLE = &H8 Const FILELISTATTR_FILES = &H100 Dim temp As Long Dim sList As String Dim info As FileListInfo Dim attributes As Long Dim retVal As Long Dim i As Long Dim j As Long Dim l As Long Dim s As String Dim lStringlist As LongPtr Dim ppstring As LongPtr Dim ppinfofields As LongPtr attributes = FILELISTATTR_FILES + FILELISTATTR_SORT + FILELISTATTR_MULTIPLE 'So this gives me the dialog, but I cant seem to get anything out of it. not sure how to deal with the StringListP structure... lStringlist = mdlFileList_edit(info, sList, attributes, "This is the title", "This is the list label", "*.dgn", "") Stop i = 0 Do While (0 = mdlStringList_getMember(ppstring, ppinfofields, lStringlist, i)) s = CharPtrToString(ppstring) j = InStr(1, s, vbNullChar) If j > 0 Then s = Left$(s, InStr(1, s, vbNullChar) - 1) Debug.Print s i = i + 1 Loop
dkleinot said:Why is it saying that this function (and others) are not in the stdmdlbltin?
The only documentation we have about declarations of MDL functions for use in VBA is in the MicroStation V8 SDK help MDL Function Reference. The VBA declarations there are not available in the equivalent MicroStation Help for the MicroStationAPI.
For each VBA declaration we have to make the appropriate edits:
PtrSafe
Feel free to post an Idea asking for VBA declarations to be included once again in MicroStationAPI help. From what you've told us, it looks like mdlStringList_getMember is implemented in another DLL.
If VBA complains (errors at run time) about a DLL, then you have to find it. Here are some suggestions.
So, what I don't understand then, is how is your code working and mine isn't? Do I have a bad version of the dll? Or did something change and both ours broke?
I will look over your suggestions (Idea and DLL) and let you know.
dkleinot said:what I don't understand then, is how is your code working and mine isn't?
The code available as a VBA project from my article was developed for MicroStation V8. As I mentioned, I haven't had time to port it to CONNECT. I don't have a version that works in CONNECT.
Ah, ok thanks.