Link to home
Start Free TrialLog in
Avatar of gonzalesblanco
gonzalesblanco

asked on

FormView graphics-problem??

Hello!

In my FormView-App I used a PictureBox(Rectangle), where I wanna draw. I tried to realize
that in this way:

OnDraw:
CWnd *pWnd = GetDlgItem(IDC_PLACE);
CDC *hdc = pWnd->GetDC();
...... pWnd->ReleaseDC();

that works!!
In OnPaint(), i call OnDraw, and in the Doc i call UpdateAllViews when necassary!!

But there is one Problem on Resizing, the content disapears, but it goes in to the OnDraw
function, I checked that with a static int var in OnDraw, but i guess a other event is called and
this lets the PictureBox empty.

I guess it is the onSize event!! But how can I handle that?????

Same happens when i shove the application out of the screen only the drawin was inside the
screen is visible afer shoving the app back!!!

Thank you
ola
gonzalesblanco
Avatar of FrenchFries
FrenchFries

>>I guess it is the onSize event!! But how can I handle >>that?????


?? it's quite simple ? Go to ClassWizard (if  VC 6.0 )and handle WM_SIZE :-)
Avatar of gonzalesblanco

ASKER

He FrenchFries!

I tried that, but how?

Did it like this:

CWnd *pWnd = GetDlgItem(IDC_PLACE);
CDC *hdc = pWnd->GetDC();
OnDraw(hdc);

But that will make my prog crash, cause it will be called before the PictureBox(IDC_PLACE) is created!!!!!
So I don't know how to do that!!!

ciao
gonzalesblanco
Ola,

>>CWnd *pWnd = GetDlgItem(IDC_PLACE);
>>CDC *hdc = pWnd->GetDC();
>>OnDraw(hdc);

NOOOO !!! don't do that !
You don't need to call OnDraw if you have already got a CDC before .
Simply get a CDC with GetDC or construct a dc on the stack with
CClientDC dc(this) ( but it works only with CView )

Or

CDC *pDC=pWnd->GetDC();
// perform some drawing
pDC->Rectangle(...);
// important release the DC
pWnd->ReleaseDC(pDC);

Regards
He,

can't really understand what you mean, cause i guess the system will crash that moment i write in the onSize, anything concerning the IDC_PLACE!!!! (PictureBox) cause the on size event is called before the wnd is initialized!!!

could you to me a favour, and write the lines you think i got to write in the OnSize down here? Thank you:

OnSize(....)

Ola, Gonzales
Dear Gonzalesblanco,

One thing that I don't understand is that you are talking about a "PictureBox" : is it an Active X ? Because there aren't any picture box controls with VC++ ( whereas Visual Basic has it ).
What I understand is that you need to repaint the client screen :
Here is a sample from MSDN , but if you want to repaint the screen , simply call Invalidate(TRUE ) or FALSE ..

void CMyView::OnSize(UINT nType, int cx, int cy)
{
   CView::OnSize(nType, cx, cy);

   m_MyPictureBox.MoveWindow (0, 0, cx, cy);
Invalidate(TRUE);
}

Regards.
Why not just force a redraw of the view in OnSize(...)?

void MyView::OnSize(UINT nType,int cx, int cy)
{
  CView::OnSize(nType,cx,cy);
// this will go into OnPaint()
  Invalidate();
}

You should check the hWnd of the child window you retrieve to ensure it is a valid window.
pWnd = GetDlgItem(IDC_PLACE);
ASSERT(pWnd->m_hWnd != NULL) // don't do anything without a valid window

When you shove the window off the screen and then back, the picture window receives a message, instructing it to paint itself.  Since your drawing code is in the parent view, it won't be called in the appropriate order.

Do you need the window, or just the rectangular region?
Sorry for the overlap of information. Missed the last post while typing.
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
You should check after the picture is created.  If you are using a CView, then you are creating the picture window programmitcally.  Somewhere you should a picturebox.Create(...) call.

If you want to draw directly from the view, don't create a window, just draw in the rectangle you would have defined.

If you are using a FormView, then you probably created a resource template containing the picturebox.  In this case, retrieve the rectangle from OnIntialUpdate after the CFormView::OnInitialUpdate has completed.
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
One other note, if you want to view the post as it is updated, click on the Reload this Question at the top left of the page.  Clicking on refresh after you have posted a comment adds your comment again to the thread.
he,

i just thought about the possibility that every control gets his own WM_PAINT so it is possible that, the message of the form is doing right, but the WM_PAINT for the IDC_PLACE overwrites the forms one!!!

ad norhternchill:
tried your way, but the app is crashing at OnInitialUpdate, where should I check if the window is valid? In OnSize? No?

Ah, and I need the window. I got the problem i can only get the dc to the window at the onDraw, otherwise it will crash (when I to that in OnInitalUpdate or in the constructor!)

ad frenchfries:
i called the picture control picturebox!

ola
gonzales
If you need the window, then do the drawing from the window, not the view.  
Hello again!!

Won't work in that ways!!!
But I wanna try another one, but therefore i need to derrive a own class from CWnd, and then give the PictureControl over to that class!!

Never done that, thats my try:

OnInitialUpdate() //in formView

HWND hwnd;
hwnd = GetDlgItem* (IDC_PLACE);

CGraphicWnd wnd;
wnd.SubclassWindow(hwnd);

And now i wanna handle all paint events in the CWnd class!!
Won't work till now, any ideas???

Thanks for any of your opinions and advices (also the already given ones!)

ola
gonzalesblanco

CGraphicWnd wnd should actually be a member variable, not a local variable to the OnInitialUpdate function so it won't go out of scope at the end of the function.

If CGraphicWnd is derived from CWnd, add a handler for the WM_PAINT message.  This will allow you to paint for the window.

You will need the view to provide all the data required to perform the drawing to the CGraphicWnd object.
he northernchill!

I made it global, but when i call the subclass it crashes, when this happens:

m_graphic.SubclassWindow(GetDlgItem(IDC_PLACE)->m_hWnd);

wrong call?!?!?

thank you.

ola gonzalesblanco
Ok, works that way!!!

m_graphic.SubclassWindow(GetDlgItem(IDC_PLACE)->m_hWnd);

but can I access the Doc from my own CWnd class???
How can i Initialize a pointer to the doc in CWnd??? Tried it but it's only crabb stuff coming out:-) typical me!!!

good night
gonzalesblanco
Dear Gonzales Blanco ,

I think that your problem "would" comes the fact that you need to create a DC in memory to constantly get access to the picture you have created.

>>but can I access the Doc from my own CWnd class???
Of course : AppWizard generates a CView method, GetDoc that returns a pointer to your app document class.
See OnDraw method where you get a CDocument pointer.

Regards;
Dear Gonzales Blanco ,

I think that your problem "would" comes the fact that you need to create a DC in memory to constantly get access to the picture you have created.

>>but can I access the Doc from my own CWnd class???
Of course : AppWizard generates a CView method, GetDoc that returns a pointer to your app document class.
See OnDraw method where you get a CDocument pointer.

Regards;
He,

wish you a wonderful day first!

So, I`m nearly finished, but one there is still to do.

I need to access my doc from CWnd out. Have you any ideas
how i can construct a pointer to doc from my CWnd class out!!

can i to that calling a membervar of CWnd in the view, giving a pDoc pointer with her to the constructer of CWnd??

Thank you guys!

Ola
gonzalesblanco
Add a member function and variable to your CWnd class
#include "MyDocument.h"
class CGraphicClass : public CWnd
{
protected:
   CMyDocument* m_pDoc;
}
SetDocument(CMyDocument* pDoc)
{
   m_pDoc = pDoc;
}

Call this after you create the instance of the CWnd object.  Now you will have access to the document.

Or you can add the above to a constructor, which would resemble the SetDocument(...) function.
hello!

thank your have, done that already same way you suggested, works fine!

But now the problem just turned 180° cause now the window redraws at resize, and move, but when i call a self-defined member function in CWnd from the view after data in the view changed, which calls CWnd::OnPaint() nothing happens but it goes there i watched with the debugger!!!

got now idea whats that now:

code:

void CMyWnd::OnPaint()
{
CString temp;
CPaintDC dc(this); // device context for painting
temp.Format("OnPaint: %s", m_pDoc->m_strName);
dc.TextOut(0,0, temp);
}

void CMyWnd::test()
{
     OnPaint();
     testpaint();
}

in view:
m_wndGraphic.test();

thank you for all your patience with a bloddy novice!!

ciao
gonzales
ASKER CERTIFIED SOLUTION
Avatar of northernchill
northernchill

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Okay works fine!!!
Invalidate, does a good job!

But how can i award you the points, will look that up!

Ciao and thanx,

next time will come I swear!! hahaha!

gonzales
Sorry for do that so late!!!