更改窗口键盘布局时应用程序冻结
创建线程后,以下代码在将焦点从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决了。
在 pas 文件中将行更改
为
和
到
Solved it.
In pas file change the line
to
and
to