Windows API - Browse for Folder

Posted by Jeff Ledbetter on 15-Aug-2016 10:34

Hi.

What is the preferred means to call SHBrowseForFolder using OE 64-bit?

The method that we have used for quite some time is crashing the OE session when executed in OE 64-bit:

PROCEDURE SHBrowseForFolder EXTERNAL "shell32":U :
  DEFINE INPUT  PARAMETER  lpbi         AS LONG.
  DEFINE RETURN PARAMETER  lpItemIDList AS LONG.
END PROCEDURE.

Is there a .Net way that one should be using these days?

I notice that the OE ADE code is using CREATE 'Shell.Application' chServer. Is that the best way?

Thanks.

Posted by Ken McIntosh on 15-Aug-2016 12:20

Would SYSTEM-DIALOG GET-DIR not suffice for some reason?  This seems the easiest and most hands-off solution.

All Replies

Posted by Mike Fechner on 15-Aug-2016 10:41

Go 21st century. Go .NET:

https://msdn.microsoft.com/en-us/library/system.windows.forms.folderbrowserdialog(v=vs.110).aspx

DEFINE VARIABLE oDialog AS System.Windows.Forms.FolderBrowserDialog NO-UNDO.
DEFINE VARIABLE oDialogResult AS System.Windows.Forms.DialogResult NO-UNDO .
oDialog = NEW System.Windows.Forms.FolderBrowserDialog () .
// set additional options.
WAIT-FOR oDialog:ShowDialog() SET oDialogResult .
IF Progress.Util.EnumHelper:AreEqual (oDialogResult, System.Windows.Forms.DialogResult:Ok) THEN ....

Posted by Jeff Ledbetter on 15-Aug-2016 10:54

Thanks.

We call other DLL procedures that function okay. Not sure why this one is being problematic.

Posted by Brian K. Maher on 15-Aug-2016 10:58

Jeff,
 
Does the function require a data structure?  If so, have to redesigned that structure for 64-bit support?
 
Brian

Posted by Mike Fechner on 15-Aug-2016 10:58

IMHO, when there’s a .NET variant, don’t waste your precious time fiddling with the DLL based API’s.

Posted by Jeff Ledbetter on 15-Aug-2016 11:16

Brian, yes it does to require the BROWSEINFO structure. No, we have no modified it as it did not appear that it would need to be modified. Out of curiousity, do you know what those changes may be?

Mike is right, it makes more sense to use .Net variant probably.

Posted by Brian K. Maher on 15-Aug-2016 11:20

Jeff,
 
I don’t know but if you could provide sample code I’ll take a shot and converting it.
 
Brian

Posted by tbergman on 15-Aug-2016 11:32

While I frequently use the .Net dialogs, you may also want to consider the Progress SYSTEM-DIALOG GET-DIR statement. The .Net dialogs are more flexible and their file dialogs allow things like multiple files. But for a simple folder browse, you may find the Progress version more than adequate.
 
Tom
 

Posted by Jeff Ledbetter on 15-Aug-2016 11:41

Tom, thanks for that tip.

Posted by Jeff Ledbetter on 15-Aug-2016 11:42

Don't worry about it Brian. There are better alternatives. :) Thanks for the offer.

Posted by Ken McIntosh on 15-Aug-2016 12:20

Would SYSTEM-DIALOG GET-DIR not suffice for some reason?  This seems the easiest and most hands-off solution.

Posted by Jeff Ledbetter on 15-Aug-2016 12:34

Yes, Ken. I think in prior releases it did not exist and we just never replaced our working solution. Using SYSTEM-DIALOG is much easier and does what we need.

Posted by Frank Meulblok on 16-Aug-2016 03:16

[quote user="Jeff Ledbetter"]

 Out of curiousity, do you know what those changes may be?

[/quote]

The OS memory layout is different between 32-bit and 64-bit, and any data you send to a dll must match that layout. Otherwise, you're effectively passing corrupt memory around and bad stuff happens. 

- Byte allignment rules will be different between 32-bit and 64-bit.

- Pointers will be 8 bytes instead of 4, so variables holding them need to be converted to 64-bit . (That means changing your INTEGER and LONG declarations to INT64 *if running on 64-bit*.

See also http://knowledgebase.progress.com/articles/Article/P104543 and http://knowledgebase.progress.com/articles/Article/000044291

Posted by Mike Fechner on 16-Aug-2016 03:22

(I know this is the way it is with DLL based API‘s)
 
But this makes DLL based API’s so unattractive. We’re using an ABL (formerly known a 4GL) and are not writing Assembly code where I’d accept having to take care of low level OS structures. .NET API’s or ABL wrappers are definitively the way to go. At least when they are available as an alterantive.

Posted by Frank Meulblok on 16-Aug-2016 04:33

Not denying that :)

I just wanted to point out what you need to know if you don't have an alternative.

Posted by Laura Stern on 17-Aug-2016 08:18

And if you really want to go 21st century, in 11.6 and up, you can simplify that last IF statement as:

IF oDialogResult = System.Windows.Forms.DialogResult:OK THEN ...

The AVM now recognizes Enums and will do the appropriate comparison on them... even .NET enums!  So you no longer need to use the EnumHelper class.

Just saying :-)

Posted by Laura Stern on 17-Aug-2016 08:20

P.S. (Sorry - I thought this would come after Mike Fechner's post way up top.)  That IF statement replaces:

IF Progress.Util.EnumHelper:AreEqual (oDialogResult, System.Windows.Forms.DialogResult:Ok) THEN ...

Posted by Mike Fechner on 17-Aug-2016 08:22

Lucky those that do not need to code for 10.2B :-(
 
But yes, that’s a really great, great improvement. Tough only if you get used to it too soon. I have to support my tools on 10.2B, 11.3 -11.6.
 

This thread is closed