Подкласс TextBox элемент управления для рисования пользовательской границы - PullRequest
1 голос
/ 06 октября 2011

Я пытаюсь создать пользовательский элемент управления, унаследованный от TextBox.Я хочу сделать некоторые пользовательские рисования границы элемента управления.В моем тестовом приложении я столкнулся с несколькими проблемами:

1) Событие TextBox.HandleCreated никогда не вызывается при отладке программы.Текстовое поле отображается в форме, и я могу взаимодействовать с ним, поэтому я знаю, что дескриптор создан.Я предполагаю, что это вызывается до того, как я подпишусь на событие?

2) Сообщение WM_NCPAINT никогда не получается, когда я отлаживаю программу.Я знаю, что это вызывается на ранних этапах существования контроля.Я предполагаю, что у меня возникла та же проблема, что и с проблемой № 1.

Есть ли способ решить эти проблемы с помощью Compact Framework 3.5?Я делаю это предпочтительным способом?

Вот соответствующий код:

public class ETextBox : TextBox
{
    private IntPtr mOldWndProc;
    private Win32Helper.WndProcDelegate mNewWndProc;

    public ETextBox(Rectangle rc)
    {
        HandleCreated += new EventHandler(ETextBox_HandleCreated);
        HandleDestroyed += new EventHandler(ETextBox_HandleDestroyed);
        Bounds = rc;
    }

    public ETextBox(String s, Rectangle rc)
        : this(rc)
    {
        Text = s;
    }

    private void SubclassWindow()
    {
        mOldWndProc = Win32Helper.GetWindowLong(Handle, Win32Helper.GWL_WNDPROC);
        mNewWndProc = new Win32Helper.WndProcDelegate(WindowProc);
        Win32Helper.SetWindowLong(Handle, Win32Helper.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(mNewWndProc));
    }

    private void UnsubclassWindow()
    {
        if (mOldWndProc == IntPtr.Zero)
            throw new InvalidOperationException();
        Win32Helper.SetWindowLong(Handle, Win32Helper.GWL_WNDPROC, mOldWndProc);
    }

    private void ETextBox_HandleDestroyed(object sender, EventArgs e)
    {
        UnsubclassWindow();
    }

    private void ETextBox_HandleCreated(object sender, EventArgs e)
    {
        SubclassWindow();
    }

    private IntPtr WindowProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam)
    {
        switch (msg)
        {
            case Win32Helper.WM_ERASEBKGND:
                return IntPtr.Zero;

            case Win32Helper.WM_NCPAINT:
                return IntPtr.Zero;

            default:
                return Win32Helper.CallWindowProc(mOldWndProc, hwnd, msg, wParam, lParam);
        }
    }
}

Ответы [ 2 ]

1 голос
/ 07 октября 2011

MSDN говорит SetWindowLong возвращает " Предыдущее значение указанного 32-разрядного целого числа указывает на успех. Ноль указывает на сбой. "

Вы проверяетевозвращаемое значение?

Формат P / Invoke из SetWindowLong, таким образом:

/// <summary>
/// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
/// </summary>
/// <param name="hWnd">A handle to the window and, indirectly, the class to which the window belongs..</param>
/// <param name="nIndex">The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values: GWL_EXSTYLE, GWL_HINSTANCE, GWL_ID, GWL_STYLE, GWL_USERDATA, GWL_WNDPROC </param>
/// <param name="dwNewLong">The replacement value.</param>
/// <returns>If the function succeeds, the return value is the previous value of the specified 32-bit integer. 
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. </returns>
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

Это то, как вы декларируете SetWindowLong?

1 голос
/ 06 октября 2011

Есть ли способ реализовать плоский TextBox в C #?

Этот ответ содержит код для этого (он будет работать на CF).Технически это не подклассификация, но это гораздо более простой способ достижения этого эффекта.

...