locked
Reusing SysIPAddress32 in WinForms, problem in Win2K RRS feed

  • Question

  • Hi all,

    I created an IPAddress control that reuse the system's SysIPAddress32 class, this is based on some old C++ tricks, here's what I did:



    public class IPAddress : TextBox
    {

     public IPAddress()
     {
      SetStyle(ControlStyles.ResizeRedraw, true);
     }

     protected override CreateParams CreateParams
     {
      get
      {
       CreateParams cp = base.CreateParams;
       cp.ClassName = "SysIPAddress32";

       return cp;
      }
     }

    }

     



    The control above work just fine on WindowsXP and Windows98, but not in Windows2000.

    Windows 2000 keeps on saying that the class name is invalid. Even after I called the InitCommonControlsEx API, the class still not registered or something, here's what I have so far:



    public class IPAddress : TextBox
    {
     internal struct INITCOMMONCONTROLSEX
     {
      int dwSize;
      int dwICC;
     }

     [DllImport("comctl32.dll")]
     internal static extern bool InitCommonControlsEx(ref INITCOMMONCONTROLSEX lpInitCtrls);

     public IPAddress()
     {
      INITCOMMONCONTROLSEX lpInitCtrls = new INITCOMMONCONTROLSEX();
      InitCommonControlsEx(ref lpInitCtrls);
      SetStyle(ControlStyles.ResizeRedraw, true);
     }

     protected override CreateParams CreateParams
     {
      get
      {
       CreateParams cp = base.CreateParams;
       cp.ClassName = "SysIPAddress32";

       return cp;
      }
     }
    }

     



    My question is, what am I missing? Is the class SysIPAddress32 not supported in Windows2000?

    Thanks in advance,

    -chris

    Monday, November 28, 2005 10:16 AM

Answers

  • >public IPAddress()
    > {
    >  INITCOMMONCONTROLSEX lpInitCtrls = new INITCOMMONCONTROLSEX();
    >  InitCommonControlsEx(ref lpInitCtrls);

    This doesn't look right. You should initialize the INITCOMMONCONTROLSEX struct properly before passing it to InitCommonControlsEx. I'm not sure you even have to call it, I would think Winforms handles it internally. If you want to do it yourself you only have to do it once, so a static constructor would be more appropriate.


    That said, when I personally tried wrapping the IP control a few year back it caused all sorts of weird font problems so  I eventully gave up.

    Monday, November 28, 2005 1:08 PM
  • I concur with Mattias - the native control seems to delete the font in use, so you have to sort of clone the font that is set in.  This is hard to get right.

    I'd recommend the MaskedTextBox if you can use it.

    Jessica
    Monday, November 28, 2005 6:15 PM

All replies

  • >public IPAddress()
    > {
    >  INITCOMMONCONTROLSEX lpInitCtrls = new INITCOMMONCONTROLSEX();
    >  InitCommonControlsEx(ref lpInitCtrls);

    This doesn't look right. You should initialize the INITCOMMONCONTROLSEX struct properly before passing it to InitCommonControlsEx. I'm not sure you even have to call it, I would think Winforms handles it internally. If you want to do it yourself you only have to do it once, so a static constructor would be more appropriate.


    That said, when I personally tried wrapping the IP control a few year back it caused all sorts of weird font problems so  I eventully gave up.

    Monday, November 28, 2005 1:08 PM
  • I concur with Mattias - the native control seems to delete the font in use, so you have to sort of clone the font that is set in.  This is hard to get right.

    I'd recommend the MaskedTextBox if you can use it.

    Jessica
    Monday, November 28, 2005 6:15 PM
  • Hi mattias and jesica,

    Thanks for the replies, I finally made it working now to Windows2000., I've done this by invoking the InitCommonControlsEx function with correct parameters in a static constructor, as mattias suggested.

    Here's the working control that I have written:



    public class IPAddress : TextBox
    {
     static INITCOMMONCONTROLSEX lpInitCtrls = new INITCOMMONCONTROLSEX();

     static unsafe IPAddress()
     {
      int ICC_INTERNET_CLASSES = 0x800;
      
      lpInitCtrls.dwICC = ICC_INTERNET_CLASSES;
      lpInitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);

      InitCommonControlsEx(ref lpInitCtrls);
     }

     [StructLayout(LayoutKind.Sequential)]
     internal struct INITCOMMONCONTROLSEX
     {
      public int dwSize;
      public int dwICC;
     }

     [DllImport("comctl32.dll")]
     internal static extern bool InitCommonControlsEx(
      ref INITCOMMONCONTROLSEX lpInitCtrls);

     public IPAddress()
     {
      SetStyle(ControlStyles.ResizeRedraw, true);
     }

     protected override CreateParams CreateParams
     {
      get
      {
       CreateParams cp = base.CreateParams;
       cp.ClassName = "SysIPAddress32";

       return cp;
      }
     }
    }

     



    -chris

    Tuesday, November 29, 2005 11:28 AM