Oh the agony of SetPixel()! I used it too, back when I did not know any better. It took about 1200 clock cycles to plot one pixel!
Like it was mentioned above, you need to call CreateDIBSection() to create a bitmap object. CreateDIBSection() allocates a one dimensional array to hold the image data. In the following code samples below, I have created my own structures that have more meaningful attribute names. You should be able to figure out what the official attribute names are. Also, the variable ImageData points to an array of unsigned ints.
where DeviceContextHandle is the device context handle returned by the call to CreateCompatibleDC(). I am using the BeginPaint() and EndPaint() functions so that the entire bitmap does not have to be copied for each paint event. Only the portion of the bitmap needed to redraw the client area is copied. Note that I am not using MFC, so the window handle has to be explicitly passed to the GetDC(), BeginPaint(), and EndPaint() Windows API functions. SaraswathiSrinath, you are passing the correct source device context handle in your call to BitBlt(), so maybe you caught my error.
Now about your code ... You should be creating the bitmap object and compatible device context in the window's create event, not in the paint event. You only want to create the bitmap object once. The paint event happens every time the window's client area needs to be redrawn, such as when another window is moved over the top of it. The code to fill the bitmap should be elsewhere as well. In your example, it should probably be in the window's create event after the bitmap object is created. The bitmap handle, the compatible device context handle, and the pointer to the image data will need to be stored in static variables so that their values are retained between events. The compatible device context and the bitmap object should be deleted in the window's destroy event. The image data memory will automatically be released when the bitmap object is deleted. Also, writing files from the paint event is a bad idea since the paint event occurs many, many times.
I have always used displays with 24-bit color. I do not understand why you are using 32 bits per pixel. 8-bit color requires a color palette, but that is probably not the route you want to take for modern graphic cards. Your code assigns the same value to the red, green, and blue components of the pixels, which is the right way to get gray.
The image data is stored as a series of horizontal rows. Each row contains 3 bytes per pixel, plus up to 3 unused bytes in order to make the number of bytes in a row a multiple of 4. Your variable pitch would be the number of bytes it takes to store one row of the bitmap, though you are using 32 bits per pixel instead of 24. The first byte of each pixel is the blue component. The second byte is the green component. The third byte is the red component. If you were to look inside a bitmap image file, the image data would appear exactly as it does in the image data array.
The bitmap object handle and the compatible device context handle need to be stored such that their values are retained after the window's create event is done. I have never used MFC, but apparently it splits the window's events into separate functions. This prohibits the use of local static variables to store information needed by multiple events. Perhaps, you could make the bitmap object handle and compatible device context handle into class variables. As a very last resort, you could make them global variables.
I played around with creating a color palette for a bitmap that uses 8 bits per pixel. The following code listing is a complete test application. I am not using MFC.
Since Windows is event driven, there needs to be an event that occurs periodically in order for the display to be updated with new data. This event could be a timer event. You start a timer by calling SetTimer(), perhaps in the create event code, and stop the timer by calling KillTimer(), perhaps in the destroy event code. It is within the code that handles the timer event that you want to sample the incoming data and redraw the image accordingly. After the image has been redrawn, call InvalidateRect(). This will put a paint message on the window's event queue. The code in the paint event then calls BitBlt() to update the display. To repaint the display immediately, call UpdateWindow() after the call to InvalidateRect(). Make sure to use BeginPaint() and EndPaint() in the code for the paint event. Otherwise, the paint event will be invoked endlessly.
// The image should not be redrawn in the paint event.
// The display just gets updated with the current image.
BitBlt(Paint.hdc, Paint.rcPaint.left, Paint.rcPaint.top,
Paint.rcPaint.right - Paint.rcPaint.left, Paint.rcPaint.bottom - Paint.rcPaint.top,
CompatibleDeviceContextHandle, Paint.rcPaint.left, Paint.rcPaint.top, SRCCOPY);
// < code to sample the incoming data and redraw the image >
// Update the entire client area.
InvalidateRect(WindowHandle, NULL, false);