windows-nt/Source/XPSP1/NT/base/ntsetup/tools/html2bmp/htmldlg.cpp
2020-09-26 16:20:57 +08:00

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;
}