Click here to Skip to main content
13,199,685 members (50,112 online)
Rate this:
Please Sign up or sign in to vote.
See more:

I have this bit of code to draw, for testing purposes, a line in a picture control (ID = IDC_GRAPH_D_GRAPH) located in a dialog box:

void CGraphDlg::ShowGraph(void)
	CPaintDC dc (GetDlgItem(IDC_GRAPH_D_GRAPH));
	CSize cs = dc.GetWindoxExt();
	CPen lpen(PS_SOLID, 1, RGB(255, 0, 0));

It works OK because it does draw the line as expected in the picture control so the declaration of dc and the link from it to the picture control in question clearly works.

Oddly enough though the member function "GetWindowExt" of "CClientDC dc" always returns a CSize with values cx = 1 and cy = 1 while the actual picture control size is several hundred pixels each way.
I am not using cx and cy for now but I would like to.

Obviously I must be missing something, anybody have an idea what it might be?

I am using: Visual studio 2010, and its a very basic MFC dialog box application.

Any help much appreciated.
Posted 18-Dec-12 3:22am
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

A CPaintDC object can only be used when responding to a WM_PAINT message.

So I'm guessing that you're not calling this during the processing of the WM_PAINT message for the picture control.

Espen Harlinn
Filip Dossche 18-Dec-12 10:06am
Unfortunately I am calling "ShowGraph" from within the OnPaint() function which does get triggered by means of WM_PAINT.
Espen Harlinn 18-Dec-12 10:17am
Which WM_PAINT? WM_PAINT for the dialog or the picture control?
Filip Dossche 18-Dec-12 10:25am
the WM_PAINT for the dialog
Espen Harlinn 18-Dec-12 10:42am
Then you can't use CPaintDC for the picture control
Filip Dossche 18-Dec-12 10:55am
Fair enough but why does the "LineTo" work then and what is the alternative ?

Oh yes, I have found out it only works once. if you trigger WM_PAINT for the dialog using Invalidate() or SendMessage(WM_PAINT) nothing happens any more except for erasing the drawing when using invalidate.

I am really new to this and I am getting more and more confused.
Espen Harlinn 18-Dec-12 11:00am
You can see how to create subclass at the bottom of hwincontrol.h and hwinstdctrls.h/.cpp in - this capability is also available with MFC

You can then handle the WM_PAINT message for the picture control. This is window subclassing, not C++ subclassing.
Filip Dossche 18-Dec-12 12:42pm
Hi Espen,
Thanks for the info. I'll check it out tomorrow.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

According to MSDN documentation CPaintDC can only be used when responding to a WM_PAINT message, usually in the OnPaint message handler. It emits internally a BeginPaint - EndPaint sequence, which requests the invalid window area and, at the end, validates that region.

If you called ShowGraph from any other place, it can't work.

Either use CClientDC, or make sure your ShowGraph function is called inside the WM_Paint message handling.


When you want to retrieve the size of the window, use GetWindowRect or GetClientRect. GetWindowExt delivers something else, namely the target size of the viewport mapping. You have to explicitly set those. I think to recall that they be default are set to 1.
Espen Harlinn 18-Dec-12 9:52am
That does sound about right, I initially wrote some gibberish ...
nv3 18-Dec-12 10:44am
Thanks Espen!
Filip Dossche 18-Dec-12 10:09am
Too bad, I am calling "ShowGraph" from within the OnPaint() message handler which does get triggered by means of WM_PAINT. The "LineTo" works fine so that should be OK.
nv3 18-Dec-12 10:43am
Please, see my additions above.
Filip Dossche 18-Dec-12 12:39pm
Hi nv3,
I was beginning to suspect that was the case. In the mean time I have successfully used GetWindowRect to get the size.
Thanks for the info.
nv3 18-Dec-12 13:11pm
Alright then. Problem solved.
jibesh 18-Dec-12 15:05pm
nice nv3 5+!!
nv3 18-Dec-12 16:14pm
Rate this: bad
Please Sign up or sign in to vote.

Solution 3


It took a while to sort things out but I have finally cracked it.

Based on the info I got from nv3 and Espen Harlin and a very instructive video I found I introduced a custom dialog control Called CGraph based on class Cwnd and integrated it into my dialog box application.
Integrating it into the dialog box is ultimately dead easy once you know how. Simply adding a custom control to the dialog and specify its class to be "GraphClass" (see c++ code) does the trick.

It works very well now and does everything I want and expect it to do.
In reality its just another case of "Glaringly obvious once pointed out".

What really tricked me is that when the dialog box initialises windows is capable of and does work on the basis of the dialog box's main WM_PAINT message and subsequent OnPaint() function, it just never repeats it afterwards.
The result was that I did get the expected graph, the code faithfully executed again without any error but it did no more redraw.

Thanks for all the help.

This is the header file for the new class:

#pragma once
#include "ToolBox.h"
#include "Data.h"
class CGraph : public CWnd
	virtual ~CGraph();
	CWorkData workData;	
	BOOL CGraph::RegisterWndClass();
	static TCHAR m_szWndClass[];
	afx_msg void OnPaint();
	void ShowGraph(void);
	int m_iCount;

This is the bit of c++ code that handles it:

// GraphDlg.cpp : implementation file
#include "stdafx.h"
#include "Eerste.h"
#include "Graph.h"
TCHAR CGraph::m_szWndClass[] = _T("GraphClass");
	m_iCount = 0;
BOOL CGraph::RegisterWndClass()
	WNDCLASS wndclass;
	if (::GetClassInfo(AfxGetInstanceHandle(),m_szWndClass, &wndclass))
		return TRUE; = 0;
	wndclass.lpfnWndProc = ::DefWindowProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = ::AfxGetInstanceHandle();
	wndclass.hIcon = NULL;
	wndclass.hCursor = NULL;
	wndclass.hbrBackground = NULL;
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = m_szWndClass;
void CGraph::OnPaint()
	int fdtest =1;
void CGraph::ShowGraph(void)
	RECT rect;
	CPaintDC dc (this);
	CPen lpen(PS_SOLID, 1, RGB(255, 0, 0));
	m_iCount +=10;

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web01 | 2.8.171020.1 | Last Updated 19 Dec 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100