Нашёл на просторах интернета следующий лаконичный код для кастомного контрола для ввода IP адресов. Всё работает замечательно, но есть одно НО. При повторном открытии формы с этим контролом размер формы с содержимым пропорционально увеличивается в 1.5-2 раза.
Артефакт проявляется сразу же при запуске приложения в Debug режиме. В конструкторе текущей формы все контролы увеличиваются и текст становится жирным.
public class IPAddressControl : TextBox
{
private const int WM_NOTIFY = 0x004E,
WM_USER = 0x0400,
WM_REFLECT = WM_USER + 0x1C00,
IPN_FIRST = -860,
IPM_SETRANGE = (WM_USER + 103),
IPM_GETADDRESS = (WM_USER + 102),
IPM_SETADDRESS = (WM_USER + 101),
IPM_CLEARADDRESS = (WM_USER + 100),
IPM_ISBLANK = (WM_USER + 105),
ICC_INTERNET_CLASSES = 0x00000800,
CS_VREDRAW = 0x0001,
CS_HREDRAW = 0x0002,
CS_DBLCLKS = 0x0008,
CS_GLOBALCLASS = 0x4000,
WS_CHILD = 0x40000000,
WS_VISIBLE = 0x10000000,
WS_TABSTOP = 0x00010000,
WS_EX_RIGHT = 0x00001000,
WS_EX_LEFT = 0x00000000,
WS_EX_RTLREADING = 0x00002000,
WS_EX_LTRREADING = 0x00000000,
WS_EX_LEFTSCROLLBAR = 0x00004000,
WS_EX_RIGHTSCROLLBAR = 0x00000000,
WS_EX_NOPARENTNOTIFY = 0x00000004,
WS_EX_CLIENTEDGE = 0x00000200;
private int[] values = new int[4];
bool initialized = false;
public event FieldChangedHandler FieldChanged;
public IPAddressControl() : base()
{
for (int i = 0; i < 4; i++)
values[i] = 0;
}
[DllImport("comctl32")]
static extern bool InitCommonControlsEx(ref InitCommonControlsEX lpInitCtrls);
protected virtual void OnFieldChanged(FieldChangedEventArgs e)
{
if (FieldChanged != null) FieldChanged(this, e);
}
protected override CreateParams CreateParams
{
get
{
if (!initialized)
{
InitCommonControlsEX ic = new InitCommonControlsEX();
ic.Size = Marshal.SizeOf(typeof(InitCommonControlsEX));
ic.Icc = ICC_INTERNET_CLASSES;
initialized = InitCommonControlsEx(ref ic);
}
if (initialized)
{
CreateParams cp = base.CreateParams;
cp.ClassName = "SysIPAddress32";
cp.Height = 23;
cp.ClassStyle = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
cp.Style = WS_CHILD | WS_VISIBLE | WS_TABSTOP | 0x80;
cp.ExStyle = WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE;
if (RightToLeft == RightToLeft.No
|| (RightToLeft == RightToLeft.Inherit
&& Parent.RightToLeft == RightToLeft.No))
{
cp.ExStyle |= WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
}
else
{
cp.ExStyle |= WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR;
}
return cp;
}
else
{
return base.CreateParams;
}
}
}
public bool SetIPRange(IPField field, byte lowValue, byte highValue)
{
if (!initialized) return false;
Message m = Message.Create(Handle, IPM_SETRANGE, (IntPtr) ((int) field), MakeRange(lowValue, highValue));
WndProc(ref m);
return m.Result.ToInt32() > 0;
}
public System.Net.IPAddress IPAddress
{
get
{
if (!initialized) return IPAddress.None;
return IPAddress.Parse(base.Text);
}
}
public bool IsBlank
{
get
{
if (!initialized) return !(base.Text.Length > 0);
Message m = Message.Create(Handle, IPM_ISBLANK, IntPtr.Zero, IntPtr.Zero);
WndProc(ref m);
return m.Result.ToInt32() > 0;
}
}
new public void Clear()
{
if (!initialized)
{
base.Clear();
return;
}
Message m = Message.Create(Handle, IPM_CLEARADDRESS, IntPtr.Zero, IntPtr.Zero);
WndProc(ref m);
}
private System.Net.IPAddress GetIpAddress(IntPtr ip)
{
if (!initialized) return IPAddress.None;
return new IPAddress(ip.ToInt64());
}
private IntPtr MakeRange(byte low, byte high)
{
return (IntPtr) ((int) ((high << 8) + low));
}
protected override void WndProc(ref Message m)
{
if (m.Msg == (WM_REFLECT + WM_NOTIFY))
{
NmIPAddress ipInfo = (NmIPAddress) Marshal.PtrToStructure(m.LParam, typeof(NmIPAddress));
if (ipInfo.Hdr.Code == IPN_FIRST)
{
if (values[ipInfo.Field] != ipInfo.Value)
{
values[ipInfo.Field] = ipInfo.Value;
OnFieldChanged(new FieldChangedEventArgs(ipInfo.Field, ipInfo.Value));
}
}
}
base.WndProc(ref m);
}
}
public class FieldChangedEventArgs : EventArgs
{
private int _field, _value;
public int Field
{
get { return _field; }
}
public int Value
{
get { return _value; }
}
public FieldChangedEventArgs(int field, int value)
: base()
{
_field = field;
_value = value;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Nmhdr
{
public IntPtr HWndFrom;
public UIntPtr IdFrom;
public int Code;
}
[StructLayout(LayoutKind.Sequential)]
public struct NmIPAddress
{
public Nmhdr Hdr;
public int Field;
public int Value;
}
[StructLayout(LayoutKind.Sequential)]
public struct InitCommonControlsEX
{
public int Size;
public int Icc;
}
public enum IPField { OctetOne = 0, OctetTwo = 1, OctetThree = 2, OctetFour = 3 }
public delegate void FieldChangedHandler(object sender, FieldChangedEventArgs e);
Подскажите как устранить этот артефакт.
P.S. Если в свойствах контрола изменить размер шрифта на больший или меньший и после обратно вернуть 8,25pt то артефакт исчезает.
P.S.S. Также замечено что все GroupBox уменьшены в размерах.
Оригинал кода здесь.
Добавьте в конструктор элемента явно заданный шрифт:
public IPAddressControl() : base()
{
for (int i = 0; i < 4; i++)
values[i] = 0;
this.Font = System.Drawing.SystemFonts.DefaultFont;
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Доброго дняРазрабатываем проект на движке Unity3D (версия 5
Можно ли средствами библиотеки Knockout js отобразить массив элементов таким образом, чтобы каждый последующий элемент появлялся на странице...
Как сделать чтобы getData() возвращала не undefined, а содержимое строки 36?