|
Alan Balkany wrote: CDC *mdc=new CDC ();
HGDIOBJ tmp = mdc->SelectObject(bm);
- do you create the DC anywhere or you just instantiate it? You need to create the DC, a CDC instance alone isn't enough. Where does bm come from? Acording to what you said bm would be a local variable in the constructor, so how would it get to OnDraw?
About the RGBQUAD thing:
Alan Balkany wrote: RGBQUAD bmiColors[1];
this means that an array of RGBQUADs containing a variable number of colors will follow directly the BITMAPINFO structure. I think the biClrUsed member would indicate this in the struct (see the documentation for the structure).
You have to allocate enough memory to contain the bitmap info struct AND the palette after it, you can set the members in the palette -if you like- thorough the bmiColors array. Something like:
BITMAPINFO *bmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);
...fill the bmiHeader ...
bmi->bmiCOlors[0] = firstColor;
bmi->bmiCOlors[1] = secondColor;
...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat, thanks for clearing up the mystery about bmiColors!
I just created a new DC because (it appears that) existing DCs will default to the color depth of my display. If this isn't correct, what's the right way to obtain a DC to draw on an 8bpp bitmap?
(The bitmap is actually declared in the class, and was just included in the constructor's code to show the type.)
|
|
|
|
|
I needed to do this some time ago and as far as i can remember i went the DIB section way myself, creating a palette that went from 0,0,0 to 255,255,255. If you create a screen-compatible DC and then select your bitmap into it i think you should be able to draw on it.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Thanks for the help, Code-o-mat! I can now generate bitmaps, but they're coming out incorrectly.
Short version: I created an 8bpp bitmap, then I BitBlt it to the screen and save it into a file. The copy on the screen has color, which suggests it's not just 8bpp. The version saved to the file is 8bpp, but it's totally black, where it should have at least *some* of the drawing.
Question: How can I draw on an 8bpp grayscale bitmap and save it to a file? Can anyone see what I'm doing wrong?
========================================================
The Details
Declarations:
CBitmap bm;
HBITMAP hbm;
BITMAPINFO* bi = (BITMAPINFO *)malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 256);
BITMAPINFOHEADER bih;
Constructor:
initBi ();
hbm = CreateDIBSection (hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
...
void CEightBitDrawingView::initBi()
{
bih.biSize = sizeof (BITMAPINFOHEADER);
bih.biWidth = 200;
bih.biHeight = -200;
bih.biPlanes = 1;
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 14173;
bih.biYPelsPerMeter = 14173;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
bi->bmiHeader = bih;
for (int i = 0; i < 256; i++)
{
bi->bmiColors [i].rgbRed = i;
bi->bmiColors [i].rgbGreen = i;
bi->bmiColors [i].rgbBlue = i;
}
}
OnDraw:
void CEightBitDrawingView::OnDraw(CDC* pDC)
{
CClientDC dc(this);
CDC *mdc = GetDC ();
HGDIOBJ tmp = mdc->SelectObject(hbm);
mdc->FloodFill (0, 0, RGB (255, 255, 255));
CBrush* br = new CBrush (RGB (255, 0, 255));
CRect rect (30, 60, 130, 160);
mdc->FillRect (&rect, br);
mdc->TextOutW (50, 50, L"Testing...");
CImage image;
image.Attach (hbm);
HRESULT hr = image.Save(_T("C:\\test.tif"), Gdiplus::ImageFormatTIFF);
GetClientRect(&rect);
dc.BitBlt(0,0,rect.right,rect.bottom, mdc, 0,0,SRCCOPY);
mdc->SelectObject (tmp);
delete br;
}
|
|
|
|
|
Am not sure where you are going wrong, i did a quick proggie to check and it produced a correct bitmap:
BITMAPINFO *bmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
BITMAPINFOHEADER &bih(bmi->bmiHeader);
bih.biSize = sizeof (BITMAPINFOHEADER);
bih.biWidth = 200;
bih.biHeight = -200;
bih.biPlanes = 1;
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 14173;
bih.biYPelsPerMeter = 14173;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
for (int I = 0; I < 255; I++)
{
bmi->bmiColors[I].rgbBlue = bmi->bmiColors[I].rgbGreen = bmi->bmiColors[I].rgbRed = (BYTE)I;
bmi->bmiColors[I].rgbReserved = 0;
}
void *Pixels;
HBITMAP hbmp = CreateDIBSection(NULL, bmi, DIB_RGB_COLORS, &Pixels, NULL, 0);
BYTE *Pix = (BYTE *)Pixels;
for (int Y = 0; Y < abs(bih.biHeight); Y++)
for (int X = 0; X < bih.biWidth; X++, Pix++)
*Pix = (BYTE)Y;
free(bmi);
CImage Image;
Image.Attach(hbmp);
Image.Save(_T("r:\\test.bmp"), Gdiplus::ImageFormatBMP);
DeleteObject(hbmp);
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I also added this:
HDC dc = ::GetDC(NULL);
HDC memdc = CreateCompatibleDC(dc);
::ReleaseDC(NULL, dc);
HGDIOBJ Ofont = ::SelectObject(memdc, GetStockObject(DEFAULT_GUI_FONT));
HGDIOBJ Obmp = ::SelectObject(memdc, hbmp);
::SetTextColor(memdc, RGB(128, 128, 128));
::SetBkColor(memdc, RGB(64, 64, 64));
::TextOutA(memdc, 2, 2, "Hello world", 11);
::SelectObject(memdc, Ofont);
::SelectObject(memdc, Obmp);
DeleteDC(dc);
between free(bmi); and CImage Image; , this works fine too, i get the text in grays.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Thanks again Code-o-mat! This gives me a lot to experiment with!
|
|
|
|
|
No probs, i hope it helps, good luck.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
It worked!! Thanks so much! A big 5 points for you! (I'd give you more if I could.)
|
|
|
|
|
Great , glad i could help, thanks for the points.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Ok I know this is a bit of a cheat but my UI is split into 3rds with the idea being I can hide the bits of the UI.
Now I can slice off the right hand side easily enough as follows.
...
CRect rect;
GetWindowRect(rect);
...
rect.right += CONSOLE_SIZE;
MoveWindow(rect, 1);
...
The problem I am having is how do I cut the dialog's window down so that only the middle 3rd is displayed? I have had a look at CRgn with the SetWindowRgn but I am getting nowhere.
Any suggestions would be appreciated.
Many thanks
Alan
|
|
|
|
|
You could try making your dialog a child of another dialog. You'd have a popup dialog and inside its client area a child dialog with its controls, thus you can shift this child dialog inside the popup's client area to show the part you wish.
On a sidenote: i don't know what kind of controls you have on your dialog, but if you use the keyboard, you can tab around controls even if they are not visible because they are "outside" of the visible client area. So if you tab onto a button you can press it by using SPACE even though you don't see it.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat wrote: ...but if you use the keyboard, you can tab around controls even if they are not visible...
Unless they are also disabled, then they get skipped over.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Of course...also if they are hidden by ShowWindow(SW_HIDE), my point was, just by "not being seen" doesn't mean "not there at all"
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I take your point but there are no input controls on the area being hidden.
Put simply, as a user of the system you only get to see the bits you have permission to see. All, Left+Middle or Right+Middle.
Alan
|
|
|
|
|
All right, just trying to help.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I find the easiest way to make such a dialog is to add a hidden 1x1 static control to the dialog where the expansion will take place. In your case, you'd need two. Then when the "shrink" button is clicked, you'd shrink the dialog's left and right edges up to those hidden controls. When the "expand" button is clicked, you'd grow the dialog's left and right edges back to their original position.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
hmmm... sounds a very messy way of cutting off the left hand edge.
The object is to show All, Left+Middle or Right+Middle.
Alan
|
|
|
|
|
Spawn@Melmac wrote: hmmm... sounds a very messy way of cutting off the left hand edge.
Not messy at all. In fact it is very clean and quite common to grow/shrink dialogs in this fashion.
Spawn@Melmac wrote: The object is to show All, Left+Middle or Right+Middle.
Even though you initially stated, "...how do I cut the dialog's window down so that only the middle 3rd is displayed", what I described will work just fine for all seven possibilities.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
I knew I had missed an option. Yes it is All, Left+Middle, Right+Middle or Middle.
Thank you for the suggestion.
Alan
|
|
|
|
|
Could it be easier to have a series of child dialogs to display/hide part of the main dialog and resize the main dialog accordingly ?
Watched code never compiles.
|
|
|
|
|
How to change the up and down arrow of DateTime Picker control. I hv created my own class which is derived from CDateTimeCtrl class. What I need is to change the look and fill of the control and also want to create the coontrol at run time.
Please help me how to work on that.
Thanks....
|
|
|
|
|
AbhiHcl wrote: How to change the up and down arrow of DateTime Picker control.
To what?
AbhiHcl wrote: What I need is to change the look and fill of the control...
To what?
AbhiHcl wrote: What I need is to...create the coontrol at run time.
Use the Create() method.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
I need to change the up and down arrow of the datetime picker control, I have to put some image there. and also need to some different color when any value is selected in the control.
|
|
|
|
|
AbhiHcl wrote: and also need to some different color when any value is selected in the control.
For this I'd look into WM_CTLCOLOR .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|