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
From: Stephen Myers on
Luigino wrote:
> 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

Luigi,

Assume that anytime a DC is created or passed as a parameter, that it is
in MM_TEXT. Your mapping is only valid for the life of the object. In
particular, your OnPaint() assumes (incorrectly) that the mapping done
in PrepareDC is only required one time. Each time you create a DC you
must do the mappings.

Having said that, why bother changing the mapping of DC at all? The CDC
that you want to map is memDC. So call PrepareDC(memDC, r) each time
through.

You will then want to memDC.SetMapMode(MM_TEXT) immediately prior to
doing the bitblt.

Steve
From: Luigino on
HI Steve!

> Having said that, why bother changing the mapping of DC at all?  The CDC
> that you want to map is memDC.  So call PrepareDC(memDC, r) each time
> through.

First, thanks for the answer...in fact mapping directly the memDC is
like saving the operation of GetMapMode...

> You will then want to memDC.SetMapMode(MM_TEXT) immediately prior to
> doing the bitblt.

This is completely new to me.... could you explain me a bit why I
should map to MM_TEXT before to do BitBlt?...
when I didn't used CreateCompatibleDC and drawn directly on DC I
didn't needed for mappnig back to MM_TEXT and it drawn correctly as I
wanted, in the specific graphic from right to left and stuff...

Thanks again
Ciao
Luigi
From: Stephen Myers on
Luigino wrote:
> HI Steve!
>
>> Having said that, why bother changing the mapping of DC at all? The CDC
>> that you want to map is memDC. So call PrepareDC(memDC, r) each time
>> through.
>
> First, thanks for the answer...in fact mapping directly the memDC is
> like saving the operation of GetMapMode...
>
>> You will then want to memDC.SetMapMode(MM_TEXT) immediately prior to
>> doing the bitblt.
>
> This is completely new to me.... could you explain me a bit why I
> should map to MM_TEXT before to do BitBlt?...
> when I didn't used CreateCompatibleDC and drawn directly on DC I
> didn't needed for mappnig back to MM_TEXT and it drawn correctly as I
> wanted, in the specific graphic from right to left and stuff...
>
> Thanks again
> Ciao
> Luigi

The default map mode for a CDC is MM_TEXT. The CDC you get when you do
the CPaintDC is in this mode. The only drawing that you will do in the
dc is the bitblt call at the very end. So long as the bitmaps are sized
correctly (which is the case), your bitblt can be in raw pixels with no
mapping modes involved.

It is only for the bitblt that you would do the mapping back to MM_TEXT.
The other way of accomplishing the same thing is to apply the scaling
to both CDCs. The potential problem is calculating in logical units
where to bitblt. If you use MM_TEXT the bitblt becomes trivial using
0,0 and r.width(),r.height()

Steve

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

>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...
****
Any DLL can contain controls. But to add it to the "custom controls" library in VS, it
has to be an OCX. So if you were asking about "custom controls" in general, any DLL
works. But if you want to add "custom controls" that have first-class support in VS, they
have to be OCXs.
****
>
>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
****
SelectObject of what? Presumably, a compatible bitmap, or the DC has no value.
****
>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?....
****
Only if it has a compatible bitmap of the same dimension selected in.
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