我写了一个Excel控件,但是有一些bug无法解决,请各位帮忙(内附代码).
主要问题:
1.打开Excel文档后,文档内容不响应鼠标,无法编辑.(Excel 应用程序有响应)
2.WorkbookBeforeClose Event 在设置Cancel为true后,不能阻止文档被关闭.
代码如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ZeroEdge.Office._Excel
{
/// <summary>
/// ExcelControl 的摘要说明。
/// </summary>
public class ExcelControl : System.Windows.Forms.UserControl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public ExcelControl()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO: 在 InitializeComponent 调用后添加任何初始化
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
//components = new System.ComponentModel.Container();
this.Name = "ExcelControl";
this.Size = new System.Drawing.Size(440, 336);
this.Resize += new System.EventHandler(this.OnResize);
}
#endregion
[DllImport("user32.dll")]
public static extern int FindWindow(string strclassName, string strWindowName);
[DllImport("user32.dll")]
static extern int SetParent( int hWndChild, int hWndNewParent);
[DllImport("user32.dll", EntryPoint="SetWindowPos")]
static extern bool SetWindowPos(
int hWnd, // handle to window
int hWndInsertAfter, // placement-order handle
int X, // horizontal position
int Y, // vertical position
int cx, // width
int cy, // height
uint uFlags // window-positioning options
);
[DllImport("user32.dll", EntryPoint="MoveWindow")]
static extern bool MoveWindow(
int Wnd,
int X,
int Y,
int Width,
int Height,
bool Repaint
);
#region Constants
const int SWP_DRAWFRAME = 0x20;
const int SWP_NOMOVE = 0x2;
const int SWP_NOSIZE = 0x1;
const int SWP_NOZORDER = 0x4;
const string EXCEL_WINDOW_CLASS_NAME = "XLMAIN";
#endregion
private Excel.Workbook _book = null;
private Excel.ApplicationClass _app = null;
private Excel.Sheets _sheets = null; //必须,否则无法释放Excel实例
private int _wnd = 0;
private bool _isInnerOperation = false;
private BasicExcelServices _bs = new BasicExcelServices();
private int _x =0;
private int _y =0;
private int _width = 0;
private int _height = 0;
public delegate void ObjectDestroyEventHandler();
public event ObjectDestroyEventHandler ObjectDestroy;
protected void OnDestroy()
{
if(ObjectDestroy != null)
{
ObjectDestroy();
}
}
public void Create()
{
if(_app != null)
{
Destroy();
}
_wnd = 0;
_app = new Excel.ApplicationClass();
_app.NewWorkbook +=new Excel.AppEvents_NewWorkbookEventHandler(OnNewWorkbook);
_app.WorkbookOpen +=new Excel.AppEvents_WorkbookOpenEventHandler(OnWorkbookOpen);
_app.WorkbookBeforeClose
+=new Excel.AppEvents_WorkbookBeforeCloseEventHandler(OnWorkbookBeforeClose);
}
public void Destroy()
{
try
{
_isInnerOperation = true;
OnDestroy();
if(_app != null)
{
CloseWorkbook(false);
_app.Quit();
_bs.ReleaseComObject (_app);
_app = null;
GC.Collect();
}
}
catch (Exception e)
{
throw new NotImplementedException(e.Message ,e);
}
_isInnerOperation = false;
}
public int AppWindow_X
{
get
{
return _x;
}
set
{
if(_x != value)
{
_x = value;
OnResize(null, null);
}
}
}
public int AppWindow_Y
{
get
{
return _y;
}
set
{
if(_y != value)
{
_y = value;
OnResize(null, null);
}
}
}
/// <summary>
/// 应用程序窗口高度增量
/// </summary>
public int AppWindow_HeightIncrement
{
get
{
return _height;
}
set
{
if(_height != value)
{
_height = value;
OnResize(null, null);
}
}
}
/// <summary>
/// 应用程序窗口宽度增量
/// </summary>
public int AppWindow_WidthIncrement
{
get
{
return _width;
}
set
{
if(_width != value)
{
_width = value;
OnResize(null, null);
}
}
}
private void OnResize(object sender, System.EventArgs e)
{
MoveWindow(_wnd,_x,_y,this.Width + _width ,this.Height+_height,true);
}
protected void OnNewWorkbook(Excel.Workbook book)
{
if(!_isInnerOperation)
{
_bs.CloseWorkbook(book, false);
}
}
protected void OnWorkbookOpen(Excel.Workbook book)
{
if(!_isInnerOperation)
{
_bs.CloseWorkbook(book, false);
}
}
protected void OnWorkbookBeforeClose(Excel.Workbook book, ref bool cancel)
{
//CloseWorkbook(false);
cancel = true;//无法阻止文档被关闭.原因?
_wnd = 0; //Force the excel window's handle be requery
}