Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 网格在模式窗口后滚动_Delphi_Windows 10_Delphi Xe3 - Fatal编程技术网

Delphi 网格在模式窗口后滚动

Delphi 网格在模式窗口后滚动,delphi,windows-10,delphi-xe3,Delphi,Windows 10,Delphi Xe3,我已经建立了这个问题的MCV,我很高兴上传它。我先试着描述一下这个问题 创建一个主窗口,并通过任何可用的数据库将TDBGrid连接到表。在显示窗口时,连接到数据库并打开表 在主窗口上创建启动非模式窗口的按钮 在非模式窗口上创建一个按钮,用于启动模式窗口 仔细按照这些步骤复制问题 运行应用程序 将焦点放在网格中,并使用鼠标滚轮上下滚动 按下按钮以启动非模式窗口 非模态窗口打开时,单击主窗口中的网格,然后再次使用鼠标滚轮上下滚动 当仍在网格中聚焦时,单击非模式窗口上的按钮以启动模式窗口 模式窗口打开

我已经建立了这个问题的MCV,我很高兴上传它。我先试着描述一下这个问题

  • 创建一个主窗口,并通过任何可用的数据库将TDBGrid连接到表。在显示窗口时,连接到数据库并打开表

  • 在主窗口上创建启动非模式窗口的按钮

  • 在非模式窗口上创建一个按钮,用于启动模式窗口

  • 仔细按照这些步骤复制问题

  • 运行应用程序

  • 将焦点放在网格中,并使用鼠标滚轮上下滚动

  • 按下按钮以启动非模式窗口

  • 非模态窗口打开时,单击主窗口中的网格,然后再次使用鼠标滚轮上下滚动

  • 当仍在网格中聚焦时,单击非模式窗口上的按钮以启动模式窗口

  • 模式窗口打开时,将鼠标悬停在网格上并使用鼠标滚轮。您将看到网格上下滚动

  • 这在Windows 7上不会发生,但在Windows 10上会发生。这看似无害,但当你在3个窗口中建立了几层父子关系时,这尤其危险

    假设模态窗口包含主窗口的子窗口。如果用户启动模式窗口的目的是编辑特定的孙子孙女,并意外地使用鼠标滚轮在主窗口上移动孙子孙女,则他们现在正在编辑他们不打算编辑的孙子孙女


    应该注意的是,在步骤4和步骤5之间,如果在启动模式窗口之前没有将焦点放在网格中,则不会发生此问题。在显示模式窗口之前,我曾尝试通过编程将焦点设置为非模式窗口上的控件,但没有成功

    这是VCL代码中的错误。如注释中所述,要在普通应用程序中复制此问题,需要启用Windows 10的非活动窗口滚动功能,或在早期操作系统中提供类似功能的软件

    但是,可以在没有特殊要求的情况下演示问题。这将是一个比问题中更简单的复制

    在窗体上放置stringgrid和按钮,按钮的单击处理程序中包含以下代码:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      StringGrid1.Enabled := False;
      SetFocusedControl(StringGrid1);
    end;
    
    单击按钮,将鼠标悬停在网格上并滚动。尽管网格被禁用,但它不应该滚动,但确实如此

    下面是一个更适合问题中情况的问题。这是因为模式窗口禁用了包含网格的表单,该表单随后会发布鼠标滚轮消息。控制盘消息是针对不具备上述要求的环境合成的

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Pt: TPoint;
    begin
      Enabled := False;
      Pt := Point(1, 1);
      MapWindowPoints(StringGrid1.Handle, HWND_DESKTOP, Pt, 1);
      SetFocusedControl(StringGrid1);
      Perform(WM_MOUSEWHEEL, MakeWParam(0, WORD(-120)), MakeLParam(Pt.X, Pt.Y));
    end;
    
    观察到网格滚动后,按Ctrl+F2


    问题的根本原因是,VCL在决定控件是否为焦点控件以及使其执行鼠标滚轮消息时,不关心控件是否已启用。将鼠标滚轮消息变为
    CM\u鼠标滚轮
    ,并完全绕过默认窗口过程,VCL应该执行这些检查

    对于解决方法,可以在启动模式窗体之前将焦点控件设置为其他控件:

    MainForm.SetFocusedControl(MainForm);
    OtherForm.ShowModal;
    
    您不能在此处设置
    ActiveControl
    ,因为该控件具有必要的可见性/状态检查

    如果不想与主窗体耦合,可以将鼠标滚轮消息处理程序放置到主窗体:

    type
      TMainForm = class(TForm)
        ...
      protected
        procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
    
    ...
    
    procedure TMainForm.WMMouseWheel(var Message: TWMMouseWheel);
    begin
      if IsWindowEnabled(Handle) then
        inherited;
    end;
    

    这是VCL代码中的错误。如注释中所述,要在普通应用程序中复制此问题,需要启用Windows 10的非活动窗口滚动功能,或在早期操作系统中提供类似功能的软件

    但是,可以在没有特殊要求的情况下演示问题。这将是一个比问题中更简单的复制

    在窗体上放置stringgrid和按钮,按钮的单击处理程序中包含以下代码:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      StringGrid1.Enabled := False;
      SetFocusedControl(StringGrid1);
    end;
    
    单击按钮,将鼠标悬停在网格上并滚动。尽管网格被禁用,但它不应该滚动,但确实如此

    下面是一个更适合问题中情况的问题。这是因为模式窗口禁用了包含网格的表单,该表单随后会发布鼠标滚轮消息。控制盘消息是针对不具备上述要求的环境合成的

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Pt: TPoint;
    begin
      Enabled := False;
      Pt := Point(1, 1);
      MapWindowPoints(StringGrid1.Handle, HWND_DESKTOP, Pt, 1);
      SetFocusedControl(StringGrid1);
      Perform(WM_MOUSEWHEEL, MakeWParam(0, WORD(-120)), MakeLParam(Pt.X, Pt.Y));
    end;
    
    观察到网格滚动后,按Ctrl+F2


    问题的根本原因是,VCL在决定控件是否为焦点控件以及使其执行鼠标滚轮消息时,不关心控件是否已启用。将鼠标滚轮消息变为
    CM\u鼠标滚轮
    ,并完全绕过默认窗口过程,VCL应该执行这些检查

    对于解决方法,可以在启动模式窗体之前将焦点控件设置为其他控件:

    MainForm.SetFocusedControl(MainForm);
    OtherForm.ShowModal;
    
    您不能在此处设置
    ActiveControl
    ,因为该控件具有必要的可见性/状态检查

    如果不想与主窗体耦合,可以将鼠标滚轮消息处理程序放置到主窗体:

    type
      TMainForm = class(TForm)
        ...
      protected
        procedure WMMouseWheel(var Message: TWMMouseWheel); message WM_MOUSEWHEEL;
    
    ...
    
    procedure TMainForm.WMMouseWheel(var Message: TWMMouseWheel);
    begin
      if IsWindowEnabled(Handle) then
        inherited;
    end;
    

    当显示模式窗口时,主窗口是否正确禁用?是否正确。AAMOF我可以在W7上用字符串网格复制它。它似乎取决于鼠标驱动程序/软件设置,而不是操作系统。如果我在我的盒子f.I.上禁用“wizmouse”,那就不会发生。不客气。然而,你仍然有一个问题。禁用的窗口不应滚动。@sertac这是vcl网格的问题。列表框是否滚动?显示模式窗口时主窗口是否正确禁用?是否。AAMOF我可以在W7上用字符串网格复制它。它似乎取决于鼠标驱动程序/软件设置,而不是操作系统。它是d