2013-04-03 41 views
0

目前,我在Adobe AIR本机扩展,它提供了可能性,以简单使用TWAIN操纵图像扫描仪。
我用在http://www.codeproject.com/Articles/296/A-C-Wrapper-for-TWAIN

发现,当我在Windows应用程序(.exe)的使用这个类它按预期工作CTwain类,但在DLL(我需要创建ANE文件),它崩溃时TWAIN设备UI正在关闭(扫描完成时,或点击取消按钮)

我一点问题是介于DllMain.cpp文件(可能是消息循环),因为在应用程序与启动功能APIENTRY _tWinMain它可以完美运行。的Adobe AIR本机扩展TWAIN图像扫描仪

代码
DllMain.cpp

#include "stdafx.h" 
#include "TwainCpp.h" 
#include "resource.h" 

using namespace std; 

HWND g_hwnd = NULL; 
HINSTANCE g_hInstance = NULL; 
BOOL isValid = false; 
BOOL isCreated = false; 
CTwain *twain = NULL; 

LRESULT CALLBACK WndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 
     case WM_CREATE:   
      break; 
     case WM_DESTROY:    
      PostQuitMessage(0); 
      break; 
    } 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 

BOOL CreateAppWindow() 
{ 
    WNDCLASS wc; 
    wc.style = 0; 
    wc.lpfnWndProc = WndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = g_hInstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); 
    wc.lpszMenuName = "FRETwainMenu"; 
    wc.lpszClassName = "FRETwainClass"; 

    if(RegisterClass(&wc)) 
    { 
     HWND hWnd;   
      char title[50]; 
      wsprintf(title, "FRETwain:%x", g_hInstance); 
      hWnd = CreateWindow("FRETwainClass", title, WS_DISABLED,    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,      HWND_MESSAGE, NULL, g_hInstance, NULL); 
      if(hWnd) 
      {  
       g_hwnd = hWnd;     
       return TRUE;      
      }    
      return FALSE;  
    } 
    return FALSE; 
} 

DWORD WINAPI CreateAppThread() 
{ 
    if(CreateAppWindow()) 
    { 
     MSG msg; 
     isCreated = true; 
     while(GetMessage(&msg, NULL, 0, 0) > 0) 
     { 
      if(twain != NULL){    
       twain->ProcessMessage(msg);    
      } 
      TranslateMessage(&msg); 
      DispatchMessage(&msg);      
     }  
     return TRUE; 
    } 
    return FALSE; 
} 

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID lpvReserved) 
{ 
    switch(reason) 
    { 
     case DLL_PROCESS_ATTACH: 
      g_hInstance = hInstance;    
      HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateAppThread, (LPVOID)NULL, 0, NULL); 
      break; 
    }   
    return TRUE; 
} 

FRETwain.cpp(背景文件)

#include <windows.h> 
#include "FRETwain.h" 

extern BOOL isValid; 
extern BOOL isCreated; 
extern HWND g_hwnd; 
extern CTwain *twain; 

extern "C" 
{ 
    FREObject AcquireTwain(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) 
    { 
     FREObject result; 
     uint32_t ret = 0; 
     if(isValid){ 
      twain->Acquire(TWCPP_ANYCOUNT); 
      ret = 1; 
     } 
     FRENewObjectFromBool(ret, &result); 
     return result; 
    } 

    FREObject setDefaultDevice(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) 
    { 
     FREObject result; 
     uint32_t ret = 0; 
     if(isValid){ 
      twain->SelectSource(); 
      ret = 1; 
     } 
     FRENewObjectFromBool(ret, &result); 
     return result; 
    } 

    FREObject initTwain(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) 
    {  
     FREObject result; 
     uint32_t isTwain = 0; 
     if(!isValid){ 
      twain = new CTwain(g_hwnd, ctx); 
      isValid = twain->IsValidDriver(); 
     }  
     if(isValid) 
      isTwain = 1; 
     FRENewObjectFromBool(isTwain, &result); 
     return result; 
    } 

} 

回答

0

我发现了另一个吐温wraper - C++的EzTwain版本 - 作品叫同一个线程中完美
header filesource file

消息循环

void EZTAPI TWAIN_ModalEventLoop(void) 
{ 
    MSG msg; 

    while ((nState >= 5) && !hDib && GetMessage((LPMSG)&msg, NULL, 0, 0)) { 
     if (!TWAIN_MessageHook ((LPMSG)&msg)) { 
      TranslateMessage ((LPMSG)&msg); 
      DispatchMessage ((LPMSG)&msg); 
     } 
    } // while 
} // TWAIN_ModalEventLoop 

还是要谢谢你

0

你不要;吨似乎没有任何线程同步。

首先,它看起来像g_hwnd的初始化和它在AcquireTwain中的使用等竞争条件。这可能不是你的问题,但你应该考虑 - 如果你从主AIR中访问g_hwnd线程,那么你必须使用CRITICAL_SECTION或互斥锁来同步对它的访问。

但是,如果你可以,也许只是使用临界区,以保证g_hwnd正确初始化,然后发布消息到它的消息队列异步做采集。 即交一个视窗消息g_hwnd然后调用CTwain ::从线程内获取。
你可能还需要从线程等内创建CTwain基本上,只是使它线程安全的。

我没写过原生扩展的Windows(仅适用于iOS)在这个如此不确定......但或许是可以不需要被用在从AIR运行时获得一个窗口句柄的方法辅助线程(除非CTwain块?)。这将使它更容易。

+0

在firsf试图创建CTwain与GetForegroundWindow()参数和没有mainDll文件。像selectSource直截了当功能工作正常,但由于消息循环没有实现,一切不能正常工作。如果有任何方法可以将消息循环添加到使用GetForegroundWindow()函数接收的HWND中? –