|
Take a look into the last sentence in my signature
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
|
|
|
|
|
I totally disagree =)
Otherwise, how would I learn?
best regards
|
|
|
|
|
I have a memory backed DC that I've drawn to.
I was trying to use InvertRgn on it and it dawned on me that Raster operations will only work on a physical device or at least that's what seems correct at the moment. Is there a way to invert a region on a memory backed DC before it's blitted onto the screen?
|
|
|
|
|
I would expect InvertRgn to work on a memory DC.
Have you tried it? If so, is it not working?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Maybe I'm doing something wrong. I'll give it another go. I may have given up too easily...
|
|
|
|
|
It works fine...here's a little test, a strange mix of MFC and native code...
CImage img;
img.Create(320,240,24); <font color="Green">
HDC hmemdc = img.GetDC(); <font color="Green">
HRGN rgn = ::CreateRectRgn(20,20,100,100);
::InvertRgn(hmemdc, rgn);
::DeleteObject(rgn);
CClientDC windowdc(this); <font color="Green">
::BitBlt(windowdc, 10, 10, 320, 240, hmemdc, 0, 0, SRCCOPY); <font color="Green">
img.ReleaseDC(); Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
That worked so I'm just fudging something up in my mess here.
I'm mixing GDI mappping modes, memory backed DC's, GDI+ graphics objects, and somewhere in the midst of the drawing I'm plopping a quick detour...
HDC hdc=graphics.GetHDC();
// detour to use ::InvertRgn
graphics.ReleaseHDC(hdc);
I'm using a region handle form a GDI+ region so I'll dig through it and I'm sure the culprit is in there somewhere.
Thanks for your help and guidance and quick proof of concept. It is much appreciated.
|
|
|
|
|
Turns out when I called...
HDC hdc=graphics.GetHDC();
my metrics got all messed up and my region was showing up teeny tiny. If I used the original handle to the DC that I created the graphics object off of, everything is just fine.
(Just gotta be careful about mixing my calls between the two)
I think I'm doing something unorthodox mixing GDI and GDI+ in the first place so it serves me right.
Anyway thanks again for taking the time to set me straight.
|
|
|
|
|
bob16972 wrote: I think I'm doing something unorthodox mixing GDI and GDI+
Calling a GDI+ method on a Graphics object you've obtained an HDC for is bad.
Also, as you've seen, make no assumptions about DC settings - save/set/restore
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
<blockquote class="FQ"><div class="FQA">Mark Salsbery wrote:</div>Calling a GDI+ method on a Graphics object you've obtained an HDC for is bad.</blockquote>
Yeah, I know. I've been careful not to cross the two. I'm just mainly using the GDI mapping mode stuff and MFC behind my Graphics objects. I still need to work on the approach a bit but you helped me identify what was going awry.
However, just for kicks, this sample is directly from MSDN (Visual Studio 2003) for GDI+ Region::GetHRGN. It uses the HDC before the graphics object goes out of scope. (Shame on them);)
VOID Example_GetHRGN(HDC hdc)
{
Graphics graphics(hdc);
Point points[] = {
Point(110, 20),
Point(120, 30),
Point(100, 60),
Point(120, 70),
Point(150, 60),
Point(140, 10)};
GraphicsPath path;
path.AddClosedCurve(points, 6);
// Create a region from a path.
Region pathRegion(&path);
// Get a handle to a GDI region.
HRGN hRegion;
hRegion = pathRegion.GetHRGN(&graphics);
// Use GDI to display the region.
HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 0));
FillRgn(hdc, hRegion, hBrush);
DeleteObject(hBrush);
DeleteObject(hRegion);
}
|
|
|
|
|
bob16972 wrote: It uses the HDC before the graphics object goes out of scope. (Shame on them);)
That MAY actually be OK, since the Graphics object is wrapping an already-existing
HDC. The only thing the docs state about that situation is:
"When you use this constructor to create a Graphics object, make sure that the Graphics
object is deleted or goes out of scope before the device context is released."
The other situation, getting an HDC from a Graphics object with Graphics::GetHDC() is more
restrictive:
"Do not call any methods of the Graphics object between the calls to GetHDC and ReleaseHDC."
I'm not sure how the Graphics class deals with HDCs internally, but I imagine when you pass an
already-created HDC into the Graphics class constructor, it just uses the DC you pass in - the
creator still "owns" the DC.
If you let the Graphics class create its own DC, however, it "owns" the DC, and the DC it gives
you through GetHDC may be a temporary copy.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: "Do not call any methods of the Graphics object between the calls to GetHDC and ReleaseHDC."
This I've seen and try to protect against.
Mark Salsbery wrote: If you let the Graphics class create its own DC, however, it "owns" the DC, and the DC it gives
you through GetHDC may be a temporary copy.
This would make sense as to why the original warning above even exists if I'm understanding you correctly. Are you saying the warning would revolve around the possibility that the HDC did not exist before the Graphics object came to life? I'm taking it to mean that if I provide the HDC to the constructor for a graphics object, I need not bother with Graphics::GetHDC() ?
|
|
|
|
|
bob16972 wrote: I'm taking it to mean that if I provide the HDC to the constructor for a graphics object, I need not bother with Graphics::GetHDC() ?
Definitely! GetHDC() may pass you back the same HDC, it may give you a temporary one.
I'd like to see the GDI+ source code to see what it does with HDCs.
I'd say it's much more flexible to start with your own HDC and wrap it with a Graphics object when you
need to do some GDI+ stuff on it. Of course, if you're just using GDI+, this doesn't apply.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Cool. Thanks for the help.
I'd email you an egg McMuffin if I could.
|
|
|
|
|
bob16972 wrote: I'd email you an egg McMuffin if I could.
Heh. I'd eat it if you could!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
*scratches head*
In c++ how do you load in a class library? And more to the point, can i load a DLL made with C#?
I am using OpenGL and the GLUT library, so i've never needed to waste time setting up windows and other such like. I thought, maybe if i just make a couple of things in C# put it into a dll then load it up.
Currently the project is just c++, there's no .Net framework involved. So err, any articles on the subject would be great. Although i suppose i could settle with just a working code snippet
I'm also using MS VC++ 6, if that relevant at all.
My current favourite word is: PIE!
I have changed my name to my regular internet alias. But don't let the 'Genius' part fool you, you don't know what 'SK' stands for.
-The Undefeated
|
|
|
|
|
I'm not a C# programmer, but I'm pretty sure a C# DLL is a managed assembly.
To interface your C++ code with a managed assembly, you'll need to use C++
code compiled to CLR. That means you need VC .NET or VC 2005+.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Zoom...
What was that? It was Mark, replying super quick!
I guess i'll not bother then, It's not worth the time, or extra effort.
My current favourite word is: PIE!
I have changed my name to my regular internet alias. But don't let the 'Genius' part fool you, you don't know what 'SK' stands for.
-The Undefeated
|
|
|
|
|
is there a limit on the number of files we keep open simultaneously?
Tnx
Tzumer
|
|
|
|
|
It depends on what you're using to open the files and what OS you're on,
what resources are available at any given time, etc.
For CRT file I/O (stdio) see _setmaxstdio()[^]
For Win32 APIs (CreateFile), I would guess thousands - try it.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
If you have to ask that question you've probably got a dubious design.
Steve
|
|
|
|
|
I have a template function that returns a variable of type T.
Here is the signature of that function:
T GetData();
When everything goes well, GetData() perform some tasks then returns a valid variable of type T.
Sometimes, for different reasons, the function cannot return a valid variable of type T. In these cases, I would have like to return NULL to notify the calling function that GetData() could not 'get' any 'data'.
Here is my problem:
I cannot return NULL since type T could be a int, a CString, a MyCar, a pointer or anything.
So I declare a local variable of type T inside the GetData() function, load it with stuff when possible, and return this local variable at the end of the function.
The problem is now that sometimes, my software crash with an exception telling me that I'm using a local variable that has not been initialized.
Also, I cannot just 'initialize' it as I would with any other kind of variables since this one is of type T, it could be anything.
Anyone has an idea how to get around this problem?
Thanks!
Benjamin Racette
CAE software developer
racette@cae.com
|
|
|
|
|
Throwing an exception ? That will avoid a lot of troubles I think.
|
|
|
|
|
Cedric Moonen wrote: Throwing an exception
That is pure genius!
Of course!
I can't believe I didn't think about it.
Thanks a lot!
Benjamin Racette
CAE software developer
racette@cae.com
|
|
|
|
|
Hello,
does anyone has any idea to get current url from firefox?
thanks
|
|
|
|