2011-10-06 87 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