您现在的位置:网站首页 > 经验分享 > 完整的图像扫描类
设计师介绍:

昵称:烦夫子
类别:界面/平面设计师
年龄:38
现所在地:北京

查看该设计师的主页>>

关注好友

统计中心

主页浏览总数:24261
总积分:89
文章数:88
作品数:70

完整的图像扫描类

作者:烦夫子  更新时间: 2007-11-19   浏览人数:38611  评论:0  
分享到:

// ctwain.h - application interface to TWAIN Protocol
//
#ifndef CTWAIN_H
#define CTWAIN_H

#include "twain.h"

//结构和用法:
// CTwain 最好作为 mainframe的第二个基类来使用,
// 这样,回调比较方便,程序也比较紧凑。
//
// RegisterApp 可以填入真实信息
//
// 0. If !TwainAvailable(), 无twain,菜单被禁止,无须其他处理。
// 1. 在main frame window 建立后(on create),调用SetDefWindow(this),
// 和 OpenSourceManager()。如果 OpenSourceManager() 失败,你可以
// 提示用户twain 出错(这需要你附加代码).
// 2. 当State() == SOURCE_MANAGER_OPEN 时,使 Acquire and Select Source
// 命令可用。
// 3. 在 Acquire 命令响应中,调用 BeginAcquire.
// 4. Override CWnd::PreTranslateMessage(pMsg),加入:
// return (TwainMessageHook(pMsg) ||
// ::PreTranslateMessage(pMsg);
// 5. Override CTwain::DibReceived 处理native transfers返回的dib句柄。
// 注意:在调用BeginAcquire后, 你可以传输多幅图象,data source
// 始终打开着,若要关闭,调用 CloseSource.
// 可待扩展:Add support for Memory and File transfer(可能不标准).


typedef enum {
NO_TWAIN_STATE, // 0 internal use only
PRE_SESSION, // 1 ground state, nothing loaded
SOURCE_MANAGER_LOADED, // 2 DSM loaded but not open
SOURCE_MANAGER_OPEN, // 3 DSM open
SOURCE_OPEN, // 4 some Source open - Negotiation state!
SOURCE_ENABLED, // 5 acquisition started
TRANSFER_READY, // 6 data ready to transfer
TRANSFERRING // 7 transfer started
} TW_STATE;

typedef enum {
TWERR_OPEN_DSM, // unable to load or open Source Manager
TWERR_OPEN_SOURCE, // unable to open Datasource
TWERR_ENABLE_SOURCE, // unable to enable Datasource
} TW_ERR;

class CTwain
{
public:

BOOL SetPixelType(TW_UINT32 pxlType);
CTwain(void);
~CTwain();

// General notes:
// 1. 一旦source manager 被装载, 直到对象被释放才被卸载。
// (或UnloadSourceManager)
// 第一次调用TwainAvailable时装载 source manager.

// attributes i.e. query functions
int TwainAvailable(void);
// TRUE ,如果 TWAIN Datasource Manager 存在并被装载。
// 不检查是否有 datasources!
// 可用IsAvailable 来 enable or disable menu items .

TW_STATE State(void);
// Return the current (presumed) state of the Twain connection.

unsigned ResultCode(void);
// last result code (see twain.h)

unsigned ConditionCode(void);
// retrieve condition code from last triplet - see twain.h.

// Top-level operations
void SetDefWindow(CWnd* pWnd);
//def window 是主窗口。
// If no default window is set, AfxGetMainWnd() is used.

int SelectSource(CWnd* pWnd = NULL);
// Post the standard Select Source dialog

void ModalAcquire(CWnd* pWnd = NULL);
// Acquire images from current or default source.
// By default, displays the u/i of the source and acquires images
// until a CLOSEDSREQ is received from the source.
// Acquire returns the Twain connection to the starting state
// or to SOURCE_ENABLED, whichever is lower.

int BeginAcquire(CWnd* pWnd = NULL);
// Open and enable the default source.
// TRUE if successful, FALSE if something goes wrong.
// If successful, State() == SOURCE_ENABLED.
// You must now pass all messages to MessageHook until the state
// drops below SOURCE_OPEN: In MFC, override PreTranslateMessage.
// If BeginAcquire fails, it returns TWAIN to the state it
// found it in.

void RegisterApp( // Record application information
int nMajorNum, int nMinorNum, // major and incremental revision of application. E.g.
// for version 2.1, nMajorNum == 2 and nMinorNum == 1
int nLanguage, // language of this version (use TWLG_xxx from TWAIN.H)
int nCountry, // country of this version (use TWCY_xxx from TWAIN.H)
LPSTR lpszVersion, // version info string e.g. "1.0b3 Beta release"
LPSTR lpszMfg, // name of manufacturer/developer e.g. "Crazbat Software"
LPSTR lpszFamily, // product family e.g. "BitStomper"
LPSTR lpszProduct); // specific product e.g. "BitStomper Deluxe Pro"
// This is not necessary for acquisition, but is required for full
// TWAIN compliance.

// 内部操作:
int OpenSourceManager(CWnd* pWnd = NULL);
// (Load and) open the Datasource Manager
// Loads the DSM if necessary, opens it if necessary.
// If State >= 3, does nothing and returns TRUE.

int OpenDefaultSource(void);
// Open the default datasource (last source selected in Select Source dialog.)
// Invalid (returns FALSE) if State > 3 (a source is already open)
// Invalid (returns FALSE) if State < 3 (DSM is not open)
// If successful, returns TRUE with State == 4.
// Otherwise, returns FALSE with State unchanged.

void SetShowUI(BOOL bShow = 1);
// Set flag for whether source should be enabled with
// user interface visible (bShow == TRUE) or not.
// At construction, ShowUI is set TRUE.

BOOL GetShowUI(void);
// Return state of ShowUI flag.

int EnableSource(CWnd* pWnd = NULL);
// Enable the open source, which allows image acquisition to begin.
// Invalid if State != 4 (source open).
// If successful, returns TRUE with State == 5.
// Otherwise, returns FALSE with State unchanged.

int DisableSource(void);
// Disable the current source.
// If State == 5, disables the current source and returns TRUE.
// If State < 5, does nothing and returns TRUE.
// If State > 5, does nothing and returns FALSE.

int CloseSource(void);
int CloseSourceManager(CWnd* pWnd = NULL);
int UnloadSourceManager(void);

int DropToState(int nS, CWnd* pWnd = NULL);

// 底层操作
int LoadSourceManager(void);
// loads the DSM (Datasource Manager) into process space

void ModalEventLoop(void);
// get and dispatch messages until source is disabled.

int TwainMessageHook(LPMSG lpmsg);

int EndXfer(void);
// In State 7, ends the current transfer by sending MSG_ENDXFER.
// If successful, goes to State 6 if there are more transfers
// available (pendingXfers != 0), or to State 5 if not.
// Returns TRUE if the resulting State < 7.

int CancelXfers(void);
// In State 6, cancels any pending transfers.
// (In State 7, does an EndXfer first)
// If successful, goes to State 5.
// Returns TRUE if the resulting State < 6.

// DS,SM
int DS(unsigned long dg, unsigned dat, unsigned msg, void FAR *pd);
// send a triplet to the current Datasource.
// returns TRUE if the result code (rc) == RC_SUCCESS, FALSE otherwise.
// Note that this is not meaningful with some triplets.
// Does ASSERT(nState < 4);

int SM(unsigned long dg, unsigned dat, unsigned msg, void FAR *pd);
// Send a triplet to the Source Manager.
// returns TRUE if the result code (rc) == RC_SUCCESS, FALSE otherwise.
// Note that this is not meaningful with some triplets.
// Does ASSERT(nState > 1);

// 回调函数
virtual void XferReady(LPMSG lpmsg);
// called when source has one or more xfers ready
// This default method assumes XferMech = Native,
// gets each native (DIB) image and calls back to DibReceived.

virtual void CloseDsRequest(void);
// called when the open source asks to be 'closed'
// It is sufficient to disable the source on this request,
// but this default handler calls CloseSource.

virtual void DibReceived(HGLOBAL hDib);
// called by the default XferReady handler
// when it has successfully transferred a DIB.
// This default handler just calls GlobalFree(hDib).

virtual void StateChange(int nState);
// called after each Twain State transition.
// nState is the new State. When this callback
// occurs, the state transition has already happened.
// Note - first call is the transition to State 1
// which occurs at construction.

virtual void TwainError(TW_ERR e);
// Called when an unexpected TWAIN malfunction occurs.
// See TW_ERR declaration at beginning of this file.

protected:

void SetState(TW_STATE nS); // assume Twain in State nS

CWnd* DefWnd(CWnd* pWnd = NULL);
// Returns pWnd if it's non-null, otherwise it
// finds a safe non-null default substitute.

BOOL bTrace; // enable TRACE output
TW_STATE nState; // current state
TW_STATE nStartState; // starting state for some operation
TW_IDENTITY AppId; // application identity structure
TW_INT16 rc; // last result code
TW_USERINTERFACE twUI;
BOOL bShowUI;
TW_PENDINGXFERS pendingXfers;
HANDLE hDib; // bitmap returned by native transfer
CWnd* pDefWnd; // default window
};

#endif

// ctwain.cpp - implementation of a mfc TWAIN class

//进行扫描处理的类

#include "stdafx.h"
#include "ctwain.h"

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


#ifdef WIN32
#define DSM_FILENAME "TWAIN_32.DLL"
#define DSM_ENTRYPOINT "DSM_Entry"
#else
#define DSM_FILENAME "TWAIN.DLL"
#define DSM_ENTRYPOINT "DSM_ENTRY"
#endif

#define IsValidHandle(h) ((h) != NULL)

#define TRACE_ERROR(e) { if (bTrace) TRACE("TWAIN: Error(%d) ", e); TwainError(e); }

static int iAvailable; // TWAIN available: 0:unknown, -1:No, 1:Yes
static DSMENTRYPROC pSM_Entry; // entry point of Data Source Manager (TWAIN_32.DLL)
static HINSTANCE hSMLib; // handle of SM

// default application identity structure:
const TW_IDENTITY DefAppId = {
0, // Id, filled in by SM
{ 1, 0, TWLG_USA, TWCY_USA, "OSM"}, // Version
TWON_PROTOCOLMAJOR,
TWON_PROTOCOLMINOR,
DG_IMAGE | DG_CONTROL,
"OSM", // Mfg
"OSM", // Family
"OSM" // Product
};
static TW_IDENTITY SourceId; // source identity structure


// CTwain class members
CTwain::CTwain(void)
: pDefWnd(NULL), nState(NO_TWAIN_STATE)
{
bShowUI = TRUE;
hDib = NULL;
rc = TWRC_SUCCESS;
// turn off if you get tired of seeing the output:
bTrace = TRUE;

AppId = DefAppId; // provide default registration
SetState(PRE_SESSION);

iAvailable= 0;//-1;
pSM_Entry = NULL;
hSMLib = NULL;
}

//注册应用信息
void CTwain::RegisterApp( // record application information
int nMajorNum, int nMinorNum, // major and incremental revision of application. E.g.
// for version 2.1, nMajorNum == 2 and nMinorNum == 1
int nLanguage, // language of this version (use TWLG_xxx from TWAIN.H)
int nCountry, // country of this version (use TWCY_xxx from TWAIN.H)
LPSTR lpszVersion, // version info string e.g. "1.0b3 Beta release"
LPSTR lpszMfg, // name of manufacturer/developer e.g. "Crazbat Software"
LPSTR lpszFamily, // product family e.g. "BitStomper"
LPSTR lpszProduct) // specific product e.g. "BitStomper Deluxe Pro"
{
AppId.Id = 0; // init to 0, but Source Manager will assign real value
AppId.Version.MajorNum = nMajorNum;
AppId.Version.MinorNum = nMinorNum;
AppId.Version.Language = nLanguage;
AppId.Version.Country = nCountry;
lstrcpy (AppId.Version.Info, lpszVersion);

AppId.ProtocolMajor = TWON_PROTOCOLMAJOR;
AppId.ProtocolMinor = TWON_PROTOCOLMINOR;
AppId.SupportedGroups = DG_IMAGE | DG_CONTROL;
lstrcpy (AppId.Manufacturer, lpszMfg);
lstrcpy (AppId.ProductFamily, lpszFamily);
lstrcpy (AppId.ProductName, lpszProduct);
}

CTwain::~CTwain()
{
// shut down the Twain connection
CloseSourceManager();
UnloadSourceManager();
}

//
int CTwain::TwainAvailable(void)
{
if (pSM_Entry) return TRUE; // SM currently loaded

if (iAvailable == 0) {
if (LoadSourceManager()) {
iAvailable = 1;
} else {
iAvailable = -1;
}
}
return (iAvailable > 0);
}

//扫描状态
TW_STATE CTwain::State(void)
{
return nState;
}

//设置扫描状态
void CTwain::SetState(TW_STATE nS)
{
#ifdef _DEBUG
if (bTrace) {
const char *pzState[] = {
"",
"1:PRE_SESSION",
"2:SOURCE_MANAGER_LOADED",
"3:SOURCE_MANAGER_OPEN",
"4:SOURCE_OPEN",
"5:SOURCE_ENABLED",
"6:TRANSFER_READY",
"7:TRANSFERRING"
};
TRACE("TWAIN: State %s -> %s ", pzState[nState], pzState[nS]);
}
#endif

nState = nS; // update the 'global'
StateChange(nS); // notify derived classes via callback
} // SetState


void CTwain::SetDefWindow(CWnd* pWnd)
// Sets the CWnd* to be used as the default for all other calls that
// take a window argument - SelectSource, OpenSourceManager, etc.
// If no default window is set, AfxGetMainWnd() is used.
{
pDefWnd = pWnd;
}


CWnd* CTwain::DefWnd(CWnd* pWnd)
// Returns pWnd if it's non-null, otherwise it
// finds a safe non-null default substitute.
{
return pWnd ? pWnd : pDefWnd ? pDefWnd : AfxGetMainWnd();
} // DefWnd

//选择扫描源
int CTwain::SelectSource(CWnd* pWnd)
{
TW_IDENTITY NewSourceId;
TW_STATE nStartState = State();
int bSuccess = FALSE;

pWnd = DefWnd(pWnd);
if (!OpenSourceManager(pWnd)) {
TRACE_ERROR(TWERR_OPEN_DSM);
//"Unable to load & open TWAIN Source Manager");
} else {
// I will settle for the system default. Shouldn't I get a highlight
// on system default without this call?
SM(DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &NewSourceId);
// now do the real thing
bSuccess = SM(DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &NewSourceId);
}

DropToState(nStartState, pWnd);

return bSuccess;
}

//接受模式
void CTwain::ModalAcquire(CWnd* pWnd)
{
pWnd = DefWnd(pWnd);
if (BeginAcquire(pWnd)) {
pWnd->EnableWindow(FALSE);
// source is enabled, wait for transfer or source closed
ModalEventLoop();
pWnd->EnableWindow(TRUE);
DropToState(nStartState);
} else {
// BeginAcquire puts everything back when it fails
}
}

//开始接受扫描源
int CTwain::BeginAcquire(CWnd* pWnd)
{
nStartState = State();
pWnd = DefWnd(pWnd);

if (State() >= SOURCE_MANAGER_OPEN || OpenSourceManager(pWnd)) {
if (State() >= SOURCE_OPEN || OpenDefaultSource()) {
SetPixelType(TWPT_BW);
if (State() >= SOURCE_ENABLED || EnableSource(pWnd)) {
return TRUE;
} else {
TRACE_ERROR(TWERR_ENABLE_SOURCE);
}
} else {
TRACE_ERROR(TWERR_OPEN_SOURCE);
}
} else {
TRACE_ERROR(TWERR_OPEN_DSM);
}
DropToState(nStartState);
return FALSE;
} // BeginAcquire


int CTwain::LoadSourceManager(void)
{
char szSM[256];
OFSTRUCT of;

if (nState >= SOURCE_MANAGER_LOADED) {
return TRUE; // SM already loaded
}

GetWindowsDirectory(szSM, sizeof(szSM));
if (szSM[lstrlen(szSM)-1] != '\') {
lstrcat(szSM, "\");
}
lstrcat(szSM, DSM_FILENAME); // could crash!
if (OpenFile(szSM, &of, OF_EXIST) != -1) {
hSMLib = LoadLibrary(szSM);
} else {
if (bTrace) TRACE("TWAIN: LoadLibrary(%s) failed ", szSM);
hSMLib = NULL;
}
if (IsValidHandle(hSMLib)) {
pSM_Entry = (DSMENTRYPROC) GetProcAddress(hSMLib, DSM_ENTRYPOINT);
if (pSM_Entry) {
iAvailable = 1;
SetState(SOURCE_MANAGER_LOADED);
} else {
if (bTrace) TRACE("TWAIN: GetProcAddress() failed!! ");
FreeLibrary(hSMLib);
hSMLib = NULL;
}
} else {
pSM_Entry = NULL;
}

if (nState != SOURCE_MANAGER_LOADED && bTrace)
TRACE("TWAIN: LoadSourceManager() failed. ");

return (nState >= SOURCE_MANAGER_LOADED);
} // LoadSourceManager

//打开资源管理器
int CTwain::OpenSourceManager(CWnd* pWnd)
{
TW_INT32 hwnd32 = (TW_INT32)(int)(DefWnd(pWnd)->m_hWnd);

if (LoadSourceManager()) {
SM(DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &hwnd32);
if (nState != SOURCE_MANAGER_OPEN && bTrace) TRACE("TWAIN: OPENDSM failed. ");
}
return (nState >= SOURCE_MANAGER_OPEN);
}

//打开缺省的扫描源
int CTwain::OpenDefaultSource(void)
{
if (nState != SOURCE_MANAGER_OPEN) return FALSE;

// open the system default source
SourceId.ProductName[0] = '

(目前有0人发表看法,  我要发表评论
<<上一篇: 我参入的软件工程之一     下一篇: dxf数据格式输出输出类>>
我要评论:
  只有登录后才能评论!
评论者: 匿名游客    (立即登录 或 注册)