tags:

views:

568

answers:

3

I am trying to make a Visual C++ 2008 program that plots some data in a Window. I have read from various places the correct way to do this is to override WndProc. So I made a Windows Forms Application in Visual C++ 2008 Express Edition, and I added this code to Form1.h, but it won't compile:

 public:
    [System::Security::Permissions::PermissionSet(System::Security::Permissions::SecurityAction::Demand, Name="FullTrust")]
 virtual void WndProc(Message %m) override
 {
  switch(m.Msg)
  {
   case WM_PAINT:
   {
    HDC     hDC;
    PAINTSTRUCT ps;
    hDC = BeginPaint(m.HWnd, &ps);

    // i'd like to insert GDI code here

    EndPaint(m.Wnd, &ps);
    return;
   }
  }
  Form::WndProc(m);
 }

When I try to compile this in Visual C++ 2008 Express Edition, this error occurs: error C2664: 'BeginPaint' : cannot convert parameter 1 from 'System::IntPtr' to 'HWND'

When I try using this->Handle instead of m.HWnd the same error occurs.

When I try casting m.HWnd to (HWND), this error occurs: error C2440: 'type cast' : cannot convert from 'System::IntPtr' to 'HWND'

Maybe I need to cast the m.HWnd to a pin_ptr or something.

+1  A: 

The articles you refer to discuss how to do in a native C++ application, not in a WinForms app. You should override OnPaint method instead of handling the message in the WndProc.

Michael
+1  A: 

I think you are getting mixed up between Win32 programming (must override WM_PAINT) and Windows Forms / .NET where you only have to override the draw method.

Drawing on a form is super-simple in .NET! You simply override the OnPaint method and then perform all of your drawing.

You can bind to the paint handler either using the Toolbox in Visual Studio or by using the following code in your class;

this.Paint += new System.Windows.Forms.PaintEventHandler(this.MyForm_Paint);

You then implement the MyForm_Paint method like so;

private void MyForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
  //create a graphics object from the form
  Graphics g = this.CreateGraphics();

  // create  a  pen object with which to draw
  Pen p = new Pen(Color.Red, 7);  // draw the line 

  // call a member of the graphics class
  g.DrawLine(p, 1, 1, 100, 100);
}
Andrew Grant
I believe he's referring to C++ code Andrew, not C#. There is enough of a difference to confuse the poor lad.
Yes, thankfully I have lots of experience in C# so I know it when I see it, and pretty quickly translate it to C++. Thanks for pointing out the difference between a Win32 application and a Windows Forms application, Andrew Grant.
David Grayson
Weird, the code in the original question looks like no C++ I've seen!
Andrew Grant
+1  A: 

If you were making a raw Win32 application then you could use those functions.

If, on the other hand, you are making a WinForms application then you need to override the OnPaint event.

  • Switch to the design view (The view that shows your form.)
  • Click on the title bar of your form
  • In the properties window (by default probably on your lower right screen) select the lightning bolt near the top. This will display a list of events.
  • Scroll down to the paint event and double click it.

You will end up with a Paint routine shell from which you can use the drawing functions of the graphics object.


private: System::Void Form1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) 
{
    e->Graphics->DrawRectangle(...)     
}

If you really want to write raw Win32 code, let me know, and I can help you write a shell. In the time being if you are interested in Win32 I recommend Charles Petzold's Programming Windows 5th edition.

If you want to learn C++ WinForms... well, I recommend switching to C# or VB.NET simply because they might be more intuitive.

Hope this helps. Cheers.