3

I am trying to change color of a Picture Control box Which I added to a Dialog box in Microsoft Visual C++ environment. I did these Procedure:

  1. In Resource file-> Dialog editor I added a Picture Control box(Type=Rectangle)
  2. I had a look at this problem and tried to keep continuing the way.
  3. Right-Click on Picture Control box and Add a variable.

4.In MainDlg.Cpp file and In Onpainting(); section, the following code Has is added:

CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
dc.FillSolidRect(&rect, RGB(120,255,0));

However I added above command to the following command which I think belongs to the Dialog painting(I don't know If it make problem or not):

CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;

    // Draw the icon
    dc.DrawIcon(x, y, m_hIcon);
}
else
{
    CDialog::OnPaint();
  1. In main.Cpp file and in function OnInitDialog(); this code added:

    m_PictureControlVariable.SubclassDlgItem(IDC_STATIC_PictureControl, this);

(Where IDC_STATIC_PictureControl is Picture Control ID in dialog editor)

  1. I am going to call Picture Contorl color be changed when an Event happens, I mean in a Callback Function which Sends Message to a Dialog I am calling this Picture Control as:

    m_PictureControlVariable.EnableWindow();

Now I recieve a debug error!!

Updated:

I added a MFC Class with a CStatic type(In Menu bar-> Project-> Add Class): A code With following .Cpp and .H included to original project:

#include "stdafx.h"
#include "Main.h"
#include "PICTURECTRL.h"


// PICTURECTRL

IMPLEMENT_DYNAMIC(PICTURECTRL, CStatic)

PICTURECTRL::PICTURECTRL()
{

}

PICTURECTRL::~PICTURECTRL()
{
}


BEGIN_MESSAGE_MAP(PICTURECTRL, CStatic)
    ON_WM_PAINT()
END_MESSAGE_MAP()



// PICTURECTRL message handlers
void PICTURECTRL::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    //@TG
//#3073
        // TODO: Add your message handler code here
        // Do not call CStatic::OnPaint() for painting messages
CRect rect;
GetClientRect(&rect);
dc.FillSolidRect(&rect, RGB(0,0,255));
}

and as you can see I added OnPaint() message handler manually from Resource View-> Class View-> Properties-> Message.

Header of derived Class is:

#pragma once


// PICTURECTRL  (Picture Control)

class PICTURECTRL : public CStatic
{
    DECLARE_DYNAMIC(PICTURECTRL)

public:
    PICTURECTRL();
    virtual ~PICTURECTRL();

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnPaint();

};

And in Original code after Adding a Variable to Picture Control these Commands Added to MainDlg.Cpp MainDlg.H, sequently:

    void CMainDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CMainDlg)
    // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
    DDX_Control(pDX, IDC_PROGRESS1, M_progressBar1);
    DDX_Control(pDX, IDC_PictureControl, m_PicCtrl);
}

and in Header file of Original file just CStatic m_PicCtrl; added to the public part of Main class, I mean:

class CMainDlg : public CDialog
{
public:
protected:
public:
    CStatic m_PicCtrl;
}
Community
  • 1
  • 1
J2015
  • 320
  • 4
  • 24

2 Answers2

1

You should be painting in OnPaint of the picture control, not OnPaint of the dialog. When you did Add Variable it should have created

CStatic m_PictureControlVariable;

and added this variable into DoDataExchange. DoDataExchange does the same thing as your call to SubclassDlgItem, so you should remove that redundant call.

Now derive a class from CStatic and replace the above CStatic with your derived class. With this done you can add a message handler in your derived class for the WM_PAINT message and paint what you like in the picture control.

Updated: In your updated code: In the dialog h file add

#include "PICTURECTRL.h" 

and change

CStatic m_PicCtrl;

to

PICTURECTRL m_PicCtrl;
ScottMcP-MVP
  • 10,337
  • 2
  • 15
  • 15
  • You mean I should create a function with the name of OnPaint() in my new Class?Since When I drive a class a new **Class.Cpp** and **Class.h** I'll have after defining a variable I take all the definitions which are created in **Main.CPP** and **Main.h** and replace the **Class.h** header in **Main.CPP**??? – J2015 May 26 '15 at 07:42
  • Visual C++ can be a big help with these steps. To create the new class use Project menu, New Class, and select MFC CStatic to derive from. To add the OnPaint function select your new class in Class View and right click Properties. Learn to add message handlers: The WM_PAINT message handler is OnPaint. – ScottMcP-MVP May 26 '15 at 11:37
  • I followed your suggestions , I added a MFC Class, then an OnPaint() function included to the **MFCClass.CPP**, then I added this piece of code to function: `CPaintDC dc(this); CRect rect; GetClientRect(&rect); dc.FillSolidRect(&rect, RGB(120,255,0));` and finally I Added this line of code `m_PictureControlVariable.EnableWindow();` to the Callback function of **Main.CPP** where I expect to apply my modification to Picture Control but nothing changed. I'm confused how **Main.CPP** should realizes that read OnPaint of my derived Class not dialog OnPaint! – J2015 May 26 '15 at 14:21
  • You are not mentioning a lot of details that are important. Edit your original post to show the code for your derived class, and for the m_PictureControlVariable and DoDataExchange function in the dialog class. Don't worry about main.cpp yet. First you need to get the basic painting working. – ScottMcP-MVP May 26 '15 at 19:56
  • I really appreciate you, it works. However this is always turn on but I would like its color changes when a Call back function happens: I added `m_PicCtrl.EnableWindow();` in that function but it did not change. – J2015 May 27 '15 at 13:03
  • When the callback function happens it should set a variable in the m_PicCtrl that controls the color, then it should call m_PicCtrl.Invalidate(). Invalidate causes a new WM_PAINT in the control. – ScottMcP-MVP May 27 '15 at 16:26
0

Try something like this:

BOOL YourCStaticDerived::OnEraseBkgnd( CDC* pDC )
{
    CBrush  brush( RGB( 240, 240, 240 ) ); // whatever color you need
    CBrush* pVBrush;
    CRect   rett;

    pVBrush = pDC->SelectObject( &brush );
    pDC->GetClipBox( &rett );
    pDC->PatBlt( rett.left, rett.top, rett.Width(), rett.Height(), PATCOPY );
    pDC->SelectObject( pVBrush );

    return TRUE;
}
IssamTP
  • 2,408
  • 1
  • 25
  • 48
  • but I already used this function for changing dialog box( Parent Window) and It does not work for a defined Rectangle(Picture Control box in my case)!! – J2015 May 25 '15 at 16:29