2011-10-06 36 views
1

我正在尝试使从TextBox继承的自定义控件。我正在寻找一些自定义绘图的控件边框。我在我的测试应用程序中遇到了几个问题:子类TextBox控件绘制自定义边框

1)调试程序时从不调用TextBox.HandleCreated事件。文本框在表单上可见,我可以与它交互,所以我知道该句柄已创建。我猜这是在我订阅该活动之前被调用的?

2)当我调试程序时,WM_NCPAINT消息从未收到。我知道这在控制的一生中被称为早期。我认为我在这里遇到了和第一个问题相同的问题。

有什么办法可以使用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); 
     } 
    } 
} 

回答

1

MSDN说:SetWindowLong返回“指定的32位整数的前值表示成功。零表示失败。

你检查返回值?

SetWindowLongP/Invoke format是这样的:

/// <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