432 lines
9.8 KiB
C++
432 lines
9.8 KiB
C++
|
// HtmlDlg.cpp : implementation file
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "Html2Bmp.h"
|
||
|
#include "HtmlDlg.h"
|
||
|
#include "IParser.h"
|
||
|
|
||
|
#include <fstream.h>
|
||
|
#include <direct.h>
|
||
|
|
||
|
#define TIMERID 1
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CHtmlDlg dialog
|
||
|
|
||
|
|
||
|
CHtmlDlg::CHtmlDlg(CWnd* pParent /*=NULL*/)
|
||
|
: CDialog(CHtmlDlg::IDD, pParent)
|
||
|
{
|
||
|
//{{AFX_DATA_INIT(CHtmlDlg)
|
||
|
// NOTE: the ClassWizard will add member initialization here
|
||
|
//}}AFX_DATA_INIT
|
||
|
|
||
|
m_nTimerID = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CHtmlDlg::DoDataExchange(CDataExchange* pDX)
|
||
|
{
|
||
|
CDialog::DoDataExchange(pDX);
|
||
|
//{{AFX_DATA_MAP(CHtmlDlg)
|
||
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||
|
//}}AFX_DATA_MAP
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CHtmlDlg, CDialog)
|
||
|
//{{AFX_MSG_MAP(CHtmlDlg)
|
||
|
ON_WM_TIMER()
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CHtmlDlg message handlers
|
||
|
|
||
|
BOOL CHtmlDlg::OnInitDialog()
|
||
|
{
|
||
|
CDialog::OnInitDialog();
|
||
|
|
||
|
if(m_OutputBitmapFile.IsEmpty())
|
||
|
m_OutputBitmapFile = m_HtmlFile + _T(".bmp");
|
||
|
|
||
|
if(m_HtmlFile.Left(2) != _T(":") && m_HtmlFile.Left(3) != _T("\\"))
|
||
|
{
|
||
|
char buffer[_MAX_PATH];
|
||
|
_getcwd(buffer, _MAX_PATH);
|
||
|
|
||
|
CString prefix(buffer);
|
||
|
|
||
|
if(prefix.Right(1) != _T("\\"))
|
||
|
prefix += _T("\\");
|
||
|
|
||
|
m_HtmlFile = prefix + m_HtmlFile;
|
||
|
}
|
||
|
|
||
|
if(m_TemplateBitmapFile.IsEmpty())
|
||
|
{
|
||
|
m_BmpFile = GetTemplateBmp();
|
||
|
|
||
|
if(m_BmpFile.Left(1) != _T(".") || m_BmpFile.Left(1) != _T("\\"))
|
||
|
{
|
||
|
char buffer[_MAX_PATH];
|
||
|
_getcwd(buffer, _MAX_PATH);
|
||
|
|
||
|
CString prefix(buffer);
|
||
|
|
||
|
if(prefix.Right(1) != _T("\\"))
|
||
|
prefix += _T("\\");
|
||
|
|
||
|
m_BmpFile = prefix + m_BmpFile;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
m_BmpFile = m_TemplateBitmapFile;
|
||
|
|
||
|
|
||
|
CFile BmpFileTest;
|
||
|
if(!BmpFileTest.Open(m_BmpFile, CFile::modeRead))
|
||
|
{
|
||
|
if(m_TemplateBitmapFile.IsEmpty())
|
||
|
AfxMessageBox(_T("The target bitmap could not be located inside the HTML page:\n") + m_HtmlFile + _T("\nCheck the HTML page."));
|
||
|
else
|
||
|
AfxMessageBox(_T("The target bitmap could not be loaded:\n") + m_TemplateBitmapFile);
|
||
|
|
||
|
EndDialog(1);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BITMAPFILEHEADER BmpFileTestHdr;
|
||
|
DIBSECTION BmpFileTestDibSection;
|
||
|
|
||
|
// file header
|
||
|
BmpFileTest.Read(&BmpFileTestHdr, sizeof(BmpFileTestHdr));
|
||
|
|
||
|
// BitmapInfoHeader
|
||
|
BmpFileTest.Read(&BmpFileTestDibSection.dsBmih , sizeof(BmpFileTestDibSection.dsBmih));
|
||
|
|
||
|
BmpFileTest.Close();
|
||
|
|
||
|
m_biCompression = BmpFileTestDibSection.dsBmih.biCompression;
|
||
|
m_bitw = BmpFileTestDibSection.dsBmih.biWidth;
|
||
|
m_bith = BmpFileTestDibSection.dsBmih.biHeight;
|
||
|
|
||
|
|
||
|
int ScreenX = GetSystemMetrics(SM_CXSCREEN);
|
||
|
int ScreenY = GetSystemMetrics(SM_CYSCREEN);
|
||
|
|
||
|
// SetWindowPos(&CWnd::wndTop, (ScreenX - m_bitw)/2, (ScreenY - m_bith)/2, m_bitw+10, m_bith+10, SWP_SHOWWINDOW);
|
||
|
SetWindowPos(&CWnd::wndTop, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
|
||
|
|
||
|
VERIFY(m_htmlCtrl.CreateFromStatic(IDC_HTMLVIEW, this));
|
||
|
|
||
|
m_htmlCtrl.MoveWindow(0, 0, ScreenX, ScreenY);
|
||
|
// m_htmlCtrl.MoveWindow((ScreenX - m_bitw)/2, (ScreenY - m_bith)/2, ScreenX, ScreenY);
|
||
|
m_htmlCtrl.Navigate(m_HtmlFile);
|
||
|
|
||
|
m_nTimerID = SetTimer(TIMERID, 100, NULL);
|
||
|
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
}
|
||
|
|
||
|
|
||
|
void CHtmlDlg::OnTimer(UINT nIDEvent)
|
||
|
{
|
||
|
if(nIDEvent == m_nTimerID )
|
||
|
{
|
||
|
// Don't know what gets all loaded into the page,
|
||
|
// so wait until everything is loaded and then start creating the bitmap
|
||
|
if(!m_htmlCtrl.GetBusy())
|
||
|
{
|
||
|
KillTimer(TIMERID);
|
||
|
m_nTimerID = 0;
|
||
|
|
||
|
Capture();
|
||
|
|
||
|
EndDialog(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CDialog::OnTimer(nIDEvent);
|
||
|
}
|
||
|
|
||
|
CString CHtmlDlg::GetTemplateBmp()
|
||
|
{
|
||
|
ifstream* pHtmlFile = new ifstream(m_HtmlFile, ios::nocreate);
|
||
|
if(*pHtmlFile == NULL || pHtmlFile->bad())
|
||
|
{
|
||
|
delete pHtmlFile;
|
||
|
return "";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pHtmlFile->seekg(0, ios::end);
|
||
|
int size = pHtmlFile->tellg();
|
||
|
pHtmlFile->seekg(0, ios::beg);
|
||
|
unsigned char* buf = new unsigned char[size];
|
||
|
pHtmlFile->read(buf, size);
|
||
|
|
||
|
CString HtmlContent(buf);
|
||
|
|
||
|
CIParser IParser(HtmlContent);
|
||
|
delete pHtmlFile;
|
||
|
|
||
|
return IParser.TemplateBitmapName;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CHtmlDlg::Capture()
|
||
|
{
|
||
|
CPaintDC dc(this); // device context for painting
|
||
|
|
||
|
CDC memdc;
|
||
|
memdc.CreateCompatibleDC(&dc);
|
||
|
|
||
|
CBitmap Bitmap;
|
||
|
if(!Bitmap.Attach(::LoadImage(NULL, m_BmpFile, IMAGE_BITMAP, 0, 0,
|
||
|
LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE)))
|
||
|
{
|
||
|
AfxMessageBox(_T("The following bitmap could not be loaded:\n") + m_BmpFile);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DIBSECTION DibSection;
|
||
|
|
||
|
::GetObject(
|
||
|
(HBITMAP)Bitmap, // handle to graphics object
|
||
|
sizeof(DIBSECTION), // size of buffer for object information
|
||
|
&DibSection // buffer for object information
|
||
|
);
|
||
|
|
||
|
|
||
|
BITMAP bmp;
|
||
|
Bitmap.GetBitmap(&bmp);
|
||
|
// int bitw = bmp.bmWidth;
|
||
|
// int bith = bmp.bmHeight;
|
||
|
int bmBitsPixel = bmp.bmBitsPixel;
|
||
|
|
||
|
|
||
|
memdc.SelectObject(&Bitmap);
|
||
|
|
||
|
memdc.BitBlt(0, 0, m_bitw, m_bith, &dc, 0, 0, SRCCOPY);
|
||
|
|
||
|
// Convert the color format to a count of bits.
|
||
|
int cClrBits = bmp.bmPlanes * bmp.bmBitsPixel;
|
||
|
if (cClrBits == 1)
|
||
|
cClrBits = 1;
|
||
|
else if (cClrBits <= 4)
|
||
|
cClrBits = 4;
|
||
|
else if (cClrBits <= 8)
|
||
|
cClrBits = 8;
|
||
|
else if (cClrBits <= 16)
|
||
|
cClrBits = 16;
|
||
|
else if (cClrBits <= 24)
|
||
|
cClrBits = 24;
|
||
|
else cClrBits = 32;
|
||
|
|
||
|
// Allocate memory for the BITMAPINFO structure. (This structure
|
||
|
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
|
||
|
// data structures.)
|
||
|
|
||
|
int nColors = 1 << cClrBits;
|
||
|
RGBQUAD* pColors = new RGBQUAD[nColors];
|
||
|
if(cClrBits != 24)
|
||
|
{
|
||
|
::GetDIBColorTable(
|
||
|
memdc.m_hDC, // handle to DC
|
||
|
0, // color table index of first entry
|
||
|
nColors, // number of entries to retrieve
|
||
|
pColors // array of color table entries
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
CFile file;
|
||
|
if(!file.Open(m_OutputBitmapFile, CFile::modeWrite | CFile::modeCreate))
|
||
|
{
|
||
|
AfxMessageBox(_T("The target bitmap could not be created:\n") + m_OutputBitmapFile);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// For Windows NT/2000, the width must be DWORD aligned unless
|
||
|
// the bitmap is RLE compressed.
|
||
|
// For Windows 95/98, the width must be WORD aligned unless the
|
||
|
// bitmap is RLE compressed.
|
||
|
int PictureSize = DWORD_ALIGNED(m_bitw * bmBitsPixel * 8) * m_bith / 8;
|
||
|
|
||
|
|
||
|
unsigned char* buf;
|
||
|
|
||
|
if(cClrBits == 4 && m_biCompression == BI_RLE4
|
||
|
|| cClrBits == 8 && m_biCompression == BI_RLE8)
|
||
|
buf = Compress((DibSection.dsBmih.biCompression = m_biCompression), (unsigned char*)DibSection.dsBm.bmBits, m_bitw, PictureSize);
|
||
|
else
|
||
|
{
|
||
|
buf = (unsigned char*)DibSection.dsBm.bmBits;
|
||
|
DibSection.dsBmih.biCompression = BI_RGB;
|
||
|
}
|
||
|
|
||
|
DibSection.dsBmih.biSizeImage = PictureSize;
|
||
|
/*
|
||
|
biCompression
|
||
|
Specifies the type of compression for a compressed bottom-up bitmap
|
||
|
(top-down DIBs cannot be compressed). This member can be one of the following values.
|
||
|
|
||
|
Value Description
|
||
|
BI_RGB An uncompressed format.
|
||
|
BI_RLE8 A run-length encoded (RLE) format for bitmaps with 8 bpp.
|
||
|
The compression format is a 2-byte format consisting of a count byte followed
|
||
|
by a byte containing a color index. For more information, see Bitmap Compression.
|
||
|
BI_RLE4 An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format
|
||
|
consisting of a count byte followed by two word-length color indexes.
|
||
|
For more information, see Bitmap Compression.
|
||
|
*/
|
||
|
|
||
|
|
||
|
// Fill in the fields of the file header
|
||
|
BITMAPFILEHEADER hdr;
|
||
|
|
||
|
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
|
||
|
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
|
||
|
DibSection.dsBmih.biSize + DibSection.dsBmih.biClrUsed
|
||
|
* sizeof(RGBQUAD) + DibSection.dsBmih.biSizeImage);
|
||
|
hdr.bfReserved1 = 0;
|
||
|
hdr.bfReserved2 = 0;
|
||
|
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
|
||
|
DibSection.dsBmih.biSize + DibSection.dsBmih.biClrUsed
|
||
|
* sizeof (RGBQUAD);
|
||
|
|
||
|
// Write the file header
|
||
|
file.Write(&hdr, sizeof(hdr));
|
||
|
|
||
|
// BitmapInfoHeader
|
||
|
file.Write(&DibSection.dsBmih , sizeof(DibSection.dsBmih));
|
||
|
|
||
|
// Color table
|
||
|
if(cClrBits != 24)
|
||
|
file.Write(pColors , DibSection.dsBmih.biClrUsed * sizeof (RGBQUAD));
|
||
|
|
||
|
|
||
|
// Write the bits
|
||
|
file.Write(buf, PictureSize);
|
||
|
}
|
||
|
|
||
|
unsigned char* CHtmlDlg::Compress(int cMode, unsigned char* bmBits, int width, int& PictureSize)
|
||
|
{
|
||
|
if(cMode == BI_RLE4)
|
||
|
{
|
||
|
unsigned char* buf = new unsigned char[2*PictureSize+1];
|
||
|
ZeroMemory(buf, 2*PictureSize+1);
|
||
|
|
||
|
int cIndex = 0;
|
||
|
int cSize = 0;
|
||
|
int LineCount = 0;
|
||
|
unsigned char c;
|
||
|
|
||
|
int i = 0;
|
||
|
while(i < PictureSize)
|
||
|
{
|
||
|
c = bmBits[i++];
|
||
|
cSize = 1;
|
||
|
while(i < PictureSize)
|
||
|
{
|
||
|
LineCount += 2; // 2 pixel pro Byte
|
||
|
|
||
|
if(bmBits[i] == c && cSize < 127 && LineCount < width)
|
||
|
{
|
||
|
cSize++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf[cIndex++] = 2*cSize; // 2 pixel pro Byte
|
||
|
buf[cIndex++] = c;
|
||
|
|
||
|
if(LineCount >= width)
|
||
|
{
|
||
|
LineCount = 0;
|
||
|
buf[cIndex++] = 0;
|
||
|
buf[cIndex++] = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// und den Rest noch bearbeiten
|
||
|
if(cSize > 1)
|
||
|
{
|
||
|
buf[cIndex++] = 2*cSize;
|
||
|
buf[cIndex++] = c;
|
||
|
}
|
||
|
|
||
|
PictureSize = cIndex;
|
||
|
return buf;
|
||
|
}
|
||
|
else
|
||
|
if(cMode == BI_RLE8)
|
||
|
{
|
||
|
unsigned char* buf = new unsigned char[2*PictureSize+1];
|
||
|
ZeroMemory(buf, 2*PictureSize+1);
|
||
|
|
||
|
int cIndex = 0;
|
||
|
int cSize = 0;
|
||
|
int LineCount = 0;
|
||
|
unsigned char c;
|
||
|
|
||
|
int i = 0;
|
||
|
while(i < PictureSize)
|
||
|
{
|
||
|
c = bmBits[i++];
|
||
|
cSize = 1;
|
||
|
while(i < PictureSize)
|
||
|
{
|
||
|
LineCount++;
|
||
|
|
||
|
if(bmBits[i] == c && cSize < 127 && LineCount < width)
|
||
|
{
|
||
|
cSize++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf[cIndex++] = (unsigned char)cSize;
|
||
|
buf[cIndex++] = c;
|
||
|
|
||
|
if(LineCount >= width)
|
||
|
{
|
||
|
LineCount = 0;
|
||
|
buf[cIndex++] = 0;
|
||
|
buf[cIndex++] = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// und den Rest noch bearbeiten
|
||
|
if(cSize > 1)
|
||
|
{
|
||
|
buf[cIndex++] = (unsigned char)cSize;
|
||
|
buf[cIndex++] = c;
|
||
|
}
|
||
|
|
||
|
PictureSize = cIndex;
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
return bmBits;
|
||
|
}
|