|
I'm having a problem with memory device contexts and bitmaps in MFC. I've gotten to the point to where I can create and use them, but natrually they are all in black in white. See here:
http://img.photobucket.com/albums/v50/blackdwarf/piegraphcontrol.jpg[^]
With a CreateCompatibleDC(NULL) call, a monochrome bitmap gets created for and selected into the CDC. When I actually create my bitmap based off of that CDC, I'm stuck with the monochrome. So my question is, how do I initialize the bitmaps with color outside of OnPaint when I can't just use CPaintDC?
Here is some of the code...
Creating the two bitmaps without a CPaintDC (where I think the problem is):
BOOL CPieGraph::Create(CWnd* pParentWnd, const RECT& rect, UINT nID, DWORD dwStyle )
{
BOOL OverallSuccess = FALSE;
BOOL CreateResult = FALSE,
TextDCResult = FALSE,
PieDCResult = FALSE;
int SelectText = 0, SelectPie = 0;
CreateResult = CWnd::Create(CPIEGRAPH_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
TextDCResult = TextMemDC.CreateCompatibleDC(NULL);
PieDCResult = PieMemDC.CreateCompatibleDC(NULL);
SelectText = m_textBitmap.CreateCompatibleBitmap(&TextMemDC, 250, 20);
SelectPie = m_pieBitmap.CreateCompatibleBitmap(&PieMemDC, 300, 300);
OldtextBitmap = TextMemDC.SelectObject(&m_textBitmap);
OldpieBitmap = PieMemDC.SelectObject(&m_pieBitmap);
TextMemDC.SetBkColor(RGB(255,255,255));
PieMemDC.SetBkColor(RGB(255,255,255));
if((CreateResult == TRUE) && (TextDCResult == TRUE) && (PieDCResult == TRUE) && (SelectText != 0) && (SelectPie != 0))
{
OverallSuccess = TRUE;
ControlRect = rect;
}
else
OverallSuccess = FALSE;
return OverallSuccess;
}
And OnPaintDC:
afx_msg void CPieGraph::OnPaint()
{
CPaintDC dc(this);
CDC ControlMemDC;
CBitmap ControlBitmap;
CBitmap* OldBitmap = NULL;
ControlMemDC.CreateCompatibleDC(&dc);
ControlBitmap.CreateCompatibleBitmap(&ControlMemDC, 300, 360);
OldBitmap = ControlMemDC.SelectObject(&ControlBitmap);
ControlMemDC.SetBkColor(RGB(255,255,255));
if(UpdateNeeded == true)
{
RedrawPieText(TextMemDC);
RedrawPieChart(PieMemDC);
ControlMemDC.BitBlt(0, 0, 250, 20, &TextMemDC, 0, 0, SRCCOPY);
ControlMemDC.BitBlt(0, 25, MainPieGraph.radius * 2,
MainPieGraph.radius * 2, &PieMemDC, 0, 0, SRCCOPY);
UpdateNeeded = true;
}
dc.BitBlt(ControlRect.left, ControlRect.top, 250, 320, &ControlMemDC, 0, 0, SRCCOPY);
ControlMemDC.SelectObject(OldBitmap);
}
|
|
|
|
|
Don't know an awfull lot about the issues, but it appears to be at first sight to be a problem about loss of information.It would appear to me that you first create a monochrome bitmap from a source, which you select into the CDC. At that stage the Die is cast as far as the CDC is concerned. The Monochrome bitmap is all it knows about. The CDC has built a Monochrome picture which it knows your Device can display. All Colour Info has been discarded. If at a later stage you want the Bitmap in colour, you have to start again from scratch in the same or another CDC, This time indicating yont to keep the colour. Mind you,to do so you could recycle most of the code. Just leave an indication somewhere about what way you want it, Monocrome or Colour. A Device Context is a Uniform Construct that Converts things like bitmaps etc into something your Hardware can display. (That's the way device-independence is Implemented).
Hope this is Usefull.
LateNightsInNewry
|
|
|
|
|
To add to LateNightsInNewry's reply...
To fix it...
When you call CreateCompatibleBitmap(), you should use the screen or paint DC, not the memory
DC. The memory DC you created with CreateCompatibleDC() is the one with a monochrome bitmap
selected into it. If you create a bitmap compatible with that, it will also be monochrome.
Outside of OnPaint, you can get a screen DC with
::GetDC(0)
or something like
CDC ScreenDC;
ScreenDC.CreateCompatibleDC(0);
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Thanks, both of you. I think it'll work. I'll try it tommorow when I wake up.
|
|
|
|
|
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Actually I just got a cup about 30 minutes ago. Unfortunatly, the problem still remains. I tried using GetDC:
CDC* ScreenDC = NULL;
CreateResult = CWnd::Create(CPIEGRAPH_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
TextDCResult = TextMemDC.CreateCompatibleDC(NULL);
PieDCResult = PieMemDC.CreateCompatibleDC(NULL);
ScreenDC = GetDC();
ASSERT(ScreenDC == NULL);
SelectText = m_textBitmap.CreateCompatibleBitmap(ScreenDC, 250, 20);
SelectPie = m_pieBitmap.CreateCompatibleBitmap(ScreenDC, 300, 300);
ReleaseDC(ScreenDC);
At first the assert statement wasn't in there and I just got black and white, then I put it in and I got a debug assertation on the same line, indicating that ScreenDC was null, and that GetDC didn't do the job. Any idea why?
|
|
|
|
|
Well the assert statement was wrong...it should have been ASSERT(ScreenDC != NULL), but it is still not rendering color for some reason. Fonts, brushes, and pens work fine, just not color.
|
|
|
|
|
CoffeeAddict19 wrote: but it is still not rendering color for some reason.
Hopefully my modified post below will help
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
CoffeeAddict19 wrote: indicating that ScreenDC was null
Is Create() failing? Never mind, I see you fixed the ASSERT
I steered you wrong with the CreateCompatibleDC, sorry
*EDIT* I DID show you a way to do what you were already doing though :)
This should work from anywhere:
CWindowDC ScreenDC(0);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&ScreenDC, 20, 20);
BITMAP bitmapstruct;
bitmap.GetObject(sizeof(BITMAP), &bitmapstruct);
You'll see in the BITMAP struct, the format matches the screen format.
Try this:
CreateResult = CWnd::Create(CPIEGRAPH_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID);
CWindowDC ScreenDC(0);
TextDCResult = TextMemDC.CreateCompatibleDC(&ScreenDC);
PieDCResult = PieMemDC.CreateCompatibleDC(&ScreenDC);
SelectText = m_textBitmap.CreateCompatibleBitmap(&ScreenDC, 250, 20);
SelectPie = m_pieBitmap.CreateCompatibleBitmap(&ScreenDC, 300, 300);
Mark
-- modified at 14:54 Thursday 31st May, 2007
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
|
mmmm Pie! Cool!
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi all:
I declared a variable of map type as below:
typedef vector<streampos> OccurrenceList;<br />
map<string, OccurrenceList> table;
I just do not know how to "insert" a new instance of map into this list.
Normally, I will use:
table.insert(make_pair(a_new_string, a_new_something); //a_new_something is only a variable of simpler type, like a int.
Can anyone help?
Thank you
|
|
|
|
|
typedef vector <<streampos>> OccurrenceList;
map <<string, occurrencelist="">> table;
|
|
|
|
|
<br />
typedef vector <<streampos>>OccurrenceList;<br />
map <<string, OccurrenceList>> table;<br />
new instance can be inserted into the map of simpler/complex type
if the necessary operators are implemented for that type.
<br />
OccurrenceList list;<br />
list.push_back(somedata);
table.insert(make_pair("a_new_string", list); <br />
this will work. note: map stores a new copy of "list"
|
|
|
|
|
|
I have a media player from microsoft playing a file.
When the player plays the file a graph is produced.
What additiionally I wanted was to get some code to connect to the microsoft media players
graph and a add some filter and configure the filters.
BEST REGARDS
|
|
|
|
|
I don't have a solution for you but I bet if/how it can be done can be found in the Windows
Media Player SDK which can be found here[^].
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I have a media player from microsoft playing a file.
When the player plays the file a graph is produced.
What additiionally I wanted was to get some code to connect to the microsoft media players
graph and a add some filter and configure the filters.
BEST REGARDS
|
|
|
|
|
Hi All,
Does the Windows API provide a function which allows one to monitor a chunk of memory for modifications (similar to watching a directory for changes using FindFirstChangeNotification())?
Jeff
microsoft.public.vc.mfc received one response with, 'What are you trying to do'? Monitor Memory for Alteration[^]
microsoft.public.win32.programmer.kernel received no responses. Monitor Memory for Alterations[^]
|
|
|
|
|
You can do this with the VS Debugger, i.e. set a memory breakpoint but only one and only monitoring 4 bytes. That's because it uses an internal feature of Intel architecture compatible processors to achieve this at a very low level. I guess it's probably an interrupt or something. I don't know of any other way if you want to be certain of catching changes as they happen.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Hi Matthew,
Matthew Faithfull wrote: You can do this with the VS Debugger
My bad - I want to do it from a Userland program - no debugger required.
BTW, I did try and think how we could do it by acting as if we were a debugger - but I don't think vanilla userland programs (i.e., not running under privlidged accounts) will allow it.
Jeff
|
|
|
|
|
I'm not sure about Vista but on previous Windows versions at least the VS Debugger is pretty much a vanilla userland program.
If I remember rightly the code to set up a memory watch style breakpoint is in John Robbins book 'Debugging Applications' which is a great book, worth a read anyway if you haven't already. I can't be sure the technique would work from 'ordinary' code but it may and if a switch to Kernel mode is required I'm sure Robbins explains how to do it. I think the book code is downloadable if you give it search
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Hi Matthew,
Matthew Faithfull wrote: I think the book code is downloadable
I have the book in my collection - John and I bounce emails every now and again. As busy as he is, he will respond to questions.
Anyway, I reworked the section and added some other information on 'what does not work'. In addition, I cited you (I hope you don't mind). See the section entitled, 'Polling Versus Notification'.
Jeff
|
|
|
|
|
Hi I'm looking to change the format of my internal classes to clean up my code but I can't get the syntax right.
I have
class A
{
class B
{
}
B b;
};
I would like to change it to something where class B is defined outside. ie.
class A;
class A::B
{
};
class A
{
B b;
};
The above code doesn't seem to compile. Anyone know how to do this?
|
|
|
|
|
Do you mean like this?
class B
{
};
class A
{
B b;
};
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|