Click here to Skip to main content
15,917,795 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: How to create delay. Pin
Paul M Watt6-May-02 21:46
mentorPaul M Watt6-May-02 21:46 
GeneralRe: How to create delay. Pin
Chanda.com6-May-02 22:04
Chanda.com6-May-02 22:04 
GeneralRe: How to create delay. Pin
Sameer Maggon6-May-02 22:27
Sameer Maggon6-May-02 22:27 
GeneralTime Delay in rendering(DirectX) Pin
VCRamesh6-May-02 21:26
VCRamesh6-May-02 21:26 
GeneralRe: Time Delay in rendering(DirectX) Pin
Sameer Maggon7-May-02 0:06
Sameer Maggon7-May-02 0:06 
GeneralRe: Time Delay in rendering(DirectX) Pin
VCRamesh7-May-02 1:51
VCRamesh7-May-02 1:51 
Generalprinting bitmap problem Pin
BlackRider6-May-02 20:59
BlackRider6-May-02 20:59 
GeneralRe: printing bitmap problem Pin
Jonathan Craig7-May-02 5:33
Jonathan Craig7-May-02 5:33 
I have had the same problem trying to print CBitmap objects. DIBs work better for printing. Here is a code sniplet that I used to print a logo in the upper right corner of a printer page. It loads the resource into a CBitmapToDIB object. You will have to modify this for you application.
...
//Show the logo.
CBitmapToDIB dib;
 
if(dib.Create(IDB_LOGO1))
{
    LPBITMAPINFOHEADER lpHdr;
    CSize sizeDisplay;
    CSize sizeLogo;
 
    lpHdr = dib.GetBitmapHeader();
    sizeLogo.cx = lpHdr->biWidth;
    sizeLogo.cy = lpHdr->biHeight;
 
    //Make logo twice as big.
    sizeDisplay.cx = sizeLogo.cx * 2;
    sizeDisplay.cy = sizeLogo.cy * 2;
 
    StretchDIBits(pDC->m_hDC, rcHeader.right - sizeDisplay.cx, rcHeader.top,
        sizeDisplay.cx, sizeDisplay.cy,
        0, 0, sizeLogo.cx, sizeLogo.cy,
        dib.GetBitmapBits(), dib.GetBitmapData(),
        DIB_RGB_COLORS, SRCCOPY);
}
...
I have added the code for CBitmapToDIB below. I can't take credit for this code, I think I got it out of the MSDN years ago. There may be some newer or better code in the current MSDN or on Code Project.

But the code below works...
// BitmapToDIB.h : interface of the CBitmapToDIB class
//
/////////////////////////////////////////////////////////////////////////////
 
#if !defined(_BITMAPTODIB_H__INCLUDED_)
#define _BITMAPTODIB_H__INCLUDED_
 
 
class CBitmapToDIB
{
public:
    CBitmapToDIB();
    ~CBitmapToDIB();
    BOOL Create(CBitmap *hBitmap, CDC *pDC, CPalette *pPal = NULL, int nBitsPerPixel = -1);
    BOOL Create(LPCSTR lpResourceString);
    BOOL Create(WORD nResourceID);
    void Destroy();
    const LPVOID GetBitmapBits();
    const LPBITMAPINFO GetBitmapData();
    const LPBITMAPINFOHEADER GetBitmapHeader();
 
    BOOL WriteDIBToFile(LPCTSTR lpszFileName, CProgressCtrl *pProgressCntrl = NULL);
    BOOL WriteDIBToFile(CFile *pFile, CProgressCtrl *pProgressCntrl = NULL);
 
private:
    void InitBitmapInfoHeader(LPBITMAPINFOHEADER pHdr, int nBitsPerPixel);
    static WORD PaletteSize(LPBITMAPINFOHEADER pHdr);
    static WORD DibNumColors(LPBITMAPINFOHEADER pHdr);
 
private:
    HANDLE m_hDIB;
    BITMAP m_Bitmap;
    LPBITMAPINFO m_lpbmInfo;
    LPBITMAPINFOHEADER m_lpbmInfoHdr;
    LPBYTE m_lpBits;
    DWORD m_dwDIBSize;
};
 
#endif //_BITMAPTODIB_H__INCLUDED_
// BitmapToDIB.cpp : implementation of the CBitmapToDIB class
//
 
#include "stdafx.h"
#include "BitmapToDIB.h"
 
// WIDTHBYTES takes # of bits in a scan line and rounds up to nearest
//  word.
 
#define WIDTHBYTES(bits)      (((bits) + 31) / 32 * 4)
 
CBitmapToDIB::CBitmapToDIB()
{
    m_hDIB = NULL;
    Destroy();
}
 
CBitmapToDIB::~CBitmapToDIB()
{
    Destroy();
}
 
void CBitmapToDIB::Destroy()
{
    if(m_hDIB)
        delete [] m_hDIB;
    m_hDIB = NULL;
    m_lpBits = NULL;
    m_lpbmInfo = NULL;
    m_lpbmInfoHdr = NULL;
    m_dwDIBSize = 0;
}
 
void CBitmapToDIB::InitBitmapInfoHeader(LPBITMAPINFOHEADER pHdr, int nBitsPerPixel)
{
    int nBPP;
 
    memset(pHdr, 0, sizeof(BITMAPINFOHEADER));
 
    pHdr->biSize = sizeof(BITMAPINFOHEADER);
    pHdr->biWidth = m_Bitmap.bmWidth;
    pHdr->biHeight = m_Bitmap.bmHeight;
    pHdr->biPlanes = 1;
 
    if ((nBitsPerPixel == 1) || (nBitsPerPixel == 4) ||
        (nBitsPerPixel == 8) || (nBitsPerPixel == 24))
    {
        nBPP = nBitsPerPixel;
    }
    else
    {
        nBPP = m_Bitmap.bmPlanes * m_Bitmap.bmBitsPixel; // color bits per pixel
    }
 
    if(nBPP <= 1)
        nBPP = 1;
    else
    if(nBPP <= 4)
        nBPP = 4;
    else
    if(nBPP <= 8)
        nBPP = 8;
    else
        nBPP = 24;
 
    pHdr->biBitCount = (unsigned short)nBPP;
    pHdr->biSizeImage = WIDTHBYTES(m_Bitmap.bmWidth * nBPP) *
        m_Bitmap.bmHeight;
}
 
const LPVOID CBitmapToDIB::GetBitmapBits()
{
    return LPVOID(m_lpBits);
}
 
const LPBITMAPINFO CBitmapToDIB::GetBitmapData()
{
    return m_lpbmInfo;
}
 
const LPBITMAPINFOHEADER CBitmapToDIB::GetBitmapHeader()
{
    return m_lpbmInfoHdr;
}
 
BOOL CBitmapToDIB::Create(CBitmap *hBitmap, CDC *pDC, CPalette *pPal, int nBitsPerPixel)
{
    CDC dc;
    BITMAPINFOHEADER tempHdr;
 
    //Make sure our pointer are ok.
    ASSERT(hBitmap);
    if(!hBitmap)
        return FALSE;
 
    //Get the BITMAP structure from the DDB.
    if(!hBitmap->GetBitmap(&m_Bitmap))
        return FALSE;
 
    //Call this incase this is getting called twice.    
    Destroy();
 
    //Create a header for the DIB   
    InitBitmapInfoHeader(&tempHdr, nBitsPerPixel);
 
    //Allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
    // into this memory, and find out where the bitmap bits go.
    m_dwDIBSize = sizeof(BITMAPINFOHEADER) + PaletteSize(&tempHdr) + tempHdr.biSizeImage;
    m_hDIB = (HANDLE)new char[m_dwDIBSize];
    if(!m_hDIB)
        return FALSE;
 
    m_lpbmInfo = (LPBITMAPINFO)m_hDIB;
    m_lpbmInfoHdr = &m_lpbmInfo->bmiHeader;
    *m_lpbmInfoHdr = tempHdr;
    m_lpBits = (LPBYTE)m_hDIB + (WORD)m_lpbmInfoHdr->biSize + PaletteSize(m_lpbmInfoHdr);
 
    // Now, we need a DC to hold our bitmap.  If the app passed us
    // a palette, it should be selected into the DC.
    if(!dc.CreateCompatibleDC(pDC))
        return FALSE;
    if(pPal)
    {
        dc.SelectPalette(pPal, FALSE);
        dc.RealizePalette();
    }
 
    // We're finally ready to get the DIB.  Call the driver and let
    //  it party on our bitmap.  It will fill in the color table,
    //  and bitmap bits of our global memory block.
    if(!::GetDIBits(dc.m_hDC, HBITMAP(*hBitmap), 0, m_Bitmap.bmHeight, m_lpBits,
        m_lpbmInfo, DIB_RGB_COLORS))
    {
        return FALSE;
    }
 
    return TRUE;
}
 
BOOL CBitmapToDIB::Create(WORD nResourceID)
{
    return Create(MAKEINTRESOURCE(nResourceID));
}
 
BOOL CBitmapToDIB::Create(LPCSTR lpResourceString)
{
    HRSRC  hRsrc;
    HGLOBAL hTemp;
    LPSTR lpRes;
    HINSTANCE hInstance = AfxGetInstanceHandle();
 
    //Make sure our pointer are ok.
    ASSERT(hInstance && lpResourceString);
    if(!hInstance || !lpResourceString)
        return FALSE;
 
    hRsrc = FindResource(hInstance, lpResourceString, RT_BITMAP);
    if(hRsrc)
    {
        //Call this incase this is getting called twice.    
        Destroy();
 
        //Load the resource.
        hTemp = LoadResource(hInstance, hRsrc);
        m_dwDIBSize = SizeofResource(hInstance, hRsrc);
        lpRes = (LPSTR)LockResource(hTemp);
 
        //Allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
        // into this memory, and find out where the bitmap bits go.
        m_hDIB = (HANDLE)new char[m_dwDIBSize];
        if(!m_hDIB)
            return FALSE;
        memcpy(m_hDIB, lpRes, m_dwDIBSize);
 
        //Free the resource.
        UnlockResource(hTemp);
        FreeResource(hTemp);
 
        m_lpbmInfo = (LPBITMAPINFO)m_hDIB;
        m_lpbmInfoHdr = &m_lpbmInfo->bmiHeader;
        m_lpBits = (LPBYTE)m_hDIB + (WORD)m_lpbmInfoHdr->biSize + PaletteSize(m_lpbmInfoHdr);
 
        return TRUE;
    }
    return FALSE;
}
 
WORD CBitmapToDIB::PaletteSize(LPBITMAPINFOHEADER pHdr)
{
    WORD NumColors;
 
    NumColors = DibNumColors(pHdr);
 
    if (pHdr->biSize == sizeof(BITMAPCOREHEADER))
        return (WORD)(NumColors * sizeof(RGBTRIPLE));
    else
        return (WORD)(NumColors * sizeof(RGBQUAD));
}
 
WORD CBitmapToDIB::DibNumColors(LPBITMAPINFOHEADER pHdr)
{
    int bits;
    LPBITMAPINFOHEADER  lpbi;
    LPBITMAPCOREHEADER  lpbc;
 
    lpbi = (LPBITMAPINFOHEADER)pHdr;
    lpbc = (LPBITMAPCOREHEADER)pHdr;
 
    /*  With the BITMAPINFO format headers, the size of the palette
     *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
     *  is dependent on the bits per pixel ( = 2 raised to the power of
     *  bits/pixel).
     */
    if(lpbi->biSize != sizeof(BITMAPCOREHEADER))
    {
        if(lpbi->biClrUsed != 0)
            return (WORD)lpbi->biClrUsed;
        bits = lpbi->biBitCount;
    }
    else
        bits = lpbc->bcBitCount;
 
    switch(bits)
    {
        case 1:
            return 2;
        case 4:
            return 16;
        case 8:
            return 256;
        default:
            /* A 24 bitcount DIB has no color table */
            return 0;
    }
}
 
BOOL CBitmapToDIB::WriteDIBToFile(LPCTSTR lpszFileName, CProgressCtrl *pProgressCntrl)
{
    CString s;
 
    //Make sure we have a DIB.
    if(!m_hDIB)
        return FALSE;
 
    try
    {
        CFileStatus rStatus;
 
        //See if the file exist.
        if(CFile::GetStatus(lpszFileName, rStatus))
        {
            s.Format("File \"%s\" already exits. Overwrite?", lpszFileName);
            if(AfxMessageBox(s, MB_OKCANCEL) == IDCANCEL)
                return FALSE;
        }
         
        CFile file(lpszFileName, CFile::modeCreate | CFile::modeWrite);
        return WriteDIBToFile(&file, pProgressCntrl);
    }
    catch(...)
    {
        s.Format("ERROR: Could not create BMP file \"%s\".", lpszFileName);
        AfxMessageBox(s);
    }
    return FALSE;
}
 
BOOL CBitmapToDIB::WriteDIBToFile(CFile *pFile, CProgressCtrl *pProgressCntrl)
{
    BITMAPFILEHEADER bfh;
    DWORD dwFileSize;
 
    //Make sure we have a DIB.
    ASSERT(m_hDIB && pFile);
    if(!m_hDIB || !pFile)
        return FALSE;
 
    //The size of the whole file.
    dwFileSize = sizeof(BITMAPFILEHEADER) + m_dwDIBSize;
 
    //Build the bitmap file header.
    bfh.bfType = 0x4d42; //'BM'
    bfh.bfSize = dwFileSize;
    bfh.bfReserved1 = 0;
    bfh.bfReserved2 = 0; 
    //Where does the data start.
    bfh.bfOffBits = (m_lpBits - (LPBYTE)m_hDIB) + sizeof(BITMAPFILEHEADER); 
       
    try
    {
        if(pProgressCntrl)
            pProgressCntrl->SetRange(0, 100);
 
        //Write the bitmap file header.
        pFile->Write(&bfh, sizeof(BITMAPFILEHEADER));
         
        if(pProgressCntrl)
            pProgressCntrl->SetPos(50);
 
        //Wrtie the DIB.
        pFile->Write(m_hDIB, m_dwDIBSize);
 
        if(pProgressCntrl)
            pProgressCntrl->SetPos(100);
 
        return TRUE;
    }
    catch(...)
    {
        CString s;
        s.Format("ERROR: Problem writing to BMP file \"%s\".", pFile->GetFilePath);
        AfxMessageBox(s);
    }
 
    return FALSE;
}
I hope this helps... Smile | :)

Jonathan Craig
www.mcw-tech.com
GeneralValidate a IP in CString Pin
Sameer Maggon6-May-02 20:08
Sameer Maggon6-May-02 20:08 
GeneralRe: Validate a IP in CString Pin
moliate7-May-02 7:50
moliate7-May-02 7:50 
GeneralCritical Sections (Semaphores etc..) Pin
Sameer Maggon6-May-02 20:04
Sameer Maggon6-May-02 20:04 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Joaquín M López Muñoz6-May-02 21:03
Joaquín M López Muñoz6-May-02 21:03 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Sameer Maggon6-May-02 21:12
Sameer Maggon6-May-02 21:12 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Joaquín M López Muñoz6-May-02 21:15
Joaquín M López Muñoz6-May-02 21:15 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Sameer Maggon6-May-02 21:30
Sameer Maggon6-May-02 21:30 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Sameer Maggon6-May-02 21:36
Sameer Maggon6-May-02 21:36 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Joaquín M López Muñoz6-May-02 22:20
Joaquín M López Muñoz6-May-02 22:20 
GeneralRe: Critical Sections (Semaphores etc..) Pin
Jonathan Craig7-May-02 7:29
Jonathan Craig7-May-02 7:29 
GeneralGetOverlapedresult Pin
meirav6-May-02 19:24
meirav6-May-02 19:24 
GeneralDetermining Data Size For Network Send/Rec :: Winsock Pin
valikac6-May-02 18:55
valikac6-May-02 18:55 
GeneralRe: Determining Data Size For Network Send/Rec :: Winsock Pin
Niklas L6-May-02 21:24
Niklas L6-May-02 21:24 
GeneralRe: Determining Data Size For Network Send/Rec :: Winsock Pin
valikac6-May-02 21:38
valikac6-May-02 21:38 
GeneralRe: Determining Data Size For Network Send/Rec :: Winsock Pin
Rickard Andersson206-May-02 21:45
Rickard Andersson206-May-02 21:45 
GeneralRe: Determining Data Size For Network Send/Rec :: Winsock Pin
6-May-02 21:56
suss6-May-02 21:56 
GeneralRe: Determining Data Size For Network Send/Rec :: Winsock Pin
Rickard Andersson206-May-02 23:48
Rickard Andersson206-May-02 23:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.