Using ICO files in MDL

Hi folks,

I am trying to incorporate support for fancy multi-coloured icons in my MDL/DLL application. The dialogs are all standard MDL definitions compiled with RCOMP.

I can get it to work by putting the ICO file in Bentley's icon search path. I can also get it to work by compiling the ICOs into a RSC file using wiconpackager and putting this file into the icon resource path. But what I would much rather do is bundle it into an existing MA or DLL so I don't need to monkey around with the workspace configuration.

Every customer has a different environment, and inserting a config file at install time is prone to problems with users locking variables, offloading the Workspace dir to some unknown network location, etc. I know I could also ignore the workspace variables and just place my icons directly into the standard Bentley search path, but I prefer to keep my own application files out of the Bentley directory - it absolves me from blame if something gets messed up with the workspace. So it would be much simpler if the icons were bundled with my existing install files.

I have experimented with wiconpackager, which seems to put ICO files into one resource file. I thought that maybe I could then link this RSC file into my MA and have the icons available, but this seems not to work (icon is blank). The fact that it doesn't seem to work makes me wonder what the point of this utility is actually - why bother putting ICOs into a RSC file, when I could put them into a DLL even easier? Is the format of the resulting RSC documented anywhere, supported by any other development tools, accessible from MDL, or useful in any way? BMAKE seems happy to link this RSC, but this seems useless since it doesn't actually work.

So I just wanted to confirm if it is indeed the case that MicroStation does not try to resolve icons at runtime by looking in the currently loaded MA or DLL? Does it always go chasing icons in the workspace configuration variables: MS_ICONLIBRARYLIST, MS_ICONRSCLIST or MS_ICONPATH. ? Is there any way to bundle BMPs or ICO files into my MDL/DLL application without having to place any files in one of the three above search paths?

PS - I guess I could do this if I switched to MFC or WinForms or something else for the GUI, but I don't have the time to rewrite the entire GUI from scratch.

Cheers.

  • You can try to use standard Win32 tools... http://msdn.microsoft.com/en-us/library/ms997538.aspx

    Or, make an IconLoader WinForm / MDL tool to convert icons to be usable in MDL. Something similar has Bentley done. Look into assembly Bentley.MicroStation.dll and look for public types Bentley.MicroStation.WinForms.Icon and Bentley.MicroStation.WinForms.IconHelper. Seems to be usable... 

    public class IconHelper
    {
    public IconHelper();
    public static StringCollection GetAvailableIconNamesFromDgnFile(string dgnFileName);
    public static StringCollection GetAvailableIconNamesFromRscFile(string rscFileName);
    public static int ImportImageAsDgnIcon(string name, Image image, IntPtr dgnFilePtr);
    public static int ImportImagesAsDgnIcon(string name, List<Image> imageList, IntPtr dgnFilePtr);
    }

    Dan

  • Piers, any progress to report on bundling the icons with the dll / ma?  I'm very interested in this as well for the same reasons.

    Rick

  • Hi Rick,

    In the end I have just bundled the multi-colour icons into the RSC file built by wiconpackager and put that RSC file into the same path as my executables. Then I have done something like this:

    MS_MDLAPPS > $(MY_BIN_PATH)

    MS_LIBRARY_PATH > $(MY_BIN_PATH)

    MS_ICONRSCLIST > $(MY_BIN_PATH)*.rsc

    So I just have to hope that the user has not locked or overwritten any of those paths. I don't think BMAKE (or maybe the MDL loader) knows what to do with icon files built by wiconpackager, so there's no point linking it in.

    HTH.

    --
    Piers Porter
    Altiva Software

  • Don't give up on this -- there are a number of undocumented MKI macros that let us set Microsoft compiler and linker switches.  They tend to have inscrutable names.  For example, here's how to create a C++ pre-compiled header using bmake.  Each time I find one, I add it to our web pages.  It's like mining for diamonds -- they are well concealed and sparsely distributed.

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    I gave up on using BMAKE for any native code that wasn't simple C. Whenever I mix in any other frameworks (MFC, ATL, etc) I get dependency linkage errors, multiply defined symbols, weird crashes, sporadic memory corruption, etc. After a long process of fiddling with link library order, tweaking undocumented MKI macros and tearing my hair out, I decided it was much easier to do native development in the native compiler, and invoke it as a DLL from an MDL wrapper.

    I found that BMAKE is very powerful, but trying to figure out what order it will link your standard libraries in and why it goes wrong is a nightmare. Since Bentley are releasing fewer and fewer examples, and new functionality is increasingly undocumented, I have found it safer to stick with what works, even if it is "old school".

    My first attempt at using dotNET for a simple example of using the new XM taskbar resulted in occasional corruption of some internal GUI setting that I could never find the source of, would permanently corrupt MicroStation's interface in every workspace and I would inevitably have to do a clean reinstall. On other machines running the same MicroStation version it worked fine. Documentation for the TemplateManager was non-existent. So I quickly decided dotNET development could wait until the API matured.

    In summary, I like to take a pragmatic approach and will stick with what is stable, reliable and reasonably well documented. Trying to get BMAKE to play nice with other frameworks was a horrible experience that has put me off trying again any time soon.

    --
    Piers Porter
    Altiva Software

  • That's my experience too, and I even use something like a wrapper ma for my application. Currently I even have toolbars therein, so it contains the icons+commands but immediately switches into a native (C++) dll, which contains everything else (even menus to be included in Ustn's main menu and so on). I have the favor of using edit+go this way and can call whatever I like from this (we're using lot's of .Net via COM).

    I even got some small examples to work as 'native ma', completely compiled/linked with bmake and containing mfc dialogs, but reworking a complex app with about 100.000 lines of code is not worth the time (while loosing edit+go even)

    The only problem that still exists and drives me mad,is that I would even like to use ICO-files for my toolbars, but couldn't get it to work as expected, and did not try now for years. Maybe it will work now with wiconpackager to create a rsc and include this in my ma, but my tests some years ago weren't successfull at all (via bmake).

    So I still have a XM installation that needs to be kept as long as I need Iconedit to provide my icons for my toolbars (almost ~200).

    So any working example that didn't require a change to MS_ICONRSCLIST would be fine.

    Unfortunately the example from Dan doesn't help, as the icons have to remain in the (pure C) ma, to be used for toolbars. For anything else I have MFC and .Net :-)

    Michael



  • As an "FYI" item, I too am interested in this. Up to this point, I had arrived at the same issues with .ico and .rsc files - why can't I just use wiconpackager and put the icons in the .ma. Inserting them into a nativecode .dll works, but it's time consuming if you have numerous icons. What I just tried (and seemed to work) is to import the .ico files into a .dgnlib, and place that .dgnlib in the search path for MS_GUIDGNLIBLIST. The only issue I've seen is that whichever icon is found first, that's what is used. For example, I had an icon named "filter", but when my app grabbed the icon, it used the "filter" icon from MicroStation that shows in the level filter dialog. To solve, I just renamed it to something else.

     

    Also, to "reference" the icon, I just did this in my resource file:

     

    IconRsc ICONID_FILTER = {32, 32, ICONFORMAT_WINDOWSICO, MGREY_INDEX, "",  "FILTER1" };

     

    Bruce

  • Unknown said:
    What I just tried is to import the .ico files into a .dgnlib, and place that .dgnlib in the search path for MS_GUIDGNLIBLIST

    Thanks for that tip!

    My only comment is that the DGNLIB is yet another file to be installed in the correct location.  It must be available to all workspaces where your app. is used.  I've so many examples of customer complaining because something doesn't work.  Then I find that they've reconfigured MicroStation or their system and files have vanished or been moved to a new location.

     
    Regards, Jon Summers
    LA Solutions

  • Even a thanks from my side, it provides a workaround that I will surely test. Jon has pointed out the problem, but for me (as I have no native code dll, but an external one) this is the only way to get stuff beside the old Iconedit-rsc's. And even (for native dll) injecting some 100 icons in a dll after each build is not fun.