Delphi ошибка 1400

I have a problem.
I have a VCL application using a thread. This thread does some calculations and calls a MainForm’s method through Synchronize(). It all works just fine, I have a «Start» button, which creates and runs the thread and a «Stop» button which stops and frees it. No errors, no nothing.

But for some reason when I close the application and I’ve run the thread I get a EOSError 1400 - Invalid window handle. I’ve breakpointed the OnClose procedure and the only thing I do there is saving an ini file, no error in that, when I trace further (using F7), I get to the very end (Application.Run; end.), after «calling» the end. I get the error, so there is no specific line of code raising it.

I hope the question is somewhat clear and I hope it’s solvable, because just ignoring the error seems a bit unclean.

Thanks inb4


ANSWER

This error occured to me when the Execute method of a thread was called, it looked like this:

procedure TRunThread.Execute;
var (...)
begin
  while not Terminated do begin
    (...)
    MainForm.Memo1.Lines.Add('Some text'); // Even though this call worked fine during
    //the application running, it caused errors on shutting the app down.
    // For acccessing GUI elements, it's necessary to use Synchronize()
    (...)
  end;
end;

You have posted a lot of code but not the key, relevant part. Specifically the implementation of your xOnAsyncRequestDone event handler/method (unless it literally only calls that log method that you posted).

This method is being executed in the context of the TMySynHTTPAsync thread and based on the behaviour you are describing — particularly the fact that Synchronize resolves your problem — it is highly likely that some activity in that event handler is creating a window handle.

That window handle is then owned by the HTTP Async thread, not the main application thread (sometimes referred to as the «VCL thread») that is otherwise running your application. When your application closes, the VCL thread performs some final housekeeping, destroying objects and windows etc. if one of those windows was created by some other thread this will cause problems.

Window handles are the strict property of the thread in which they were created. You cannot create a window handle in one thread and then destroy it in another.

NOTE: This is a fundamental of Windows, not Delphi.

Worth noting here is that window handles in VCL can often be created indirectly. You won’t necessarily see an explicit creation of a control that marks the creation of the underlying window handle. It is quite common for window handles only to be actually created when required. Similarly changing the properties of a control can trigger the VCL to attempt to recreate the window for that control, destroying the current one in the process.

It should be fairly apparent that these mechanisms are highly vulnerable to problems that can arise when VCL methods are called by threads other than the VCL thread. This is why you will often here it said that «the VCL is not thread-safe«.

The safest way to operate is to only manipulate VCL objects from code running in the VCL thread itself.

Synchronize to the Rescue

This is in fact precisely why Synchronize exists.

The mechanism that you are invoking by using Synchronize actually works to ensure that the method you are Synchronizing is execute on the VCL thread. If this is in fact creating a window handle then when the VCL thread later comes to destroy that window handle it is quite free to do so since it did in fact create it.

Hence your problem is solved.

Other Options

The Synchronize mechanism is quite complex however, dealing (these days) with cross platform concerns among other things, and as a result may be overkill in this case.

If your code is specific to Windows, a possible alternate solution to this problem may be to exploit the fact that windows allows threads to send (or post) messages to windows in other threads. When those messages are received by those windows, they are then processed by that window’s own thread just as all other messages to those windows are. i.e. you cannot end up interrupting a «click» message received by that window by suddenly jumping across to run the notification from the thread. That notification message simply has to wait it’s turn while the window finishes processing that click message. For example.

You can think of this as a ‘Synchronize’ system «built-in» in to the OS.

So you could, for example, pass a window handle to a form (or control or anything with a window handle) to your HTTP async thread during initialisation, identifying a VCL window that wishes to receive the «request complete» or other notifications from the thread. The thread can then send notifications to that window handle using PostMessage or SendMessage which you could handle either by overriding the WindowProc on the form or using a declared message handler.

If the thread uses SendMessage() to send the notification, then it is automatically suspended and forced to wait until the message is received and processed by the window (in the VCL thread).

If the thread uses PostMessage() then the message is sent asynchronously and the thread can continue with other work without having to wait. The VCL thread will eventually pick up the message and process it.

NOT a Recommendation

This is not to say that I would recommend this alternative in this case. Although it does seem that it might be appropriate given that it does appear to be a simple «work is complete» notification in this case, without a more comprehensive understanding of your specific needs it is impossible to say which is most appropriate.

I mention it only to highlight the fact that alternatives do exist and that the key to safe, reliable threading is to understand the principles and the mechanisms involved.

I have a problem.
I have a VCL application using a thread. This thread does some calculations and calls a MainForm’s method through Synchronize(). It all works just fine, I have a «Start» button, which creates and runs the thread and a «Stop» button which stops and frees it. No errors, no nothing.

But for some reason when I close the application and I’ve run the thread I get a EOSError 1400 - Invalid window handle. I’ve breakpointed the OnClose procedure and the only thing I do there is saving an ini file, no error in that, when I trace further (using F7), I get to the very end (Application.Run; end.), after «calling» the end. I get the error, so there is no specific line of code raising it.

I hope the question is somewhat clear and I hope it’s solvable, because just ignoring the error seems a bit unclean.

Thanks inb4


ANSWER

This error occured to me when the Execute method of a thread was called, it looked like this:

procedure TRunThread.Execute;
var (...)
begin
  while not Terminated do begin
    (...)
    MainForm.Memo1.Lines.Add('Some text'); // Even though this call worked fine during
    //the application running, it caused errors on shutting the app down.
    // For acccessing GUI elements, it's necessary to use Synchronize()
    (...)
  end;
end;

Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

1

21.06.2011, 09:05. Показов 17364. Ответов 29

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Доброго времени суток.
После того как перенес некоторый код в поток при завершении программы стала вылетать ошибка EOSError 1400 «Недопустимый дескриптор окна». Код программно помещает на форму некоторое количество некоторых компонентов(таких как tlabel, timage, tbutton итп). Когда код был вне потока все было нормально, причина появления ошибки мне совершенно не ясна т.к. код выполняется до конца без ошибок и по идее поток должен при этом завершаться.
Вот этот код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
procedure TNewThread.Execute;
begin
 
//Çàãðóæàåì äðóçåé
reply_friends:=Form1.HTTPAction('index.php?action=friends&login='+Login+'&pass='+Password);
 
if Pos('<error>', reply_friends) = 0 then begin
friends_count:=StrToInt(Pars('<count>',reply_friends,'<>'));
 
  for element_i2 := 0 to friends_count-1 do
  begin
    friend:=element_i2+1;
    friend_str:=IntToStr(friend);
    friend_id:=Pars('<start>'+friend_str+'<>',reply_friends,'<end>'+friend_str+'<>');
    element_i:=StrToInt(Pars('<id>',friend_id,'<>'));
  //Àâàòàðû
    avatars[element_i] := TImage.Create(nil);
    avatars[element_i].Width := 60;
    avatars[element_i].Height := 60;
    avatars[element_i].Left := 8;
    if element_i2 = 0 then avatars[element_i].Top := 8;
    if element_i2 > 0 then avatars[element_i].Top := 8+(8+avatars[element_i].Height)*element_i2;
    MS:= TMemoryStream.Create;
    PNG := TPNGObject.Create;
    Form1.HTTPActionMS('avatars/'+Pars('<id>',Pars('<start>'+friend_str+'<>',reply_friends,'<end>'+friend_str+'<>'),'<>')+'.png', MS);
    MS.Position := 0;
    PNG.LoadFromStream(MS);
    avatars[element_i].Picture.Assign(PNG);
    MS.Free;
    PNG.Free;
    avatars[element_i].Parent := sScrollBox1;
 
  //Íèê:
    el_nick1[element_i] := TsLabel.Create(nil);
    el_nick1[element_i].Left := 72;
    el_nick1[element_i].Caption := 'Íèê:';
    if element_i2 = 0 then el_nick1[element_i].Top := 8;
    if element_i2 > 0 then el_nick1[element_i].Top := 8+(8+60)*element_i2;
    el_nick1[element_i].Parent := sScrollBox1;
 
  //Íèê
    el_nick2[element_i] := TsLabel.Create(nil);
    el_nick2[element_i].Left := 120;
    el_nick2[element_i].Caption := Pars('<name>',friend_id,'<>');
    if element_i2 = 0 then el_nick2[element_i].Top := 8;
    if element_i2 > 0 then el_nick2[element_i].Top := 8+(8+60)*element_i2;
    el_nick2[element_i].Parent := sScrollBox1;
 
  //Ñòàòóñ:
    el_status1[element_i] := TsLabel.Create(nil);
    el_status1[element_i].Left := 72;
    el_status1[element_i].Caption := 'Ñòàòóñ:';
    if element_i2 = 0 then el_status1[element_i].Top := 24;
    if element_i2 > 0 then el_status1[element_i].Top := 24+(8+60)*element_i2;
    el_status1[element_i].Parent := sScrollBox1;
 
  //Ñòàòóñ
    el_status2[element_i] := TsLabel.Create(nil);
    el_status2[element_i].Left := 120;
    st:=StrToInt(Pars('<status>',friend_id,'<>'));
    if st=0 then el_status2[element_i].Caption := 'Â èãðå';
    if st=1 then el_status2[element_i].Caption := 'Â ñåòè';
    if st=2 then el_status2[element_i].Caption := 'Îòøåë';
    if st=3 then el_status2[element_i].Caption := 'Çàíÿò';
    if st=4 then el_status2[element_i].Caption := 'Îòêëþ÷åí îò ñåòè';
    if element_i2 = 0 then el_status2[element_i].Top := 24;
    if element_i2 > 0 then el_status2[element_i].Top := 24+(8+60)*element_i2;
    el_status2[element_i].Parent := sScrollBox1;
 
  //Èãðà:
    el_game1[element_i] := TsLabel.Create(nil);
    el_game1[element_i].Left := 72;
    el_game1[element_i].Caption := 'Èãðà:';
    if element_i2 = 0 then el_game1[element_i].Top := 40;
    if element_i2 > 0 then el_game1[element_i].Top := 40+(8+60)*element_i2;
    el_game1[element_i].Parent := sScrollBox1;
 
  //Èãðà
    el_game2[element_i] := TsLabel.Create(nil);
    el_game2[element_i].Left := 120;
    el_game2[element_i].Caption := Pars('<game>',friend_id,'<>');
    if element_i2 = 0 then el_game2[element_i].Top := 40;
    if element_i2 > 0 then el_game2[element_i].Top := 40+(8+60)*element_i2;
    el_game2[element_i].Parent := sScrollBox1;
 
  //Ñåðâåð:
    el_server1[element_i] := TsLabel.Create(nil);
    el_server1[element_i].Left := 72;
    el_server1[element_i].Caption := 'Ñåðâåð:';
    if element_i2 = 0 then el_server1[element_i].Top := 56;
    if element_i2 > 0 then el_server1[element_i].Top := 56+(8+60)*element_i2;
    el_server1[element_i].Parent := sScrollBox1;
 
  //Ñåðâåð
    el_server2[element_i] := TsLabel.Create(nil);
    el_server2[element_i].Left := 120;
    el_server2[element_i].Caption := Pars('<server>',friend_id,'<>');
    if element_i2 = 0 then el_server2[element_i].Top := 56;
    if element_i2 > 0 then el_server2[element_i].Top := 56+(8+60)*element_i2;
    el_server2[element_i].Parent := sScrollBox1;
 
  //Êíîïêà ìåíþ
    el_menu_btn[element_i] := TsButton.Create(form10);
    el_menu_btn[element_i].Left := 220;
    el_menu_btn[element_i].Caption := '^';
    el_menu_btn[element_i].Width := 17;
    el_menu_btn[element_i].Height := 17;
    el_menu_btn[element_i].Tag := StrToInt(Pars('<id>',friend_id,'<>'));
    el_menu_btn[element_i].OnClick:=Form10.onbtn;
    if element_i2 = 0 then el_menu_btn[element_i].Top := 8;
    if element_i2 > 0 then el_menu_btn[element_i].Top := 8+(8+60)*element_i2;
    el_menu_btn[element_i].Parent := sScrollBox1;
 
  //ID
    el_id[element_i] := StrToInt(Pars('<id>',friend_id,'<>'));
 
  end;
 
sLabel1.Caption:='';
end
else
begin
sLabel1.Caption:=Pars('<error>',reply_friends,'<>');
end;
 
Form10.Loading_Anim.Visible:=false;
Form10.Loading_Anim.Animate:=false;
end;

Подскажите пожалуйста что в этом коде может вызывать эту ошибку?
Заранее спасибо.
P.S. Мб мысль глупая но всеже — а не может это быть из за того что если динамически создавать объекты в потоке то поток не завершиться после выполнения и будет продолжать жить пока эти объекты существуют?



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

21.06.2011, 09:05

Ответы с готовыми решениями:

‘System Error. Code: 1400. Недопустимый дескриптор окна’
Пишу многопоточную программу, а при ее закрытии после работы потоков выдает эту ошибку, из-за чего…

Недопустимый дескриптор окна =)
Все пашет вот только… Обьясняю))) В общем Основное Приложение вызывает SendPPMsg из DLL и все…

В каждом слове текста замените «а» на букву «е», если «а» стоит на четном месте, и заменить букву «б» на сочетание «ак»,
В каждом слове текста замените &quot;а&quot; на букву &quot;е&quot;, если &quot;а&quot; стоит на четном месте, и заменить букву…

Из слов «Работа», «крест», «тон» составить фразу «Кто не работает, тот не ест» и определить ее длину
Из слова &quot;Работа&quot;,&quot;крест&quot;,&quot;тон&quot; составить фразу:&quot;Кто не работает, тот не ест&quot; и определить ее длину.

29

16 / 16 / 3

Регистрация: 14.06.2011

Сообщений: 64

21.06.2011, 09:16

2

Какая связь из Form10. Возможно при обращении к форме она не create.



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 09:49

 [ТС]

3

Запуск потока происходит внутри той самой form10 по ее onshow т.ч. невозможно, полюс как я уже сказал код выполняется до конца без ошибок(я это проверил поставив в конец кода showmessage).

Добавлено через 29 минут
Нашел то что вызывает ошибку, эта строчка:

Delphi
1
el_menu_btn[element_i].Parent := sScrollBox1;

Но почему? У остальных компонентов родительским точно также является sScrollBox1…



0



16 / 16 / 3

Регистрация: 14.06.2011

Сообщений: 64

21.06.2011, 09:50

4

К компонентам которые динамически созданы обращаетесь не из потока?
Желательно бы увидеть код где запускается поток и что там еще делается.



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:04

 [ТС]

5

Нет обращаюсь не из потока, код который выше привел это полный код этого потока. Запускается поток из onshow как я уже говорил, вот код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
procedure Tform10.FormShow(Sender: TObject);
begin
Button1.SetFocus;
Timer1.Enabled:=true;
 
//Çàãðóæàåì ñâîè äàííûå
sLabel3.Caption:=auth_name;
image1.Picture:=form2.avatar.picture;
sComboBox1.ItemIndex:=Form2.sComboBox1.ItemIndex;
if auth_gamed <> '1' then begin
sLabel2.Caption:='';
sLabel8.Caption:='';
end;
if auth_gamed = '1' then begin
sLabel2.Caption:='Íå îïðåäåëåíî';
sLabel8.Caption:='Íå îïðåäåëåíî';
end;
 
if last_update_friends < time then begin
  Loading_Anim.Animate:=true;
  Loading_Anim.Visible:=true;
  TNewThread.Create(false);
 
  last_update_friends:=time+(1/(24*3600))*15;
  
  //Óäàëÿåì âñå ýëåìåíòû
  sScrollBox1.Free;
 
//ScrollBox
  sScrollBox1 := TsScrollBox.Create(Form10);
  sScrollBox1.Left := 16;
  sScrollBox1.Top := 88;
  sScrollBox1.Width := 265;
  sScrollBox1.Height := 361;
  sScrollBox1.HorzScrollBar.Visible := false;
  sScrollBox1.VertScrollBar.ButtonSize := 5;
  sScrollBox1.AutoMouseWheel := true;
  sScrollBox1.TabOrder := 1;
  sScrollBox1.Parent := Form10.sPanel1;
 
//sLabel1
  sLabel1 := TsLabel.Create(Form10);
  sLabel1.Left := 8;
  sLabel1.Width := 3;
  sLabel1.Height := 13;
  sLabel1.Top := 8;
  sLabel1.Parent := sScrollBox1;
end;
end;



0



MiheyJumaric

16 / 16 / 3

Регистрация: 14.06.2011

Сообщений: 64

21.06.2011, 10:16

6

Delphi
1
TNewThread.Create(false);

после

Delphi
1
2
3
4
5
6
7
8
9
10
sScrollBox1 := TsScrollBox.Create(Form10);
  sScrollBox1.Left := 16;
  sScrollBox1.Top := 88;
  sScrollBox1.Width := 265;
  sScrollBox1.Height := 361;
  sScrollBox1.HorzScrollBar.Visible := false;
  sScrollBox1.VertScrollBar.ButtonSize := 5;
  sScrollBox1.AutoMouseWheel := true;
  sScrollBox1.TabOrder := 1;
  sScrollBox1.Parent := Form10.sPanel1;



1



deathNC

1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:22

7

Ничего не пойму:

Delphi
1
2
3
4
5
6
TNewThread.Create(false);
 
  last_update_friends:=time+(1/(24*3600))*15;
  
  //Удаляем все элементы
  sScrollBox1.Free;

Тут что? Создаётся поток, и не известно, успеет он всё сделать, не успеет — всё равно sScrollBox1 сносим, а поток будет продолжать в несуществующий sScrollBox1 пихать компоненты?
Или я что-то путаю?



1



1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:22

 [ТС]

8

Ппц я и правда идиот… Странно что тут вообще чето работало… А еще странно то что это исправление ошибку не устранило. И еще один момент забыл написать — на форме все динамически созданные объекты показываются нормально, а вот эта злосчастная кнопка из за которой вылетает ошибка не показывается.
deathNC
да да я идиот xD хз каким волшебным образом но несморя на то что я такую глупую ошибку допустил он успевал xD но проблема все равно осталась после исправления этой глупой ошибки =\
Тут дело в том что открытие 10 формы предусмотрено не 1 разовое и данные там меняются, по этому при показе формы скорллбокс со всем содержимым стирается и создается заново если с момент последнего показа формы прошло более 15 секунд, вобщем я просто запуск потока поставил до абсурдности неправильно)



0



deathNC

21.06.2011, 10:26

Не по теме:

Crystallon, если при сносе компонентов через метод Free будет ошибка, то пробуй сносить через Destroy :)
Это просто на будущее :D



1



MiheyJumaric

16 / 16 / 3

Регистрация: 14.06.2011

Сообщений: 64

21.06.2011, 10:26

10

Delphi
1
2
//Кнопка меню
    el_menu_btn[element_i] := TsButton.Create(form10);

на

Delphi
1
2
//Кнопка меню
    el_menu_btn[element_i] := TsButton.Create(nil);



1



1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:28

11

А с этим проектом — отдельную процедуру писать, в которую перенести всё, что после запуска потока и запустить её по завершению потока. Это если другими путями не справишься!



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:30

 [ТС]

12

Цитата
Сообщение от MiheyJumaric
Посмотреть сообщение

Delphi
1
2
//Кнопка меню
    el_menu_btn[element_i] := TsButton.Create(form10);

на

Delphi
1
2
//Кнопка меню
    el_menu_btn[element_i] := TsButton.Create(nil);

Уже пробовал, также пробовал всем остальным компонентам поставить form10 вместо nil, вообще ничего не меняется.

Цитата
Сообщение от deathNC
Посмотреть сообщение

А с этим проектом — отдельную процедуру писать, в которую перенести всё, что после запуска потока и запустить её по завершению потока. Это если другими путями не справишься!

Ды эт я понимаю, в том то и дело что там ничего не должно быть после запуска потока, я просто не туда его запуск поставил

А вообще это бред какойто…чем tbutton хуже других компонентов что приводит к такой проблеме…ведь его создание полностью аналогично созданию других компонентов…



0



1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:35

13

Проверь индексы element_i и типы элементов. МОж не то что-то написал. А то поди el_menu_btn у тебя как TButton какой-нибудь объявлен, а создаёшь TSButton



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:36

 [ТС]

14

Цитата
Сообщение от deathNC
Посмотреть сообщение

Проверь индексы element_i и типы элементов. МОж не то что-то написал. А то поди el_menu_btn у тебя как TButton какой-нибудь объявлен, а создаёшь TSButton

Это в первую очередь проверил, каждую строчку сверил =\
Плюс к тому я код просто скопировал из onshow, он раньше там был а не в потоке и нормально работал
И методом коментирования строчек и групп строчек я точно определил что если все оставить как есть и закомменить одну лишь строчку

Delphi
1
el_menu_btn[element_i].Parent := sScrollBox1;

ошибка уже не возникает, но кнопки на форме по прежнему отсутствуют, и еслиб они там были при этом то было бы очень странно)



0



deathNC

1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:45

15

Попробуй

Delphi
1
Form10.InsercControl([COLOR="DimGray"]<<<твой компонент>>>[/COLOR])ж



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:49

 [ТС]

16

Цитата
Сообщение от deathNC
Посмотреть сообщение

Попробуй

Delphi
1
Form10.InsercControl([COLOR="DimGray"]<<<твой компонент>>>[/COLOR])ж
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
    el_menu_btn[element_i] := TsButton.Create(Form10);
    el_menu_btn[element_i].Left := 220;
    el_menu_btn[element_i].Caption := '^';
    el_menu_btn[element_i].Width := 17;
    el_menu_btn[element_i].Height := 17;
    el_menu_btn[element_i].Tag := StrToInt(Pars('<id>',friend_id,'<>'));
    el_menu_btn[element_i].OnClick:=Form10.onbtn;
    if element_i2 = 0 then el_menu_btn[element_i].Top := 8;
    if element_i2 > 0 then el_menu_btn[element_i].Top := 8+(8+60)*element_i2;
    el_menu_btn[element_i].Parent := sScrollBox1;
 
    Form10.InsertControl(el_menu_btn[element_i]);

Ничего не изменилось =\



0



deathNC

1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:51

17

А

Delphi
1
el_menu_btn[element_i].Show;

если есть такое конечно



1



1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:53

 [ТС]

18

Есть) но все как было так и осталось =\



0



deathNC

1904 / 1015 / 123

Регистрация: 08.12.2009

Сообщений: 2,792

Записей в блоге: 2

21.06.2011, 10:56

19

Это не относится к ошибке, но я не увидел смысла в первой строке и в условии второй:

Delphi
1
2
If element_i2 = 0 then el_menu_btn[element_i].Top := 8;
If element_i2 > 0 then el_menu_btn[element_i].Top := 8+(8+60)*element_i2;

На мой взгляд:

Delphi
1
el_menu_btn[element_i].Top := 8+(8+60)*element_i2;



1



Crystallon

1 / 1 / 0

Регистрация: 20.06.2011

Сообщений: 55

21.06.2011, 10:58

 [ТС]

20

Цитата
Сообщение от deathNC
Посмотреть сообщение

Это не относится к ошибке, но я не увидел смысла в первой строке и в условии второй:

Delphi
1
2
If element_i2 = 0 then el_menu_btn[element_i].Top := 8;
If element_i2 > 0 then el_menu_btn[element_i].Top := 8+(8+60)*element_i2;

На мой взгляд:

Delphi
1
el_menu_btn[element_i].Top := 8+(8+60)*element_i2;

Эт сейчас неважно) главное работает xD все равно исправление таких «извращений» не даст заметного прироста в производительности)



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

21.06.2011, 10:58

Помогаю со студенческими работами здесь

На форме располагаются компоненты: редактор Edit; линейка ScrollBar; радионабор с опциями «Цветы», «Деревья», «Рыбы», «Звери»
Доброго времени суток, 2 курс 2 семестр, пришли, препод раздал задачи, сказал качайте дома и…

Тысячные числа исправлять к примеру с «1200» на «1 200», «12000» на «12 000» и т.д
Собственно числа исправлять к примеру с &quot;1200&quot; на &quot;1 200&quot;, &quot;12000&quot; на &quot;12 000&quot;, &quot;120000&quot; на…

В слове Х перед каждой буквой «к», которой предшествует буква «с», вставить букву «н»
Привет всем) вот условие задачи:В слове Х перед каждой буквой &quot;к&quot;, которой предшествует буква &quot;с&quot;,…

Товар стоит «a» руб. «b» коп. За него заплатили «c» руб. «d» коп. Сколько сдачи требуется получить?
Товар стоит a руб. b коп. За него заплатили c руб. d коп. Сколько сдачи требуется получить?…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

20

Вы отправили много кода, но не ключевую, релевантную часть. Конкретно реализация вашего xOnAsyncRequestDone обработчик / метод события (если он буквально не вызывает только тот метод журнала, который вы опубликовали).

Этот метод выполняется в контексте потока TMySynHTTPAsync и основан на поведении, которое вы описываете — особенно тот факт, что Synchronize решает вашу проблему — весьма вероятно, что некоторые действия в этом обработчике событий создают дескриптор окна.

Этот дескриптор окна затем принадлежит асинхронному потоку HTTP, а не основному потоку приложения (иногда называемому «потоком VCL»), который в противном случае выполняет ваше приложение. Когда ваше приложение закрывается, поток VCL выполняет некоторую окончательную служебную работу, уничтожая объекты и окна и т. Д. Если одно из этих окон было создано каким-либо другим потоком, это вызовет проблемы.

Описатели окна — это строгое свойство потока, в котором они были созданы. Вы не можете создать дескриптор окна в одном потоке, а затем уничтожить его в другом.

ПРИМЕЧАНИЕ. Это основа Windows, а не Delphi.

Стоит отметить, что дескрипторы окон в VCL часто могут создаваться косвенно. Вы не обязательно увидите явное создание элемента управления, который отмечает создание основного дескриптора окна. Обычно дескрипторы окон создаются только при необходимости. Аналогичным образом изменение свойств элемента управления может привести к тому, что VCL попытается воссоздать окно для этого элемента управления, уничтожив текущее в процессе.

Должно быть совершенно очевидно, что эти механизмы очень уязвимы для проблем, которые могут возникнуть, когда методы VCL вызываются потоками, отличными от потока VCL. Вот почему вы часто будете здесь говорить, что «VCL не является потокобезопасным«.

Самый безопасный способ работы — манипулировать объектами VCL только из кода, выполняемого в самом потоке VCL.

Синхронизировать на помощь

Это на самом деле именно поэтому Synchronize существует.

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

Следовательно, ваша проблема решена.

Другие опции

Synchronize Механизм, однако, довольно сложный, он имеет дело (в наши дни) с кроссплатформенными проблемами, среди прочего, и в результате может быть излишним в этом случае.

Если ваш код относится к Windows, возможное альтернативное решение этой проблемы может заключаться в том, чтобы использовать тот факт, что windows позволяет потокам отправлять (или публиковать) сообщения окнам в других потоках. Когда эти сообщения принимаются этими окнами, они затем обрабатываются собственным потоком этого окна, так же как и все другие сообщения этих окон. то есть вы не можете в конечном итоге прервать сообщение «click», полученное этим окном, внезапно перепрыгнув, чтобы запустить уведомление из потока. Это уведомляющее сообщение просто должно дождаться своей очереди, пока окно завершит обработку этого сообщения о клике. Например.

Вы можете думать об этом как о «встроенной» в систему «Синхронизировать» системе.

Таким образом, вы можете, например, передать дескриптор окна в форму (или элемент управления или что-либо с дескриптором окна) асинхронному потоку HTTP во время инициализации, идентифицируя окно VCL, которое хочет получить «запрос завершен» или другие уведомления от нить. Затем поток может отправлять уведомления на этот дескриптор окна, используя PostMessage или же SendMessage который вы можете обработать, переопределив WindowProc в форме или используя объявленный обработчик сообщений.

Если поток использует SendMessage() чтобы отправить уведомление, оно автоматически приостанавливается и вынуждено ждать, пока сообщение не будет получено и обработано окном (в потоке VCL).

Если поток использует PostMessage() затем сообщение отправляется асинхронно, и поток может продолжить другую работу без ожидания. Поток VCL в конечном итоге получит сообщение и обработает его.

НЕ рекомендация

Это не значит, что я бы порекомендовал эту альтернативу в этом случае. Хотя кажется, что это может быть уместно, учитывая, что в данном случае это простое уведомление «работа завершена», без более полного понимания ваших конкретных потребностей невозможно сказать, какой из них наиболее уместен.

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

Содержание

  1. Delphi и потоки: «Системная ошибка. Код: 1400. Недействительный дескриптор окна »
  2. 3 ответа
  3. Синхронизация для спасения
  4. Другие варианты
  5. НЕ рекомендация
  6. Недопустимый дескриптор окна
  7. Вложенный файл:
  8. Вложенный файл:
  9. Вложенный файл:
  10. Вложенный файл:
  11. Вложенный файл:
  12. Code 1400 недопустимый дескриптор окна
  13. Решение
  14. Другие решения
  15. Признаки ошибки 1400
  16. Причины ошибки 1400
  17. Ошибки во время выполнения в базе знаний
  18. Как исправить ошибку Internet Explorer 1400
  19. Шаг 1: Восстановить записи реестра, связанные с ошибкой 1400
  20. Шаг 2: Проведите полное сканирование вашего компьютера на вредоносное ПО
  21. Шаг 3: Очистить систему от мусора (временных файлов и папок) с помощью очистки диска (cleanmgr)
  22. Шаг 4: Обновите драйверы устройств на вашем компьютере
  23. Шаг 5: Используйте Восстановление системы Windows, чтобы «Отменить» последние изменения в системе
  24. Шаг 6: Удалите и установите заново программу Internet Explorer, связанную с Ошибка 1400
  25. Шаг 7: Запустите проверку системных файлов Windows («sfc /scannow»)
  26. Шаг 8: Установите все доступные обновления Windows
  27. Шаг 9: Произведите чистую установку Windows
  28. Информация об операционной системе
  29. Проблема с 1400 все еще не устранена?
  30. 2 ответов

Поскольку я новичок в потоковой передаче, я столкнулся с проблемой:

Я создал небольшую оболочку для объекта Synapse THTTPSend для обработки вызовов Async с помощью потока. Кажется, все идет хорошо, пока я не выйду из приложения и не получу эту ошибку (используя обработчик исключений madExcept) «Системная ошибка. Код: 1400. Недопустимый дескриптор окна».

Я отследил это до доступа к списку, это выглядит так:

  • GUI вызывает процедуру в моей оболочке и назначает метод обратного вызова
  • Wrapper создает поток и устанавливает обратный вызов
  • Thread выполняет свою работу (сообщение http), а затем вызывает обратный вызов оболочки
  • Обратный вызов Wrapper запускает другой обратный вызов в графическом интерфейсе, который затем обновляет некоторые элементы в списке.

Если я пропущу эту часть списка, ошибка никогда не произойдет, поэтому я думаю, что что-то может быть не так в моем коде потока, который портит vcl / gui, вероятно, потому, что он все еще работает, пока осуществляется доступ к VCL? Если я проверю список, то после завершения потока с ним что-то очень странное, иногда список даже не отображается, или добавленные элементы не доступны для кликов.

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

если назначено (sObj.xOnAsyncRequestDone), то sObj.xOnAsyncRequestDone;

Как я мог это решить?

3 ответа

Вы разместили много кода, но не ключевую, релевантную часть. В частности, реализация вашего обработчика / метода событий xOnAsyncRequestDone (если только он буквально не вызывает только тот метод журнала, который вы опубликовали).

Этот метод выполняется в контексте потока TMySynHTTPAsync , и в зависимости от поведения, которое вы описываете, в частности того факта, что Synchronize решает вашу проблему, весьма вероятно, что некоторые действия в этом обработчик событий создает дескриптор окна.

Этот дескриптор окна затем принадлежит потоку HTTP Async , а не главному потоку приложения (иногда называемому «потоком VCL»), который в противном случае запускает ваше приложение. Когда ваше приложение закрывается, поток VCL выполняет окончательную уборку, уничтожая объекты, окна и т. Д., Если одно из этих окон было создано каким-либо другим потоком, это вызовет проблемы.

Оконные дескрипторы — это строгое свойство потока, в котором они были созданы. Вы не можете создать дескриптор окна в одном потоке, а затем уничтожить его в другом.

ПРИМЕЧАНИЕ. Это основа Windows, а не Delphi .

Здесь стоит отметить, что дескрипторы окон в VCL часто могут создаваться косвенно. Вы не обязательно увидите явное создание элемента управления, который отмечает создание базового дескриптора окна. Довольно часто оконные ручки создаются только тогда, когда это необходимо. Аналогичным образом изменение свойств элемента управления может привести к тому, что VCL попытается воссоздать окно для этого элемента управления, уничтожив текущее окно в процессе.

Должно быть совершенно очевидно, что эти механизмы очень уязвимы для проблем, которые могут возникнуть, когда методы VCL вызываются потоками, отличными от потока VCL. Вот почему вы часто здесь говорите, что « VCL не является потокобезопасным ».

Самый безопасный способ работы — манипулировать объектами VCL только из кода, выполняемого в самом потоке VCL.

Синхронизация для спасения

Фактически, именно поэтому существует Synchronize .

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

Значит, ваша проблема решена.

Другие варианты

Механизм Synchronize , однако, довольно сложен, он решает (в наши дни), помимо прочего, кроссплатформенные проблемы, и в результате в этом случае может оказаться излишним.

Если ваш код специфичен для Windows, возможным альтернативным решением этой проблемы может быть использование того факта, что окна позволяют потокам отправлять (или публиковать) сообщения окнам в других потоках. Когда эти сообщения принимаются этими окнами, они затем обрабатываются собственным потоком этого окна, как и все другие сообщения этим окнам. то есть вы не можете в конечном итоге прервать сообщение «щелчок», полученное этим окном, внезапным прыжком через него, чтобы запустить уведомление из потока. Это уведомление просто должно дождаться своей очереди, пока окно не завершит обработку этого сообщения щелчка. Например.

Вы можете думать об этом как о системе «Синхронизация», «встроенной» в ОС.

Таким образом, вы могли бы, например, передать дескриптор окна в форму (или элемент управления, или что-либо еще с дескриптором окна) вашему асинхронному потоку HTTP во время инициализации, идентифицируя окно VCL, которое желает получить «запрос завершен» или другие уведомления от нить. Затем поток может отправлять уведомления этому дескриптору окна с помощью PostMessage или SendMessage , которые вы можете обработать, переопределив WindowProc в форме, или используя объявленный обработчик сообщений.

Если поток использует SendMessage() для отправки уведомления, он автоматически приостанавливается и вынужден ждать, пока сообщение не будет получено и обработано окном (в потоке VCL).

Если поток использует PostMessage() , то сообщение отправляется асинхронно, и поток может продолжить другую работу без ожидания. Поток VCL в конечном итоге получит сообщение и обработает его.

НЕ рекомендация

Это не означает, что я рекомендовал бы эту альтернативу в данном случае. Хотя кажется, что это может быть уместно, учитывая, что в данном случае это действительно простое уведомление «работа завершена», без более полного понимания ваших конкретных потребностей невозможно сказать, что является наиболее подходящим.

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

Источник

Недопустимый дескриптор окна

  • Сообщений: 1
  • Спасибо получено: 0

Вложенный файл:

Вложенный файл:

Вложенный файл:

Вложенный файл:

Вложенный файл:

Вложения:

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • MotoArhangel
  • —>
  • Не в сети
  • Сообщений: 293
  • Репутация: 19
  • Спасибо получено: 79

Что то пошло не так.
1. Либо у Вас проблемы с самой виндовс
2. Либо после создания окна у программы нет возможности получить дескриптор созданного окна или объекта(кнопки и т.п.) Может блокировать какой нить антивирус, либо другое ПО, которое пытается перехватить окна, в том числе и вирусы.
3. Либо что то просто тормозит программу и разработчики не предусмотрели такого случая при использовании потоков(либо что то не успевает выполниться, либо появляется системное сообщение при выводе которого происходит такая фигня).

Во всяком случае проблема в вашей рабочей станции. И как это решить, никто Вам не ответит, все в Ваших руках.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • jurganov
  • —>
  • Не в сети
  • Сообщений: 28
  • Спасибо получено: 1

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • jurganov
  • —>
  • Не в сети
  • Сообщений: 28
  • Спасибо получено: 1

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • Wmffre
  • —>
  • Не в сети
  • Сообщений: 623
  • Репутация: 23
  • Спасибо получено: 177

jurganov пишет: Значит ТОЧНО дело не в наших рабочих станциях (отличных друг от друга), а в недоработанности приложения.
придется админам ждать, когда разрабы допилят. Но казнчейство -то ждать от бухгалтерии не станет.

Попробуйте устанавливать Континент TLS Клиент 2.0.1440.0 с отключенным в BIOS Secure Boot (если он был включён).

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

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • jurganov
  • —>
  • Не в сети
  • Сообщений: 28
  • Спасибо получено: 1

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • alyam
  • —>
  • Не в сети
  • Сообщений: 31
  • Спасибо получено: 0

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • Wmffre
  • —>
  • Не в сети
  • Сообщений: 623
  • Репутация: 23
  • Спасибо получено: 177

В качестве эксперимента попробуйте выполнить следующее:

Попробуйте скачать, нажав кнопку «Download Sciter SDK«, sciter-sdk.zip со следующей страницы: https://sciter.com/download . В zip-архиве по пути sciter-sdk.zipbin32 (или по пути sciter-sdk.zipbin64, если операционная система 64-хразрядная) находится файл sciter.dll, его и извлеките.

В папке C:Program FilesSecurity CodeContinent TLS Client находится точно такой же файл sciter.dll, его необходимо куда-нибудь скопировать в другое место, а в саму папку поместите sciter.dll из архива.

Пересчитайте контрольные суммы, запустив в папке Continent TLS Client GUIIntegrityController.exe, нажав на него правой кнопкой мыши и выбрав «Запуск от имени администратора», а далее нажав кнопку «Пересчитать контрольные суммы».

Дальше запустите Континент TLS-клиент по правой кнопке мыши, выбрав «Запуск от имени администратора». Если ошибки «Недопустимый дескриптор окна» не возникнет и Континент TLS-клиент запустится без ошибок, то останется только его настроить, а его окно настроек будет при работе от новой библиотеки немного глючить. На Windows 7 чтобы отобразились ресурсы и пользовательские сертификаты необходимо, чтобы в правой части всегда отображалась панель «Настройки» — смотрите приложенный рисунок. Сертификат сервера lk2012.budget.gov.ru.cer импортировать через Континент TLS-клиент не получится, поэтому его придётся импортировать через оснастку «Сертификаты» Windows в следующее место: Сертификаты (локальный компьютер) —> ContinentTLSClientServer —> Сертификаты.

Вложения:

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Источник

Code 1400 недопустимый дескриптор окна

Почему при создании окна возвращается 1400 недействительных дескрипторов? Не так ли? В функции создания окна нет дескриптора окна, хорошо? Как это может быть неверный дескриптор? Я долго искал в поисковике, но до сих пор не могу решить эту проблему?
Почему CreateWindowExW() вернуть 1400?
Код в строке 44.

Решение

Вы используете WindowHandle в процедуре окна, прежде чем он был установлен на возвращаемое значение CreateWindowEx , Часть этого CreateWindowEx вызов вызывает оконную процедуру с WM_NCCREATE а также WM_CREATE , Ваша оконная процедура вызывает DefWindowProc с нулевой ручкой в ​​этой точке.

Простое решение здесь заключается в использовании _windowHandle параметр вместо вашего WindowHandle Глобальный.

Также обратите внимание, что для того, чтобы ваше окно было видно, вам нужно позвонить ShowWindow , Кроме того, сообщение о выходе, которое вы публикуете, не относится к этому окну, поэтому ваш GetMessage вызов не получит его, и приложение не будет завершено.

Другие решения

Вы не проверяли, действительно ли произошла ошибка. Вам нужно проверить дескриптор, который вы получаете от CreateWindowEx, прежде чем вызывать GetLastError. В противном случае он вернет некоторую предыдущую, не связанную ошибку или какое-либо случайное значение.

Вызывайте GetLastError только после неудачного CreateWindow (то есть, если CreateWindow возвращает NULL).

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

Номер ошибки: Ошибка 1400
Название ошибки: IE Error Code 1400
Описание ошибки: Ошибка 1400: Возникла ошибка в приложении Internet Explorer. Приложение будет закрыто. Приносим извинения за неудобства.
Разработчик: Microsoft Corporation
Программное обеспечение: Internet Explorer
Относится к: Windows XP, Vista, 7, 8

Совместима с Windows 2000, XP, Vista, 7, 8 и 10

Признаки ошибки 1400

  • Появляется сообщение «Ошибка 1400» и окно активной программы вылетает.
  • Ваш компьютер часто прекращает работу после отображения ошибки 1400 при запуске определенной программы.
  • Отображается “IE Error Code 1400”.
  • Windows медленно работает и медленно реагирует на ввод с мыши или клавиатуры.
  • Компьютер периодически «зависает» на несколько секунд.

Такие сообщения об ошибках 1400 могут появляться в процессе установки программы, когда запущена программа, связанная с Microsoft Corporation (например, Internet Explorer), при запуске или завершении работы Windows, или даже при установке операционной системы Windows. Отслеживание момента появления ошибки 1400 является важной информацией при устранении проблемы.

Причины ошибки 1400

  • Поврежденная загрузка или неполная установка программного обеспечения Internet Explorer.
  • Повреждение реестра Internet Explorer из-за недавнего изменения программного обеспечения (установка или удаление), связанного с Internet Explorer.
  • Вирус или вредоносное ПО, которые повредили файл Windows или связанные с Internet Explorer программные файлы.
  • Другая программа злонамеренно или по ошибке удалила файлы, связанные с Internet Explorer.

Ошибки типа Ошибки во время выполнения, такие как «Ошибка 1400», могут быть вызваны целым рядом факторов, поэтому важно устранить каждую из возможных причин, чтобы предотвратить повторение ошибки в будущем.

Ошибки во время выполнения в базе знаний

star rating here

Как исправить ошибку Internet Explorer 1400

Ниже описана последовательность действий по устранению ошибок, призванная решить проблемы Ошибка 1400. Данная последовательность приведена в порядке от простого к сложному и от менее затратного по времени к более затратному, поэтому мы настоятельно рекомендуем следовать данной инструкции по порядку, чтобы избежать ненужных затрат времени и усилий.

Пожалуйста, учтите: Нажмите на изображение [ ] , чтобы развернуть инструкции по устранению проблем по каждому из шагов ниже. Вы также можете использовать изображение [ ], чтобы скрывать инструкции по мере их выполнения.

Шаг 1: Восстановить записи реестра, связанные с ошибкой 1400

Редактирование реестра Windows вручную с целью удаления содержащих ошибки ключей Ошибка 1400 не рекомендуется, если вы не являетесь специалистом по обслуживанию ПК. Ошибки, допущенные при редактировании реестра, могут привести к неработоспособности вашего ПК и нанести непоправимый ущерб вашей операционной системе. На самом деле, даже одна запятая, поставленная не в том месте, может воспрепятствовать загрузке компьютера!

В связи с подобным риском мы настоятельно рекомендуем использовать надежные инструменты очистки реестра, такие как WinThruster [Загрузить] (разработанный Microsoft Gold Certified Partner), чтобы просканировать и исправить любые проблемы, связанные с Ошибка 1400. Используя очистку реестра [Загрузить], вы сможете автоматизировать процесс поиска поврежденных записей реестра, ссылок на отсутствующие файлы (например, вызывающих ошибку %%error_name%%) и нерабочих ссылок внутри реестра. Перед каждым сканированием автоматически создается резервная копия, позволяющая отменить любые изменения одним кликом и защищающая вас от возможного повреждения компьютера. Самое приятное, что устранение ошибок реестра [Загрузить] может резко повысить скорость и производительность системы.

Предупреждение: Если вы не являетесь опытным пользователем ПК, мы НЕ рекомендуем редактирование реестра Windows вручную. Некорректное использование Редактора реестра может привести к серьезным проблемам и потребовать переустановки Windows. Мы не гарантируем, что неполадки, являющиеся результатом неправильного использования Редактора реестра, могут быть устранены. Вы пользуетесь Редактором реестра на свой страх и риск.

Перед тем, как вручную восстанавливать реестр Windows, необходимо создать резервную копию, экспортировав часть реестра, связанную с Ошибка 1400 (например, Internet Explorer):

  1. Нажмите на кнопку Начать.
  2. Введите «command» в строке поиска. ПОКА НЕ НАЖИМАЙТЕENTER!
  3. Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
  4. Будет выведено диалоговое окно для доступа.
  5. Нажмите Да.
  6. Черный ящик открывается мигающим курсором.
  7. Введите «regedit» и нажмите ENTER.
  8. В Редакторе реестра выберите ключ, связанный с Ошибка 1400 (например, Internet Explorer), для которого требуется создать резервную копию.
  9. В меню Файл выберите Экспорт.
  10. В списке Сохранить в выберите папку, в которую вы хотите сохранить резервную копию ключа Internet Explorer.
  11. В поле Имя файла введите название файла резервной копии, например «Internet Explorer резервная копия».
  12. Убедитесь, что в поле Диапазон экспорта выбрано значение Выбранная ветвь.
  13. Нажмите Сохранить.
  14. Файл будет сохранен с расширением .reg.
  15. Теперь у вас есть резервная копия записи реестра, связанной с Internet Explorer.

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

Мы не несем никакой ответственности за результаты действий, совершенных по инструкции, приведенной ниже – вы выполняете эти задачи на свой ​​страх и риск.

Шаг 2: Проведите полное сканирование вашего компьютера на вредоносное ПО

Есть вероятность, что ошибка 1400 может быть связана с заражением вашего компьютера вредоносным ПО. Эти вредоносные злоумышленники могут повредить или даже удалить файлы, связанные с Ошибки во время выполнения. Кроме того, существует возможность, что ошибка 1400 связана с компонентом самой вредоносной программы.

Совет: Если у вас еще не установлены средства для защиты от вредоносного ПО, мы настоятельно рекомендуем использовать Emsisoft Anti-Malware (скачать). В отличие от других защитных программ, данная программа предлагает гарантию удаления вредоносного ПО.

Шаг 3: Очистить систему от мусора (временных файлов и папок) с помощью очистки диска (cleanmgr)

Со временем ваш компьютер накапливает ненужные файлы в связи с обычным интернет-серфингом и повседневным использованием компьютера. Если такие ненужные файлы иногда не удалять, они могут привести к снижению быстродействия Internet Explorer или к ошибке 1400, возможно вследствие конфликтов файлов или перегрузки жесткого диска. Удаление таких временных файлов при помощи утилиты Очистка диска может не только устранить ошибку 1400, но и существенно повысить быстродействие вашего компьютера.

Совет: Хотя утилита Очистки диска является прекрасным встроенным инструментом, она удаляет не все временные файлы с вашего компьютера. Другие часто используемые программы, такие как Microsoft Office, Firefox, Chrome, Live Messenger, а также сотни других программ не поддаются очистке при помощи программы Очистка диска (включая некоторые программы Microsoft Corporation).

Из-за недостатков утилиты Windows Очистка диска (cleanmgr) мы настоятельно рекомендуем использовать специализированное программное обеспечение очистки жесткого диска / защиты конфиденциальности, например WinSweeper [Загрузить] (разработано Microsoft Gold Partner), для очистки всего компьютера. Запуск WinSweeper [Загрузить] раз в день (при помощи автоматического сканирования) гарантирует, что ваш компьютер всегда будет чист, будет работает быстро и без ошибок %%error_name%%, связанных с временными файлами.

Как запустить Очистку диска (cleanmgr) (Windows XP, Vista, 7, 8 и 10):

  1. Нажмите на кнопку Начать.
  2. Введите «command» в строке поиска. ПОКА НЕ НАЖИМАЙТЕENTER!
  3. Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
  4. Будет выведено диалоговое окно для доступа.
  5. Нажмите Да.
  6. Черный ящик открывается мигающим курсором.
  7. Введите «cleanmgr» и нажмите ENTER.
  8. Программа Очистка диска приступит к подсчету занятого места на диске, которое вы можете освободить.
  9. Будет открыто диалоговое окно Очистка диска, содержащее флажки, которые вы можете выбрать. В большинстве случаев категория «Временные файлы» занимает большую часть дискового пространства.
  10. Установите флажки напротив категорий, которые вы хотите использовать для очистки диска, и нажмите OK.

Шаг 4: Обновите драйверы устройств на вашем компьютере

Ошибки 1400 могут быть связаны с повреждением или устареванием драйверов устройств. Драйверы с легкостью могут работать сегодня и перестать работать завтра по целому ряду причин. Хорошая новость состоит в том, что чаще всего вы можете обновить драйверы устройства, чтобы устранить проблему с Ошибка 1400.

В связи с временными затратами и общей сложностью обновления драйверов мы настоятельно рекомендуем использовать утилиту обновления драйверов, например DriverDoc (разработана Microsoft Gold Partner), для автоматизации этого процесса.

Пожалуйста, учтите: Ваш файл Ошибка 1400 может и не быть связан с проблемами в драйверах устройств, но всегда полезно убедиться, что на вашем компьютере установлены новейшие версии драйверов оборудования, чтобы максимизировать производительность вашего ПК.

Шаг 5: Используйте Восстановление системы Windows, чтобы «Отменить» последние изменения в системе

Восстановление системы Windows позволяет вашему компьютеру «отправиться в прошлое», чтобы исправить проблемы Ошибка 1400. Восстановление системы может вернуть системные файлы и программы на вашем компьютере к тому времени, когда все работало нормально. Это потенциально может помочь вам избежать головной боли от устранения ошибок, связанных с 1400.

Пожалуйста, учтите: использование восстановления системы не повлияет на ваши документы, изображения или другие данные.

Чтобы использовать Восстановление системы (Windows XP, Vista, 7, 8 и 10):

  1. Нажмите на кнопку Начать.
  2. В строке поиска введите «Восстановление системы» и нажмите ENTER.
  3. В окне результатов нажмите Восстановление системы.
  4. Введите пароль администратора (при появлении запроса).
  5. Следуйте инструкциям Мастера для выбора точки восстановления.
  6. Восстановить ваш компьютер.

Шаг 6: Удалите и установите заново программу Internet Explorer, связанную с Ошибка 1400

Инструкции для Windows 7 и Windows Vista:

  1. Откройте «Программы и компоненты», нажав на кнопку Пуск.
  2. Нажмите Панель управления в меню справа.
  3. Нажмите Программы.
  4. Нажмите Программы и компоненты.
  5. Найдите Internet Explorer в столбце Имя.
  6. Нажмите на запись Internet Explorer.
  7. Нажмите на кнопку Удалить в верхней ленте меню.
  8. Следуйте инструкциям на экране для завершения удаления Internet Explorer.

Инструкции для Windows XP:

  1. Откройте «Программы и компоненты», нажав на кнопку Пуск.
  2. Нажмите Панель управления.
  3. Нажмите Установка и удаление программ.
  4. Найдите Internet Explorer в списке Установленные программы.
  5. Нажмите на запись Internet Explorer.
  6. Нажмите на кнопку Удалить справа.
  7. Следуйте инструкциям на экране для завершения удаления Internet Explorer.

Инструкции для Windows 8:

  1. Установите указатель мыши в левой нижней части экрана для показа изображения меню Пуск.
  2. Щелкните правой кнопкой мыши для вызова Контекстного меню Пуск.
  3. Нажмите Программы и компоненты.
  4. Найдите Internet Explorer в столбце Имя.
  5. Нажмите на запись Internet Explorer.
  6. Нажмите Удалить/изменить в верхней ленте меню.
  7. Следуйте инструкциям на экране для завершения удаления Internet Explorer.

После того, как вы успешно удалили программу, связанную с Ошибка 1400 (например, Internet Explorer), заново установите данную программу, следуя инструкции Microsoft Corporation.

Совет: Если вы абсолютно уверены, что ошибка 1400 связана с определенной программой Microsoft Corporation, удаление и повторная установка программы, связанной с Ошибка 1400 с большой вероятностью решит вашу проблему.

Шаг 7: Запустите проверку системных файлов Windows («sfc /scannow»)

Проверка системных файлов представляет собой удобный инструмент, включаемый в состав Windows, который позволяет просканировать и восстановить поврежденные системные файлы Windows (включая те, которые имеют отношение к Ошибка 1400).

Чтобы запустить проверку системных файлов (Windows XP, Vista, 7, 8 и 10):

  1. Нажмите на кнопку Начать.
  2. Введите «command» в строке поиска. ПОКА НЕ НАЖИМАЙТЕENTER!
  3. Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
  4. Будет выведено диалоговое окно для доступа.
  5. Нажмите Да.
  6. Черный ящик открывается мигающим курсором.
  7. Введите «sfc /scannow» и нажмите ENTER.
  8. Проверка системных файлов начнет сканирование на наличие проблем Ошибка 1400 и других системных файлов (проявите терпение – проверка может занять длительное время).
  9. Следуйте командам на экране.

Шаг 8: Установите все доступные обновления Windows

Microsoft постоянно обновляет и улучшает системные файлы Windows, связанные с Ошибка 1400. Иногда для решения проблемы Ошибки во время выполнения нужно просто напросто обновить Windows при помощи последнего пакета обновлений или другого патча, которые Microsoft выпускает на постоянной основе.

Чтобы проверить наличие обновлений Windows (Windows XP, Vista, 7, 8 и 10):

  1. Нажмите на кнопку Начать.
  2. Введите «update» в строке поиска и нажмите ENTER.
  3. Будет открыто диалоговое окно Обновление Windows.
  4. Если имеются доступные обновления, нажмите на кнопку Установить обновления.

Шаг 9: Произведите чистую установку Windows

Предупреждение: Мы должны подчеркнуть, что переустановка Windows займет очень много времени и является слишком сложной задачей, чтобы решить проблемы Ошибка 1400. Во избежание потери данных вы должны быть уверены, что вы создали резервные копии всех важных документов, изображений, программ установки программного обеспечения и других персональных данных перед началом процесса. Если вы сейчас е создаете резервные копии данных, вам стоит немедленно заняться этим (скачать рекомендованное решение для резервного копирования), чтобы защитить себя от безвозвратной потери данных.

Пожалуйста, учтите: Если проблема 1400 не устранена после чистой установки Windows, это означает, что проблема Ошибки во время выполнения ОБЯЗАТЕЛЬНО связана с аппаратным обеспечением. В таком случае, вам, вероятно, придется заменить соответствующее оборудование, вызывающее ошибку 1400.

Информация об операционной системе

Сообщения об ошибках 1400 могут появляться в любых из нижеперечисленных операционных систем Microsoft Windows:

  • Windows 10
  • Windows 8
  • Windows 7
  • Windows Vista
  • Windows XP
  • Windows ME
  • Windows 2000

Проблема с 1400 все еще не устранена?

Обращайтесь к нам в любое время в социальных сетях для получения дополнительной помощи:

Об авторе: Джей Гитер (Jay Geater) является президентом и генеральным директором корпорации Solvusoft — глобальной компании, занимающейся программным обеспечением и уделяющей основное внимание новаторским сервисным программам. Он всю жизнь страстно увлекался компьютерами и любит все, связанное с компьютерами, программным обеспечением и новыми технологиями.

у меня проблема. У меня есть приложение VCL, использующее поток. Этот поток выполняет некоторые вычисления и вызывает метод MainForm через Synchronize(). Все работает отлично, у меня есть кнопка «Пуск», которая создает и запускает поток и кнопку» Стоп», которая останавливает и освобождает его. Никаких ошибок, ничего.

но по какой-то причине, когда я закрыть приложение и я запустил поток Я EOSError 1400 – Invalid window handle . Я breakpointed процедуру onclose и единственное, что я делаю существует сохранение ini-файла, нет ошибки в этом, когда я отслеживаю дальше (используя F7), я добираюсь до самого конца ( Application.Run; end. ), после «захода» end. Я получаю ошибку, поэтому нет конкретной строки кода, вызывающей ее.

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

ответ

эта ошибка произошла со мной, когда метод Execute нить называлась, она выглядела так:

2 ответов

возможной причиной является несинхронизированный доступ к GUI из потока. Вы сказали, что нить этого не делает, но не видя TRunThread.Execute исходный код, который выглядит как догадка.

у меня была такая же проблема, код ошибки 5 Access is denied . Это оказалось связано с тем, что поток начал тестировать подключение к интернету на встроенной панели (используя BeginThread ). Если пользователь выходит из формы (которая тестирует подключение к Интернету) сразу после отображения формы, AV возникает.

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

решение было простым: при выходе из формы (напр. в FormDestroy event) убедитесь, что поток определенно не работает перед продолжением.

Источник

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Delphi ошибка 12175
  • Delphi ошибка 10061
  • Delphi обратное распространение ошибки
  • Delphi отловить ошибку
  • Delphi не показывает ошибки

  • Добавить комментарий

    ;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: