更改窗口键盘布局时应用程序冻结

发布于 2024-11-09 09:47:08 字数 3588 浏览 0 评论 0原文

创建线程后,以下代码在将焦点从 Edit1 更改为 Edit2 时使应用程序冻结。

重现步骤:

  • 单击创建线程按钮
  • 在 Edit1 / Edit2 之间切换焦点。

我认为线程内的 ADO 对象创建导致应用程序冻结。

有谁知道确切的问题是什么?

注意:我猜想当更改默认输入语言时会出现问题。 Win xp - 文本服务和输入语言对话框 - 默认输入语言。

与以下问题相同:

http://social .msdn.microsoft.com/Forums/en/vcgeneral/thread/1d27c2ad-7ef1-45e9-b9af-6bfb458c1165

pas 文件

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ADODB, SyncObjs, ActiveX,
  ComObj, Menus, StdCtrls;

type

  TMyThread = class(TThread)
  private
    FEvent : TEvent;
    adoConnection : TADOConnection;
  protected
    procedure Execute; override;
  public
    constructor Create(ASuspended : boolean);
    destructor Destroy; override;
  end;


  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure TextEdit1Enter(Sender: TObject);
    procedure TextEdit2Enter(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MyThread : TMyThread;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(ASuspended: boolean
                            );
begin
  inherited Create(ASuspended);
  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test'
                          );
end;

destructor TMyThread.Destroy;
begin
  FreeAndNil(FEvent);
  inherited;
end;

procedure TMyThread.Execute;
begin
  CoInitializeEx(nil,
                 COINIT_MULTITHREADED
                );
  try
    adoConnection := TADOConnection.Create(nil);
    FEvent.WaitFor(INFINITE);
    adoConnection.Free;
  finally
    CoUnInitialize;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyThread.Resume;
end;

procedure TForm1.TextEdit1Enter(Sender: TObject);
begin
  LoadKeyboardLayout(PChar(IntToHex(1081, 8)), KLF_ACTIVATE);
end;

procedure TForm1.TextEdit2Enter(Sender: TObject);
begin
  LoadKeyboardLayout(PChar(IntToHex(1043, 8)), KLF_ACTIVATE);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  MyThread.FEvent.SetEvent;
  MyThread.Terminate;
  FreeAndNil(MyThread);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyThread := TMyThread.Create(true);
end;

end.

表单文件

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 115
  ClientWidth = 147
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 8
    Top = 8
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
    OnEnter = TextEdit1Enter
  end
  object Edit2: TEdit
    Left = 8
    Top = 35
    Width = 121
    Height = 21
    TabOrder = 1
    Text = 'Edit2'
    OnEnter = TextEdit2Enter
  end
  object Button1: TButton
    Left = 8
    Top = 62
    Width = 121
    Height = 45
    Caption = 'Create Thread'
    TabOrder = 2
    WordWrap = True
    OnClick = Button1Click
  end
end

The below code makes application freeze when changing focus from Edit1 to Edit2 after creating the thread.

Steps to reproduce:

  • Click Create thread button
  • Switch focus between Edit1 / Edit2.

I think the ADO object creation inside the thread is causing the application to freeze.

Does anyone have any idea of the what is the exact problem?

Note : I guess the problem occurs when default input language is changed.
Win xp - Text Service and Input langauges dialog - Default input language.

Same issue as :

http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/1d27c2ad-7ef1-45e9-b9af-6bfb458c1165

pas file

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ADODB, SyncObjs, ActiveX,
  ComObj, Menus, StdCtrls;

type

  TMyThread = class(TThread)
  private
    FEvent : TEvent;
    adoConnection : TADOConnection;
  protected
    procedure Execute; override;
  public
    constructor Create(ASuspended : boolean);
    destructor Destroy; override;
  end;


  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure TextEdit1Enter(Sender: TObject);
    procedure TextEdit2Enter(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MyThread : TMyThread;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(ASuspended: boolean
                            );
begin
  inherited Create(ASuspended);
  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test'
                          );
end;

destructor TMyThread.Destroy;
begin
  FreeAndNil(FEvent);
  inherited;
end;

procedure TMyThread.Execute;
begin
  CoInitializeEx(nil,
                 COINIT_MULTITHREADED
                );
  try
    adoConnection := TADOConnection.Create(nil);
    FEvent.WaitFor(INFINITE);
    adoConnection.Free;
  finally
    CoUnInitialize;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyThread.Resume;
end;

procedure TForm1.TextEdit1Enter(Sender: TObject);
begin
  LoadKeyboardLayout(PChar(IntToHex(1081, 8)), KLF_ACTIVATE);
end;

procedure TForm1.TextEdit2Enter(Sender: TObject);
begin
  LoadKeyboardLayout(PChar(IntToHex(1043, 8)), KLF_ACTIVATE);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  MyThread.FEvent.SetEvent;
  MyThread.Terminate;
  FreeAndNil(MyThread);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MyThread := TMyThread.Create(true);
end;

end.

form file

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 115
  ClientWidth = 147
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 8
    Top = 8
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
    OnEnter = TextEdit1Enter
  end
  object Edit2: TEdit
    Left = 8
    Top = 35
    Width = 121
    Height = 21
    TabOrder = 1
    Text = 'Edit2'
    OnEnter = TextEdit2Enter
  end
  object Button1: TButton
    Left = 8
    Top = 62
    Width = 121
    Height = 45
    Caption = 'Create Thread'
    TabOrder = 2
    WordWrap = True
    OnClick = Button1Click
  end
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨洒年华 2024-11-16 09:47:08

解决了。

在 pas 文件中将行更改

 CoInitializeEx(nil,
                 COINIT_MULTITHREADED
                );

  CoInitializeEx(nil,
                 COINIT_APARTMENTTHREADED
                );

  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test'
                          );

  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test',
                          true
                          );

Solved it.

In pas file change the line

 CoInitializeEx(nil,
                 COINIT_MULTITHREADED
                );

to

  CoInitializeEx(nil,
                 COINIT_APARTMENTTHREADED
                );

and

  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test'
                          );

to

  FEvent := TEvent.Create(nil,
                          false,
                          false,
                          'test',
                          true
                          );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文