Monday, August 16, 2010

Replacing special characters from SOAP object / DB string

Finding the special characters in XML / SOAP / Database string sometimes it is painful. I've recently come across similar situation where user has copied the text from Word document and paste in Rich text editor / text editor. Error has occurred while processing the text to deserialize / saving it to database.
Code below is used to replace some known special character but you can keep adding the list if you wish.
    // Unicode function
    public static string GetUnicodeString(string s)
    {
          byte[] unicodeByte = Encoding.Unicode.GetBytes(s);
          string unicodechars = (Encoding.Default.GetString(unicodeByte)).ToString().Replace("\0", "").Replace("\f", "").Replace("", "");
          return (unicodechars);
    }

    public static string GetUnicodeString(string s, bool replaceQuotes)
    {
      //Replace MS Word quotes with standard quotes (Oracle seems to store only 7-bit ASCII)
      if (replaceQuotes)
      {
        if (s.IndexOfAny(new char[] { (char)8220, (char)8221, (char)8217, (char)8216 }) != -1)
        {
          s = s.Replace((char)8220, '\'').Replace((char)8221, '\'').Replace((char)8217, (char)34).Replace((char)8216, (char)34);
        }
      }
      return (GetUnicodeString(s));
    }
  }

Hope this helps.

Development Continues...

Thursday, August 12, 2010

Cut, Copy, Paste events on TextBox & ComboBox in C# .NET

Well, I have been wondering why .NET hasn't got the Cut, Copy, Paste events on editor controls like TextBox, RichTextEditor, ListView, ComboBox and TreeView ???
Anyways, here I have got these events for you...
First we will extend / inherit the standard TextBox to TextBoxEx as in TextBoxEx.cs below
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Text;
using System.Windows.Forms;

namespace KurapatySolutions.Controls
{
 public partial class TextBoxEx : TextBox
 {
  #region - Constants -
  private const int WM_CUT = 0x0300;
  private const int WM_COPY = 0x0301;
  private const int WM_PASTE = 0x0302;
  #endregion

  #region - Constructor -
  public TextBoxEx()
  {
   InitializeComponent();
  }
  #endregion

  #region - Private Methods -
  private void DoOnCutText()
  {
   if (OnCutText != null)
    OnCutText(this, new ClipboardEventArgs(SelectedText));
  }
  private void DoOnCopyText()
  {
   if (OnCopyText != null)
    OnCopyText(this, new ClipboardEventArgs(SelectedText));
  }
  private void DoOnPasteText()
  {
  if (OnPasteText != null)
  OnPasteText(this, new ClipboardEventArgs(Clipboard.GetText()));
  }
  #endregion

  #region - Event Handlers -
  public event ClipboardEventHandler OnCutText;
  public event ClipboardEventHandler OnCopyText;
  public event ClipboardEventHandler OnPasteText;
  #endregion

  #region - WndProc - Handler -
  protected override void WndProc(ref Message m)
  {
   base.WndProc(ref m);
   if (m.Msg == WM_CUT)
   {
    //Cut Event
    DoOnCutText();
   }
   else if (m.Msg == WM_COPY)
   {
    //Copy Event
    DoOnCopyText();
   }
   else if (m.Msg == WM_PASTE)
   {
    //Paste Event
    DoOnPasteText();
   }   
  }
  #endregion
 }
 public class ClipboardEventArgs : EventArgs
 {
  public string ClipboardText { get; set; }

  public ClipboardEventArgs(string clipboardText)
  {
   ClipboardText = clipboardText;
  }
 }
public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);
}
Now that the new control is ready, build your project and use the new events.

In second example, we will inherit standard ComboBox to ComboBoxEx control, this would require some kind of hacking with NativeWindow... see the code below and you will understand as its self explanatory.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;

namespace KurapatySolutions.Controls
{
 /// 
 /// ComboBox with extended functionality to support Cut, Copy & Paste events
 /// 
 public partial class ComboBoxEx : ComboBox
 {
  #region - Constants -
  private const int WM_CUT = 0x0300;
  private const int WM_COPY = 0x0301;
  private const int WM_PASTE = 0x0302;
  private const UInt32 CB_GETCOMBOBOXINFO = 0x0164;
  #endregion

  #region - DLL Import -
  [DllImport("USER32", EntryPoint = "SendMessage")]
  extern static void SendCbInfoMsg(IntPtr wnd, UInt32 msg, IntPtr wParam, [In, Out] ref ComboBoxInfo lParam);
  #endregion

  #region - Constructor -
  public ComboBoxEx()
  {
   InitializeComponent();
  }
  public ComboBoxEx(IContainer container)
  {
   container.Add(this);
   InitializeComponent();
  }
  #endregion

  #region - Private Members -
  private NativeWindowEx _nativeWindowEx;
  #endregion

  #region - Private Methods -
  private void DoOnCutText(object sender, EventArgs e)
  {
   if (OnCutText != null)
    OnCutText(sender, new ClipboardEventArgs(SelectedText));
  }
  private void DoOnCopyText(object sender, EventArgs e)
  {
   if (OnCopyText != null)
    OnCopyText(sender, new ClipboardEventArgs(SelectedText));
  }
  private void DoOnPasteText(object sender, ClipboardEventArgs e)
  {
   if (OnPasteText != null)
    OnPasteText(this, e);
  }
  #endregion

  #region - Event Handlers -
  public event ClipboardEventHandler OnCutText;
  public event ClipboardEventHandler OnCopyText;
  public event ClipboardEventHandler OnPasteText;
  #endregion
        
  #region - Private Structures & Class -
  struct Rect
  {
   public int Left;
   public int Top;
   public int Right;
   public int Bottom;
  }

  struct ComboBoxInfo
  {
   public Int32 cbSize;
   public Rect rcItem;
   public Rect rcButton;
   public Int32 buttonState;
   public IntPtr hwndCombo;
   public IntPtr hwndEdit;
   public IntPtr hwndList;
  }

  /// 
  /// This window is inherited from NativeWindow and overrides WndProc.
  /// 
  class NativeWindowEx : NativeWindow 
  {
   #region - Event Handlers -
   public event EventHandler OnCutText;
   public event EventHandler OnCopyText;
   public event ClipboardEventHandler OnPasteText;
   #endregion

   #region - Private Methods -
   private void DoOnCutText()
   {
    if (OnCutText != null)
     OnCutText(this, new EventArgs());
   }

   private void DoOnCopyText()
   {
    if (OnCopyText != null)
     OnCopyText(this, new EventArgs());
   }

   private void DoOnPasteText()
   {
    if (OnPasteText != null)
     OnPasteText(this, new ClipboardEventArgs(Clipboard.GetText()));
   }
   #endregion

   #region - WndProc - Handler -
   protected override void WndProc(ref Message m)
   {
    if (m.Msg == WM_CUT)
    {
     DoOnCutText();
    }
    if (m.Msg == WM_COPY)
    {
     DoOnCopyText();
    }
    if (m.Msg == WM_PASTE)
    {
     DoOnPasteText();
    }
    base.WndProc(ref m);
   }
   #endregion
  }
  #endregion

  #region - Overrides -
  protected override void OnHandleCreated(EventArgs e)
  {
   var cbInfo = new ComboBoxInfo();
   cbInfo.cbSize = Marshal.SizeOf(cbInfo);
   SendCbInfoMsg(Handle, CB_GETCOMBOBOXINFO, IntPtr.Zero, ref cbInfo);
   _nativeWindowEx = new NativeWindowEx();
   _nativeWindowEx.AssignHandle(cbInfo.hwndEdit);
   _nativeWindowEx.OnCutText += DoOnCutText;
   _nativeWindowEx.OnCopyText += DoOnCopyText;
   _nativeWindowEx.OnPasteText += DoOnPasteText;
   base.OnHandleCreated(e);

  }
  #endregion
 }
 public class ClipboardEventArgs : EventArgs
 {
  public string ClipboardText { get; set; }

  public ClipboardEventArgs(string clipboardText)
  {
   ClipboardText = clipboardText;
  }
 }
 public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);
}

You can move the shared EventArgs & Delegate to EventDelegate.cs as mentioned below:
using System;

namespace KurapatySolutions.Controls
{
 public class ClipboardEventArgs : EventArgs
 {
  public string ClipboardText { get; set; }

  public ClipboardEventArgs(string clipboardText)
  {
   ClipboardText = clipboardText;
  }
 }
 public delegate void ClipboardEventHandler(object sender, ClipboardEventArgs e);
}


Hope it helps!

Development Continues...