Example: Native / Buffered Acquisition (DTWAIN_MODELESS)
The example below shows an example of a 'C' Windows API program that acquires images using the Native transfer mode and adjusts the main application loop. If your language has the ability of altering the main application loop, and can simulate the Windows MSG structure, this method is the preferred way to acquire images.
In the example, DTWAIN Notification handing is also demonstrated. The images are retrieved and then deleted (in a real world application, the images would be used for display purposes). The number of acquisitions attempted by the user, as well as the number of images acquired by each acquisition is computed and outputted using the Windows API MessageBox function.
The same example can be used for the Buffered transfer mode. The only difference would be a call to DTWAIN_AcquireBuffered instead of DTWAIN_AcquireNative, and that the images may not be DIB's but compressed data (if compression is requested by the application).
The Source is selected by using the traditional TWAIN 'Select Source' dialog, and the application is responsible for adjusting the main message loop so that TWAIN messages can be processed successfully (the call to DTWAIN_SetTwainMode function with the DTWAIN_MODELESS flag). The example consists of the source and resource files. The example is lengthy, but most of this accounted for by the traditional Window's 'C' SDK initializations.
The example is broken down into four files. DTWDEMO.C, DTWDEMO.H, DTWDEMO.RC, and DTWDEMO.DEF.
-------------------------------------------------- /* DTWDEMO.C */ #include "dtwdemo.h" #include <tchar.h>
long FAR PASCAL WndProc (HWND, UINT, UINT, LONG) ; DTWAIN_BOOL bTwainExists, bInitialized; DTWAIN_SOURCE SelectedSource = NULL; DTWAIN_ARRAY DibArray; LONG DTWAINMessage;
void AcquireImage(HMENU hMenu);
int WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static TCHAR szAppName[] = _T("DTwainDemo") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ;
/* Set up window class */ if (!hPrevInstance) wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = _T("DTwainDemo"); wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
/* Create the main window hwnd = CreateWindow (szAppName, _T("DTWAIN Demo Program"), WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ; UpdateWindow (hwnd) ;
/* Check if TWAIN exists. If so, initialize DTWAIN */ bTwainExists = DTWAIN_IsTwainAvailable( ); if ( bTwainExists )
/* Check if DTWAIN was initialized successfully */ bInitialized = DTWAIN_IsInitialized( );
/* If initialized, set the acquire mode and start a TWAIN session. For DTWAIN_ACQMODELSS, it is always to start the Twain session explicitly */ if ( bInitialized ) { /* Get the DTWAIN Registered message */ /* Enable message notification */ DTWAIN_EnableMsgNotify(TRUE); /* Set the acquisition mode */ DTWAIN_SetTwainMode(DTWAIN_MODELESS);
/* Start the TWAIN session using the main window as the notification window */ DTWAIN_StartTwainSession(hwnd,NULL); }
/* Start the traditional message loop. The only difference is the call to DTWAIN_IsTwainMsg( ) */ while (GetMessage (&msg, NULL, 0, 0)) { if ( !DTWAIN_IsTwainMsg(&msg) )
TranslateMessage (&msg) ; DispatchMessage (&msg) ;
}
/* Close up. MAKE SURE THAT THIS IS CALLED BEFORE EXITING!!! */ return msg.wParam ; }
long FAR __stdcall_export WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam) { HMENU hMenu ; TCHAR szBuf[32]; TCHAR msgBuf[100];
/* Check if message is a DTWAIN message */ if ( message == DTWAINMessage ) { switch (wParam ) { /* Notification of acquistion being started */ case DTWAIN_TN_ACQUIRESTARTED: DTWAIN_GetSourceProductName(SelectedSource, szBuf, 31); wsprintf(msgBuf, _T("DTWAIN Is about to acquire an image from %s..."),szBuf); MessageBox(NULL, msgBuf, _T("DTWAIN Notification - DTWAIN_TN_ACQUIRESTARTED"), MB_OK); break;
/* Transfer is about to take place */ case DTWAIN_TN_TRANSFERREADY: DTWAIN_GetSourceProductName(SelectedSource, szBuf, 31); wsprintf(msgBuf, _T("TWAIN is in State 6"),szBuf); MessageBox(NULL, msgBuf, _T("DTWAIN Notification - DTWAIN_TN_TRANSFERREADY"), MB_OK); break;
/* Transfer was done! */ case DTWAIN_TN_TRANSFERDONE: DTWAIN_GetSourceProductName(SelectedSource, szBuf, 31); wsprintf(msgBuf, _T("TWAIN is in State 7"), szBuf); MessageBox(NULL, msgBuf, _T("DTWAIN Notification - DTWAIN_TN_TRANSFERDONE"), MB_OK); break;
/* Acquired all pages. We can get the DIBs! */ case DTWAIN_TN_ACQUIREDONE: DTWAIN_GetSourceProductName(SelectedSource, szBuf, 31); wsprintf(msgBuf, _T("DTWAIN has successfully transferred image from %s!"),szBuf); MessageBox(NULL, msgBuf, _T("DTWAIN Notification - DTWAIN_TN_ACQUIREDONE"), MB_OK); /* This function gets all of the acquired pages */ DibArray = DTWAIN_GetSourceAcquisitions( SelectedSource ); break;
case DTWAIN_TN_PAGECONTINUE: { /* Check if user wants to continue scanning */ DTWAIN_BOOL bYes; bYes = MessageBox(NULL, _T("Continue scanning next page?"), _T("DTWAIN Notification - DTWAIN_TN_PAGECONTINUE"), MB_YESNO); if ( bYes == IDYES ) return TRUE; /* Yes, continue scanning */ return FALSE; /* No, quit scanning */ } break;
/* The UI has been closed, so enable the buttons so that another Source can be selected */ case DTWAIN_TN_UICLOSED: EnableMenuItem(hMenu, IDM_SELECT_SOURCE, MF_ENABLED); EnableMenuItem(hMenu, IDM_ACQUIRE, MF_ENABLED ); break;
case DTWAIN_TN_ACQUIRECANCELLED: DTWAIN_GetSourceProductName(SelectedSource, szBuf, 31); wsprintf(msgBuf, _T("DTWAIN has cancelled transferring image from %s!"),szBuf); MessageBox(NULL, msgBuf, _T("DTWAIN Notification - DTWAIN_TN_ACQUIRECANCELLED"), MB_OK); break; } return TRUE; }
/* Normal Windows message processing */ switch (message) { case WM_COMMAND : hMenu = GetMenu(hwnd) ; switch (wParam) { case IDM_SELECT_SOURCE: if ( bInitialized ) SelectedSource = DTWAIN_SelectSource( ); break;
case IDM_ACQUIRE: if (SelectedSource) AcquireImage(hMenu); break;
case IDM_EXIT : SendMessage (hwnd, WM_CLOSE, 0, 0L) ; return 0 ; } break;
case WM_DESTROY : PostQuitMessage(0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
void AcquireImage(HMENU hMenu) { if (SelectedSource) { /* Turn off the various menu options*/ EnableMenuItem(hMenu, IDM_SELECT_SOURCE, MF_GRAYED); EnableMenuItem(hMenu, IDM_ACQUIRE, MF_GRAYED ); DTWAIN_AcquireNative(SelectedSource, DTWAIN_PIXELRGB, 1, TRUE, TRUE, NULL); } }
-------------------------------------------------- /* DTWDEMO.RC */ DTWDEMO MENU DISCARDABLE BEGIN POPUP "&Demo" BEGIN MENUITEM "&Select Source...", IDM_SELECT_SOURCE MENUITEM "&Acquire...", IDM_ACQUIRE MENUITEM SEPARATOR MENUITEM "E&xit", IDM_EXIT END END
---------------------------------------------------
/* DTWDEMO.H */ #include "dtwain.h' #define IDM_SELECT_SOURCE 1 #define IDM_ACQUIRE 2 #define IDM_EXIT 3
----------------------------------------------------
|