2013-04-03 61 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中? –