2012-03-21 2 views
3

Я пишу приложение, которое использует TwainDotNet для сканирования.Могу ли я фильтровать сообщение из окна в другом потоке?

Все работает нормально, но сканирование делает пользовательский интерфейс непригодным для использования. Поэтому я решил отсканировать в другом потоке, но у меня никогда не было успешного сканирования. Поэтому я решил взять более близкий взгляд на реализацию:

public DataSourceManager(Identity applicationId, 
    IWindowsMessageHook messageHook) 
{ 
    // Make a copy of the identity in case it gets modified 
    ApplicationId = applicationId.Clone(); 

    ScanningComplete += delegate { }; 
    TransferImage += delegate { }; 

    _messageHook = messageHook; 
    _messageHook.FilterMessageCallback = FilterMessage; 
    IntPtr windowHandle = _messageHook.WindowHandle; 

    _eventMessage.EventPtr = 
      Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WindowsMessage))); 

И метод, который делает фильтрацию:

protected IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, 
    IntPtr lParam, ref bool handled) 
{ 

Обычно этот метод фильтрует журнал сообщений, но если я просматриваю в другой нить не получаю.

Сканирующая часть моего кода:

var scanningThread = new Thread((ThreadStart) delegate 
    { 
     // Previously I got the main UI form here, but that didn't work either 
     var form = new Form(); 
     var messageHook = new WinFormsWindowMessageHook(form.Handle); 

     var scanner = new TwainEngine(messageHook); 
     scanner.TransferImage += TransferImage; 
     scanner.ScanningComplete += ScanningComplete; 
     scanner.StartScanning(twainSettings); 

    }); 
    scanningThread.Start(); 

Я ничего не знаю об архитектуре сообщений Win32 так что любой вход на том, как я мог бы решить эту проблему или то, что вызывает эта проблема была бы полезно.

+0

Бадди, ты ошибешься. Не создавайте форму в другой теме. И ручка для формы, которая не показана, бесполезна. Вы уверены, что не блокируете графический интерфейс, ожидая завершения сканирования? – Brannon

+0

@Brannon: Спасибо за ответ. Я уверен, что я ничего не блокирую. У этой демонстрационной программы есть такая же проблема. – xsl

ответ

2

Код, который у вас есть, не будет работать правильно, потому что вы создаете форму в потоке без контура сообщения. Если в этой библиотеке действительно нужен цикл формы или сообщения, и он висит в пользовательском интерфейсе, а кроме того, что он имеет проблемы с дизайном, это может быть один из очень редких сценариев, когда вы можете захотеть, чтобы второй поток выполнял цикл сообщений.

Чтобы создать поток, который использует цикл сообщений, используйте Application.Run. Ваш модифицированный код может выглядеть так.

var scanningThread = new Thread((ThreadStart) delegate 
{ 
    var form = new Form(); 
    form.Load += (sender, args) => 
    { 
     var messageHook = new WinFormsWindowMessageHook(form.Handle); 
     var scanner = new TwainEngine(messageHook); 
     scanner.TransferImage += TransferImage; 
     scanner.ScanningComplete += ScanningComplete; 
     scanner.StartScanning(twainSettings); 
    }; 
    Application.Run(form); 
}); 
scanningThread.Start(); 

Я должен указать, что наличие более одного потока пользовательского интерфейса может вызвать некоторые странные проблемы, поэтому обычно это не рекомендуется. Однако, как я уже сказал, у вас может не быть выбора. Кроме того, все действия, происходящие в этих двух потоках пользовательского интерфейса, полностью разделяются. Не следует пытаться получить доступ к элементам управления пользовательским интерфейсом, работающим на вашем основном потоке пользовательского интерфейса, из этого вторичного потока пользовательского интерфейса. Есть всевозможные непредсказуемые и впечатляющие проблемы, которые произойдут. Если вам необходимо принудительно выполнить действие в одном потоке, используйте Invoke или BeginInvoke для маршала выполнения делегата.

+0

Большое спасибо за ваш ответ. Я попробую, когда у меня будет время. – xsl

+0

Большое спасибо, я изменил его, чтобы скрыть форму и закрыть ее после завершения сканирования. – xsl

Смежные вопросы