Ask a questionAsk a question
 

AnswerPrevent pasting object in Word Document

  • Tuesday, March 17, 2009 8:28 AMTai Ly Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi
    I create an add-in Word 2007 to check user copy and paste something in the document. When user want to paste something, I need to check the data user will paste and prevent the pasting process.

    Which event of which object or interface I should register to implement the interception?

    Thanks and regards

    tui

Answers

  • Monday, March 23, 2009 8:18 AMTim LiMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi tui,

    Word 2007 Object Mode doesn't provide any clipboard event, thus we need to use some Windows API to achieve your objective,following code is a illustration about how we retrieve the content while user perfrom the copy command.

    The idea is when user perform a copy command, it will cause a "drawcllipboard" message be sent.
    so we find the Word main window then monitor it's messages by using WndProc method

    public partial class ThisAddIn  
        {
            #region NativeMethods  
            [System.Runtime.InteropServices.DllImport("User32.dll")]  
            public static extern IntPtr SetClipboardViewer(IntPtr hWnd);  
            [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "FindWindowExW")]  
            public static extern System.IntPtr FindWindowExW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWndParent, [System.Runtime.InteropServices.InAttribute()] System.IntPtr hWndChildAfter, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpszClass, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpszWindow);  
            [System.Runtime.InteropServices.DllImport("user32.dll")]  
            public static extern int FindWindow(String className, String windowName);
            #endregion  
            private void ThisAddIn_Startup(object sender, System.EventArgs e)  
            {  
                Native_GetWindowMessage();  
     
            }  
            void Native_GetWindowMessage()  
            {  
                string className = "OpusApp";  
                string windowName = Application.ActiveDocument.Name + " - Microsoft Word";  
                IntPtr h = Process.GetCurrentProcess().MainWindowHandle;  
                h = (IntPtr)FindWindow(className, windowName);  
                SubclassHWND s = new SubclassHWND();  
                s.AssignHandle(h);  
                s._ClipboardViewerNext = SetClipboardViewer(s.Handle);  
            }  
     
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)  
            {  
     
            }
            #region VSTO generated code  
     
            /// <summary>  
            /// Required method for Designer support - do not modify  
            /// the contents of this method with the code editor.  
            /// </summary>  
            private void InternalStartup()  
            {  
                this.Startup += new System.EventHandler(ThisAddIn_Startup);  
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);  
            }
            #endregion  
        }  
        public class SubclassHWND : System.Windows.Forms.NativeWindow  
        {  
            
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]  
            public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);  
     
            public IntPtr _ClipboardViewerNext;  
            protected override void WndProc(ref Message m)  
            {  
                if ((Msgs)m.Msg == Msgs.WM_DRAWCLIPBOARD)  
                {  
                    Debug.Print(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text));  
                    SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);  
                }  
                else 
                {  
                    base.WndProc(ref m);  
                }  
            }  
            public enum Msgs  
            {  
                WM_DRAWCLIPBOARD = 0x0308  
            }  
     
        } 
    Here's a link of the source where my idea comes:
    http://www.radsoftware.com.au/articles/clipboardmonitor.aspx

    Thanks
    We have published a VSTO FAQ recently, you can view them from the entry thread http://social.msdn.microsoft.com/Forums/en/vsto/thread/31b1ffbf-117b-4e8f-ad38-71614437df59. If you have any feedbacks or suggestions on this FAQ, please feel free to write us emails to colbertz@microsoft.com.

All Replies

  • Monday, March 23, 2009 8:18 AMTim LiMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi tui,

    Word 2007 Object Mode doesn't provide any clipboard event, thus we need to use some Windows API to achieve your objective,following code is a illustration about how we retrieve the content while user perfrom the copy command.

    The idea is when user perform a copy command, it will cause a "drawcllipboard" message be sent.
    so we find the Word main window then monitor it's messages by using WndProc method

    public partial class ThisAddIn  
        {
            #region NativeMethods  
            [System.Runtime.InteropServices.DllImport("User32.dll")]  
            public static extern IntPtr SetClipboardViewer(IntPtr hWnd);  
            [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "FindWindowExW")]  
            public static extern System.IntPtr FindWindowExW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWndParent, [System.Runtime.InteropServices.InAttribute()] System.IntPtr hWndChildAfter, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpszClass, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpszWindow);  
            [System.Runtime.InteropServices.DllImport("user32.dll")]  
            public static extern int FindWindow(String className, String windowName);
            #endregion  
            private void ThisAddIn_Startup(object sender, System.EventArgs e)  
            {  
                Native_GetWindowMessage();  
     
            }  
            void Native_GetWindowMessage()  
            {  
                string className = "OpusApp";  
                string windowName = Application.ActiveDocument.Name + " - Microsoft Word";  
                IntPtr h = Process.GetCurrentProcess().MainWindowHandle;  
                h = (IntPtr)FindWindow(className, windowName);  
                SubclassHWND s = new SubclassHWND();  
                s.AssignHandle(h);  
                s._ClipboardViewerNext = SetClipboardViewer(s.Handle);  
            }  
     
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)  
            {  
     
            }
            #region VSTO generated code  
     
            /// <summary>  
            /// Required method for Designer support - do not modify  
            /// the contents of this method with the code editor.  
            /// </summary>  
            private void InternalStartup()  
            {  
                this.Startup += new System.EventHandler(ThisAddIn_Startup);  
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);  
            }
            #endregion  
        }  
        public class SubclassHWND : System.Windows.Forms.NativeWindow  
        {  
            
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]  
            public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);  
     
            public IntPtr _ClipboardViewerNext;  
            protected override void WndProc(ref Message m)  
            {  
                if ((Msgs)m.Msg == Msgs.WM_DRAWCLIPBOARD)  
                {  
                    Debug.Print(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text));  
                    SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);  
                }  
                else 
                {  
                    base.WndProc(ref m);  
                }  
            }  
            public enum Msgs  
            {  
                WM_DRAWCLIPBOARD = 0x0308  
            }  
     
        } 
    Here's a link of the source where my idea comes:
    http://www.radsoftware.com.au/articles/clipboardmonitor.aspx

    Thanks
    We have published a VSTO FAQ recently, you can view them from the entry thread http://social.msdn.microsoft.com/Forums/en/vsto/thread/31b1ffbf-117b-4e8f-ad38-71614437df59. If you have any feedbacks or suggestions on this FAQ, please feel free to write us emails to colbertz@microsoft.com.