TWAIN Working Group

Newsletter Signup
Donate
Help keep TWAIN free
  • About TWAIN
    • What’s New?
    • News
    • Events
    • Membership
    • Consider a Donation
    • Contact Us
  • Why TWAIN?
  • Developers
    • Driver Developer
    • Application Developer
    • TWAIN Features
    • Specification & Tools
    • Self Certification Process
  • Support Forums
  • Scanner End-User
  • Find Certified Drivers
    • Facebook
    • LinkedIn
    • Vimeo

Twain Callback — Developing with MFC

Forums › TWAIN Classic › Twain Callback — Developing with MFC

  • This topic has 5 replies, 3 voices, and was last updated 11 years, 9 months ago by garbuck.
Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • April 26, 2009 at 9:44 pm #22491 Reply
    dcreeron
    Participant
    • Topics - 1
    • Replies - 4
    • Total Posts - 5

    Hi All,

    I’m trying to develop an MFC class to interface with Twain 2.0. I’ve gotten most of my code working except for the implementation of the callback function.

    MFC/C++ has an implicit THIS pointer which I need to pass through the callback mechanism. I set up the TWAIN callback and try to put the THIS pointer in the REFCON parameter so I can access it through the pData variable later in the process.

    Everything is working until my callback function is executed. pData is always coming through as NULL. Am I just not using the callback structure appropriately or is there an issue with the DSM/DS not properly passing the pData through to the callback?

    If I could get the callback working I’d be able to finish up my MFC class. Otherwise I’ll need to implement a message pump and do things the old way, or perhaps just write something in C instead.

    Any direction or input is appreciated.

    Thanks.

    Daniel

    April 27, 2009 at 10:07 pm #24896 Reply
    dcreeron
    Participant
    • Topics - 1
    • Replies - 4
    • Total Posts - 5

    No one has any suggestions about implementing the callback using MFC? Is it possible, or am I just spinning my wheels?

    Specifically, am I supposed to be able to pass user data into the create callback twain call and then access that data later when the DSM/DS calls me back?

    Thanks.

    Daniel

    May 5, 2009 at 3:49 am #24897 Reply
    garbuck
    Participant
    • Topics - 0
    • Replies - 2
    • Total Posts - 2

    I, too, assumed that the RefCon value was intended for passing back context variables such as this pointers. It works fine for that on the Mac. The Mac implementation relies entirely on the callback and does not need an event pump.

    The 2.0 DSM is broken. When I discovered the RefCon passback was not implemented, I decided just to ignore the callback feature on Windows. That worked fine for the Epson scanner I was using for tests. However, when I tested with the TWAIN dummy software source, it blocked on the GetMessage call, even though I had not defined a callback. Reverting back to twain_32.dll (and supplying a window handle to DSM_Entry on startup) worked fine with the software source. So, that made me worry that future drivers for real devices might rely on the callback being there for the 2.0 DSM, causing apps that don’t implement it to hang.

    The docs also do not make it clear that, on Windows, you need to implement both the callback and the event pump. I assumed it would work like the Mac — no more message pump. But when I tried that with the Epson, it showed empty UI windows, making it obvious the event pump was still needed.

    I looked at the TWAIN sample application. It implements the callback, but uses a global variable to track it. That’s poor coding practice: globals are not thread-safe.

    One possibility would be to store your this pointer in thread local storage (google TlsAlloc and friends). Another might be to cram it past the end of your manufacturer or product name in the appId and make sure your name string is 29 characters or less (better make that 25 to allow for 64-bit).

    May 5, 2009 at 7:21 pm #24898 Reply
    dcreeron
    Participant
    • Topics - 1
    • Replies - 4
    • Total Posts - 5

    Thanks for the feedback garbuck. Appreciate you taking the time to respond.

    I haven’t tried anything else at this point, but I will look into your reccommendations with the TLS.

    If I get it to work I’ll update this thread.

    – Daniel

    May 5, 2009 at 9:20 pm #24899 Reply
    jimwatters
    Participant
    • Topics - 2
    • Replies - 72
    • Total Posts - 74

    Thank you for bringing this to our attention.

    The intention of RefCon is missing from the spec and will be fixed. RefCon will be returned in pData in the next release of the DSM. Because it was not defined as TW_MEMREF it should not be used to store a pointer because it will fail on 64bit OS.

    How is Apple getting around this on 64bit if they are passing pointers?

    Maybe passing in a TlsAlloc value is the way to go.
    Yes the Sample App uses globals. 🙂

    Modifying the application name might unwanted have side effects. Some DS choose to store the last used settings for each Application name that opens it. If the name keeps changing you might not get the settings you expected.

    Using callbacks does not eliminate the need of the windows event message pump.

    On the Mac starting with OSX if was required for the DS to register their own functions with the OS for handling windows messages. That meant they no longer needed the DAT_EVENT for pumping messages and added the Callback to handle the DS notifying the App.

    Unlike the Mac on Windows TWAIN 1.x DS will continue to work with TWAIN 2.x Applications. It does not matter if the TWAIN application implements notification via callbacks or DAT_EVENT.

    The important thing to remember in the callback routine is to get the message and data passed. Return immediately. Then act on the message received.

    Regards,
    Jim Watters

    **************************************************
    JFL Peripheral Solutions Inc.
    http://www.jflinc.com/
    Your Expert Source of Custom Software and Services
    for TWAIN Applications, Data Sources,
    Peripheral Drivers and Support Software.
    **************************************************

    May 7, 2009 at 4:09 am #24900 Reply
    garbuck
    Participant
    • Topics - 0
    • Replies - 2
    • Total Posts - 2

    @jimwatters wrote:

    How is Apple getting around this on 64bit if they are passing pointers?

    I don’t know. My app was 32-bit, so I was able to use it to pass along an Objective-C self pointer.

    However, according to the file command, the TWAIN binary for OS 10.5 supports four architectures: ppc7400, ppc64, i386, and x86_64. OS X also supports thread-local storage (not that it’s hard to implement on your own). And, of course, you can just be dirty and use a global, if you are sure it won’t be an issue for your app.

    Modifying the application name might unwanted have side effects. Some DS choose to store the last used settings for each Application name that opens it. If the name keeps changing you might not get the settings you expected.

    In that connection, I noticed that the DSM will let you open multiple appId blocks, as long as the product names are different (it doesn’t consider the manufacturer or product family fields). I assume that’s what you would need to do if you wanted to drive multiple devices simultaneously. The message queue that the Windows window handle supports is per-thread, and the handle is per DSM app, not per source. So, to drive eight scanners at once, you would start up eight threads, each of which would open the DSM with a slightly different product name … ScannerMaster 1, ScannerMaster 2, etc.

    BTW, I found that my problem with the dummy software datasource hanging under DSM 2 went away if I supplied a window handle on the open. I had ripped out the window handle code, so I put it back in.

  • Author
    Posts
Viewing 6 posts - 1 through 6 (of 6 total)
Reply To: Reply #24897 in Twain Callback — Developing with MFC
Your information:




Quick Links

Service Providers
TWAIN Support Forums
Membership
Contact Us
Privacy Policy

Newsletter Signup

TWAIN Working Group Family

TWAIN Working Group
TWAIN Direct®
TWAIN Resources
TWAIN Certified Drivers
PDF/raster

  • Facebook
  • GitHub
  • LinkedIn
  • Vimeo

Recent Topics

  • Scanner starts transfer when console gets closed (CITRIX)
  • Kodak RFS 3600
  • Didn’t save enough file scan
  • EPSON V600 TWAIN and WIA on Windows 10
  • When and how to use WaitForEvents command ?
  • Quarterly Newsletter
  • TWAIN Working Group Membership
  • Logo Usage
  • TWAIN License
  • Contact Us
Privacy Policy • Privacy Tools • Copyright © 2021 TWAIN Working Group • by iHwy, LLC • Log in

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.