c++leadtools-sdk

Cannot set Scanner Capability because L_TwainStartCapsNeg returns error -84


I'm trying to use the Leadtools API version 21 for automatically scanning some documents and here is a sudo code of what I have done (it runs in a secondary thread and the unlock has been done in the main thread):

void CheckRetCode(int rc)
{
    if (SUCCESS != rc)
    {
        L_TCHAR errMsg[1024];

        memset(errMsg, 0, sizeof(errMsg));
        L_GetFriendlyErrorMessage(rc, errMsg, 1024, L_FALSE);

        throw TLeadException(errMsg, rc);
    }
} 
void OnThreadExecute(void)
{
    HTWAINSESSION hSession = nullptr;
    APPLICATIONDATA appData;
    L_INT nRet;
    L_TCHAR pszTwnSourceName[1024];
    LTWAINSOURCE sInfo;

    memset(&appData, 0, sizeof(APPLICATIONDATA));
    appData.uStructSize = sizeof(APPLICATIONDATA);
    appData.hWnd = hWnd;// hWnd is valid handle of my main window
    appData.uLanguage = TWLG_ENGLISH_USA;
    appData.uCountry = TWCY_USA;
    wcscpy(appData.szManufacturerName, L"MyCompanyName");
    wcscpy(appData.szAppProductFamily, L"MyProductName");
    wcscpy(appData.szAppName, appData.szAppProductFamily);
    wcscpy(appData.szVersionInfo, L"Version 0.1.0.1");
    nRet = L_TwainInitSession2(&hSession, &appData, LTWAIN_INIT_MULTI_THREADED);
    CheckRetCode(nRet);// the exception gets catched elsewhere but no error reported here
    memset(pszTwnSourceName, 0, sizeof(pszTwnSourceName));
    wcscpy(pszTwnSourceName, L"EPSON Artisan837/PX830"); // the name of the scanner is verifyed
    sInfo.uStructSize = sizeof(LTWAINSOURCE);
    sInfo.pszTwainSourceName = pszTwnSourceName;
    CheckRetCode(L_TwainSelectSource(hSession, &sInfo)); // No error reported here
    CheckRetCode(L_TwainStartCapsNeg(hSession)); // in here I get the return value -84 which is reported as "TWAIN DS or DSM reported error, app shouldn't (no need for your app to report the error)."
    // the rest of the code but we cannot get there since above code reports error
}

Can anyone tell me what I'm doing wrong? Is there a step that I'm missing here?

Edit
The function L_TwainSelectSource() make no effort to make sure the supplied source is valid and does not even return an error. As result, if you set the selected source to a garbage name, it will act as if it accepted it. From that point on if you try to Get/Set anything or try to acquire an image, every function returns -84.

Thank you Sam


Solution

  • To test your code, I put the main window’s handle in a global variable:

    globalhWnd = hWnd;
    

    And modified your function to use that handle like this:

    void OnThreadExecute(void *)
    {
    ...
    appData.hWnd = globalhWnd; // hWnd is valid handle of my main window
    ...
    }
    

    Then created a thread for it from the main program like this:

    globalhWnd = hWnd;
    _beginthread(OnThreadExecute, 0, 0);
    

    I tried this with 5 different Twain sources: 2 virtual and 3 physical scanners (one of them an old Epson). All 5 drivers returned SUCCESS when calling L_TwainStartCapsNeg() from within the thread.

    Two possibilities come to mind:

    1. The problem might be caused by something else in your code other than the thread function.
    2. Or the problem could be specific to your Twain driver.

    To rule out the first possibility, I suggest creating a small test project that only creates a similar thread and does nothing else and trying it with different scanners. If it causes the same problem with all scanners, send that test project (not your full application) to support@leadtools.com and our support engineers with test it for you.

    If the problem only happens with a specific Twain driver, try contacting the scanner’s vendor to see if they have an updated driver.