[原创]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;
        }
    }
}
posted @ 2008-01-13 11:51  E.L.---黑者如斯夫,不舍昼夜......  阅读(719)  评论(1)    收藏  举报