• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 406
  • Last Modified:

filling a dc manually

void CMainWindow::OnPaint()
      CPaintDC dc(this);
      char buf[8] = { 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF};

      CDC dcMem;

      dc.BitBlt( 10,10,10,10, &buf, 0, 0, SRCCOPY);

// how would i get above call to work properly ?
// is there a way to fill a dc manually ?

  • 9
  • 5
  • 3
  • +1
1 Solution
I don't know what you mean by "fill a dc manually"

but if you want to BitBlt a bitmap into an image, you have to create a source bitmap and select it into a source DC and then BitBlt () the source bitmap into the DC.

example follows.
Here is a prepared answer
You can copy a bitmap, or a portion of a bitmap between two compaible DC's using BitBlt.  So to copy a bitmap to the screen you need to create a DC that is compatible with the screen and copy the source bitmap from it to the screen.

First you need to have a Source DC, this is a memory DC for the source bitmap, that is the image to be copied to the display.  This DC must be compatible with the source bitmap and (since the source bitmap is compatible with the display) also compatible with the display.  You can use

HDC SrcDC = CreateCompatibleDC(DspDC);

to create a memory DC (SrcDC) that is compatible with the display DC (DspDC).  (The display DC may be a window's DC or a DC for the screen (display) obtaned with CreateDC().)

Next you need to select the source bitmap into the source DC.  Now this works like selecting any other tool, you must save the previous tool so you can select it back in before the DC is returned to the OS.  So you would do

HBITMAP OldSrcBmp = SelectObject(SrcDC,SrcBmp);

Now the memory DC contains the bitmap to be copied.  You can copy the source DC's image to the destination DC using BitBlt().

Next you need to clean up.  You do this by selecting the original bitmap back into the memory DC and then deleting the DC.  Like

That does not uise MFC, but the changes needed to use MFC should be obvious.  Let me know if you have any questions.
jabes012399Author Commented:

i was hoping for a simpler answer
possibly along these lines:

void CMainWindow::OnPaint()
 CPaintDC dc(this);
char buf[8] = {... some data ..};

 CDC dcMem;

memcpy( dc, buf, 8 );

dc.BitBlt( 10,10,10,10, &dc, 0, 0, SRCCOPY);


this is what i mean by manually.
i would like to poke values into the dc
via memcpy or another simple call      

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

Well you can do that. You need to know a lot of unpublished information about the formats of bitmaps, DCs etc.  You probably will need to use verious tehcniques to get access to protected memory (forget that in NT) etc..

In the end (many months) you might have a solution that works just as well as what windows has provided for you.

Is there some reason you don't want to do this the "accepted" way.
jabes012399Author Commented:
Adjusted points from 93 to 200
jabes012399Author Commented:

well, i'm trying to avoid many months of trying to do it the  "accepted" way

seem's to me it would be a lot simpler to:

1) allocate memory for data.
2) fill data.
3) copy data to screen(application window).

i've visited code guru and all the bitmap stuff
is overwhelming.

i find your explanation regarding bitmaps and dc's confusing as well

i am rejecting your answer in hopes someone
has found a way around the "accepted" way.

more info:

i will be filling the data with unsigned char
hex values to produce a black and white image
0xFF = eight white pixels
0x00 = eight black pixels
0xAA = alternating black and white pixels

>> 3) copy data to screen(application window).
Where are you going to copy it to?  the destination might be in RAM, but if so won't be in your address space.  More likely it isn't even in RAM.  i could be video memory on a video adapter card, that means the data has to be sent across the bus.  it could be memory in a printer, that means the data has to be sent out a com port, it could be....

how what format do you want to copy it to?  The format depends on the device and its manufacturer and its driver.  How do you know what forma to use?

>> i'm trying to avoid many months of
>> trying to do it the  "accepted" way
It shouldn't tke months.  Trying to do it yourself will be somewhere between nearly impossible and impossible.  The OS not only doesn't make it easy, it trieds to make it impossible.  If you don't have the expertiose to copy a bitmap to a DC, I doubt you can break windows NT security in a reliable way.  And if you do succeed, what happens when the security changes, a new device driver is developend a new piece of hardware is used etc etc etc.   All those months or years of work will be wasted.

>>  am rejecting your answer in hopes someone
>> has found a way around the "accepted" way.
There are plenty of alternatives, I just suggested the only reasonable one.

But you could use DOS instead of windows.  You could write your own GUI to be sued from DOS.   Or you could use DirectDraw which would really have no advantage over the API, it certainly isn't simpler.

>>  will be filling the data with unsigned char
>> hex values to produce a black and white image
>> 0xFF = eight white pixels
>> 0x00 = eight black pixels
>> 0xAA = alternating black and white pixels
That is easy enough to do with the windows API.

You create a monochrom bitmap with CreateBitmap() using a pointer to a data buffer that contains these values for the pixels.  Then you select that bitmap into a memory DC and BitBlt() it to the screen.   Were are talking about maybe 10 API calls and 10 minutes of programming and 20 minutes of debugging.  Or you can rewrite windows....
Why don't you use CDC::SetPixel Funcion ?
You can paint dc manually but must write a little code than memcpy() which i think you can not do it because DC prevent us from direct access to Video memory like Dos you have to do the DC's way and if you use this solution you have to be sure about color value you will paint on that pixel

or if you do want to take it manually you can use directx the directdraw object allow us to write to vram directly ( direct is the key for DirectX ;)

SetPixel() is fine for setting a very small number of pixels.  When setting large numbers of pixels the overhead is tremendous.  (like by more than 2 orders of magnitude.  i.e a BitBlt() that takes 1/10th of a second would take more than 10 seconds with SetPixel().  If you want to use an algorithm that sets individual pixels, you can use directdraw,  That will be substrancially faster than SetPixel(), but still much slower than setting them al at once.
I think you can memcpy in directdraw ,either

nils pipenbrinckCommented:
ok.. a simple way to display graphics using win32 api is to create a dib and use the gdi functions to blit the stuff.

Here is a code I used some while ago (I'm now using ddraw, but it still works, and it's not that slow as you might expect it to be).

first I create a BitmapInfoHeader structure which describes my virtual bitmap: I use a 24 Bit per pixel truecolor bitmap because it can be converted fast to any other bitdepth.

Please take a look at the biHeight member. I'm passing a negative value to it. This is a trick which tells gdi that my bitmap is a topdown bitmap (e.g. the first pixel is the upper left, not the lower left). That made it easier for me to calculate the pixels.. (you can change that if you want..)


    int bisize = sizeof( BITMAPINFOHEADER );
    bitmapinfo = (BITMAPINFO *)malloc( bisize + 12 );
    ZeroMemory( &bitmapinfo->bmiHeader, bisize );

    // BitmapInfoHeader eines normalen 16 Bit Bitmaps
    // wie wir es brauchen erzeugen
    bitmapinfo->bmiHeader.biSize        = bisize;
    bitmapinfo->bmiHeader.biWidth       = 256;
    bitmapinfo->bmiHeader.biHeight      = -256;
    bitmapinfo->bmiHeader.biPlanes      = 1;
    bitmapinfo->bmiHeader.biBitCount    = 24;
    bitmapinfo->bmiHeader.biCompression = BI_BITFIELDS;
    *((long*) bitmapinfo->bmiColors +0) = 0x0FF0000;
    *((long*) bitmapinfo->bmiColors +1) = 0x00FF00;
    *((long*) bitmapinfo->bmiColors +2) = 0x00FF;

Now as you created your bitmapinfoheader you can create a virtual buffer which holds the pixels of yuor bitmap. I used a 256x256 bitmap, but you can of cause change that to your needs:

unsigned char * buffer = new unsigned char [256*256*3];

fill a funny pattern into the bitmap.. here is the place where you can put anything in the buffer you want to:

// this code makes a blue scale going from left to right and filling the bitmap with a black to blue gradient.

for (int i=0; i<256*256*3; i++)
  buffer[i] =  (i&255);

Now - as you prepared your bitmap you can wait until you are in your Paint message handler.

If you're there you can simply call SetDiBitsToDevice or StrechDiBits to display the dib.

Here i fill the entire client window of the screen with the bitmap:

HDC Dc; // the dc must be requested from win32.. I don't know how this  works under mfc, but I'm sure you'll know how to get it...
GetClientRect( WindowHandle, &r );
StretchDIBits( Dc, 0, 0, r.right, r.bottom, 0, 0,256, 256, (void *) buffer ,bitmapinfo, DIB_RGB_COLORS, SRCCOPY );

That's all I think.. Hope it helps.

btw. you can reuse the buffer and the BitmapInfoHeader as often as you want.. Whenever you changed your buffer content make sure that the window will be repainted.

Hope this helps,

  NIls Pipenbrínck


nils pipenbrinckCommented:
btw.. forget about the german comment in the code.. it's not valid anymore.. I just forgot to delete it.
nils, I already suggested using the windows API.  He rejected that!
nils pipenbrinckCommented:

Hm.. sounds funny.. how else should he access pixels on the screen in a compatible way?

I think one could hack itself into the gdi, but this is incompatible and I don't think it'll be any bit faster..

jabes012399Author Commented:
nils -

thanks for code but could not get it to go.

nietod -

i figured it out finally.
following your advice.
2 days is better than 2 months.
how do you get your points now ?

actually i'd like to split the points with you and nils
since he was nice enough to send some code
and enthusiasm.

how does one go about that ?
i don't want to step on anyone's toes . . . .

teerawatw  -  sorry. but setpixel painfully slow

Actually, I did post code, only it is "annotated" to explain what it is doing.

As for splitting points--there is no feature for this.   Here is another preprepared answer on that
There is no way to split points between experts.   You must choose the expert that you feel contributed the most and ask them to submit an answer (if they have not).  

If you feel two or more experts really deserve the credit you have two choices.  

First, if you have sufficient points and are feeling very generous, you can ask one expert to submit an answer to the current question, then ask additional "Dummy" questions for the other expert(s) to answer.  

Second, you can post a request at the EE customer service topic are that the points for the question be reduced or that you be given additional points in order to ask "dummy" question(s) for the other expert(s).  This should only be done in extreme cases as the customer service people are quite busy.

If you do ask dummy questions, post a comment on this message to let the experts know to look for the questions.  Also be sure to include the expert's name in the question so that other expert know what the question is for.  i.e. give the question a title like "Points for XXXXXXX"
jabes, what is happening to this question?
jabes012399Author Commented:
nietod -

collect your points.

i posted a question

entitled :

points for nietod

I see it, I'll answer it if you thought my "work" here was worth it.

I am curious to know what is happenign with this question though.  What did you decide to do?
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

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.

  • 9
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now