Solved

Changing CPen data after created

Posted on 1997-12-23
8
321 Views
Last Modified: 2008-02-01
I wanted to draw with blending effect. The color changes eventually from color A to color B. Therefore I have to set the pen color frequently. But I found that no books or MS Visual C++ help file talks about changing the data of a pen. They just told me how to create a pen. If I create a pen and destroy it and then create another one, the on draw function will surely become very slow. How can I change the color of a pen after it is created?
0
Comment
Question by:sccheung
  • 3
  • 3
  • 2
8 Comments
 
LVL 7

Accepted Solution

by:
galkin earned 50 total points
Comment Utility
Create two pens with diffrent colors and select them into DC periodically. To completely avoid flickering use memory DC and draw onto your window from this memory DC.
0
 

Author Comment

by:sccheung
Comment Utility
If two pens is created, I still have to change the data of each pen before selecting them into the DC. Please tell me how. I do not need two colors only. I want to fill a rectangle with blending effect. e.g. from yellow to blue: the first line is draw with yellow using LineTo. The second line is closer to blue. The third line is more closer to blue......The middle part lines is green......The last line is blue. Therefore if the rectangle is 200x200 pixels, I need 200 pens or I have to know how to change the color of a already created. The problem is not flikering. The problem is the user have to wait for a long long time when it is displayed. When I am using Delphi, I can simply use"Canvas.Pen.Color := [The color I want]". But in the MSVC help file, I can only find "CPen", "CreatePen", "CreatePenIndirect"...... When I try to use "GetLogPen", I get a access violation error!
0
 
LVL 7

Expert Comment

by:galkin
Comment Utility
So you need not only create to pens but also two brushes or change images inside rectangle to simulate effect. You must create pens and brushes and draw rectangle offscreen on memory DC. When you need to chage visual aspect of your rectangle(change pen etc.) blit image from memory DC on your window DC. Since image is already ready in memory DC this operation will be very fast and can even be done during one frame.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
There is no way around it.  You have to create and select in a pen for each color.  That could be hundreds of pens.

However, creating and selecting in a pen is not too slow.  creating is pretty fast, the only slow part is that it must dynamicallu allocate the pen.  Selecting is pretty fast too, the slow part here is that windows may do some color maping calculations.

The color mapping slow down cannot be avoided in any graphics environment, the dynamic allocation is the only extra slow down in the windows environment.  And there is no way around it.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 22

Expert Comment

by:nietod
Comment Utility
Note you can speed things up by not using too many pens.  For example if mathematically there are 200 colors between A and B, but you are on a 16 color display, then at most there will be 16 colors used in the line!  Most likely there will be even less than 16 since will probably not map the colors you request to each of the colors available.

This is getting out of my area of expertise, but you could (probably) determine what colors windows will map to and select only those colors, it will probably be only a few colors throughout the line.
0
 

Author Comment

by:sccheung
Comment Utility
How to completely destroy a pen? I tried to create a CPen, destroy it and then create another one. But I always get assertion failure. The debugger give me this:
BOOL CGdiObject::Attach(HGDIOBJ hObject)
{
      ASSERT(m_hObject == NULL);      // only attach once, detach on destroy <-The debugger pointer points to here
      if (hObject == NULL)
            return FALSE;
      CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not exist
      ASSERT(pMap != NULL);
      pMap->SetPermanent(m_hObject = hObject, this);
      return TRUE;
}
Can you tell me how to completely destroy a CPen?
I do it like this:
for (int i=0; ......
{
      pMyPen->CreatePen(PS_SOLID, 1, ......
      pDC->SelectObject(pMyPen);
//Use the pen
      pMyPen->DeleteObject();
}
0
 
LVL 7

Expert Comment

by:galkin
Comment Utility
// first you must create pen using either parameters passed to
// CPen constructor or create pen class instance using default // constructor and then call CPen::CreatePen which takes the
// same parameters as cPen constructor
// for example I create black pen first
CPen pen(PS_SOLID, 1, 0x000000);
CPen *pOldPen = (CPen *)pDC->SelectObject(&pen);
// draw with the pen selected into DC
// when you are done with this pen reselect old pen into DC
pDC->SelectObject(pOldPen);
//You don't need to destroy pen using DeleteObject since
// CPen class destructor does it itself
// Now you can create another pen for example I create blue pen
// Here you can only create pen using CreatePen function since //constructor has already been called
pen.CreatePen(PS_SOLID, 1, 0x0000ff);
// then you do the same steps: selecting pen into DC drawing,
// and then reselecting old pen
pOldPen = (CPen *)pDC->SelectObject(&pen);
// draw with blue pen
//when you are done with blue pen reselect old pen into dc
pDC->SelectObject(pOldPen);
// then create another pen and do the same...
0
 

Author Comment

by:sccheung
Comment Utility
I've tried your suggestion, but I still get the same error! Finally, I suceeded! Here is my code:
      CPen *pMyPen, *pOriPen;
      pMyPen = new CPen;
for (......
{
   pMyPen->CreatePen(......
   pOriPen = (CPen *)pDC->SelectObject(pMyPen);
   // Use the pen to draw
   pDC->SelectObject(pOriPen);
   pMyPen->DeleteObject();
}

I don't understand why I have to delete the object. But the error disappear when I added that line.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now