[原创]SBO 调用模态与非模态窗体
SBO显示非模态窗体
"itemEvent"
viewWinForm vWForm =new ViewWinForm();
Thread T=new Thread(new ThreadStart(vWForm.view));
t.SetApartmentState(ApartmentState.STA);
t.start();
CLASS ViewWinForm
{
Private bool run;
Form oForm;
public ViewWinForm()
{
//构造函数
oForm=new Form();
oForm.FormClosed+=new ormClosedEventHandler(form_FormClosed);
}
public void view()
{
run = true;
form.Show();
while (run)
{
Application.DoEvents();
Thread.Sleep(1);
}
}
void form_FormClosed(object sender, FormClosedEventArgs e)
{
run = false;
}
}
SBO中显示模态窗体(如:对话框)
摘自https://www.sdn.sap.com/irj/sdn/thread?threadID=45710&tstart=0
After searching the forums for a way to reliably open an open file dialog I didn't really find any examples showing what I needed. Anyway, here's what I came up with.
There are two problems to deal with:
1. The dialog must be run on a separate thread.
2. The dialog must be modal for the CORRECT INSTANCE of the SAP client window.
With my item events I invoke the dialog with the following code example for an excel file. I was using the try/catch for debugging purposes.
I hope this helps someone out in the future.
GetFileNameClass oGetFileName = new GetFileNameClass();
oGetFileName.Filter = "Excel files (*.xls)|*.xls";
oGetFileName.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
Thread threadGetExcelFile = new Thread(new ThreadStart(oGetFileName.GetFileName));
threadGetExcelFile.ApartmentState = ApartmentState.STA;
try
{
threadGetExcelFile.Start();
while (!threadGetExcelFile.IsAlive); // Wait for thread to get started
Thread.Sleep(1); // Wait a sec more
threadGetExcelFile.Join(); // Wait for thread to end
// Use file name as you will here
string strValue = oGetFileName.FileName;
}
catch(Exception ex)
{
_SBO_Application.MessageBox(ex.Message,1,"OK","","");
}
threadGetExcelFile = null;
oGetFileName = null;
The following is my GetFileName class. More properties can be easily added like FileName, Filter, and InitialDirectory were. Change the namespace as appropriate.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MyNamespace
{
/// <summary>
/// Wrapper for OpenFileDialog
/// </summary>
public class GetFileNameClass
{
[DllImport( "user32.dll" )]
private static extern IntPtr GetForegroundWindow();
OpenFileDialog _oFileDialog;
// Properties
public string FileName
{
get { return _oFileDialog.FileName; }
set { _oFileDialog.FileName = value; }
}
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()
{
_oFileDialog = new OpenFileDialog();
}
// Methods
public void GetFileName()
{
IntPtr ptr = GetForegroundWindow();
WindowWrapper oWindow = new WindowWrapper(ptr);
if (_oFileDialog.ShowDialog(oWindow) != DialogResult.OK)
{
_oFileDialog.FileName = string.Empty;
}
oWindow = null;
} // End of GetFileName
}
}
Edit: Changed namespace to "MyNamespace"
Whoops, I forgot the window wrapper:
using System;
namespace MyNamespace
{
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;
}
}
}
"itemEvent"
viewWinForm vWForm =new ViewWinForm();
Thread T=new Thread(new ThreadStart(vWForm.view));
t.SetApartmentState(ApartmentState.STA);
t.start();
CLASS ViewWinForm
{
Private bool run;
Form oForm;
public ViewWinForm()
{
//构造函数
oForm=new Form();
oForm.FormClosed+=new ormClosedEventHandler(form_FormClosed);
}
public void view()
{
run = true;
form.Show();
while (run)
{
Application.DoEvents();
Thread.Sleep(1);
}
}
void form_FormClosed(object sender, FormClosedEventArgs e)
{
run = false;
}
}
SBO中显示模态窗体(如:对话框)
摘自https://www.sdn.sap.com/irj/sdn/thread?threadID=45710&tstart=0
After searching the forums for a way to reliably open an open file dialog I didn't really find any examples showing what I needed. Anyway, here's what I came up with.
There are two problems to deal with:
1. The dialog must be run on a separate thread.
2. The dialog must be modal for the CORRECT INSTANCE of the SAP client window.
With my item events I invoke the dialog with the following code example for an excel file. I was using the try/catch for debugging purposes.
I hope this helps someone out in the future.
GetFileNameClass oGetFileName = new GetFileNameClass();
oGetFileName.Filter = "Excel files (*.xls)|*.xls";
oGetFileName.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
Thread threadGetExcelFile = new Thread(new ThreadStart(oGetFileName.GetFileName));
threadGetExcelFile.ApartmentState = ApartmentState.STA;
try
{
threadGetExcelFile.Start();
while (!threadGetExcelFile.IsAlive); // Wait for thread to get started
Thread.Sleep(1); // Wait a sec more
threadGetExcelFile.Join(); // Wait for thread to end
// Use file name as you will here
string strValue = oGetFileName.FileName;
}
catch(Exception ex)
{
_SBO_Application.MessageBox(ex.Message,1,"OK","","");
}
threadGetExcelFile = null;
oGetFileName = null;
The following is my GetFileName class. More properties can be easily added like FileName, Filter, and InitialDirectory were. Change the namespace as appropriate.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MyNamespace
{
/// <summary>
/// Wrapper for OpenFileDialog
/// </summary>
public class GetFileNameClass
{
[DllImport( "user32.dll" )]
private static extern IntPtr GetForegroundWindow();
OpenFileDialog _oFileDialog;
// Properties
public string FileName
{
get { return _oFileDialog.FileName; }
set { _oFileDialog.FileName = value; }
}
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()
{
_oFileDialog = new OpenFileDialog();
}
// Methods
public void GetFileName()
{
IntPtr ptr = GetForegroundWindow();
WindowWrapper oWindow = new WindowWrapper(ptr);
if (_oFileDialog.ShowDialog(oWindow) != DialogResult.OK)
{
_oFileDialog.FileName = string.Empty;
}
oWindow = null;
} // End of GetFileName
}
}
Edit: Changed namespace to "MyNamespace"
Whoops, I forgot the window wrapper:
using System;
namespace MyNamespace
{
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;
}
}
}

浙公网安备 33010602011771号