///////////////////////////////////////////////////////////////////////////////
//
// CTCopyDlg
// ----------
// Dialog of copy TWAIN utility
//
////Holger Kloos, 2004/////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TCopy.h"
#include "AboutDlg.h"
#include "TCopyDlg.h"
#include "DlgHelper.h"
#include "FindFax.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const UINT WU_FINISHINIT = WM_APP + 1;
const char* STR_BITMAPFILETYPE = "Bitmap (*.BMP)|*.BMP||";
const char* STR_BRIGHTNESS = "Brightness";
const char* STR_CONTRAST = "Contrast";
const char* STR_PICTURE = "Bild";
/////////////////////////////////////////////////////////////////////////////
// CTCopyDlg dialog
CTCopyDlg::CTCopyDlg(int nDlgResource, CWnd* pParent /*=NULL*/)
: CDialog(nDlgResource, pParent)
, m_TwainPP(AfxGetAppName(), &m_TraceFile)
, m_ComboPrinterSelect(m_PrinterAccess)
{
//{{AFX_DATA_INIT(CTCopyDlg)
m_sStateInfo = _T("");
m_RCImageColorSelect = 1;
m_RCModusSelect = 0;
m_RCResolution = 1;
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bPrintImageAutomatic = FALSE;
m_bFaxSelect = FALSE;
m_nBrightnessOffset = 0;
m_nContrastOffset = 0;
}
void CTCopyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTCopyDlg)
DDX_Control(pDX, IDC_SPIN_SCALING, m_SpinCtrlScaling);
DDX_Control(pDX, IDC_EC_SCALING, m_ECScaling);
DDX_Control(pDX, IDC_SLIDER_CONTRAST, m_ContrastSlider);
DDX_Control(pDX, IDC_SLIDER_BRIGHTNESS, m_BrightnessSlider);
DDX_Control(pDX, IDC_CB_PRINTERSELECT, m_ComboPrinterSelect);
DDX_Control(pDX, IDC_BITMAP_PREVIEW, m_ctlrShowBitmap);
DDX_Text(pDX, IDC_SC_STATEINFO, m_sStateInfo);
DDX_Radio(pDX, IDC_RC_IMAGE_COLOR, m_RCImageColorSelect);
DDX_Radio(pDX, IDC_RC_MODUS_FAST, m_RCModusSelect);
DDX_Radio(pDX, IDC_RC_RESOLUTION_96, m_RCResolution);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTCopyDlg, CDialog)
//{{AFX_MSG_MAP(CTCopyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_COPY, OnBtnCopy)
ON_COMMAND(IDM_ABOUT, OnMenuAbout)
ON_UPDATE_COMMAND_UI(IDM_COPY, OnMenuUpdateCopy)
ON_COMMAND(IDM_COPY, OnMenuCopy)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BTN_PRINTEROPTIONS, OnBtnPrinterOptions)
ON_MESSAGE(WU_FINISHINIT, OnFinishInit)
ON_BN_CLICKED(IDC_BTN_PREVIEW, OnBtnPreview)
ON_BN_CLICKED(IDC_RC_MODUS_DLG, OnRcModusChange)
ON_COMMAND(IDM_FINISH, OnFinish)
ON_BN_CLICKED(IDC_BTN_PRINT, OnBtnPrint)
ON_COMMAND(IDM_FILESAVEAS, OnMenuFileSave)
ON_COMMAND(IDM_FILELOAD, OnMenuFileLoad)
ON_CBN_SELCHANGE(IDC_CB_PRINTERSELECT, OnPrinterSelection)
ON_BN_CLICKED(IDC_BTN_FAX, OnBtnFax)
ON_BN_CLICKED(IDC_RC_MODUS_FAST, OnRcModusChange)
ON_COMMAND(IDM_PRINT, OnBtnPrint)
ON_COMMAND(IDM_SAVEDEFAULTS, OnMenuSaveDefaults)
ON_COMMAND(IDM_RESETDEFAULTS, OnMenuResetDefaults)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTCopyDlg message handlers
BOOL CTCopyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CString sAppPath = AfxGetApp()->m_pszHelpFilePath;
sAppPath = sAppPath.Left(sAppPath.ReverseFind('\\'));
m_TraceFile.OpenTraceFile(sAppPath + "\\Trace.log");
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu = LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_BrightnessSlider.SetTicFreq(200);
m_BrightnessSlider.SetRange(-400,400, TRUE);
m_ContrastSlider.SetTicFreq(200);
m_ContrastSlider.SetRange(-400,400, TRUE);
m_SpinCtrlScaling.SetBuddy(&m_ECScaling);
m_SpinCtrlScaling.SetPos(100);
if (!IsPrinterValid())
{
SetStateInfo(IDS_NOPRINTER);
EnableCtrlsOfGroupBox(this, IDC_SC_PRINTERSELECT, false);
}
PostMessage(WU_FINISHINIT, 0, 0);
SetStateInfo(IDS_INITSCANNER);
return TRUE; // return TRUE unless you set the focus to a control
}
LPARAM CTCopyDlg::OnFinishInit(WPARAM, LPARAM)
{
BOOL bTwain = m_TwainPP.Create(m_hWnd, this) && m_TwainPP.OpenSource();
if (bTwain)
{
ReadDefaults();
OnRcModusChange();
EnableCtrlsOfGroupBox(this, IDC_ST_SELECTCONFIGMODE, !IsDlgModusSelected());
EnableCtrlWithId(this, IDC_BTN_COPY, IsPrinterValid());
EnableCtrlWithId(this, IDC_BTN_PREVIEW, true);
SetStateInfo(IDS_READYTOSCANWITHSCANNER, m_TwainPP.GetSourceName());
OnPrinterSelection();
CFindFax findFax(m_PrinterAccess);
EnableCtrlWithId(this, IDC_BTN_FAX, findFax.GetFaxName(m_sFax));
}
else
SetStateInfo(IDS_NOSCANNER);
return 1;
}
void CTCopyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 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 CTCopyDlg::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();
}
}
HCURSOR CTCopyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTCopyDlg::OnBtnCopy()
{
UpdateData(TRUE);
GetBitmap(TRUE);
}
void CTCopyDlg::OnTwainImageInfo(int /*nSizeX*/, int /*nSizeY*/)
{
/* CString sInfo;
sInfo.Format(" (%d x %d)", nSizeX, nSizeY);
SetStateInfo(IDS_SCANNING, sInfo);
*/
SetStateInfo(IDS_SCANNING);
}
BOOL CTCopyDlg::OnTwainBitmap(HDIB hDIB)
{
BOOL bRes = m_DIBUse.SetDIB(hDIB)
&& m_ctlrShowBitmap.SetDIBitmap(m_DIBUse);
EnableMenuItems(TRUE);
EnableCtrlWithId(this, IDC_BTN_PRINT, IsPrinterValid());
if (m_bPrintImageAutomatic)
{
if (DoPrint())
return FALSE;
}
SetStateInfo(IDS_READYTOSCAN);
return bRes;
}
void CTCopyDlg::OnTwainError(CTwainPP::ETWainError eTwainError)
{
SelectFax(FALSE);
switch (eTwainError)
{
case CTwainPP::eNoTwain:
SetStateInfo(IDS_NOSCANNER);
break;
case CTwainPP::eCancel:
SetStateInfo(IDS_SCANCANCELED);
break;
case CTwainPP::eGetCapability:
SetStateInfo(IDS_ERRORGETOPTION);
break;
case CTwainPP::eSetCapability:
SetStateInfo(IDS_ERRORSETOPTION);
break;
case CTwainPP::eDeviceNotReady:
SetStateInfo(IDS_ERRORDEVICENOTREADY);
break;
case CTwainPP::eErrorReading:
SetStateInfo(IDS_ERRORREADING);
break;
}
}
void CTCopyDlg::EnableMenuItems(BOOL bEnable)
{
CMenu* pMenu = GetMenu();
if (pMenu)
{
UINT nFlag = bEnable ? MF_ENABLED : MF_DISABLED;
pMenu->EnableMenuItem(IDM_COPY, nFlag);
pMenu->EnableMenuItem(IDM_PRINT, nFlag);
pMenu->EnableMenuItem(IDM_FILESAVEAS, nFlag);
}
}
void CTCopyDlg::OnMenuAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
void CTCopyDlg::OnMenuUpdateCopy(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_DIBUse.IsValid());
}
void CTCopyDlg::OnMenuCopy()
{
if (!OpenClipboard())
return;
EmptyClipboard();
SetClipboardData(CF_DIB, m_DIBUse.GetDIBHandle());
CloseClipboard();
}
void CTCopyDlg::OnClose()
{
m_TwainPP.Close();
if (OpenClipboard())
{
if (GetClipboardData(CF_DIB) == m_DIBUse.GetDIBHandle())
{
m_DIBUse.Detach();
// EmptyClipboard();
}
CloseClipboard();
}
CDialog::OnClose();
}
void CTCopyDlg::OnBtnPrinterOptions()
{
UpdateData(TRUE);
m_PrinterAccess.ShowConfigDialog(GetPrinterName(), this);
}
const CString CTCopyDlg::LoadString(UINT nId) const
{
CTCopyApp* pCopyApp = dynamic_cast<CTCopyApp*>(AfxGetApp());
return pCopyApp->LoadString(nId);
}
void CTCopyDlg::SetStateInfo(UINT nID, const char* pAddInfo)
{
m_sStateInfo = LoadString(nID);
if (pAddInfo)
m_sStateInfo += pAddInfo;
m_TraceFile.MakeTrace(m_sStateInfo);
UpdateData(FALSE);
}
void CTCopyDlg::OnBtnPreview()
{
UpdateData(TRUE);
GetBitmap(FALSE);
}
BOOL CTCopyDlg::IsPrinterValid() const
{
return m_ComboPrinterSelect.IsWindowEnabled();
}
BOOL CTCopyDlg::GetResolution()
{
UpdateData(TRUE);
switch (m_RCResolution)
{
case 0:
return 96;
case 1:
return 360;
case 2:
return 720;
}
return 360;
}
BOOL CTCopyDlg::GetBitmap(BOOL bPrint)
{
SetStateInfo(IDS_STARTSCANNING);
m_bPrintImageAutomatic = bPrint;
CTwainPP::EImageType eImageType = (CTwainPP::EImageType)m_RCImageColorSelect;
CTwainPP::SBitmapOptions Options;
Options.eImageType = eImageType;
Options.nResolution = GetResolution();
Options.nBrightness = m_BrightnessSlider.GetPos() + m_nBrightnessOffset;
Options.nContrast = m_ContrastSlider.GetPos() + m_nContrastOffset;
const SIZE printSize = m_PrinterAccess.GetPrintSizeMM(GetPrinterName());
double f = 10.0 / m_SpinCtrlScaling.GetPos(); // [mm] -> [cm]
Options.fSizeX = float(printSize.cx * f);
Options.fSizeY = float(printSize.cy * f);
return m_TwainPP.GetBitmap(IsDlgModusSelected(), Options);
}
void CTCopyDlg::OnRcModusChange()
{
UpdateData(TRUE);
BOOL bEnable = !IsDlgModusSelected();
EnableCtrlsOfGroupBox(this, IDC_ST_SELECTCOLORMODE, bEnable);
EnableCtrlsOfGroupBox(this, IDC_ST_SELECTRESOLUTION, bEnable);
EnableCtrlsOfGroupBox(this, IDC_ST_BRIGHTNESS, bEnable);
EnableCtrlsOfGroupBox(this, IDC_ST_CONTRAST, bEnable);
EnableCtrlsOfGroupBox(this, IDC_ST_SCALING, bEnable);
}
void CTCopyDlg::OnFinish()
{
EndDialog(IDOK);
}
BOOL CTCopyDlg::DoPrint()
{
SetStateInfo(IDS_PRINTING);
CString sJobName;
GetWindowText(sJobName);
CString sPrinterName = GetPrinterName();
SelectFax(FALSE);
if (!m_PrinterAccess.PrintDIB(sJobName, sPrinterName, m_DIBUse))
{
SetStateInfo(IDS_ERRORPRINTING);
return FALSE;
}
return TRUE;
}
void CTCopyDlg::OnBtnPrint()
{
DoPrint();
}
BOOL CTCopyDlg::DoWriteFile(const char* pFileName) const
{
CFile file;
if (!file.Open(pFileName, CFile::modeReadWrite | CFile::modeCreate))
return FALSE;
HDIB hDIB = m_DIBUse.GetDIBHandle();
const BITMAPINFO* pDIB = (const BITMAPINFO*)GlobalLock(hDIB);
if (!pDIB)
return FALSE;
BOOL bRes = TRUE;
try
{
BITMAPFILEHEADER header;
if (m_DIBUse.FillFileHeader(header))
{
file.Write(&header, sizeof(BITMAPFILEHEADER));
file.Write(pDIB, pDIB->bmiHeader.biSizeImage);
}
else
bRes = FALSE;
}
catch(CFileException*)
{
bRes = FALSE;
}
GlobalUnlock(hDIB);
return bRes;
}
BOOL CTCopyDlg::DoLoadFile(const char* pFileName)
{
CFile file;
if (!file.Open(pFileName, CFile::modeRead))
return FALSE;
BITMAPFILEHEADER header;
if (file.Read(&header, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER) || header.bfType != MARK_BMP)
return FALSE;
DWORD nBitmapSize = header.bfSize - sizeof(BITMAPFILEHEADER);
HDIB hDIB = GlobalAlloc(GMEM_MOVEABLE, nBitmapSize);
if (!hDIB)
return FALSE;
BITMAPINFO* pDIB = (BITMAPINFO*)GlobalLock(hDIB);
if (!pDIB)
return FALSE;
BOOL bRes = file.Read(pDIB, nBitmapSize) >= pDIB->bmiHeader.biSizeImage;
GlobalUnlock(hDIB);
if (!bRes || !m_DIBUse.SetDIB(hDIB))
GlobalFree(hDIB);
m_ctlrShowBitmap.SetDIBitmap(m_DIBUse);
return bRes;
}
void CTCopyDlg::OnMenuFileSave()
{
CFileDialog SaveDlg(FALSE, ".bmp", STR_PICTURE, OFN_OVERWRITEPROMPT, STR_BITMAPFILETYPE);
if (SaveDlg.DoModal() == IDOK)
{
SetStateInfo(IDS_WRITEFILE);
if (DoWriteFile(SaveDlg.m_ofn.lpstrFile))
SetStateInfo(IDS_READYTOSCAN);
else
SetStateInfo(IDS_ERRORWRITINGFILE);
}
}
void CTCopyDlg::OnMenuFileLoad()
{
CFileDialog LoadDlg(TRUE, ".bmp", STR_PICTURE, OFN_FILEMUSTEXIST, STR_BITMAPFILETYPE);
if (LoadDlg.DoModal() == IDOK)
{
SetStateInfo(IDS_LOADFILE);
if (DoLoadFile(LoadDlg.m_ofn.lpstrFile))
SetStateInfo(IDS_READYTOSCAN);
else
SetStateInfo(IDS_ERRORLOADINGFILE);
}
}
void CTCopyDlg::OnPrinterSelection()
{
float fMaxScanWidth;
float fMaxScanHeight;
int nMinScaling = 100;
if (m_TwainPP.GetMaxImageSize(fMaxScanWidth, fMaxScanHeight))
{
SIZE paperSize = m_PrinterAccess.GetPrintSizeMM(GetPrinterName());
nMinScaling = int(100.0 * max(paperSize.cx / (fMaxScanWidth * 10.0), paperSize.cy / (fMaxScanHeight * 10.0)));
}
int nLower;
int nUpper;
m_SpinCtrlScaling.GetRange32(nLower, nUpper);
if (nLower != nMinScaling)
m_SpinCtrlScaling.SetRange32(nMinScaling, 400);
}
const CString CTCopyDlg::GetPrinterName() const
{
if (m_bFaxSelect)
return m_sFax;
return m_ComboPrinterSelect.GetSelectedPrinter();
}
void CTCopyDlg::SelectFax(BOOL bSelect)
{
m_bFaxSelect = bSelect;
EnableCtrlsOfGroupBox(this, IDC_SC_PRINTERSELECT, !bSelect);
}
void CTCopyDlg::OnBtnFax()
{
if (!m_sFax.IsEmpty())
{
SelectFax(TRUE);
OnBtnCopy();
}
}
BOOL CTCopyDlg::WriteIniFileData(int nBrightness, int nContrast) const
{
CTCopyApp* pCopyApp = dynamic_cast<CTCopyApp*>(AfxGetApp());
return pCopyApp->WriteIniFileValue(STR_BRIGHTNESS, nBrightness)
&& pCopyApp->WriteIniFileValue(STR_CONTRAST, nContrast);
}
void CTCopyDlg::ReadDefaults()
{
CTCopyApp* pCopyApp = dynamic_cast<CTCopyApp*>(AfxGetApp());
pCopyApp->ReadIniFileValue(STR_BRIGHTNESS, m_nBrightnessOffset);
pCopyApp->ReadIniFileValue(STR_CONTRAST, m_nContrastOffset);
}
void CTCopyDlg::OnMenuSaveDefaults()
{
UpdateData(TRUE);
m_nBrightnessOffset += m_BrightnessSlider.GetPos();
m_nContrastOffset += m_ContrastSlider.GetPos();
WriteIniFileData(m_nBrightnessOffset, m_nContrastOffset);
m_BrightnessSlider.SetPos(0);
m_ContrastSlider.SetPos(0);
UpdateData(FALSE);
}
void CTCopyDlg::OnMenuResetDefaults()
{
m_nBrightnessOffset = m_nContrastOffset = 0;
WriteIniFileData(0,0);
}