⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twain.c

📁 清华紫光twain扫描仪编程接口范例
💻 C
字号:

// UNISCAN windows scanning program
// Tsinghua Unisplendour Group
// Programmed in MS VC/C++
// Daohong Kan, Aug.23, 1996

#include "windows.h"
#include "stdio.h"
#include "string.h"
#include "scan.h"
#include "twain.h"

extern HWND  hWnd;

DSMENTRYPROC pDSMEntry;
HANDLE       hDSMLib;
TW_IDENTITY  AppID, ScannerID;
char dsmOpened = 'N', dsOpened = 'N';

extern void UNMessageBox(char *);
UNTwainError(char*, TW_UINT16);

UNLoadDSM(void)    // State 1 to 2, 3
    {
    char TwainDir[MAX_FILENAME];
    OFSTRUCT of;
    TW_UINT16 rc;

    // State 1 to 2, Load DSM    
    GetWindowsDirectory(TwainDir, MAX_FILENAME);
    lstrcat(TwainDir, "\\TWAIN_32.DLL");
    if (OpenFile(TwainDir, &of, OF_EXIST) != -1)
        hDSMLib = LoadLibrary(TwainDir);
    else
        hDSMLib = NULL;
    if (!hDSMLib)
        pDSMEntry = NULL;
    else
        {
        pDSMEntry = (DSMENTRYPROC)GetProcAddress(hDSMLib, MAKEINTRESOURCE(1));
        if (!pDSMEntry)
            FreeLibrary(hDSMLib);
        }
    if (pDSMEntry == NULL)
        {
        UNMessageBox("No TWAIN DSM");
        return(UN_ERROR);
        }
        
    // State 2 to 3, Open DSM
    AppID.Id               = 0;
    AppID.Version.MajorNum = 1;
    AppID.Version.MinorNum = 5;
    AppID.Version.Language = TWLG_USA;
    AppID.Version.Country  = TWCY_USA;
    lstrcpy(AppID.Version.Info, "Uniscan V1.0");
    AppID.ProtocolMajor    = TWON_PROTOCOLMAJOR;
    AppID.ProtocolMinor    = TWON_PROTOCOLMINOR;
    AppID.SupportedGroups  = DG_IMAGE | DG_CONTROL;
    lstrcpy(AppID.Manufacturer, "Tsinghua Unisplendour Group Company");
    lstrcpy(AppID.ProductFamily, "Uniscan Application");
    lstrcpy(AppID.ProductName, "Uniscan");
    rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM,
                      (TW_MEMREF)&hWnd);
    if (UNTwainError("Open DSM", rc) == UN_OK)
        {
        dsmOpened = 'Y';
        // State 3, Get default DS
        rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT,
                           (TW_MEMREF)&ScannerID);
        UNTwainError("DefaultDS", rc);
        }
    return(UN_OK);
    }

UNSelectSource(void)    // State 3
    {
    TW_UINT16    rc;

    ScannerID.Id             = 0;
    ScannerID.ProductName[0] = '\0';
    rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT,
                      (TW_MEMREF)&ScannerID);
    UNTwainError("Select Source", rc);
    return (UN_OK);
    }
    
UNOpenDS(void)    // State 3 to 4
    {
    TW_UINT16    rc;

    rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS,
                      (TW_MEMREF)&ScannerID);
    if (UNTwainError("Open DS", rc) == UN_OK)
        dsOpened = 'Y';
    return (UN_OK);
    }
    
UNNegotiateCap(void)    // State 4
    {
    TW_UINT16     rc;
    TW_CAPABILITY twCap;
    pTW_ONEVALUE  pval;

    twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
    pval = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
    
/*  The following is for ADF only, can be deleted
    // Set ADF
    twCap.Cap        = CAP_FEEDERENABLED;
    twCap.ConType    = TWON_ONEVALUE;
    pval->ItemType   = TWTY_UINT16;
    pval->Item       = FALSE;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
                      (TW_MEMREF)&twCap);
    if (UNTwainError("Negotiate FEEDERENABLED", rc) == UN_OK)
        {
        // Set paper autofeeding
        twCap.Cap        = CAP_AUTOFEED;
        twCap.ConType    = TWON_ONEVALUE;
        pval->ItemType   = TWTY_UINT16;
        pval->Item       = TRUE;
        rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
                          (TW_MEMREF)&twCap);
        UNTwainError("Negotiate AUTOFEED", rc);
        }
 */

    // Set multi-image transfer
    twCap.Cap        = CAP_XFERCOUNT;
    twCap.ConType    = TWON_ONEVALUE;
    pval->ItemType   = TWTY_UINT16;
    pval->Item       = (TW_UINT32)-1;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
                      (TW_MEMREF)&twCap);
    UNTwainError("Negotiate XFERCOUNT", rc);
    // Set buffer memory transfer
    twCap.Cap        = ICAP_XFERMECH;
    twCap.ConType    = TWON_ONEVALUE;
    pval->ItemType   = TWTY_UINT16;
    pval->Item       = TWSX_MEMORY;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
                       (TW_MEMREF)&twCap);
    UNTwainError("Negotiate XFERMECH", rc);
    // Set pixel flavor
    twCap.Cap        = ICAP_PIXELFLAVOR;
    twCap.ConType    = TWON_ONEVALUE;
    pval->ItemType   = TWTY_UINT16;
    pval->Item       = TWPF_CHOCOLATE;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
                       (TW_MEMREF)&twCap);
    UNTwainError("Negotiate PIXELFLAVOR", rc);

    GlobalUnlock(twCap.hContainer);
    GlobalFree(twCap.hContainer);
    return (UN_OK);
    }

UNEnableDS(void)    // State 4 to 5
    {
    TW_UINT16 rc;
    TW_USERINTERFACE ui;
    
    ui.ShowUI  = TRUE;
    ui.ModalUI = FALSE;
    ui.hParent = hWnd;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS,
                      (TW_MEMREF)&ui);
    UNTwainError("Enable DS", rc);
    return (UN_OK);
    }
    
UNGetImage()    // State 6 to 7, 7 to 6
    {
    TW_UINT16       rc;
    TW_IMAGEINFO    iInfo;
    TW_IMAGELAYOUT  iLay;
    TW_SETUPMEMXFER iMem;
    TW_IMAGEMEMXFER iBuf;
    TW_PENDINGXFERS iEnd;
    HANDLE          hBuf;
    char hasNextBuf, str[256];
    unsigned char TW_HUGE *buf;
    HFILE hFile;
    OFSTRUCT of;
    
    iEnd.Count = 1;
    while (iEnd.Count != 0)
        {
        // Get image information
        rc = (*pDSMEntry)(&AppID, &ScannerID, DG_IMAGE, DAT_IMAGEINFO, MSG_GET,
                          (TW_MEMREF)&iInfo);
        sprintf(str, "xRes=%d  yRes=%d\nWidth=%ld  Height=%ld\nSamp=%d  Bits=%d",
                 iInfo.XResolution.Whole, iInfo.YResolution.Whole,
                 iInfo.ImageWidth, iInfo.ImageLength,
                 iInfo.SamplesPerPixel, iInfo.BitsPerPixel);
        switch (iInfo.PixelType)
            {
        case TWPT_BW  : lstrcat(str, "\nType=BW");   break;
        case TWPT_GRAY: lstrcat(str, "\nType=GRAY"); break;
        case TWPT_RGB : lstrcat(str, "\nType=RGB");  break;
        default:    // Not accepted by application, such as TWPT_CMYK, TWPT_YUV
            lstrcat(str, "\nType=Error"); break;
            }
        UNMessageBox(str);
        // Get image layout
        rc = (*pDSMEntry)(&AppID, &ScannerID, DG_IMAGE, DAT_IMAGELAYOUT, MSG_GET,
                          (TW_MEMREF)&iLay);
        sprintf(str, "L=%d  T=%d  R=%d  B=%d\nDNo=%ld  PNo=%ld  FNo=%ld",
                iLay.Frame.Left.Whole, iLay.Frame.Top.Whole,
                iLay.Frame.Right.Whole, iLay.Frame.Bottom.Whole,
                iLay.DocumentNumber, iLay.PageNumber, iLay.FrameNumber);
        UNMessageBox(str);
        // Get memory preferred
        rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET,
                          (TW_MEMREF)&iMem);
        //sprintf(str, "Min=%ld  Max=%ld  Pre=%ld",
        //         iMem.MinBufSize, iMem.MaxBufSize, iMem.Preferred);
        //UNMessageBox(str);

        hBuf = GlobalAlloc(GHND, iMem.Preferred);
        buf = (unsigned char TW_HUGE *)GlobalLock(hBuf);

        iBuf.Memory.Flags  = TWMF_APPOWNS | TWMF_POINTER;
        iBuf.Memory.Length = iMem.Preferred;
        iBuf.Memory.TheMem = buf;
        iBuf.Compression   = TWON_DONTCARE16;
        iBuf.BytesPerRow   = TWON_DONTCARE32;
        iBuf.Columns       = TWON_DONTCARE32;
        iBuf.Rows          = TWON_DONTCARE32;
        iBuf.XOffset       = TWON_DONTCARE32;
        iBuf.YOffset       = TWON_DONTCARE32;
        iBuf.BytesWritten  = TWON_DONTCARE32;
        hasNextBuf = 'Y';
        hFile = OpenFile("IMAGE.DAT", &of, OF_CREATE);
        _lwrite(hFile, (const char*)&iInfo.ImageWidth, 4);
        _lwrite(hFile, (const char*)&iInfo.ImageLength, 4);
        while (hasNextBuf == 'Y')
            {
            rc = (*pDSMEntry)(&AppID, &ScannerID, 
                               DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET,
                               (TW_MEMREF)&iBuf);
            switch (rc)
                {
            case TWRC_SUCCESS:
                sprintf(str, "Byte/Row=%ld  Columns=%ld\nRows=%ld  Bytes=%ld",
                        iBuf.BytesPerRow, iBuf.Columns, iBuf.Rows, iBuf.BytesWritten);
                UNMessageBox(str);
                // Here to process or save image data in buf
                _lwrite(hFile, buf, (UINT)iBuf.BytesWritten);
                iBuf.Memory.TheMem = buf;
                //_fmemset(buf, 0, (size_t)iMem.Preferred);
                break;
    
            case TWRC_XFERDONE:
                sprintf(str, "Byte/Row=%ld  Columns=%ld\nRows=%ld  Bytes=%ld",
                        iBuf.BytesPerRow, iBuf.Columns, iBuf.Rows, iBuf.BytesWritten);
                UNMessageBox(str);
                // Here to process or save image data in buf
                _lwrite(hFile, buf, (UINT)iBuf.BytesWritten);
                _lclose(hFile);
                hasNextBuf = 'N';
                GlobalUnlock(hBuf);
                GlobalFree(hBuf);
                rc = (*pDSMEntry)(&AppID, &ScannerID,
                                   DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
                                   (TW_MEMREF)&iEnd);
                SendMessage(hWnd, UN_XFERDONE, 0, 0);
                break;
    
            case TWRC_CANCEL:
            case TWRC_FAILURE:
            default:
                _lclose(hFile);
                hasNextBuf = 'N';
                GlobalUnlock(hBuf);
                GlobalFree(hBuf);
                rc = (*pDSMEntry)(&AppID, &ScannerID, 
                                   DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
                                   (TW_MEMREF)&iEnd);
                SendMessage(hWnd, UN_XFERDONE, 0, 0);
                break;
                }
            }
        sprintf(str, "Image Ready=%d", iEnd.Count);
        UNMessageBox(str);
        }

    return(UN_OK);
    }
    
UNCloseDS(void)    // State 5 to 3
    {
    TW_UINT16 rc;
    TW_USERINTERFACE ui;
    
    ui.ShowUI  = TRUE;
    ui.ModalUI = TRUE;
    ui.hParent = hWnd;
    rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS,
                      (TW_MEMREF)&ui);
    rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS,
                      (TW_MEMREF)&ScannerID);
    dsOpened = 'N';
    return (UN_OK);
    }
    
UNCloseDSM(void)    // State 3 to 1
    {
    TW_UINT16    rc;
    
    rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
                      (TW_MEMREF)&hWnd);
    FreeLibrary(hDSMLib);
    dsmOpened = 'N';
    return (UN_OK);
    }
    
UNTwainError(char *act, TW_UINT16 rc)
    {
    char str[256];
                   
    lstrcpy(str, act);
    switch(rc)
        {
    case TWRC_SUCCESS:
        lstrcat(str, ": Success");
        //UNMessageBox(str);
        return(UN_OK);
        break;
        
    case TWRC_FAILURE:
    default:
        lstrcat(str, ": Failure");
        UNMessageBox(str);
        return(UN_ERROR);
        break;
        }
    }
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -