Гадост: sys err 1400 Invalid window handle

6 отговора 0 прегледа
#1

Гадост: sys err 1400 Invalid window handle

Гадост:
D7: "System error. Code: 1400. Invalid window handle."
D5: "Win32 error. Code: 1400. Invalid window handle."

Компилирам един проект под Д7 (за проба след това и под Д5), в тоя проект имам 4-5 вида еднотипни форми, наследени от общ родител.
Ако създам някоя такава форма при създаване на главната форма и АКО ПРОМЕНЯ НЕЩО ВИЗУАЛНО В НЕЯ (ПОЛЗВАМ ПО ВРЕМЕ НА РАБОТА НА ПРОГРАМАТА) - при унищожаването й в деструктора на главната форма грми с горната грешка.
Ако всеки път, когато ми потрябва, създавам и унищожавам формата - понякога в конструктора казва, че canvas на формата е недостъпен (преди да имам достъп до Show/Hide).
Тия форми активно се ползват в друг проект БЕЗ ПРОБЛЕМИ.

Ако някой има идеи или е добър гадател :) , моля да ми помогне.
В гугъла тая грешка я има по различни поводи - не открих моя, (не мисля, че е заради английския ми)


ПП сега се сещам, че докато рових и бях сложил маса редове в коментар, минималната промяна, след която започва да се появява "1400", е добавянето на реда
ToolButtonOut.Visible := false;
(Е, това е когато много редове са в коментар. Бих се замисли как да го заобиколя тоя бутон, но когато кода е пълен (без коментарти) има и други редове, водещи до "1400".)

Редактирано от NikB на

Отговор
в отговор на NikB #2

Re: Гадост: sys err 1400 Invalid window handle

Някъде нещо в паметта се омазва. Потърси ли memory leaks?

Mixy
Отговор
в отговор на Mixy #3

Вече и: sys err 5 Access is denied - напредък :)

Мааму, мислех, че Делфито не може да ме изненада вече с нищо.

Някъде нещо наистина се омазва - ако формите, с които работя, се визуализират (с "show") - работата си е ОК, дори и да се визуализират извън десктопа (Left=-2000).
С това ще заобиколя проблема, ама мноо мъ е яд, както се пее в една песен.

И нещо друго видя за първи път.
Ако на видима форма изпълня се опитам да установя:
aComboBox.Sorted := true;
казва "System error. Code 5. Access is denied."
Същото е и ако се опитам да променя стила на комбо бокса.

ПП code 5 става в RecreateWnd процедурата.

Редактирано от NikB на

Отговор
в отговор на NikB #4

Re: Вече и: sys err 5 Access is denied - напредък :)

Нещо друго си омазал. Направих експеримент с D7 и CB6, и с главна и с вторична форма, независимо дали са видими или не - реда:
ComboBox.Sorted := True;
си работи.

Според мен това изключение възниква в TWinControl.DestroyWindowHandle, където има следното:

if not Windows.DestroyWindow(FHandle) then
RaiseLastOSError;

И ако приемем, че си се опитал да направиш RecreateWnd, преди в действителност да имаш създаден HWND, е нормално. Що не проверяваш предварително дали ComboBox.HandleAllocated ?

Отговор
в отговор на nop #5

RecreateWnd се вика в ComboBox.Sorted ...

(Благодаря ти за мнението)

В действителност RecreateWnd се вика в ComboBox.Sorted := True;

Значи постановката е такава:
(1) Имам 4 форми, наследници на една и съща форма, като върху 4-те има разни фреймове с едит-и и комбобоксове.
(2) Създавам ги в момент, който съм си избрал, няколко секунди след създаването на главната форма (тя не се активира - вижда се трай иконка), има и други инициализации.
(3) По-късно получвам заявка и някоя от тия форми трябва да сърши нещо. За да го свърши, трябва да сортирам Комбобоксове. Това си е ОК.
(4) При излизане от приложението, като дестройвам ползваната (ползваните) форми се появява 1400.

Вариант 2:
Ако се опитам да променя ComboBox.Sorted докато създавам формите се появява Code 5 - това може да е коментирания от теб проблем

Вариант 3 (това беше в началото): Ако всяка от формите я създавам когато ми потрябва и я унищочавам веднага след това - няма проблем, но ме заболява сърцето като програмист - губят се моите 20нс. (Впрочем, сещам се, че понякога при създаване се оплакваше, че canvas не бил доволен нещо си)

Вариант 4(това работи сега): Веднага, след като създам формите ги слагам на координати Left:=-20000; визуализирам ги и им "оправям" сортирането на комбобоксове. Няма проблем.

Отговор
в отговор на NikB #6

Re: RecreateWnd се вика в ComboBox.Sorted ...

Точно RecreateWnd имах предвид, именно там има обръщение към
DestroyHandle, което от своя страна през няколко метода достига до
DestroyWindowHandle - от където е и цитирания ред.

Това, което се опитах да ти подскажа е, че в момента в който се обръщаш към
ComboBox::SetChecked( bool Value ) най-вероятно нямаш джам (HWND) нито за комбото, нито за формата. Имай предвид, че TCustomForm::Create() вътрешно никъде не извиква ::CreateWindowEx, т.е. реално прозореца се създава в момента Visible = true. Което е същото като Show()/ShowModal().

И тогава опитваш нещо от сорта на:

if ( !SecondaryForm->HandleAllocated() )
SecondaryForm->HandleNeeded();

като на мястото на SecondaryForm би могъл да сложиш
и ComboBox, щото в HandleNeeded() има обръщение
към Parent->HandleNeeded();

Дано съм бил полезен.

Отговор
в отговор на nop #7

Re: RecreateWnd се вика в ComboBox.Sorted ...

Пропуснах - прегледай също OldCreateOrder. Ако е TRUE, и стила е Visible = TRUE, ще се създаде в конструктора.

Отговор