cancel
Showing results for 
Search instead for 
Did you mean: 

How to create a "Open file" form

Former Member
0 Kudos

I'm trying to do an Open file form with vb6. I create a common dialog object in a form and calls showopen when I need it, but the open form doesn't show at top of SAP B.O., it shows at the back... Anyone knows how to show it properly?

Message was edited by:

Frank Moebius

Solution based on std. B1 behavior: See this message:

Accepted Solutions (0)

Answers (4)

Answers (4)

Former Member
0 Kudos

Frank wrote:

<i>"Define UDF as "Link" and bind an EditText to it

Then just "double-click" into it... "</i>

I dont understand, what it means as "Link". I created user defined field in user table but there is no possibility to make .Type = ..Link.. Could somebody explain it to me?

Thx

Petr

Former Member
0 Kudos

Yes, I make visible the form containing de common dialog (with Height and weight value of 1 and a left value=-100) before de showopen and it works. I was asking in order to see if there is an other option (more correct).

Thanks!

Former Member
0 Kudos

--Create a window form myForm, put there openFileDialogue

--declare global modal variable

Private OpenFile As String

--insert this function in your class(not in the form!!):

Sub openfile1()

Dim frm MyForm

frm.Show()

frm.TopMost = True

frm.OpenFileDialog1.Title = "Title"

If frm.OpenFileDialog1.ShowDialog = DialogResult.OK Then

OpenFile = frm.OpenFileDialog1.FileName

System.Threading.Thread.CurrentThread.Abort()

Else

OpenFile = ""

System.Threading.Thread.CurrentThread.Abort()

End If

End Sub

--and now, put this code where you want to open the dialogue.

Dim myThread As New System.Threading.Thread(AddressOf openfile1)

myThread.Start()

myThread.Join()

Hagai

Former Member
0 Kudos

No, I think that forms in SBO miss a 'handle' property...this could be very helpful when displaying other forms on top of system forms.

Former Member
0 Kudos

I figured out an alternate method of doing this in .net a little while ago.

The basic idea is:

Dim a New FolderBrowserDialog

Use the overide for the .Showdialog method that allows you to specify an instance of SBO as the owner.

In effect, you create a modal dialog and tell it that the SAP Business one main form owns the dialog. This puts the dialog in the foreground and has the additional benefit of "locking" the rest of the SBO UI until the dialog is "complete".

There are a couple of tricks you need to do. The first one is getting a handle to the SBO window. You could use the old win32 API stuff. However, I use the following code to get an array of process objects for each instance of SBO that is running.


Dim MyProcs() As Process
MyProcs = Process.GetProcessesByName("SAP Business One")

You can use the process array to get the main windowhandle (IntPtr/hWnd)

Once you have the windowhandle you can do a little trick. You can construct a new window wrapper class that you have created with the windowhandle of an SBO instance and get an iWin32Window that can be used for all sorts of arguments in .net. One of the useful things you can do with an iWin32Window is use it as an argument when using common dialogs such as the FolderDialogBrowser class. You will notice that there is an overide for the FolderBrowserDialog.ShowDialog method that looks like this:

[Visual Basic] Overloads Public Function ShowDialog(IWin32Window) As DialogResult

This Runs a common dialog box with the specified owner. We want to set that owner to SBO.

What we need is a wrapper class that looks like this:


Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As IntPtr

        Public Sub New(ByVal handle As IntPtr)
            _hwnd = handle
        End Sub

        Public ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property

End Class

What does this class do? It simply implements System.Windows.Forms.IWin32Window and takes an IntPtr (hWnd) in it's constructor. If we construct it using the IntPtr(hWnd) of an SBO instance we can then use our new wrapper class for some useful purposes.

EXAMPLE

Put this code in your startup module:


    Public Sub ShowFolderBrowser()
        Dim MyTest As New FolderBrowserDialog
        Dim MyProcs() As Process

        MyProcs = Process.GetProcessesByName("SAP Business One")
        If MyProcs.Length <> 0 Then
            For i As Integer = 0 To MyProcs.Length - 1
                Dim MyWindow As New WindowWrapper(MyProcs(i).MainWindowHandle)
                MyTest.ShowDialog(MyWindow)
             Next
        Else
            Console.WriteLine("No SBO instances found.")
        End If

    End Sub

Add the following as a class module in your project:


Public Class WindowWrapper
        Implements System.Windows.Forms.IWin32Window
        Private _hwnd As IntPtr

        Public Sub New(ByVal handle As IntPtr)
            _hwnd = handle
        End Sub
        Public ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _hwnd
            End Get
        End Property

End Class

In your ADD-On class, declare this:


Public Shared ShowFolderBrowserThread As New Threading.Thread(AddressOf ShowFolderBrowser)

Now finally in the sub where you trap item events (perhaps a button click) you simply do this:


ShowFolderBrowserThread.Start()

I hope this was clear enough and that you can use this functionality for something useful.

It does get a little tricky when working with multiple instances of SBO. It would be nice if the IntPtr for the main form was exposed as a readonly property of the SBO application object. Who knows what's in store next though!

Good luck

Ty Babcox

Former Member
0 Kudos

FileDialog implementation on C#

namespace SBOPlugins.Enumerations

{

public enum eFileDialog { en_OpenFile = 0, en_SaveFile = 1 };

}

namespace SBOPlugins.Utils

{

#region The class implements FileDialog for open in front of B1 window

#region an example of using GetFileNameClass()

/*

using(GetFileNameClass oGetFileName = new GetFileNameClass())

{

oGetFileName.Filter = "txt files (.txt)|.txt|All files (.)|." ;

oGetFileName.InitialDirectory = "c:
";

Thread threadGetFile = new Thread(new ThreadStart(oGetFileName.GetFileName));

threadGetFile.ApartmentState = ApartmentState.STA;

try

{

threadGetFile.Start();

while (!threadGetFile.IsAlive); // Wait for thread to get started

Thread.Sleep(1); // Wait a sec more

threadGetFile.Join(); // Wait for thread to end

// Use file name as you will here

if (oGetFileName.FileName != string.Empty)

{

//

// ADD YOU CODE HERE!!!!

//

}

}

catch(Exception ex)

{

SBOApp.MessageBox(ex.Message,1,"OK","","");

}

}

*/

#endregion

public class GetFileNameClass : IDisposable

{

[DllImport("user32.dll")]

private static extern IntPtr GetForegroundWindow();

System.Windows.Forms.FileDialog _oFileDialog;

// Properties

public string FileName

{

get { return _oFileDialog.FileName; }

set { _oFileDialog.FileName = value; }

}

public string[] FileNames

{

get { return _oFileDialog.FileNames; }

}

public string Filter

{

get { return _oFileDialog.Filter; }

set { _oFileDialog.Filter = value; }

}

public string InitialDirectory

{

get { return _oFileDialog.InitialDirectory; }

set { _oFileDialog.InitialDirectory = value; }

}

// Constructor

public GetFileNameClass(SBOPlugins.Enumerations.eFileDialog dlg)

{

switch ((int)dlg)

{

case 0: _oFileDialog = new System.Windows.Forms.OpenFileDialog(); break;

case 1: _oFileDialog = new System.Windows.Forms.SaveFileDialog(); break;

default: throw new ApplicationException("GetFileNameClass incorrect parameter");

}

}

public GetFileNameClass()

: this(SBOPlugins.Enumerations.eFileDialog.en_OpenFile)

{

}

// Dispose

public void Dispose()

{

_oFileDialog.Dispose();

}

// Methods

public void GetFileName()

{

IntPtr ptr = GetForegroundWindow();

WindowWrapper oWindow = new WindowWrapper(ptr);

if (_oFileDialog.ShowDialog(oWindow) != System.Windows.Forms.DialogResult.OK)

{

_oFileDialog.FileName = string.Empty;

}

oWindow = null;

} // End of GetFileName

}

#endregion

#region WindowWrapper : System.Windows.Forms.IWin32Window

public class WindowWrapper : System.Windows.Forms.IWin32Window

{

private IntPtr _hwnd;

// Property

public virtual IntPtr Handle

{

get { return _hwnd; }

}

// Constructor

public WindowWrapper(IntPtr handle)

{

_hwnd = handle;

}

}

#endregion

}

Former Member
0 Kudos

Thanks Denis, it works!

That is why we love SAP, simply solutions for simply problems.

former_member185703
Active Contributor
0 Kudos

You can do it way simpler:

Just define a UDF of type "link" - and plug it behind an input field; then you can just use the B1 standard functionality...

...just added to the "FAQ": https://www.sdn.sap.com/irj/sdn/wiki?path=/display//b1/faq

Regards,

Frank

Former Member
0 Kudos

Hello Frank,

I did not understand your post.

Is ist possible to show an FileOpen Dialog with B1 standard functionality?

If so, tell me how, please.

Thank you in advance.

Rudy.

WOW! I tried it and now I understood it. My question is answered. Nevertheless, Thanks

Message was edited by:

Ruediger Gertz

former_member185703
Active Contributor
0 Kudos

Hi Rudy,

In my post I pointed to the B1 FAQ - and there (in the section UI General; maybe I should have added that...) you will find the following hint:

<i>UI General

...

File select dialog:

Define UDF as "Link" and bind an EditText to it

Then just "double-click" into it...</i>

HTH,

Frank

Former Member
0 Kudos

Hi Frank!

Thanks! It works. I had a problem with the UDF type "link".

But now I'm know: you mean the type "General" and structure "Link".

Greetings from Berlin

Rudy.

former_member185703
Active Contributor
0 Kudos

...sorry for having been too lazy

...I thought talking in riddles might be somewhat entertaining

Greetings in turn - from St.Leon-Rot

Frank

Former Member
0 Kudos

Oh no!

How can I avoid the behavior around the UDF(General->Link)?

The folowing is happen:

1. I doubleklick in the EditText-Field (bound to that UDF with structure "link")

2. The OpenFile Dialog appear like expected(but every time with the Attachement Folder as root directory)

3. I choose a file in an arbitrary directory

4. This File will be copied to the B1 "Attachement" Directory(unwanted)

5. The Path of the copied File appear in the EditText

I just want to select a file in the filesystem. I don't want to copy a file!

Is there a way to avoid the behavior from point 4?!

Otherwise I can't use the B1 standard functionality.

Thank you in advance.

Rudy.

Former Member
0 Kudos

Okay,

no further tipps?

Now I adapted the solution from Denis Sapunkov for my addon.

This works verry well. Thanks Denis!

That solution from Frank is a verry good choice, if you want to select files in the B1 Attachement Folder only. Thanks Frank.

Both solutions are displaying only a windows(not SAP) styled diolog.

I hope there will be a UI API Object for selecting files in future B1 Versions.

Bye

Rudy.

former_member185703
Active Contributor
0 Kudos

Hi Rudy,

Sorry, but I didn't get to test it until today... (Somehow I didn't notice the problem you mentioned; sorry)

...but you are right - there seems to be no way (except even weird workarounds) to get around the "unwanted" behavior (...that the file gets copied into the Attachments folder). I will add a remark to the FAQ - thanks for checking.

Regards,

Frank

Former Member
0 Kudos

Maybe you'll be lucky with some window activation function

of Win32 sdk, such as SetForegroundWindow...or just display the 'dummy' form containing the CommDlg control using the Show method (modeless).

Hope this helps.

Former Member
0 Kudos

HTH

Juha