From: Luigino on
HI Joe,

> No. You have it backwards. There is no "automatic deselection" and the concept does not
> exist. Instead, what happens is that the DC retains a pointer to the graphics object,
> which does not go away. Then, when the DC is destroyed, the object no longer has any
> application-visible reference, and therefore cannot be deleted.
>
> The way you handle this is to either re-select the original object back into the DC, or
> use SaveDC/RestoreDC to ensure the DC is restored to its pre-SaveDC state and therefore
> any objects selected in are implicitly deselected. I find this preferable to the
> old-fashioned approach of declaring tons of "old object" variables and having to remember
> to restore them.
> ****

Ah ok, in fact in my code I'm using before: int save = dc.SaveDC();
and after the drawing with Pen I'm calling dc.RestoreDC(save);

> ****
> What part of "the right and bottom limits are off by one pixel" did you miss? I said that
> extents of graphical objects are up-to-but-not-including, so the 0 point is not part of
> the area that is drawable. It is one pixel beyond that area. You keep trying flawed
> experiments and keep being surprised when they don't work. I said to draw an "X" for a
> very good reason, and you just drew a straight line. It didn't work, and that isn't
> surprising.
> ****
> No, remember that you reversed coordinates. So x=0 is the right side of the rectangle,
> and x = r.right means r.right positive logical units from (0,0), which of course is the
> left edge. And what you probably saw was the line ended up at (0,0) but all that was
> visible was (1,1). So it sounds like you were getting the expected result with this
> experiment.
> ****

In fact I was veryfing all that because the line doesn't appear
exactly at (1,1) as you said but at minimum (86,86) it appears,
wouldn't that minimum of 86 depending from the monitor or it is like
fixed?...

> ****
> The DLL presumably creates the dialog, right? If it creates the dialog, then you can do
> it at design time. If the DLL is just drawing into an existing control, then create the
> control and just pass its CWnd* to the DLL.
>
> You haven't really said who creates what when. Note that a DLL would not create a CWnd
> and keep it in a variable local to the DLL because then you couldn't create more than one
> of them.
> ****

I'm creating a DLL with the control class so I can use the DLL in
whatever application I want to use...
and after saying to create it at design time, I inserted in the test
application CDialog form a ICustomEditor where I initialized inside
the custom control class calling my Create() method. Is that what you
were meaning or to create a control and add it in the Toolbox?...
If you intended the second way, then how I can add a custom control in
the toolbox when I create it with a DLL?...


thanks
Ciao
Luigi

From: Joseph M. Newcomer on
See below...
On Mon, 15 Feb 2010 01:03:54 -0800 (PST), Luigino <npuleio(a)rocketmail.com> wrote:

>HI Joe,
>
>> No. You have it backwards. There is no "automatic deselection" and the concept does not
>> exist. Instead, what happens is that the DC retains a pointer to the graphics object,
>> which does not go away. Then, when the DC is destroyed, the object no longer has any
>> application-visible reference, and therefore cannot be deleted.
>>
>> The way you handle this is to either re-select the original object back into the DC, or
>> use SaveDC/RestoreDC to ensure the DC is restored to its pre-SaveDC state and therefore
>> any objects selected in are implicitly deselected. I find this preferable to the
>> old-fashioned approach of declaring tons of "old object" variables and having to remember
>> to restore them.
>> ****
>
>Ah ok, in fact in my code I'm using before: int save = dc.SaveDC();
>and after the drawing with Pen I'm calling dc.RestoreDC(save);
>
>> ****
>> What part of "the right and bottom limits are off by one pixel" did you miss? I said that
>> extents of graphical objects are up-to-but-not-including, so the 0 point is not part of
>> the area that is drawable. It is one pixel beyond that area. You keep trying flawed
>> experiments and keep being surprised when they don't work. I said to draw an "X" for a
>> very good reason, and you just drew a straight line. It didn't work, and that isn't
>> surprising.
>> ****
>> No, remember that you reversed coordinates. So x=0 is the right side of the rectangle,
>> and x = r.right means r.right positive logical units from (0,0), which of course is the
>> left edge. And what you probably saw was the line ended up at (0,0) but all that was
>> visible was (1,1). So it sounds like you were getting the expected result with this
>> experiment.
>> ****
>
>In fact I was veryfing all that because the line doesn't appear
>exactly at (1,1) as you said but at minimum (86,86) it appears,
>wouldn't that minimum of 86 depending from the monitor or it is like
>fixed?...
****
It's a function of your mapping mode. If, under the mapping mode, the lines map to a
coordinate outside the plane, they won't appear until you get a number large enough to map
to the first visible pixels.
*****
>
>> ****
>> The DLL presumably creates the dialog, right? If it creates the dialog, then you can do
>> it at design time. If the DLL is just drawing into an existing control, then create the
>> control and just pass its CWnd* to the DLL.
>>
>> You haven't really said who creates what when. Note that a DLL would not create a CWnd
>> and keep it in a variable local to the DLL because then you couldn't create more than one
>> of them.
>> ****
>
>I'm creating a DLL with the control class so I can use the DLL in
>whatever application I want to use...
>and after saying to create it at design time, I inserted in the test
>application CDialog form a ICustomEditor where I initialized inside
>the custom control class calling my Create() method. Is that what you
>were meaning or to create a control and add it in the Toolbox?...
>If you intended the second way, then how I can add a custom control in
>the toolbox when I create it with a DLL?...
*****
As far as I know, custom controls can only be added as OCX controls. I've never done
this, because I don't develop OCX controls.

Note that as an OCX control, there's a fair amount of power available; for example, you
don't have to create a window because the control is its own window when you place it in
the dialog editor.
joe
****
>
>
>thanks
>Ciao
>Luigi
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Luigino on
HI Joe,

> *****
> As far as I know, custom controls can only be added as OCX controls.  I've never done
> this, because I don't develop OCX controls.
>
> Note that as an OCX control, there's a fair amount of power available; for example, you
> don't have to create a window because the control is its own window when you place it in
> the dialog editor.
> ****

But also DLL can contains controls as far as I know...

But I figured a thing: while I draw with MM_ANISOTROPIC first drawing
grid, then mapping the MM_ANISOTROPIC inverting coordinates, then
drawing the PolyLine it works, even if flickering...

If I call CreateCompatibleDC and SelectObject to have a memory dc copy
then mapping and drawing polyline doesn't work.... if a memory copy DC
is just a copy of the device, shouldn't just behave as like as on
CPaintDC device context?....

Thanks
Ciao,
Luigi
From: Luigino on
HI Joe,

I figured to draw correctly horizontal scrolling having origin point
at right bottom so the graphic starts from right to left but it
flickers.
So I created a memory DC with CreateCompatibleDC but looks like memory
dc doesn't behave really the same about mapping as you can see in this
code:

void CMyDLL::PrepareDC(CDC & dc, CRect rc)
{
dc.SetMapMode(MM_ANISOTROPIC);

switch (iGraphType)
{
case GRAPH_BARS:
{
//dc.Rectangle()
}
break;

case GRAPH_LINES:
{
dc.SetWindowExt(-rc.Width(), iYMaxInterval);
dc.SetViewportExt(rc.Width(), -rc.Height());
dc.SetWindowOrg(rc.Width(), 0);
dc.SetViewportOrg(0, rc.Height());
}
break;

default:
break;
}
}

void CMyDLL::DoDrawing(CDC & dc, CRect rc)
{
// *********** graphic component ***********
// based on choice of graph type
CPen qPolylinePen(PS_SOLID, 1, RGB(0, 255, 0));

switch (iGraphType)
{
case GRAPH_BARS:
{
//dc.Rectangle()
}
break;

case GRAPH_LINES:
{
if (vtPoints.capacity() == 1)
{

for (int i=vtPoints[0].size()-1;i>=0;i--) {
vtToDraw[0].at(i).x = vtPoints[0].at(i).x;
vtToDraw[0].at(i).y = ( (vtPoints[0].at(i).y > 0) ?
vtPoints[0].at(i).y : 86 );
}

dc.SelectObject(qPolylinePen);
vectfPoints* pointsline = &vtToDraw[0];
dc.Polyline(&(*pointsline)[0], (int)pointsline->size());
//dc.PolyPolyline()
}
}
break;

default:
break;
}
GDI_FLUSH();
}

void CNyDLL::OnPaint()
{
CPaintDC dc(this); // device context for painting

CRect r;
dc.GetClipBox(&r);
dc.SetBkColor(RGB(0,0,0));

int saveobject = dc.SaveDC();

if(bSetDraw)
{
// ********** Background ***********
// Grid
if (firstTime) {
PrepareDC(dc, r);
firstTime = FALSE;
}

CDC memDC;
CBitmap bBitmap; // Offscreen bitmap
CBitmap* bOldBitmap; // bitmap originally found

memDC.CreateCompatibleDC(&dc);
bBitmap.CreateCompatibleBitmap(&dc, r.Width(), r.Height());
bOldBitmap = memDC.SelectObject(&bBitmap);

memDC.FillSolidRect(r, dc.GetBkColor());
memDC.SetMapMode(dc.GetMapMode());
memDC.SetWindowExt(dc.GetWindowExt());
memDC.SetViewportExt(dc.GetViewportExt());
memDC.SetWindowOrg(dc.GetWindowOrg());
memDC.SetViewportOrg(dc.GetViewportOrg());

if (bActivateGrid)
{
CPen qLinePen(PS_SOLID, 0, RGB(0,139,0));
memDC.SelectObject(qLinePen);

// Grid - Horizontal lines
for(int y = 0; y < r.bottom; y += (int)12) {
/* scan y */
memDC.MoveTo(r.left, y);
memDC.LineTo(r.right, y);
} /* scan y */

// Grid - Vertical lines
for(int x = 0 - (int)gridOffset; x <= r.right - (int)gridOffset; x
+= (int)12 ) {
/* scan x */
memDC.MoveTo(x, r.top);
memDC.LineTo(x, r.bottom);
} /* scan x */
}

DoDrawing(memDC, r);

// Copy the offscreen bitmap onto the screen.
dc.BitBlt(r.left, r.top, r.Width(), r.Height(),
&memDC, r.left, r.top, SRCCOPY);

//Swap back the original bitmap.
memDC.SelectObject(bOldBitmap);
}
//}
dc.RestoreDC(saveobject);
}


because the PolyLine now starts from left to rigtht and on the other
hand it looks like it doesn't apply correctly the Y interval...
Did I maybe forgot something or is there a possible alternative to
avoid flickering if CreateCompatibleDC isn't the right solution for
this?...

Thanks,
Ciao
Luigi
From: Luigino on
Hi again,

I was trying some testing and I figured also if I set Y interval to
32766 or 65534 after BitBlt it shows as like a little line instead to
fill the whole client, in fact if I do, after assigning to memory dc
the mapping:

CRect memdc_rect;
memDC.GetClipBox(&memdc_rect);

I get something like: top=65534 bottom=0 left=613 right=0 when the top
should be 380 and 65534 is only the scale...

plus the grid goes left to right instead to be right to left...

any hint?...

Thanks a lot
Ciao
Luigi