// PrintScrToFileDlg.cpp : implementation file
//

#include "stdafx.h"
#include "PrintScrToFile.h"
#include "PrintScrToFileDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CPrintScrToFileDlg dialog

CPrintScrToFileDlg::CPrintScrToFileDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPrintScrToFileDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CPrintScrToFileDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  m_hwndClipboardViewer = NULL;
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  m_fInCall = FALSE; 
  m_nCurrentCount = 0;
}

void CPrintScrToFileDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPrintScrToFileDlg)
	DDX_Control(pDX, IDC_BITMAP_FORMAT, m_lstFormats);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPrintScrToFileDlg, CDialog)
	//{{AFX_MSG_MAP(CPrintScrToFileDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
  ON_WM_DRAWCLIPBOARD()
  ON_WM_CHANGECBCHAIN()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPrintScrToFileDlg message handlers

BOOL CPrintScrToFileDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
  m_fInCall = TRUE;
  m_hwndClipboardViewer = SetClipboardViewer();
  m_fInCall = FALSE;
  int nCur = LB_ERR;
  int nDefault = LB_ERR;
  nDefault = nCur = m_lstFormats.AddString("<Default Data Format>");
  if (nCur != LB_ERR)
  {
    m_lstFormats.SetItemData(nCur, 0);
  }
  nCur = m_lstFormats.AddString("As CF_DIB (default format)");
  if (nCur != LB_ERR)
  {
    m_lstFormats.SetItemData(nCur, 1);
  }
  nCur = m_lstFormats.AddString("32 bit uncompressed");
  if (nCur != LB_ERR)
  {
    m_lstFormats.SetItemData(nCur, 2);
  }
  nCur = m_lstFormats.AddString("24 bit uncompressed");
  if (nCur != LB_ERR)
  {
    m_lstFormats.SetItemData(nCur, 3);
  }
  nCur = m_lstFormats.AddString("16 bit uncompressed");
  if (nCur != LB_ERR)
  {
    m_lstFormats.SetItemData(nCur, 4);
  }
  


  m_lstFormats.SetCurSel(nDefault);
	return TRUE;  // return TRUE  unless you set the focus to a control
}



// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CPrintScrToFileDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CPrintScrToFileDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


void CPrintScrToFileDlg::OnOK() 
{
  //
  // App ends when this happens
  //
	CDialog::OnOK();
  PostQuitMessage(0);
}

BOOL CPrintScrToFileDlg::DestroyWindow() 
{
  
  ChangeClipboardChain(m_hwndClipboardViewer);	
	return CDialog::DestroyWindow();

}

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::OnDrawClipboard()
{
  int nCur = m_lstFormats.GetCurSel();
  if (nCur != LB_ERR ) // use current format if none selected
  {
    int iItemData = m_lstFormats.GetItemData(nCur);
    switch (iItemData)
    {
      case 1: // DrawClipboardPassedIn
        DrawClipboardPassedIn();
        break;

      case 2: // 32-bit Uncompressed
        DrawClipboard32Uncompressed();
        break;

      case 3: // 24bit Uncompressed
        DrawClipboard24Uncompressed();
        break;

      case 4: // 16-bit Uncompressed
        DrawClipboard16Uncompressed();
        break;

      case 0:
        DrawClipboardDefault();
      default:
        break;
    }

  }
}

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboard32Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    32  / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));

        lpv = malloc(nSize);
        pbmInfo3->bmiHeader.biBitCount = 32;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;
        pbmInfo3->bmiHeader.biClrUsed = 0;

        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}


//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

#if 0
void CPrintScrToFileDlg::DrawClipboard32Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    32  / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));

        lpv = malloc(nSize);
        pbmInfo3->bmiHeader.biBitCount = 32;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;
        pbmInfo3->bmiHeader.biClrUsed = 0;

        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}
#endif

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboard16Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = pbmInfo1->bmiHeader.biClrUsed * sizeof(DWORD);


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    16  / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));

        lpv = malloc(nSize);
        pbmInfo3->bmiHeader.biBitCount = 16;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;

        

        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}


#if 0
//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboard16Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = pbmInfo3->bmiHeader.biClrUsed * sizeof(DWORD);


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    16 / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));

        lpv = malloc(nSize);
        pbmInfo3->bmiHeader.biBitCount = 16;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;

        

        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}

#endif
//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboard24Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    24  / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));
        lpv = malloc(nSize);
        if (!lpv)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }

        pbmInfo3->bmiHeader.biBitCount = 24;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;
        pbmInfo3->bmiHeader.biClrUsed = 0;
        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************
#if 0
void CPrintScrToFileDlg::DrawClipboard24Uncompressed()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

        if (!hbmClipboardHBitmap)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hbmClipboardHBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap , 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);


        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmInfo1->bmiHeader.biHeight * pbmInfo1->bmiHeader.biWidth *
                    24  / sizeof(BYTE); 
        
        pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) + nSizeOfColorTable);
        memcpy(pbmInfo3, pbmInfo1, sizeof(BITMAPINFOHEADER));

        lpv = malloc(nSize);
        pbmInfo3->bmiHeader.biBitCount = 24;
        pbmInfo3->bmiHeader.biCompression = BI_RGB;
        pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;
        pbmInfo3->bmiHeader.biClrUsed = 0;
        pDC = GetDC();

        bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);


        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo3->bmiHeader.biSizeImage ? pbmInfo3->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  



}

#endif
//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboardPassedIn()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      pbmPassedIn = (BITMAPINFO *)GetClipboardData(CF_DIB);

        if (!pbmPassedIn)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmPassedIn->bmiHeader.biSize,   
                  pbmPassedIn->bmiHeader.biWidth,        
                  pbmPassedIn->bmiHeader.biHeight,       
                  pbmPassedIn->bmiHeader.biPlanes,       
                  pbmPassedIn->bmiHeader.biBitCount,      
                  pbmPassedIn->bmiHeader.biCompression,  
                  pbmPassedIn->bmiHeader.biSizeImage/1024,    
                  pbmPassedIn->bmiHeader.biXPelsPerMeter,
                  pbmPassedIn->bmiHeader.biYPelsPerMeter,
                  pbmPassedIn->bmiHeader.biClrUsed,      
                  pbmPassedIn->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);

        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmPassedIn->bmiHeader.biHeight * pbmPassedIn->bmiHeader.biWidth *
                    pbmPassedIn->bmiHeader.biBitCount  / sizeof(BYTE); 
        if (pbmPassedIn->bmiHeader.biBitCount < 24)
        {
          nSizeOfColorTable = sizeof(RGBQUAD)*256 * pbmPassedIn->bmiHeader.biBitCount ;
        }
        else if (pbmPassedIn->bmiHeader.biCompression == BI_BITFIELDS )
        {
          nSizeOfColorTable = 3 * sizeof(DWORD);
        }
        else
        {
          nSizeOfColorTable = 0; 
        }
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmPassedIn->bmiHeader.biSizeImage ? pbmPassedIn->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmPassedIn, (LPVOID)((DWORD)&(pbmPassedIn->bmiHeader) + (DWORD)pbmPassedIn->bmiHeader.biSize), strOutput);

        
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  
}

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

void CPrintScrToFileDlg::DrawClipboardDefault()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  HANDLE hFile = INVALID_HANDLE_VALUE;
  DWORD dwError = ERROR_ALREADY_EXISTS;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      HANDLE hBitmap = GetClipboardData(CF_BITMAP);
      if (hBitmap)
      {
        //
        // Find the first file that isn't used already fitting the format
        //
        while (hFile == INVALID_HANDLE_VALUE && 
              (dwError == ERROR_ALREADY_EXISTS  || dwError == ERROR_FILE_EXISTS))
        {
          strFilename.Format("PrintScrToFile_%03d.bmp", m_nCurrentCount);
          hFile = CreateFile((LPCSTR)strFilename, GENERIC_WRITE | GENERIC_READ, 0, NULL,
                              CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
          dwError = GetLastError();
          m_nCurrentCount++;
        }
        if (hFile == INVALID_HANDLE_VALUE) // we had some other error
        {
          strOutput.Format("Failed save, couldn't open file");
          goto FunctionEnd;
        }
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) /* + 
                                                sizeof(RGBQUAD)*256*/);
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hBitmap, 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
        

        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmInfo1->bmiHeader.biSize,   
                  pbmInfo1->bmiHeader.biWidth,        
                  pbmInfo1->bmiHeader.biHeight,       
                  pbmInfo1->bmiHeader.biPlanes,       
                  pbmInfo1->bmiHeader.biBitCount,      
                  pbmInfo1->bmiHeader.biCompression,  
                  pbmInfo1->bmiHeader.biSizeImage/1024,    
                  pbmInfo1->bmiHeader.biXPelsPerMeter,
                  pbmInfo1->bmiHeader.biYPelsPerMeter,
                  pbmInfo1->bmiHeader.biClrUsed,      
                  pbmInfo1->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);



        int nSize = pbmInfo1->bmiHeader.biSizeImage; // we're asking for 24bpp no matter what below
        int nSizeOfColorTable = 0;

        if (pbmInfo1->bmiHeader.biBitCount < 16)
        {
          nSizeOfColorTable = sizeof(RGBQUAD)*256 * pbmInfo1->bmiHeader.biBitCount ;
        }
        else if (pbmInfo1->bmiHeader.biCompression == BI_BITFIELDS )
        {
          nSizeOfColorTable = 3 * sizeof(DWORD);
        }
        else if (pbmInfo1->bmiHeader.biBitCount == 16)
        {
          nSizeOfColorTable = sizeof(RGBQUAD) * pbmInfo1->bmiHeader.biClrUsed ;
        }
        else
        {
          nSizeOfColorTable = 0; 
        }

        pbmInfo2 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable);
        memset(pbmInfo2, 0, sizeof(BITMAPINFO));
        memcpy(pbmInfo2, pbmInfo1, sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable);
        pbmInfo2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

        if (!pbmInfo2)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        lpv = malloc(nSize);
        if (!lpv)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
            
        if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hBitmap, 0, pbmInfo2->bmiHeader.biHeight, lpv, pbmInfo2, DIB_RGB_COLORS))
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        CloseClipboard();
        fClipboardOpen = FALSE;
        //
        // Now we have all the data, so save it off
        //

//        SaveBitmap(nSizeOfColorTable, (BITMAPINFOHEADER *)pbmInfo2, (LPVOID)((DWORD)&(pbmInfo2->bmiHeader) + (DWORD)pbmInfo2->bmiHeader.biSize), strOutput);
        if (fClipboardOpen )
          CloseClipboard();
        fClipboardOpen = FALSE;
        SaveBitmap(nSizeOfColorTable, pbmInfo2->bmiHeader.biSizeImage ? pbmInfo2->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmInfo2, lpv, strOutput);
/*

        DWORD dwBytesOut = 0;
        BITMAPFILEHEADER bmHeader;
        bmHeader.bfType = 'MB';
        bmHeader.bfReserved1 = 0;
        bmHeader.bfReserved2 = 0;
        bmHeader.bfSize = nSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable;
        bmHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable;
        WriteFile(hFile, &bmHeader, sizeof(BITMAPFILEHEADER), &dwBytesOut, NULL);
        WriteFile(hFile, pbmInfo2, sizeof(BITMAPINFOHEADER) + nSizeOfColorTable, &dwBytesOut, NULL);
        WriteFile(hFile, lpv, nSize, &dwBytesOut, NULL);

        // update the IDC_LASTSAVED field
        strOutput.Format("Saved '%s'", (LPCSTR)strFilename);
*/
      }
    }

FunctionEnd:
    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  
}

//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************
void CPrintScrToFileDlg::SaveBitmap(int nSizeOfColorTable, int nSizeofData, BITMAPINFOHEADER * pbmInfo2, LPVOID lpv, CString & strOutput)
{
  HANDLE hFile = INVALID_HANDLE_VALUE;
  DWORD dwError = ERROR_ALREADY_EXISTS;
  CString strFilename;
  //int nSize = pbmInfo2->biSizeImage;
  int nSize = nSizeofData;
  
        DWORD dwBytesOut = 0;
        BITMAPFILEHEADER bmHeader;
  //
        // Find the first file that isn't used already fitting the format
        //
        while (hFile == INVALID_HANDLE_VALUE && 
              (dwError == ERROR_ALREADY_EXISTS  || dwError == ERROR_FILE_EXISTS))
        {
          strFilename.Format("PrintScrToFile_%03d.bmp", m_nCurrentCount);
          hFile = CreateFile((LPCSTR)strFilename, GENERIC_WRITE | GENERIC_READ, 0, NULL,
                              CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
          dwError = GetLastError();
          m_nCurrentCount++;
        }
        if (hFile == INVALID_HANDLE_VALUE) // we had some other error
        {
          strOutput.Format("Failed save, couldn't open file");
          goto FunctionEnd;
        }
        //
        // Now we have all the data, so save it off
        //
        bmHeader.bfType = 'MB';
        bmHeader.bfReserved1 = 0;
        bmHeader.bfReserved2 = 0;
        bmHeader.bfSize = nSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable;
        bmHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable;
        WriteFile(hFile, &bmHeader, sizeof(BITMAPFILEHEADER), &dwBytesOut, NULL);
        WriteFile(hFile, pbmInfo2, sizeof(BITMAPINFOHEADER) + nSizeOfColorTable, &dwBytesOut, NULL);
        WriteFile(hFile, lpv, nSize, &dwBytesOut, NULL);

        // update the IDC_LASTSAVED field
        strOutput.Format("Saved '%s'", (LPCSTR)strFilename);

FunctionEnd:
    if (hFile != INVALID_HANDLE_VALUE)
        CloseHandle(hFile);


}

void CPrintScrToFileDlg::OnChangeCbChain( HWND hWndRemove, HWND hWndAfter )
{
  if (m_hwndClipboardViewer == hWndRemove)
  {
    m_hwndClipboardViewer = hWndAfter;
  }

  if (m_hwndClipboardViewer)
  {
    SendMessage(WM_DRAWCLIPBOARD, 0, 0);
  }


}



//***************************************************************************************************
//***************************************************************************************************
//***************************************************************************************************

#if 0

void CPrintScrToFileDlg::OnDrawClipboard()
{
  CString strOutput;
  strOutput.Format("Failed save.");
  BOOL fClipboardOpen = FALSE;
  CString strFilename;
  BOOL bRet = FALSE;
  BITMAPINFO * pbmInfo1 = NULL;
  BITMAPINFO * pbmInfo2 = NULL;
  BITMAPINFO * pbmInfo3 = NULL;
  BITMAPINFO * pbmPassedIn = NULL;
  HBITMAP hbmDeviceDependentBitmap = NULL;
  HBITMAP hbmClipboardHBitmap = NULL;
  CDC * pDC = NULL;
  LPVOID lpv = NULL;
  if (!m_fInCall)
  {
    if (OpenClipboard())
    {  
      fClipboardOpen = TRUE;
      pbmPassedIn = (BITMAPINFO *)GetClipboardData(CF_DIB);
/*
      HANDLE hBitmap = GetClipboardData(CF_BITMAP);
      if (hBitmap)
      {
        //
        // We now have a file open and a handle to a bitmap.
        //
        BITMAP bm; 
        bm.bmBits = NULL;

        int nBytes = ::GetObject(hBitmap, sizeof(bm), &bm);
        if (!nBytes)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        //
        // We now have the memory, lets load it into memory
        //
        pbmInfo1 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) // + 
                                                //sizeof(RGBQUAD)*256
                                                );
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
        memset(pbmInfo1, 0, sizeof(BITMAPINFOHEADER) );
        pbmInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pDC = GetDC();

        bRet = GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hBitmap, 0, 1, NULL, pbmInfo1, DIB_RGB_COLORS);
        if (!bRet)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        // we now have the header info
  */

        if (!pbmPassedIn)
        {
          strOutput.Format("Failed save '%s' failed to get data from GetClipboardData(CF_DIB)", (LPCSTR)strFilename);
          goto FunctionEnd;

        }
      
        strOutput.Format("Size (%ld), H/W (%ld, %ld), Planes (%d),\r\n"
                         "BitCount (%d), Compression (0x%08X), SizeImage (%ldKB),\r\n"
                         "XPels/YPels per M (%ld, %ld), ClrUsed (%ld), ClrImportant (%ld)",
                         
                  pbmPassedIn->bmiHeader.biSize,   
                  pbmPassedIn->bmiHeader.biWidth,        
                  pbmPassedIn->bmiHeader.biHeight,       
                  pbmPassedIn->bmiHeader.biPlanes,       
                  pbmPassedIn->bmiHeader.biBitCount,      
                  pbmPassedIn->bmiHeader.biCompression,  
                  pbmPassedIn->bmiHeader.biSizeImage/1024,    
                  pbmPassedIn->bmiHeader.biXPelsPerMeter,
                  pbmPassedIn->bmiHeader.biYPelsPerMeter,
                  pbmPassedIn->bmiHeader.biClrUsed,      
                  pbmPassedIn->bmiHeader.biClrImportant); 
        GetDlgItem(IDC_NATIVE_FORMAT)->SetWindowText(strOutput);

        //
        // At this point we know the native format, so lets put it up for display
        //

        int nSizeOfColorTable = 0;


        int nSize = pbmPassedIn->bmiHeader.biHeight * pbmPassedIn->bmiHeader.biWidth *
                    pbmPassedIn->bmiHeader.biBitCount / sizeof(BYTE); 
        
        int nCur = m_lstFormats.GetCurSel();
        if (nCur != LB_ERR ) // use current format if none selected
        {
          int iItemData = m_lstFormats.GetItemData(nCur);
          switch (iItemData)
          {
            case 1: // 32-bit Uncompressed
              {
              hbmClipboardHBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
              nSize = pbmPassedIn->bmiHeader.biHeight * pbmPassedIn->bmiHeader.biWidth *
                    pbmPassedIn->bmiHeader.biBitCount  / sizeof(BYTE); 
              pbmInfo3 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER));
              memcpy(pbmInfo3, pbmPassedIn, sizeof(BITMAPINFOHEADER));

              lpv = malloc(pbmInfo3->bmiHeader.biWidth * pbmInfo3->bmiHeader.biHeight * 32);
              pbmInfo3->bmiHeader.biBitCount = 32;
              pbmInfo3->bmiHeader.biCompression = BI_RGB;
              pbmInfo3->bmiHeader.biSizeImage = /*nSize*/0;
  
             pDC = GetDC();

              bRet = ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hbmClipboardHBitmap, 0, pbmInfo3->bmiHeader.biHeight, lpv, pbmInfo3, DIB_RGB_COLORS);

              //
              // Experiment with creating a device dependent bitmap then getting what I want from it
              //

              //
              //
              //



              if (!bRet)
              {
                strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
                goto FunctionEnd;
              }
              ReleaseDC(pDC);
              pDC = NULL;
              SaveBitmap(nSizeOfColorTable, nSize, (BITMAPINFOHEADER *)pbmInfo3, (LPVOID)lpv, strOutput);
              
              }
              break;
            case 2: // 24-bit uncompressed
              {
              }
              break;
              
/*              // 32-bit RLE8
            case 3: // 32-bit RLE4
              {
              }
              break;
            case 4: // 32-bit BITFIELD
              {
              }
              break;
            case 5: // 32-bit JPEG
              {
              }
              break;
            case 6: // 32-bit PNG
              {
              }
              break;
              */
            case 0:
            default: // do nothing, just use the passed in stats for the bitmap
              {
              if (pbmPassedIn->bmiHeader.biBitCount < 16)
              {
                nSizeOfColorTable = sizeof(RGBQUAD)*256 * pbmPassedIn->bmiHeader.biBitCount ;
              }
              else if (pbmPassedIn->bmiHeader.biCompression == BI_BITFIELDS )
              {
                nSizeOfColorTable = 3 * sizeof(DWORD);
              }
              else
              {
                nSizeOfColorTable = 0; 
              }
              SaveBitmap(nSizeOfColorTable, pbmPassedIn->bmiHeader.biSizeImage ? pbmPassedIn->bmiHeader.biSizeImage : nSize, (BITMAPINFOHEADER *)pbmPassedIn, (LPVOID)((DWORD)&(pbmPassedIn->bmiHeader) + (DWORD)pbmPassedIn->bmiHeader.biSize), strOutput);

              }
              break;
          }


        }

        
/*
        if (!pbmInfo1)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;

        }

          
  

        //
        // Now I have to do a bunch of annoying detection to find out how big tieh color table is supposed
        // to be for this specific format.
        //
        int nSize = pbmInfo1->bmiHeader.biSizeImage; // we're asking for 24bpp no matter what below
        int nSizeOfColorTable = 0;

        if (pbmInfo1->bmiHeader.biBitCount < 24)
        {
          nSizeOfColorTable = sizeof(RGBQUAD)*256 * pbmInfo1->bmiHeader.biBitCount ;
        }
        else if (pbmInfo1->bmiHeader.biCompression == BI_BITFIELDS )
        {
          nSizeOfColorTable = 3 * sizeof(DWORD);
        }
        else
        {
          nSizeOfColorTable = 0; 
        }

        pbmInfo2 = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable);
        memset(pbmInfo2, 0, sizeof(BITMAPINFO));
        memcpy(pbmInfo2, pbmInfo1, sizeof(BITMAPINFOHEADER)  + 
                                                nSizeOfColorTable);
        pbmInfo2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

        if (!pbmInfo2)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        lpv = malloc(nSize);
        if (!lpv)
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
            
        if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)hBitmap, 0, pbmInfo2->bmiHeader.biHeight, lpv, pbmInfo2, DIB_RGB_COLORS))
        {
          strOutput.Format("Failed save '%s'", (LPCSTR)strFilename);
          goto FunctionEnd;
        }
        ReleaseDC(pDC);
        pDC = NULL;
        CloseClipboard();
        fClipboardOpen = FALSE;
      }
      void SaveBitmap(int nSizeOfColorTable, BITMAPINFOHEADER * pbmInfo2, LPVOID lpv, CString & strOutput)

  */
    }

FunctionEnd:
    if (pbmPassedIn)
      LocalFree(pbmPassedIn); // am I supposed to do this?
    if (hbmDeviceDependentBitmap)
      ::DeleteObject(hbmDeviceDependentBitmap);

    if (fClipboardOpen )
      CloseClipboard();
    GetDlgItem(IDC_LASTSAVED)->SetWindowText(strOutput);
    if (pDC)
      ReleaseDC(pDC);
    if (lpv)
      free(lpv);
    if (pbmInfo1 )
      free(pbmInfo1);
    if (pbmInfo2 )
      free(pbmInfo2);
    if (m_hwndClipboardViewer)
      ::SendMessage(m_hwndClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  }

  
}

#endif
