2013-03-16 25 views
1

在ownerdraw自定義控件上做一些測試。Visual c + + WndProc重寫MySplitContainerControl :: WndProc(m);

這段代碼編譯,但是崩潰...歸因於「m」是<undefined value>

MySplitContainerControl::WndProc(m);/*與brakepoint,我可以看到一個消息....但拆下制動點會導致崩潰!

我試圖重寫從Splitcontainer窗口的外觀。

protected: static int WM_PAINT = 0x000F; 
protected: virtual void WndProc(Message% m) override 
    { 
    MySplitContainerControl::WndProc(m); 
    /*Form::WndProc(m);*/ 
    if (m.Msg == WM_PAINT) 
     { 
       Graphics^ graphics = Graphics::FromHwnd(this->Handle); 
       PaintEventArgs^ pe = gcnew PaintEventArgs(graphics, Rectangle(0,0, this->Width, this->Height)); 
       OnPaint(pe); 
     } 

爲了得到一個想法,我在做什麼這裏是完整的代碼:

#pragma once 

using namespace System; 
using namespace System::ComponentModel; 
using namespace System::Collections; 
using namespace System::Windows::Forms; 
using namespace System::Data; 
using namespace System::Drawing; 


namespace MySplitContainer { 

    /// <summary> 
    /// Summary for MySplitContainerControl 
    /// </summary> 
    public ref class MySplitContainerControl : public System::Windows::Forms::SplitContainer 
    { 
    public: 
     MySplitContainerControl(void) 
     { 
      InitializeComponent(); 
      // 
      //TODO: Add the constructor code here 
      // 
     } 

    protected: 
     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     ~MySplitContainerControl() 
     { 
      if (components) 
      { 
       delete components; 
      } 
     } 

    private: 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     System::ComponentModel::Container^ components; 

#pragma region Windows Form Designer generated code 
     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     void InitializeComponent(void) 
     { 
      this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; 
     } 
#pragma endregion 

    protected: static int WM_PAINT = 0x000F; 
    protected: virtual void WndProc(Message% m) override 
     { 
     MySplitContainerControl::WndProc(m); 
     /*Form::WndProc(m);*/ 
     if (m.Msg == WM_PAINT) 
      { 
        Graphics^ graphics = Graphics::FromHwnd(this->Handle); 
        PaintEventArgs^ pe = gcnew PaintEventArgs(graphics, Rectangle(0,0, this->Width, this->Height)); 
        OnPaint(pe); 
      } 
     } 

    protected: virtual void OnPaint(PaintEventArgs ^e) override 
     { 

     } 

    }; 
} 

回答

1

您有:

protected: virtual void WndProc(Message% m) override 
{ 
    MySplitContainerControl::WndProc(m); 
    // ... 
} 

所以,你所呼叫的覆蓋WndProc方法本身。這導致無限遞歸調用,導致StackOverflowException

讓它成爲Form::WndProc(m)(註釋行)。它應該調用基類的WndProc,而不是它本身。

其次,覆蓋WM_PAINT的時候,你應該叫BeginPaintEndPaint方法,而不是創建的窗口的新Graphics(和DC)。

+1

真正的問題是,爲什麼他在處理'WM_PAINT'的時候,WinForms框架已經爲他做了這些?只要調用基類的'WndProc'過程,'OnPaint'的默認實現就可以正常工作。 – 2013-03-16 07:04:19

+0

@CodyGray你說得對。通過重寫'OnPaintBackground' /'OnPaint'可以實現一切(與繪圖有關)。 – 2013-03-16 07:11:21

+0

我發佈問題後,我試過「SplitContainer :: WndProc(m);」它的工作。 我試圖改變splitcontainer的行爲。 我幾乎成功了我想要的。 – NaturalDemon 2013-03-16 21:59:04