Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Changing CPen data after created

Posted on 1997-12-23
8
326 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
ID: 1177000
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
ID: 1177001
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
ID: 1177002
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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 22

Expert Comment

by:nietod
ID: 1177003
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
 
LVL 22

Expert Comment

by:nietod
ID: 1177004
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
ID: 1177005
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
ID: 1177006
// 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
ID: 1177007
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

856 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