on 05-16-2005 11:09 AM
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:
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
--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
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
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
}
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
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
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.
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.
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
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
107 | |
12 | |
11 | |
6 | |
5 | |
4 | |
4 | |
3 | |
3 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.