From: Luigino on 15 Feb 2010 04:03 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 15 Feb 2010 08:48 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 15 Feb 2010 19:56 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 18 Feb 2010 01:07 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 18 Feb 2010 06:47
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 |