基于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引用的焦点和样式进行调整(找了其他的资料,但是无法成功运用),故很多代码选择删除或者。

posted on 2018-06-26 17:35  风不止灬  阅读(1056)  评论(0编辑  收藏  举报