Do Not Call GetLastError()

Содержание

Коды ошибок getlasterror c

Will I be able to display error messages in different languages.

void PASCAL wfc_get_error_string( DWORD error_code, CString& error_string )

I often wrap it in another function that looks more like:

I will try to be brief

Re: Your points 1. and 2: MyFunction (Vanilla version) does not return locally declared CWin32Error but its copy.

Correctitude: In C++, user-defined types ought to be treated at par with built-in types. Remember: If you return an int variable, you are still asking the compiler to produce code to copy four bytes. For CPoint : eight bytes. For const char* allocated on the heap (and not locally declared): four bytes—plus other code you are bound to write to check its lifetime elsewhere in the program to avoid runtime failures. For CWin32Error : four bytes plus just a few inlined code steps involving just one call to InterlockedIncrement(). InterlockedIncrement(), handled right in the Win32 subsystem rather than after a contex switchover to kernel mode, is very fast.

No function returns are ever free—for user-defined types or built-in types. But, overall, the cost involved in returning CWin32Error object by value, rather than an int value, carries so small an extracost that it can be even smaller than the overhead of stack-frame maintenance code introduced due to an extra function you write elsewhere to check the health of an on-the-heap or a static object.

So, there always is cost. The issue is: how do you organize it. CWin32Error urges to exploit the C++ language features and so lets you organize in the cleanest way with no extra overheads.

Re: Your concerns in 3. and 4.: That’s why CWin32Error copy constructor and assignment operators do not call GetLastError(). Please see the class comments and documentation for further details.

CWin32Error guaruntees—I repeat guaruntees—never to throw an error when everything is OK. Two interpretations of this statement: (i) It never calls an extra GetLastError(). If at all necessary (which I doubt), you can always use CWin32Error::ReGetLastError member function. (ii) To be accurate, you throw CWin32Error. CWin32Error does not raise any exception on its own (which is something that some other people may not like )

Re: Your point 5: The sample usage is just that: sample. It does not cover every usage scenario. For the case you write about, the code would look something like:

Hope this clarifies.

Bottomline: CWin32Error can be used without hesitation in all cases.

Good points, Sardurkar. Tells me you are seriously thinking of using CWin32Error—which is very welcom. Feel free to voice your other concerns about CWin32Error too.

Microsoft’s already ahead of you there, with the Compiler COM Support’s _com_error class.

It’s OK to use _com_error even if you aren’t writing COM software. Essentially, it takes any error you would normally call GetLastError() on, or any HRESULT from a COM call, and will give you the text equiv. of the error, all with just one call.

It works like this:

DWORD dwLastError = ::SomeSDKFunction(. );

That’s it. The class can be used just by #including <comerror. h> in your STDAFX. H file, and it can also be thrown in an exception.

CWin32Error compared with _com_error

Absent method calls, the CWin32Error code looks prettier to my eyes.

Beauty is in. Analysis

Analysis

1. Time Cost

To repeat: CWin32Error is faster.

1.2. To be fair: After commenting out the szDesc2 and szDesc3 defining lines in the above test, both classes
are almost equally fast
(differing by less than 1% in actual execution tests in the release build).

1.3 The real determinant of the execution time appears to be the number of times FormatMessage is called.

Algorithmic Rationale of Time Cost

3. Space Cost

4. Conclusion of Cost Analysis

5. The Road Behind

5.0 The main purpose—and hence the class design—differs.

6. An Exercise Ahead

Special thanks to Briant Hart for galvanizing me into analysis. I wouldn’t have done it myself!

Ajit Jadhav

«Can we still be friends?»

Your project today is your great-grandchildrens’ «ancestor clock.»

First let me say I love classes like CWin32Error. Simplifying the little things that we encounter constantly is great. But there are a couple issues with how your using it.

For example given your second function:

CWin32Error MyFunction( void );

Yes your class is much more efficient than _com_error the best choice of all is still going to be:

Also, in general you never want to catch exceptions by value. Yes it’ll happen when throwing/catching simple types but your class is *not* a simple type nor a replacement for one. So when catching CWin32Errors you’d still want to:

Thanks for posting your code! CWin32Error has some very nice features.

Thanks for your thoughtful comments! I really appreciated your comment.

2. Let me reply on your second point first (ie. catching by ref). This is an issue independent of CWin32Error, and really requires a separate discussion of catching, throwing, and especially, rethrowing. Yes, I agree completely that catching by ref involves much less cost, especially as long as intermediate throw s too have passed the reference to the original object. But this is really at the discretion of the programmer, and so, a somewhat separate issue.

The sample scenario in CWin32Error is just an advertisement to show that even a novice programmer can’t incur too many costs with CWin32Error—smart copying will kick in.

2. About your first point (i. e. the heap usage in normal times (no-error) at runtime). Good observation! The point is well taken.

Soon after posting, I started thinking of an upgrade to further improve runtime conditions precisely on the lines you mentioned. But I realized it only after posting the code. (That always happens!!). Please wait a few days time to see the planned upgrade.

If interested here’s the descriptive preview of what it will have.

Warning: Being descriptive, it’s a bit lengthy. Also very tentative. (I am not sure I really need the extra static variable I mention in the following description). Anyway, check out the CWin32Error page within a week for the upgrade.

The specific solution I am currently thinking is to introduce a class static member variable to hold the error code in normal times (error == 0). Then, there can be hungry capture of only the numeric code in construction or in ReGetLastError(). The fallout (after such upgrade) will be:

On the Plus side:
—————-
(i) For Normal Execution (member error == 0 ) at Runtime: CWin32Error will then aovid hitting the heap altogether.

Thus, CWin32Error will be costlier to calling ::GetLastError() only by an extra if condition, testing only equality of int variables. For a program that run completely normally, this would mean, (a) no new[], (b) no delete[], (c) not even a single InterlockedXXX() call introduced by CWin32Error during the entire program execution!

On the Minus Side:
——————
An extra space cost of a static member variable of unsigned int type. That is, 4 static bytes (only). Being static, the space cost will be constant, irrespective of the # of CWin32Error objects at runtime.

It seems to me that the plus side far outweighs the minus side. So, please check out the CWin32Error page later this week for the above upgrade.

Ok catching exceptions is hardly what your post is about so I’ll leave off any lengthy discussion of it but.. I will go out on a limb and say there is no reason to catch anything, other than a simple type, by value. It’ll only lead to problems. So it’s at the discretion of the programmer only because the compiler allows it.

Almost all my work related programming involves multi-threaded server applications so I cringe anytime anyone mentions statics. It takes a lot of work to make a class with read/write static variables thread safe and efficient.

More than that however just make sure you’ve thought out how your class is going to be used. It’s tempting to envision using CWin32Error as you did in your second example:

if( AlertUser(dwErr))
<
AfxMessageBox(CWin32Error(dwErr));
>

// doing something in a loop that fails.

if( AlertUser(dwErr))
<
AfxMessageBox(CWin32Error(«failed during %d try at doing Foo»,loop, dwErr));
>

Another thought would be to provide a way to extract error messages without hitting the heap at all. Something like:

Anyway, the point is to avoid trying to add to many bells an whistles. Think about how you’ll use the class most effectively and design it to maximize that core functionality with a minimal interface. You’ll end up with an effective, useful class, that you return to time and time again.

A few comments right here. More, later. Perhaps offline discussion by email??

— The core idea behind this class: CWin32Error objects as first-class entities indicating runtime status. (Perhaps the class-name is a misnomer, but I wanted to keep it associated with ::GetLastError to spread usage.)

By core idea, CWin32Error is not just a DWORD number, not just a TCHAR string, not just a conversion functionality, but an integration of them all. A status-indicating thing. I just happened to take the view that the Win32 API seems to artificially separate the two (to maintain C-compatibility); and that in C++ programming, a char* string should be as easily available as the DWORD is (without losing the convenience and the small runtime cost of the DWORD). That was the core idea. Perhaps not always possible cost-wise. But worth getting as close to DWORD usage as is possible.

So, whatever you think of doing with a DWORD, it should be possible to do the same with the object. For example, TRACEing, returning, throwing exceptions, as a member variable in the class, as true state-indicating objects (using app-private FACILITY codes) in a state-transition map, anything else.

That in turn meant making the class time-efficient in terms of FormatMessage calls it makes, and space-efficient in terms of its sizeof value and avoiding multiple string buffers as far as possible. Hence, the rest of the class code involving smart copying and meta-mem management.

But to think of a member function returning a char* given a DWORD would be somewhat off the core of the C++ idea—it will be closer to the C-way of thinking, not C++.

Actually, any DWORD => char* conversion should be seen as only a part of the class. Per core idea: you have this error/status object, and you probe it for whatever reason, and it will return what it knows about the status and/or health of the program in that context. You can be a user (returns a human readable, standard string message) or a programmer (returns a variable-address that is TRACE-compatible) or the program at run-time (captures and returns error-code numbers with negligible overheads).

— The Received Opinion varies a lot for throwing user-defined types in addition to built-in types. For example, the standard C++ includes «exception» class, and Stroustrup advocates thinking exception first. On the other hand, there can be situations where exception frames and unwinding cost and/or semantics is not most desirable. In these later cases, CWin32Error can be used in the simple object sense.

— Ditto for retvals. A lot of folks in quite a few projects I worked on seemed to require something like returning status-strings! Returning status strings seems like a natural thing to think for many programmers—and not all of them are recent converts from VB. If they can have smart-copies.

— About multi-threading and static member variables. Yes of course. Any static members, if at all introduced, will be purely readonly.

Looks like statics (a small array of them, in fact), will be inevitable under the constraints: viz. that CWin32Error will not raise exceptions on its own. Here, I am aware that memory for exception frames and objects is guarunteed by the C++ language. But many may deliberately disable exception-handling support in the code generation (e. g. ATL COM projects.)

Mem allocation, and even FormatMessage can fail internal to the class. Yet, by core-idea, the user-programmer will not check on DWORD before using the const char* conversion. Now, rather than introduce static allocation into the program from back-door via macro substitution:
if (msg string is not available) return _TEXT(«class internal error message»)
it would be better to introduce static readonly variables explicitly. There seems to be no other choice when memory allocation the internal buffers fail, and yet the user-programmer has fully relied on the const char** operator in his code.

— Hiding copy ctor, = operator : Interesting idea.

— Extracting into user-providing buffer. This is a v. good way of looking at the class, and might increase its practical appeal. Sure will include this functionality.

2B in this case: Supporting printf-style format strings turns out to be a desirable revision but a big one. Variable sized args, preproc defines and format string interpretation (UNICODE/OLE2ANSI. ), processing failure possibilities, MC-compiled message resources and their DLL hInstance, etc. Perhaps this is better served by a small cluster of classes than a single class. TBD: in future.

— About minimal i/face: Yes. I am reminded that famous quote (don’t remember who said it): Interface design attains perfection not when there is nothing else left to add, but when there is nothing else left to take away.

Thanks again for your interest. Unbelievably, writing this smallest of classes turns out to be such a big-time headache! Thoughtful comments like yours help a lot! And I seem unable to refrain from writing loooong messages!

But the Win32 status value really is just a DWORD. Worse than that it’s actually just a DWORD *sized* value. In some instances it’s an int, in some a long. And to further complicate matters it’s not always associated with ::GetLastError(). The registry functions for exmaple don’t set ::GetLastError() instead they directly return their error value. (as a long).

I would argue that it’s much more desirable in the C++ modeling world to separate the two simply because they do completly different things. The status value allows us to alter program logic and respond to error conditions, the explanatory text allows us to format nice error messages.

I’m not sure what you mean by a status string. Do you mean they want you to return an LPCTSTR that they’re going to parse to determine if the function succeeded or failed? If so just take them by the hand and lead them to the padded room for shock therapy.

Would you ever routinly format an error message before being certain there was an error? I can’t think of a single scenario.

1. About CWin32Error and DWORD:

* CWin32Error-defined DWORD conversion adequately provides for all DWORD usages, including the registry API that has been mentioned on this article a couple of times. The usage is so simple I actually left out discussing it in the main article.

I wonder how people miss it except may be by deliberate overlooking. If that, neither argument nor better C++ code is going to help, anyway. Barring that, here’s an example:

What permits this? The fact that ERROR_SUCCESS and ERROR_MORE_DATA and all the other ret vals are all basically defined in the same file: WinError. h (or Error. h). Irrespective of whether they set thread variable or not.

* int, long, DWORD. Gosh! I am talking Win32 here! Neither Win3.1 nor IA64!

* You can use CWin32Error to alter status logic. Obvious. If not, pl. let me know.

2. The thing preceding shock therapy ( )
* No, they seriously entertain the idea that in big multi-location, multi-teams projects, it’s easier to fix the source of error, blame, not to mention bugs, if the source-code itself carried the ability to show status. If the feature is built right down to the class-level granularity. But at no appreciable extra cost. They stand to benefit by using a class like CWin32Error. Whether they will choose to use it or not takes us to a completely different realm.

3. Parsing-related apprehensions:
* Parsing is not necessary.
* Think again about app-private FACILITY. It’s there. People simply don’t use it (Just like MC-dlls. People don’t even know about it, except as in localization issues).

4. Pattern:
Thanks for the tip. I seem only dimly aware of the book. I read Gang of Four (also have the CD). But not the one you mention.

I have virtually lost all my enthusiasm about both patterns and UML—for that matter, anything to do with large-scale architectural thinking. The trouble is, I am a contract software engineer, and people don’t always (i) use patterns or (ii) incorporate a contractor’s suggestion when it impinges at the architectural level. I do get a lot of freedom at the class implementation level, but should not expect more. So, through first hand experience I have learnt how to operate at sub-pattern level. This being America, I anticipate this thing to go on until my residency status changes, or people change, whichever is earlier, if possible! (Yep, there seems to be a lot of parsing going on in here!)

So, for the time being, if you would like to see external polymorphism applied to CWin32Error, I am afraid, you will have to present pseudo-code/code-fragments that show how to do it.

(BTW, which geographical area are you in? How’s the market for contractors currently in there?)

Relax I’m not deliberately overlooking the DWORD conversion, in fact I’m not overlooking it at all. You where talking about how the status value and text where «artificially separate.» This lead me to believe you where trying to model ( in a C++ object sense of the word ) a Win32 status value. I was trying to show that from a conceptual stand point Win32 doesn’t have a single clean error reporting paradigm.

Again, with regards to ‘status logic’ and status reporting I’m trying to touch upon how the separation of the two concepts in the Win32 API could affect how you develop a C++ object model. Here’s a more concrete example of what I mean. Pardon the length..

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

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

Решение

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

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

Вы не проверяли, действительно ли произошла ошибка. Вам нужно проверить дескриптор, который вы получаете от 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 могут появляться в процессе установки программы, когда запущена программа, связанная с Microsoft Corporation (например, Internet Explorer), при запуске или завершении работы Windows, или даже при установке операционной системы Windows. Отслеживание момента появления ошибки 1400 является важной информацией при устранении проблемы.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Шаг 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):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ответ

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

2 ответов

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

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

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

Источники:

https://www. codeproject. com/Articles/1025/Do-Not-Call-GetLastError

https://web-shpargalka. ru/code-1400-nedopustimyj-deskriptor-okna. php

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

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