|
You can't change the color of the existing pen. Are you sure that *every* line you draw must have different color?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Why it is not possible?
I work on a math grapher, which can draw any number of math functions (limited only by the memory) together on the screen. The user is allowed to set different color for every function, moreover he can set distinct color for every "x" value.
You can imagine that (f(x), f(x + delta)) makes one line. So I have thousands of lines on the screen and every line may have different color.
How to deal with this?
|
|
|
|
|
> Why it is not possible?
This question should be adressed to Microsoft, not to me
> The user is allowed to set different color for every
> function, moreover he can set distinct color for every
> "x" value.
And every function has its own color settings for every x value? In this case, the only solution to make things faster is calling API functions directly instead of CPens - I'm assuming your app uses MFC.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Yes it uses MFC, but it is not so important. I can use API calls as well, but what? I searched MSDN and no such API function is out there. In API you create pens as you do in MFC, there is no difference. MFC does a lot of work for you, of course, but there's no real difference. I experimented with CDC::EnumObjects for OBJ_PEN, however this function can only read pen information and there is no function to store color or style or width into existing pen. I cannot create thousands of pens. I would be a fool if I did.
|
|
|
|
|
> In API you create pens as you do in MFC, there is
> no difference.
There's a big difference if you create thousands of them. MFC uses maps to associate GDI entities with its own C++ objects, and this takes time/memory.
> I cannot create thousands of pens.
You don't need to create thousands of them *at once*.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
OK, there is difference. Yet, the internal GDI object is created regardless you use MFC or not. And it takes time and memory. I don't want to do "create and delete" system, because it would be slow and inefficient.
|
|
|
|
|
> I don't want to do "create and delete" system, because it
> would be slow and inefficient.
Before you call something 'slow and inefficient', try to *measure* its performance. On my old 333MHz box it takes less than 120 msec to perform this:
for (int j = 0; j < 10000; j ++)
{
HPEN hp = CreatePen(PS_SOLID, 1, RGB(j % 255, j % 255, j % 255));
SelectObject(hdc, hp);
MoveToEx(hdc, j, 0, NULL);
LineTo(hdc, j, 1);
SelectObject(hdc, GetStockObject(NULL_PEN));
DeleteObject(hp);
}
It's roughly 83300 pens per second. Are you sure that pens are *real* bottleneck in your program?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Doesn't every single CreatePen, DeleteObject pair fragment memory?
I suppose it does.
BTW 120 ms is pretty long time .
|
|
|
|
|
> Doesn't every single CreatePen, DeleteObject pair fragment
> memory?
I doubt there's any significant performance hit. Many programs create and destroy pens/brushes during each WM_PAINT processing. GDI must deal with this.
> BTW 120 ms is pretty long time
For 10000 cycles? I don't think so. How much time does it take to compute data points you're going to visualize?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I'm not very certain about this, but I believe there's no memory fragmentation,
because Windows allows a fixed number of GDI resources (am I right ), so there must be an efficient way of handling them. I don't think the system allocates and frees memory every time you create a pen.
Any comments?
|
|
|
|
|
Wow - this is quite a lengthy conversation you two have had. My 2 cents worth, which is just over 1 cent, US.
1/ You *can* use DrawSolidRect and pass in a colour to draw a line without creating a pen, but the API will just create one internally.
2/ There is *no* way that 'thousands' of different line colours will be visible to the naked eye unless they form a gradient and the interaction between them is the point. The only other reason to do this would be colour keying
3/ MFC is a thin wrapper for the API - look at the code and it more often than not calls an API function directly. CPen is just a wrapper that helps prevent memory leaks.
4/ Windows does have finite GDI space, and you will find that unless you are careful handling all these pens and deleting them properly you will find your system will go down. I strongly recommend running the resource meter while you work on this code. This is also why I would not recommend pre-creating your pens in memory.
5/ The other option if you feel so strongly about it is to grab a DIBSection wrapper to help you get access to the bits and set the pixel data yourself. No CPens or HANDLEs needed, just an implimentation of the Bresenham algorithm, which is pretty simple stuff.
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
You could try using GDI+, its in beta 2 and not too long before is public release.
It requires only 1 DLL to be deployed with your application.
It is supported on all operating systems apart from Win95.
You'll coverage in Februarys 2001 Platform SDK.
I've started implementing GDI+ in my commercial applications which are due out in last quarter 2001, thats how much faith I have in GDI+.
Hope this helps
Norm
|
|
|
|
|
Is it "must pay"?
Where it can be obtained and how it can be used in my application?
Thanks.
-Mato
|
|
|
|
|
Nope, you can redistribute free of charge.
heres a snippet of GDI+
Pen blackPen(Color(255, 0, 0, 0), 5);
graphics.DrawRectangle(&blackPen, 10, 10, 100, 50);
See Christian Graus's article on GDI+, they should tell you everything need to know to get started.
|
|
|
|
|
Why not create all pens you will use in advance and save them in an array ? Then all you have to do is select the one you want to draw with and use it. This will be much faster than continual create/select/draw/deletes.
The absolute fastest way to go is to use PolyLine but that is limited to connected lines of one color. If each function's line was limited to one color this would work very well. I once wrote a spirograph program with hundreds of lines and PolyLine was so fast I could not even see them drawn.
|
|
|
|
|
Thousands of pens would be hard to track individual colors of ( unless you did them in a 3 dimensional array or used the RGB marco to generate indices ), and would also be an unreasonable hit on GDI resources IMHO.
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
Thousands would be but I seriously doubt he deals with thousands of pens.
|
|
|
|
|
I have to draw number (thousands) of lines and every line must be drawn in different color
I don't get it, but that's what he said.
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
No doubt!
Color is (or may be) function of x. It is only for effect.
|
|
|
|
|
Mato-
Pls post the code that you think is inefficient..
Some tips'
1. Dont use CPen, use a HPEN directly using CreatePen
2. Cache all the HPENs you need in an internal data structure.
3. If you Must use a CPen object, create it as a member variable and then
Attach and Detach a HPEN from the cache.
4. Dont worry there is very minimum overhead for CreatePen. I have seen folks work with many thousands of pens, brushes, with very little visual performance impact.
Finally as Christian pointed out, use a Bitmap if you want to take matters into your own hands...
Again, lets see some code that you thnk is slow..
vivek
|
|
|
|
|
I think there is no need to post the code. I will use the "create delete" approach with direct API calls. At last you convinced me. Thanks for the ideas and effort.
-Mato
|
|
|
|
|
Hi,
I have a SDI application, and i like to change it to MDI.
1- is it possible?
2- what is the easiest way?
3- will my program work in MDI the same way as it works in SDI?
Thanks
Ehsan
Ehsan Behboudi
|
|
|
|
|
Does any one know how to program in VC++ " For sending and receiving a Message as Short Message Service(SMS)through local PC connected with Mobile Phone to another remote PC connected with Mobile Phone" using SMS Gateway?
Please refer http://www.winsms.com for SMS Gateway.
a sample code would be great!
Thanks!
Best Regards
Nagajothi
|
|
|
|
|
How do you make to convert html files to rtf format?
Thanks
|
|
|
|
|
When working through the DAOEnroll tutorial I came across something odd: The text says I should add a combo box and add a member variable to it using ClassWizard. I'm supposed to accept the default value (which should be m_pSet->m_CourseID but is only m_) but this is not correct and I'm not allowed to enter the correct value either. After some experimenting i found that everything works fine if I change the type of the combo box from the suggested "drop list" to something else (i.e "Simple" or "Dropdown"). Is there a bug or is it just me?
ps. The default value ClassWizard generates is based on the tab order of the controls, I'm not doing anything wrong there I'm sure.
Is DAO alive and kicking btw.? ADO seems to be the way to go but our app will only need very simple database support so I reckon DAO (with MFC support) will do the job.
/Erik
|
|
|
|