?
Solved

FormView graphics-problem??

Posted on 2003-03-20
28
Medium Priority
?
490 Views
Last Modified: 2013-11-20
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
0
Comment
Question by:gonzalesblanco
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 15
  • 8
  • 5
28 Comments
 

Expert Comment

by:FrenchFries
ID: 8174467
>>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 :-)
0
 

Author Comment

by:gonzalesblanco
ID: 8174554
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
0
 

Expert Comment

by:FrenchFries
ID: 8174755
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
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:gonzalesblanco
ID: 8174993
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
0
 

Expert Comment

by:FrenchFries
ID: 8175286
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.
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8175324
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?
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8175341
Sorry for the overlap of information. Missed the last post while typing.
0
 

Author Comment

by:gonzalesblanco
ID: 8175417
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
0
 

Author Comment

by:gonzalesblanco
ID: 8175452
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
0
 

Author Comment

by:gonzalesblanco
ID: 8175456
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
0
 

Author Comment

by:gonzalesblanco
ID: 8175479
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
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8175509
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.
0
 

Author Comment

by:gonzalesblanco
ID: 8175524
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
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8175539
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.
0
 

Author Comment

by:gonzalesblanco
ID: 8175562
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
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8175755
If you need the window, then do the drawing from the window, not the view.  
0
 

Author Comment

by:gonzalesblanco
ID: 8177029
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

0
 
LVL 2

Expert Comment

by:northernchill
ID: 8177098
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.
0
 

Author Comment

by:gonzalesblanco
ID: 8177398
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
0
 

Author Comment

by:gonzalesblanco
ID: 8177827
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
0
 

Expert Comment

by:FrenchFries
ID: 8179616
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;
0
 

Expert Comment

by:FrenchFries
ID: 8179637
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;
0
 

Author Comment

by:gonzalesblanco
ID: 8179965
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
0
 
LVL 2

Expert Comment

by:northernchill
ID: 8181074
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.
0
 

Author Comment

by:gonzalesblanco
ID: 8181780
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
0
 
LVL 2

Accepted Solution

by:
northernchill earned 360 total points
ID: 8181944
Instead of calling OnPaint() call Invalidate().  This will force a redraw of the control.
0
 

Author Comment

by:gonzalesblanco
ID: 8181964
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
0
 

Author Comment

by:gonzalesblanco
ID: 8310367
Sorry for do that so late!!!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question