Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Drawing in Dialog in VC++ MFC

Mano_pmtMano_pmt Member Posts: 1
I have drawn drawing on a dialog using CRect function with CClientDC. This drawing is set of 90 rectangles. I am updating the position of rectangles using the following code. The values of LeafA[i] value will be changes during the running time. automatically the rectangle position also should change. But updation is not happening. for that I am using InvalidateRect() function. Flickring is happening when I am using InvalidateRect() to update the rectangles position.

Please suggest if any thing is wrong or any other process to update or process for not flickering the region.

void CMLCTreatDlg::OnPaint()
{
CPaintDC dc(this);
DrawMLC();
}

void CMLCTreatDlg::DrawMLC()
{
CPaintDC dc(this);
int lpos,spos;
int i;
HDC hdc;

CButton * but=(CButton*)GetDlgItem(IDC_STATIC_MLC);
but->GetWindowRect(rect);

CPen NewPen(PS_DASH,1,RGB(0,0,0));
CPen NewPen1(PS_SOLID,1,RGB(0,0,0));
CPen *OldPen;
CBrush WinBrush(RGB(236,233,216));
CBrush Setbrush(RGB(100,149,237));
CBrush Actbrush(RGB(150,0,90));
CBrush *OldBrush;//(RGB(216,233,236));
hdc = GetDC ()->m_hDC;

lpos=274,spos=157;
CClientDC dcline(this);
CClientDC actDC(this);
CClientDC setDC(this);

CDC memdc;
memdc.CreateCompatibleDC(&dc);
/* HBITMAP hbmp=CreateCompatibleBitmap(dc.m_hDC,rectArea->right,rectArea->bottom);
HBITMAP hOld=(HBITMAP)memdc.SelectObject(hbmp);*/

dcline.SelectObject(NewPen);

actDC.SetBkMode(TRANSPARENT);
setDC.SetBkMode(TRANSPARENT);
setDC.SelectObject(Setbrush);
actDC.SelectObject(WinBrush);



GetClientRect(&rect);

int pos;


actDC.SetBkMode(TRANSPARENT);
actDC.SelectObject(Actbrush);

for(i=0;i<NOOFLEAVES;i++)
{
pos=(LEAFLENGTH/175)*LeafB[i];
rect=CRect(spos+pos,lpos,spos+LEAFLENGTH+pos,lpos+LEAFWIDTH);
setDC.Rectangle(rect);

t=(float)(LEAFLENGTH/175.0)*LeafA[i];
pos=(int)t;
if(((spos+2*LEAFLENGTH)+pos)<=847)
rect=CRect(spos+LEAFLENGTH+pos,lpos,(spos+2*LEAFLENGTH)+pos,lpos+LEAFWIDTH);
else
rect=CRect(spos+LEAFLENGTH+pos,lpos,847,lpos+LEAFWIDTH);
//RedrawWindow(rect,NULL,RDW_ERASE);
setDC.Rectangle(rect);

lpos+=LEAFWIDTH;
}


/*to draw X-Axis and Y axis*/
dcline.MoveTo(432,150);
dcline.LineTo(432,950);
dcline.MoveTo(25,550);
dcline.LineTo(835,550);

/*10x10 field*/
dcline.MoveTo(353,471);
dcline.LineTo(353,629);
dcline.MoveTo(511,471);
dcline.LineTo(511,629);

dcline.MoveTo(353,471);
dcline.LineTo(511,471);
dcline.MoveTo(353,629);
dcline.LineTo(511,629);

/*20x20 field*/
dcline.MoveTo(274,392);
dcline.LineTo(274,708);
dcline.MoveTo(590,392);
dcline.LineTo(590,708);

dcline.MoveTo(274,392);
dcline.LineTo(590,392);
dcline.MoveTo(274,708);
dcline.LineTo(590,708);
}


Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]The following code may not work - it depends on what are you trying to do. See my changes in RED.

    Few issues:

    1. Cannot call any of InvalidateRect or RedrawWindow from within current painting operation. Very bad! These function cause repainting and the code is already in the painting, so it is like recursion.

    2. SetBkMode is not for rectangles, but for text, lines and hatch brushes only. I removed these.

    3. There is only one DC - the one which is created by calling CPaintDC(this); There are no creating piles of DC - also bad. The DC must be passed from function to function if needed, but that MUST BE SAME one created by CPaintDC class.

    4. If you need to change brushes when painting rectangles simply do it just before drawing - no need for multiple DCs.

    I have used the drawing in memory DC first and then dropping all that onto a 'real' DC - the one which was created by CPaintDC. This produces very fast and flicker-less paint operation.

    Now,

    What are you trying to do? What is this GetDlgItem for? Are you trying to draw on top of some control? What if that control is not transparent? Then your painting will conflict with that of what control draws itself. It is better to use the owner drawn button control or static control and then respond to WM_DRAWITEM message in OnDrawItem method. Also, if you want still to use the control - GetWindowRect returns the screen coordinates for a control - even if it is a child control in a dialog. To convert the rectangle into dialog client area coordinates I used the ScreenToClient method. This must be done because the we drawing on dialog DC - not on DC from IDC_STATIC_MLC control.[/color]
    [code]
    : void CMLCTreatDlg::OnPaint()
    : {
    : CPaintDC dc(this);
    : DrawMLC([color=Red]dc[/color]);
    : }
    :
    : void CMLCTreatDlg::DrawMLC([color=Red]CDC& dc[/color])
    : {
    : int lpos,spos;
    : int i;
    :
    : CButton * but=(CButton*)GetDlgItem(IDC_STATIC_MLC);
    : CRect client;
    : but->GetWindowRect(client);
    : [color=Red]ScreenToClient (client);
    : SIZE area = { client.Width(), client.Height() };[/color]
    :
    : [color=Red]CBitmap canvas;
    : canvas.CreateCompatibleBitmap (&dc, area.cx, area.cy);[/color]
    :
    : CPen NewPen(PS_DASH,1,RGB(0,0,0));
    : CPen NewPen1(PS_SOLID,1,RGB(0,0,0));
    : CPen *OldPen;
    : CBrush WinBrush(RGB(236,233,216));
    : CBrush Setbrush(RGB(100,149,237));
    : CBrush Actbrush(RGB(150,0,90));
    : CBrush *OldBrush [color=Red]= memdc.SelectObject (&Actbrush)[/color];
    :
    : lpos=274, spos=157;
    :
    : CDC memdc;
    : memdc.CreateCompatibleDC(&dc);
    :
    : [color=Red]CBitmap* oldBmp = memdc.SelectObject (&canvas);[/color]
    : [color=Red]OldPen = memdc[/color].SelectObject([color=Red]&[/color]NewPen);
    :
    : int pos[color=Red], rleft, bottom[/color];
    : [color=Red]CRect rect[/color];
    :
    : for(i=0;i<NOOFLEAVES;i++)
    : {
    : pos=(LEAFLENGTH/175)*LeafB[i];
    : rect=CRect(spos+pos, lpos, spos+LEAFLENGTH+pos, lpos+LEAFWIDTH);
    :
    : [color=Red]memdc.SelectObject(Actbrush);[/color]
    : [color=Red]memdc[/color].Rectangle(rect);
    :
    : t=(float)(LEAFLENGTH/175.0)*LeafA[i];
    : pos=(int)t; [color=Red]rleft=spos+LEAFLENGTH+pos; bottom=lpos+LEAFWIDTH;[/color]
    :
    : if(((spos+2*LEAFLENGTH)+pos)<=847)
    : rect=CRect([color=Red]rleft[/color],lpos,(spos+2*LEAFLENGTH)+pos,[color=Red]bottom[/color]);
    : else
    : rect=CRect([color=Red]rleft[/color],lpos,847,[color=Red]bottom[/color]);
    :
    : [color=Red]memdc.SelectObject(Setbrush);[/color]
    : [color=Red]memdc[/color].Rectangle(rect);
    :
    : lpos+=LEAFWIDTH;
    : }
    :
    :
    : [color=Green]/*to draw X-Axis and Y axis*/[/color]
    : [color=Red]memdc[/color].MoveTo(432,150);
    : [color=Red]memdc[/color].LineTo(432,950);
    : [color=Red]memdc[/color].MoveTo(25,550);
    : [color=Red]memdc[/color].LineTo(835,550);
    :
    : [color=Green]/*10x10 field*/[/color]
    : [color=Red]memdc[/color].MoveTo(353,471);
    : [color=Red]memdc[/color].LineTo(353,629);
    : [color=Red]memdc[/color].MoveTo(511,471);
    : [color=Red]memdc[/color].LineTo(511,629);
    :
    : [color=Red]memdc[/color].MoveTo(353,471);
    : [color=Red]memdc[/color].LineTo(511,471);
    : [color=Red]memdc[/color].MoveTo(353,629);
    : [color=Red]memdc[/color].LineTo(511,629);
    :
    : [color=Green]/*20x20 field*/[/color]
    : [color=Red]memdc[/color].MoveTo(274,392);
    : [color=Red]memdc[/color].LineTo(274,708);
    : [color=Red]memdc[/color].MoveTo(590,392);
    : [color=Red]memdc[/color].LineTo(590,708);
    :
    : [color=Red]memdc[/color].MoveTo(274,392);
    : [color=Red]memdc[/color].LineTo(590,392);
    : [color=Red]memdc[/color].MoveTo(274,708);
    : [color=Red]memdc[/color].LineTo(590,708);
    :
    : [color=Red]dc.BitBlt (0, 0, area.cx, area.cy, &memdc, 0, 0, SRCCOPY);[/color]
    :
    : [color=Red]memdc.SelectObject (oldBmp);[/color]
    : [color=Red]memdc.SelectObject (OldPen);[/color]
    : [color=Red]memdc.SelectObject (OldBrush);[/color]
    : }
    [/code]
Sign In or Register to comment.