首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以在不同的线程中过滤窗口中的消息?

是否可以在不同的线程中过滤窗口中的消息?
EN

Stack Overflow用户
提问于 2012-03-22 04:31:11
回答 1查看 1K关注 0票数 3

我正在编写一个使用TwainDotNet进行扫描的应用程序。

一切正常,但扫描会使用户界面不可用。所以我决定在另一个线程中扫描,但我从未获得扫描成功事件。所以我决定仔细看看它的实现:

代码语言:javascript
复制
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)));

以及执行过滤的方法:

代码语言:javascript
复制
protected IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, 
    IntPtr lParam, ref bool handled)
{

通常,此方法会过滤消息日志,但如果我在另一个线程中扫描,则不会收到任何消息。

我的代码的扫描部分是:

代码语言:javascript
复制
    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消息体系结构一无所知,所以任何关于我如何解决这个问题或者是什么导致这个问题的意见都会很有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-22 22:14:53

您拥有的代码将无法正常工作,因为您正在没有消息循环的线程上创建窗体。如果这个库确实需要一个表单或消息循环,并且它挂起了UI,那么除了它有设计问题之外,这可能是非常罕见的情况之一,您可能会考虑让第二个线程运行消息循环。

要创建运行消息循环的线程,请使用Application.Run。修改后的代码可能如下所示。

代码语言:javascript
复制
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();

我必须指出,拥有多个UI线程可能会导致一些奇怪的问题,因此通常不建议这样做。然而,就像我说的,你可能别无选择。另外,将这两个UI线程上发生的所有活动完全分开。不应尝试从此辅助UI线程访问在主UI线程上运行的UI控件。将会出现各种各样不可预测和引人注目的问题。如果需要强制在一个线程上执行某个操作,请使用InvokeBeginInvoke来封送委托的执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9812346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档