Windows mobile 子类TextBox控件以绘制自定义边框

Windows mobile 子类TextBox控件以绘制自定义边框,windows-mobile,Windows Mobile,我正在尝试创建一个从TextBox继承的自定义控件。我想做一些自定义绘制的边界控制。我在测试应用程序中遇到了一些问题: 1) 调试程序时从未调用TextBox.HandleCreated事件。文本框在表单上可见,我可以与之交互,因此我知道句柄是创建的。我猜这是在我订阅活动之前被调用的 2) 调试程序时从未收到WM_NCPAINT消息。我知道这是在控制生命的早期。我想我在这里遇到了与问题1相同的问题 有没有办法使用Compact Framework 3.5解决这些问题?我是不是更喜欢这样做 以下是

我正在尝试创建一个从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);
        }
    }
}

此答案包含执行此操作的代码(它将在CF上工作)。从技术上讲,这不是子分类,但它是实现此效果的一种更简单的方法。

SetWindowLong
返回“指定的32位整数的上一个值表示成功。零表示失败。”

你在检查返回值吗

因此,
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);
//
///更改指定窗口的属性。该函数还将指定偏移量处的32位(长)值设置到额外窗口内存中。
/// 
///窗口的句柄,以及间接地窗口所属的类的句柄。。
///要设置的值的从零开始的偏移量。有效值的范围为0到额外窗口内存的字节数减去整数的大小。要设置任何其他值,请指定以下值之一:GWL_EXSTYLE、GWL_HINSTANCE、GWL_ID、GWL_STYLE、GWL_USERDATA、GWL_WNDPROC
///重置价值。
///如果函数成功,则返回值为指定的32位整数的上一个值。
///如果函数失败,则返回值为零。要获取扩展错误信息,请调用GetLastError。
[DllImport(“user32.dll”)]
静态外部int SetWindowLong(IntPtr hWnd、intnindex、intdwnewlong);
这就是您声明的
SetWindowLong