基于word API 创建的可以打开word的自定义控件
代码基本框架来源: CSDN 博主:zjlovety的专栏 地址:https://blog.csdn.net/zjlovety/article/details/24463117
public partial class WinWordViewer : UserControl
{
public WinWordViewer()
{
InitializeComponent();
this.ParentChanged += new EventHandler(WinWordViewer_ParentChanged);
this.Disposed += new EventHandler(WinWordViewer_Disposed);
this.Click += new EventHandler(WinWordViewer_Click);
}
#region 窗体事件
void WinWordViewer_Click(object sender, EventArgs e)
{
if (wd != null)
{
wd.ActiveWindow.SetFocus(); //嵌入的窗体焦点是独立与父窗体,此功能为能生效。
}
}
void WinWordViewer_Disposed(object sender, EventArgs e)
{
this.CloseControl(); //父窗体资源释放时,主动释放打开的创建的word应用、文档和进程。
}
void WinWordViewer_ParentChanged(object sender, EventArgs e)
{
if (wd != null)
{
if (this.Parent == null)
{
wd.Visible = false;
}
else
{
wd.Visible = true; // 当WinWordViewer加入到其他控件中时才展示。
}
}
}
#endregion
public Microsoft.Office.Interop.Word.Document document; //文档的引用
public Microsoft.Office.Interop.Word.ApplicationClass wd = null; //应用的引用
public int wordWnd = 0; //word引用的句柄
public string filename = null; //打开的文件名称
private bool deactivateevents = false; //窗体激活标识
public void PreActivate()
{
if (wd == null) wd = new Microsoft.Office.Interop.Word.ApplicationClass();
}
/// <summary>
/// 关闭引用
/// </summary>
public void CloseControl()
{
try
{
deactivateevents = true;
object dummy = null;
object dummy2 = (object)false;
if (wd != null)
{
wd.Visible = false;
}
if (document != null)
{
document.Close(ref dummy, ref dummy, ref dummy);
}
// Change the line below.
if (wd != null)
{
wd.Quit(ref dummy2, ref dummy, ref dummy);
wd = null;
}
deactivateevents = false;
foreach (Process pro in Process.GetProcesses()) //这里是找到那些没有界面的Word进程
{
if (pro.ProcessName == "WINWORD")
{
IntPtr ip = pro.MainWindowHandle;
string str = pro.MainWindowTitle; //发现程序中打开跟用户自己打开的区别就在这个属性
//用户打开的str 是文件的名称,程序中打开的就是空字符串
if (str == "")
{
pro.Kill();
}
}
}
//以下2种方法都无法获取进程。
//int id;
//int td;
//td = User32.GetWindowThreadProcessId(new IntPtr(wordWnd), out id);
//if (id == 0)
//{
// Process[] processes = Process.GetProcesses();
// foreach(Process process in processes)
// {
// if (process.ProcessName == "WINWORD")
// {
// if(process.Handle == new IntPtr(wordWnd))
// {
// MessageBox.Show(process.Id.ToString());
// }
// }
// }
//}
//if (id != 0)
//{
// var p = Process.GetProcessById(id);
// p.Kill();
//}
}
catch (Exception ex)
{
String strErr = ex.Message;
}
}
/// <summary>
/// catches Word's close event
/// starts a Thread that send a ESC to the word window ;)
/// </summary>
/// <param name="doc"></param>
/// <param name="test"></param>
private void OnClose(Microsoft.Office.Interop.Word.Document doc, ref bool cancel)
{
if (!deactivateevents)
{
cancel = true;
}
}
/// <summary>
/// catches Word's open event
/// just close
/// </summary>
/// <param name="doc"></param>
private void OnOpenDoc(Microsoft.Office.Interop.Word.Document doc)
{
OnNewDoc(doc);
}
/// <summary>
/// catches Word's newdocument event
/// just close
/// </summary>
/// <param name="doc"></param>
private void OnNewDoc(Microsoft.Office.Interop.Word.Document doc)
{
if (!deactivateevents)
{
deactivateevents = true;
object dummy = null;
doc.Close(ref dummy, ref dummy, ref dummy);
deactivateevents = false;
}
}
/// <summary>
/// 加载文件
/// </summary>
/// <param name="t_filename"></param>
public void LoadDocument(string t_filename)
{
deactivateevents = true;
filename = t_filename;
if (wd == null) wd = new Microsoft.Office.Interop.Word.ApplicationClass();
try
{
wd.DocumentBeforeClose += new Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentBeforeCloseEventHandler(OnClose);
wd.ApplicationEvents2_Event_NewDocument += new Microsoft.Office.Interop.Word.ApplicationEvents2_NewDocumentEventHandler(OnNewDoc);
wd.DocumentOpen += new Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentOpenEventHandler(OnOpenDoc);
}
catch
{
}
if (document != null)
{
try
{
object dummy = null;
wd.Documents.Close(ref dummy, ref dummy, ref dummy);
}
catch
{
}
}
if (wordWnd == 0) wordWnd = User32.FindWindow("Opusapp", null);
if (wordWnd != 0)
{
User32.SetParent(wordWnd, this.Handle.ToInt32());
object fileName = filename;
object newTemplate = false;
object docType = 0;
object readOnly = true;
object isVisible = true;
object missing = System.Reflection.Missing.Value;
try
{
if (wd == null)
{
throw new WordInstanceException();
}
if (wd.Documents == null)
{
throw new DocumentInstanceException();
}
if (wd != null && wd.Documents != null)
{
document = wd.Documents.Add(ref fileName, ref newTemplate, ref docType, ref isVisible);
}
if (document == null)
{
throw new ValidDocumentException();
}
}
catch
{
}
try
{
//int wordWndN = 0;
////取消所有边框
//User32.SetWindowLong(wordWnd, GWL_STYLE, User32.GetWindowLong(wordWnd, (int)WinWordViewer.GWL_STYLE) & ~(int)Enum.WindowStyles.WS_CAPTION & ~(int)Enum.WindowStyles.WS_THICKFRAME);
//User32.SetWindowPos(wordWnd, wordWndN, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
//long style = User32.GetWindowLong(wordWnd, (int)WinWordViewer.GWL_STYLE);
////style &= ~(int)Enum.WindowStyles.WS_SIZEBOX; //去掉可变大小
//style &= ~(int)Enum.WindowStyles.WS_BORDER; //去掉边框
//style |= (int)Enum.WindowStyles.WS_MAXIMIZE; //最大化
//// 设置风格
//User32.SetWindowLong(wordWnd, (int)WinWordViewer.GWL_STYLE, style);
//int counter = wd.ActiveWindow.Application.CommandBars.Count;
//for (int i = 1; i <= counter; i++)
//{
// wd.ActiveWindow.Application.CommandBars[i].Visible = false;
// wd.ActiveWindow.View.DisplayBackgrounds = true;
// wd.ActiveWindow.View.DisplayPageBoundaries = false;
//}
}
catch
{
}
}
deactivateevents = false;
}
//static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
//static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
//static readonly IntPtr HWND_TOP = new IntPtr(0);
//const UInt32 SWP_NOSIZE = 0x0001;
//const UInt32 SWP_NOMOVE = 0x0002;
//const UInt32 SWP_NOZORDER = 0x0004;
//const UInt32 SWP_NOREDRAW = 0x0008;
//const UInt32 SWP_NOACTIVATE = 0x0010;
//const UInt32 SWP_FRAMECHANGED = 0x0020;
//const UInt32 SWP_SHOWWINDOW = 0x0040;
//const UInt32 SWP_HIDEWINDOW = 0x0080;
//const UInt32 SWP_NOCOPYBITS = 0x0100;
//const UInt32 SWP_NOOWNERZORDER = 0x0200;
//const UInt32 SWP_NOSENDCHANGING = 0x0400;
//const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
}
public class User32
{
//获取句柄
[DllImport("User32.dll", EntryPoint = "FindWindow")]
internal static extern int FindWindow(
string lpClassName,
string lpWindowName);
//设置父控件(将句柄转至父控件)
[DllImport("User32.dll", EntryPoint = "SetParent")]
internal static extern int SetParent(
int hWndChild,
int hWndNewParent);
//[DllImport("User32.dll", EntryPoint = "SetWindowLong")]
//internal static extern int SetWindowLong(
//int hWnd,
//int nIndex,
//long dwNewLong);
[DllImport("User32.dll", EntryPoint = "SetWindowLong")]
internal static extern long SetWindowLong(
int hWnd,
int nIndex,
long dwNewLong);
[DllImport("User32.dll", EntryPoint = "GetWindowLong")]
internal static extern long GetWindowLong(
int hWnd,
int nIndex);
[DllImport("user32.dll", EntryPoint = "MoveWindow")]
internal static extern int MoveWindow(
int hWnd,
int x,
int y,
int cx,
int cy,
bool repaint);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
internal 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 = "DrawMenuBar")]
internal static extern Int32 DrawMenuBar(
Int32 hWnd
);
[DllImport("user32.dll", EntryPoint = "GetMenuItemCount")]
internal static extern Int32 GetMenuItemCount(
Int32 hMenu
);
[DllImport("user32.dll", EntryPoint = "GetSystemMenu")]
internal static extern Int32 GetSystemMenu(
Int32 hWnd,
bool Revert
);
[DllImport("user32.dll", EntryPoint = "RemoveMenu")]
internal static extern Int32 RemoveMenu(
Int32 hMenu,
Int32 nPosition,
Int32 wFlags
);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ID);
}
--------------------------------------------------------------------------------------------
由于个人水平不高,对原代码的修改主要还是基于对自定义控件本身逻辑的调整。
对 word API 的使用还是比较简单。
无法成功的对调用的word引用的焦点和样式进行调整(找了其他的资料,但是无法成功运用),故很多代码选择删除或者。