We help IT Professionals succeed at work.

clearing a bad word in a global setting

r3nder
r3nder asked
on
I have a class that checks for bad words - on pressing the enter key or the button in the application it is running in it throws an alert that says it is a bad word. now this is global so any app running- like notepad - if you are typing a bad word in is effected by it-  how do I clear that bad word or change the bad word to hash marks (####)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Management;
using System.Xml;
using System.Xml.Schema;
using System.IO;
using System.Security;
using System.Runtime.InteropServices;


namespace Nomad
{
    public partial class frmMain : Form
    {
        BadWordFilter newBadwordFilter;
       
        public frmMain()
        {
            InitializeComponent();
            comboBox1.SelectedIndex = 0;
            newBadwordFilter = BadWordFilter.Instance;
            InterceptKeys.AttachHook(); <- this starts the bad word process
            //bool a = which one
            //a = newBadwordFilter.IsCleanString("Fuck");//to check
            //a = newBadwordFilter.IsCleanString("Duck");//to check
            int c = 0;
           


        }
       
   



        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            webBrowser1.Navigate(new Uri(comboBox1.SelectedItem.ToString()));

        }

        private void btnStartLP_Click(object sender, EventArgs e)
        {

            var proc = new Process();
            proc.StartInfo.FileName = "chat/chat.exe";
            proc.StartInfo.Arguments = "-v -s -a";
            proc.Start();
            proc.WaitForExit();
            var exitCode = proc.ExitCode;
            proc.Close();
        }
        ///////////////////////////////Knowledge  Base//////////////////
        /// <summary>
        /// Question answer Pair
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///
        private void btnSearchKnowledge_Click(object sender, EventArgs e)
        {
            char[] delimiters = new char[] { ',', ' ' };
            string[] keywords = txtBoxKnowledgeQuestion.Text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

            XmlDocument doc = new XmlDocument();
            doc.Load("XMLQandA.xml");

            XmlElement root = doc.DocumentElement;

            XmlNodeList nodeList = root.SelectNodes("/messages/messageItem");

            foreach (XmlNode node in nodeList)
            {
                bool hasAllWords = true;
                bool hasAnyWord = false;
                foreach (string keyword in keywords)
                {
                    if (node.InnerText.Contains(keyword))
                    {
                        hasAnyWord = true;
                    }
                    else hasAllWords = false;
                }


                if (hasAllWords)
                {
                    // add the node to found-items-list        
                    lstBoxQA.Items.Add(node.InnerText);
                    lstBoxQA.Items.Add("======================");
                    //lstBoxQA.Items.AddRange(node.InnerText);
                    return;

                }
                if (hasAnyWord)
                {
                   

                    //process found-items-list
                    lstBoxQA.Items.Add(node.InnerText);
                    lstBoxQA.Items.Add("======================");
                    //lstBoxQA.Items.AddRange(node.InnerText);
                   
                }
                               

               

            }
            //frmWarning frm = new frmWarning();
            //frm.Show();
            MessageBox.Show("You have typed a word that has been deemed \n inapropriate - it will be blanked out - Next time an email \n will be sent to HR and IT to have your access cut off"); <-this is the test area          
            int c = 1;
        }

        private void btnEVid_Click(object sender, EventArgs e)
        {
            webBEVid.Navigate(new Uri("http://172.0.0.1//Login.aspx"));
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnLogon_Click(object sender, EventArgs e)
        {
           
           
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
           
        }

        private void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
           
        }

        private void btnCamp_Click(object sender, EventArgs e)
        {
            webBrowser2.Navigate(new Uri("http://et2app01/Ensercle/index.htm"));
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            lstBoxQA.Items.Clear();
            txtBoxKnowledgeQuestion.Clear();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            InterceptKeys.DetachHook(); <- this ends the bad word process
        }
       
       
    }
}
Comment
Watch Question

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
This is harder than you think...

The mere typing of a sequence of characters doesn't mean the word is actually present.

From your last question:
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26257983.html

...it's evident that you are only filtering out the letter keys and completely disregarding control keys (arrows, home, pageup, etc):

                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode > 64 && vkCode < 91)
                {
                    statement.Append((Keys)vkCode);
                }
                else if (vkCode == 32)
                {
                    statement.Append(" ");
                }

You are not tracking when focus between controls has changed or when complete windows change focus (which can be done with the mouse and won't be seen by your keyboard hook).

So if I typed a bad word, one character at a time, into different, multiple notepad instances, your filter would think I've typed a bad word.  Or if I happened to edit a sequence of existing words by adding letters but using the arrow keys with backspace and delete in between keypresses it could also trigger your filter even though the letters of the bad word were not together and are in fact part of other words.  What if I hit Ctrl-A (to select everything) and then replaced all that text by typing "ss"?  Right...you'd assume that I typed "ass".

Even if you work out all the nuances of determining if keypresses actually formed a word or not...there isn't any guaranteed method for getting/setting text in a control.  Editable controls don't all support the same windows messages!  You certainly can't suppress the keystrokes that generated the word since they were already typed (we can't go back in time).  One approach would be to attempt to use the SendMessage() API with WM_GETTEXT and WM_SETTEXT.  As I said before, though, not all controls support all messages so it's possible that a control wouldn't respond to this message.  Don't get me started on Web Browsers either...interacting with editable fields in a browser is a completely different ball of wax and has its difficulties as well.  You could take a naive approach and send left arrows keys while holding down the shift key to select the offending word and then simply paste the mask r send new keystrokes to replace the selection.

Anyhoo, what you're attempting isn't impossible...just way more difficult to do in a reliable manner than you probably considered.    =\

Author

Commented:
Here is what I am doing

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Linq;



namespace Nomad
{
    class InterceptKeys
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        private static StringBuilder statement = new StringBuilder();
        private static BadWordFilter filter = BadWordFilter.Instance;

        static InterceptKeys()
        {

        }

       
        public static void AttachHook()
        {
            _hookID = SetHook(_proc);
        }
       

        public static void DetachHook()
        {
            UnhookWindowsHookEx(_hookID);
        }
       


       
        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelKeyboardProc(
            int nCode, IntPtr wParam, IntPtr lParam);

        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
           
        {
             if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode > 64 && vkCode < 91)
                {
                    statement.Append((Keys)vkCode);
                }
                else if (vkCode == 32)
                {
                    statement.Append(" ");
                }


                if (((Keys)vkCode).Equals(Keys.Return))
                {
                   
                    if (!filter.IsCleanString(statement.ToString()))
                    {

                       
                        statement = new StringBuilder();
                        //MessageBox.Show("the text is:" + statement.ToString());
                       
                       
                        MessageBox.Show("you have typed a word that has been deemed \n inapropriate - it will be blanked out - Next time an email \n will be sent to HR and IT to have your access cut off" + statement.ToString());
                        //statement.Replace(statement.ToString(), "*******");
                        int c = 1;
                           
                       
                       
                    }

                   
                 
                   
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
       
        }
        //public event EventHandler Igotthebadword;
        //public void Raise()
        //{
        //    if (statement != null)
        //    {
        //        MessageBox.Show("you have typed a word that has been deemed /n inapropriate - it will be blanked out - Next time an email /n will be sent to HR and IT to have your access cut off");
        //        int c = 1;
        //    }
           

        //}



        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);


       
    }
}
Top Expert 2010

Commented:
This looks like a fun little project. This would be very easy if it was limited to a single application but it will be extremely difficult to make it work correctly for all windows without hooking a DLL into each process. What you might be able to do is just work with the foreground window using GetForegroundWindow() or GetFocus(). The window which might have the keyboard focus. Use GetCaretPos() this will give you a POINT structure of the caret cursor on screen that you can pass to WindowFromPoint(). Then you might be able to run your routines for badwords using Idle_Mind suggestion WM_GETTEXT. I haven't tried it before so this is just an idea that seems like it might work. There is always culprits that might get in the way those I can't predict but it wouldn't be a bad idea to mess around with the approach.

Author

Commented:
how about we take this one step at a time :  try getting  the typed  word from focus and WM_GETTEXT  if the bad word is typed then sending the first messagebox if they type one again tell them in a second message box an email has been sent
use the mail send in .net to generate this mail
Top Expert 2010

Commented:
If your going to change your mind and use a message box instead then stick with the hook. You will just need to add some type of scheme that keeps track of the typed data when application lose and gain focus. You might be able to create a list that maps the foreground hWnd to PID and use the PID as the unique id. Then when windows lose or gain focus insert typed data into the collection using PID as the key.

Author

Commented:
I would still like to clear the badword and replace it with hash marks - I want to stay with the hook. The rest of it is like I stated aboove 1 warning 2nd warning email is sent. I was thinking that maybe combining the 2 ideas would lead to an answer and the end of the code.
Top Expert 2010

Commented:
Yeah, I understand your requirment but this is the feature that will give you the most trouble to implement. You might want to consider having them remove the word  as your first warning. The problem as mentioned by Idle_Mind is that not every window will work using these messages. Thats why this is easier to develop if you know your specific target. There is applications that do this specifically for Internet Explorer. In your case you would need to write a different filtering for browsers, standard windows that accept user input, clipboard chains, instant messaging. The idea is you want it to work globally so you'll end having to write multiple filters to make it work correctly. If you want to start by just trying to make it work with most window controls then you can try to use the approach where you check the foreground window or caret position on screen and use ChildWindowFromPoint() to "attempt" to get the control handle that "might" have the keyboard focus and remove the data. If you leave this extra feature out you would be able to make it work globally with the hook but you will still need to implement a design that can determine when a window loses focus also associating instances in some unique manner. I like the idea of this project and it would be fun to write but this is something that will take alot planning to make it work right and tons of debugging.
 
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
I probably won't be able to post a good example until Monday but basically you use GetForegroundWindow() to get a handle to the main window that has focus.  Next you call GetWindowThreadProcessId() to get the PID and send that to AttachThreadInput() so that you can use GetFocus() to obtain a handle to the control that currently has focus.  Another option is to use GetGUIThreadInfo().  Once you have the handle to the focused window you send that to SendMessage() with WM_GETTEXT to attempt to extract the value out of it.  Replace the bad words with hashes and then use SendMessage() again but with WM_SETTEXT to put the text back.  You'll probably have to restore the caret to the original position too...
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
*...and of course the approach I just outlined will only work on traditional windows applications.  It will not work on webbrowsers and the newer applications developed with WPF.

Author

Commented:
I think your right - the approach is ask them to replace the word  - this interops class is kicken my butt - believe me all your suggestions and any examples off this code would and are greatly appreciated

Author

Commented:
I was thinking of something like this:
           bool badWordFound = false;
                foreach (string kw in keywords)
                {
                    if (newBadwordFilter.IsCleanString(kw) == false)
                    {
                        badWordFound = true;
                        txtBoxKnowledgeQuestion.Text = txtBoxKnowledgeQuestion.Text.Replace(kw, new string('#', kw.Length));
                    }
                }

                if (badWordFound)
                {
                    if (!isMessageAlreadyShown)
                    {
                        isMessageAlreadyShown = true;
                        MessageBox.Show("You have typed a word that has been deemed inapropriate - it \n will be blanked out on the console - Next time an email will be \n sent to Human Resources and IT to have your access reviewed", "Warning");
                    }
                    else
                    {
                        //Show second message box here
                        MessageBox.Show("You have typed a word deemed improper for \n the second time. HR has been notifed via email. \n You will be contacted by the Human Resources \n Department for further instructions");
                        MailToHR();
                    }
                }
            }

            public void MailToHR()
            {
                if (txtBxUser.Text.Trim() == string.Empty)
                {
                    MessageBox.Show("enter your login info");
                    return;
                }
                //create the mail message
                MailMessage mail = new MailMessage();

                //set the addresses
                mail.From = new MailAddress(txtBxUser.Text + "@google.com");
                mail.To.Add("render@google.com");
                mail.Bcc.Add("render@google.com");

                //set the content
                mail.Subject = "Inappropriate Word in Remote application by" + " " + txtBxUser.Text;
                mail.Body = txtBxUser.Text + " " + "typed a word deemed inappropriate. That word was: " + txtBoxKnowledgeQuestion.Text + " " + "on" + " " + DateTime.Now;
                //send the message
                SmtpClient smtp = new SmtpClient("mail.google.com", 25);
                smtp.Credentials = new System.Net.NetworkCredential("user", "pass");
                smtp.Send(mail);
               
                MessageBox.Show("Email Sent.....You will be contacted shortly","Done");
                this.Close();
                this.Dispose();
            }
Top Expert 2010

Commented:
When you remove the requirment to erase the word from the screen the project will become much easier to manage "make work correctly".  It's just a matter of deciding how to associate the keyboard hook data with the focus window that has keyboard input.  I mentioned to map the hWnd to a Process Id and use that as a key.  What this might render is as the person types and switches windows the keyboard hook data can be placed into the appropriate bucket using they key.  Then at a specific time or when the collection reaches a specified length run your filter.  If you don't find bad words erase the collection rinse and repeat.  I might make it sound simple but I know it's not that easy especially once you dive into it but it shouldn't be nearly as hard as removing the word fromt he screen.

Author

Commented:
I have decided that removing the word is ok

Author

Commented:
heres what I have can anyone correct it? I have 3 errors (in bold)

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Linq;
using System.Net.Mail;


namespace Nomad
{
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static StringBuilder statement = new StringBuilder();
private static BadWordFilter filter = BadWordFilter.Instance;
static InterceptKeys()
{
}

public static void AttachHook()
{
_hookID = SetHook(_proc);
}

public static void DetachHook()
{
UnhookWindowsHookEx(_hookID);
}

private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)

{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode > 64 && vkCode < 91)
{
statement.Append((Keys)vkCode);
}
else if (vkCode == 32)
{
statement.Append(" ");
}

if (((Keys)vkCode).Equals(Keys.Return))
{
if (!filter.IsCleanString(statement.ToString()))
{
filter.IsCleanString(statement.ToString()) = true;
statement = new StringBuilder();
//MessageBox.Show("the text is:" + statement.ToString());
MessageBox.Show("You have typed a word that has been deemed \n inapropriate - Please remove it - Next time an email \n will be sent to HR and IT to have your access cut off");
}
else
{
//Show second message box here
MessageBox.Show("You have typed a word deemed improper for \n the second time. HR has been notifed via email. \n You will be contacted by the Human Resources \n Department for further instructions");
MailToHR();
} <- expected '}'



public void MailToHR()
{
if (txtBxUser.Text.Trim() == string.Empty)
{
MessageBox.Show("enter your login info");
return;
}
//create the mail message
MailMessage mail = new MailMessage();
//set the addresses
mail.From = new MailAddress(txtBxUser.Text + "@blah.com");
mail.To.Add("blah@blah.com");
mail.Bcc.Add("blah@blah.com");
//set the content
mail.Subject = "Inappropriate Word in Remote application by" + " " + txtBxUser.Text;
mail.Body = txtBxUser.Text + " " + "typed a word deemed inappropriate. That word was: " + txtBoxKnowledgeQuestion.Text + " " + "on" + " " + DateTime.Now;
//send the message
SmtpClient smtp = new SmtpClient("mail.blah.com", 25);
smtp.Credentials = new System.Net.NetworkCredential("blah", "blah");
smtp.Send(mail);

MessageBox.Show("Email Sent.....You will be contacted shortly","Done");
this.Close();
this.Dispose();
}
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam); <- A namespace does not directly contain members such as fields or methods

} <-Type or namespace definition, or end-of-file expected

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);


}
}

Author

Commented:
how about this - the only problem now is that I can not get focus on the messagebox's - they open then close instantly


using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Linq;
using System.Net.Mail;


namespace Nomad
{
    class InterceptKeys
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        private static StringBuilder statement = new StringBuilder();
        private static BadWordFilter filter = BadWordFilter.Instance;
        private static bool showedMessageOnce = false;
        static InterceptKeys()
        {
        }

        public static void AttachHook()
        {
            _hookID = SetHook(_proc);
        }

        public static void DetachHook()
        {
            UnhookWindowsHookEx(_hookID);
        }

        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }
        private delegate IntPtr LowLevelKeyboardProc(
            int nCode, IntPtr wParam, IntPtr lParam);
        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode > 64 && vkCode < 91)
                {
                    statement.Append((Keys)vkCode);
                }
                else if (vkCode == 32)
                {
                    statement.Append(" ");
                }

                if (((Keys)vkCode).Equals(Keys.Return))
                {
                    if (!filter.IsCleanString(statement.ToString()))
                    {
                        //filter.IsCleanString(statement.ToString()) = true;
                        //statement = new StringBuilder();
                        //MessageBox.Show("the text is:" + statement.ToString());
                        if (showedMessageOnce == false)
                        {
                            showedMessageOnce = true;
                            MessageBox.Show("You have typed a word that has been deemed \n inapropriate - Please remove it - Next time an email \n will be sent to HR and IT to have your access cut off");
                        }
                        else
                        {
                            //Show second message box here
                            MessageBox.Show("You have typed a word deemed improper for \n the second time. HR has been notifed via email. \n You will be contacted by the Human Resources \n Department for further instructions");
                            MailToHR();
                        }
                    }
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        public static void MailToHR()
        {
            frmMain frm = Application.OpenForms[0] as frmMain;
            if (frm.txtBxUser.Text.Trim() == string.Empty)
            {
               
                MessageBox.Show("enter your login info");
                return;
            }
            //create the mail message
            MailMessage mail = new MailMessage();
            //set the addresses
            mail.From = new MailAddress(frm.txtBxUser.Text + "@google.com");
            mail.To.Add("rc@google.com");
            mail.Bcc.Add("mc@google.com");
            //set the content
            mail.Subject = "Inappropriate Word in Remote application";
            mail.Body = frm.txtBxUser.Text + " " + "typed a word deemed inappropriate. That word was: " + statement.ToString() + " " + "on" + " " + DateTime.Now;
            //send the message
            SmtpClient smtp = new SmtpClient("mail.google.com", 25);
            smtp.Credentials = new System.Net.NetworkCredential("user", "pass");
            smtp.Send(mail);

            MessageBox.Show("Email Sent.....You will be contacted shortly", "Done");
            frm.Close();
           
        }

    }
}
Top Expert 2010

Commented:
It's generally unsafe to display a message box from inside the hook procedure.  You want to handle the message and return immediately.  What you can do is raise an event when you detect badwords then display your message boxes from the event.
 

Author

Commented:
show me?......please
Top Expert 2010
Commented:
Uhh.. I mean async delegate event but you just want to make sure your hook doesn't become tied up when you use modal message box.   In your hookproc call DisplayMessage()

private static IAsyncResult result;

        private static AsyncMessageBoxDelegate caller = new AsyncMessageBoxDelegate(AsyncMessageBox);
        private delegate void AsyncMessageBoxDelegate(string msg);
        private static void AsyncMessageBox(string msg)
        {
            MessageBox.Show(msg);
            caller.EndInvoke(result);
        }
        public static void DisplayMessage(string msg)
        {
            result = caller.BeginInvoke(msg, null, null);
        }

Open in new window

Author

Commented:
This is great but it still does not set focus on the message box's - they minimizes almost instantly? any thoughts on that?
Top Expert 2010

Commented:
I have no idea why the messagebox would minimize and if it does something is really wrong :( .. Do you mean it just loses focus like hide behind your form window or other windows?

Author

Commented:
Thanks for everything