| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Проблем с затваряне на модален диалог. http://mcu-bg.com/mcu_site/viewtopic.php?f=16&t=5300 |
Страница 1 от 2 |
| Автор: | Nikola Kirov [ Чет Яну 10, 2008 4:16 pm ] | |||||||||||||||||||||||||||
| Заглавие: | Проблем с затваряне на модален диалог. | |||||||||||||||||||||||||||
Случая е следния: Имам един модален диалог който стартира друг модален диалог. Това е извикването на 2 рия модален диалог
Но в първия диалог имам проверка за наличност на един процес която се извиква периодично от таймера. Ако процеса е прекъснат дава OnOK() и по този начин диалога се затваря. Това е извикването на първия диалог от main window
Но по този начин 2 рия модален диалог не се затваря. Не намерих при затварянето си първия диалог да праща на 2 рия някакво съобщение. Затова и прецених че мога да проверявам CWnd * укзателя който предавам на 2 рия диалог. След затварянето и изтриването на CPhoneNumbersDlg очаквам указателя към него който имам предаден на 2 рия диалог да е невалиден. А не е така. Получавам си съвсем валиден handle към класа също и не мога по него по нормален начин да установя дали първия диалог съществува. Най накрая написах това в 2 рия диалог и неочаквано си работи съвсем нормално.
Някой може ли да обясни тази мистерия,как така извиквам функция в член на клас който е вече изтрит и това работи и стабилно на това отгоре. И има ли някакъв по цивилизован метод по който да разбера дали parrent window се е затворил? |
||||||||||||||||||||||||||||
| Автор: | Реконструктор [ Чет Яну 10, 2008 5:48 pm ] |
| Заглавие: | |
Диалозите се затварят единствено и само с OnOK() и OnCancel(). |
|
| Автор: | Nikola Kirov [ Чет Яну 10, 2008 7:02 pm ] |
| Заглавие: | |
Ами така е. Първия съм написал че го затварям с OnOK(). А втория в сорса се вижда че пак го затварям с OnOK. Но в случая това не е въпроса,с това проблеми няма. |
|
| Автор: | zaphod [ Чет Яну 10, 2008 8:52 pm ] | |||||||||
| Заглавие: | ||||||||||
това е проблема, махни го. излизайки от ДоМодал, вече прозореца е утрепан. а, и още нещо, защо new/delete? просто си декларирай "променлива", както си декларираш инт или флоат, динамичната памет не е за игра |
||||||||||
| Автор: | Nikola Kirov [ Чет Яну 10, 2008 11:26 pm ] |
| Заглавие: | |
Това го сложих допълнително като видях че се държи алогично и тръгнах да търся проблема. Чета тук в Msdn-a че е проблематично да изтривам с delete CWnd обект и било по добре така. Но Разлика нема. В много книжки за visual C++ съм виждал че се създават диалозите динамично в примерите. И откак програмирам така си ги и създавам и аз. Явно не е съвсем неправилна техника. |
|
| Автор: | Реконструктор [ Пет Яну 11, 2008 2:08 am ] |
| Заглавие: | |
Също така е много важно диалога да е направен в основния тред и пак там да е затворен. Иначе стават бози (най-често не се затваря коректно). |
|
| Автор: | Nikola Kirov [ Пет Яну 11, 2008 2:56 am ] |
| Заглавие: | |
Така е направено. Не е проблема в това. |
|
| Автор: | zaphod [ Пет Яну 11, 2008 9:25 am ] |
| Заглавие: | |
динамичното създаване не е проблем технически, абсолютно еквивалентно е на директното инстанциране. за това че в книгите така го показват и аз май съм виждал, което ме дразни. както и да е, проблема явно е някъде извън това което си дал. явно още овладяваш нещата, понеже си писал някои забавни неща, например това GetOwner()->IsWindowVisible() == NULL значи кажи накратко какво трябва да става по замисъл, какво става реално и може да дадеш ключовите парчета код, ако не е твърде много. |
|
| Автор: | Nikola Kirov [ Пет Яну 11, 2008 1:39 pm ] |
| Заглавие: | |
Виж в първото съобщение. Там детайлно съм описал какво правя и какво става. Друга част от кода не е намесена. Нещо особенно има в работата с динамични обекти което не схващам. А и вероятно това което искам да направя се прави по някакъв по цивилизован начин. Най синтезирано казано трябва в един модален диалог да правя проверка дали диалога който го е стартирал не е затворен вече. А какво му е комичното на GetOwner()->IsWindowVisible() == NULL освен че трябва да е GetOwner()->IsWindowVisible() == 0 но и така с NULL си работи по същия начин и се интерпретира като 0. Не че твърдя че съм спец по VC++. По скоро съм аматьор. |
|
| Автор: | ps66 [ Пет Яну 11, 2008 4:27 pm ] | |||||||||
| Заглавие: | ||||||||||
не ползвам VC ... и без да се задълбавам в проблема ти: 1) това: GetOwner()->IsWindowVisible() никак не е желателно - ако GetOwner() - е вече невалиден - викаш функция от невалиден клас. 2) най-лесния и сигурен начин да провериш дали един прозорец е валиден е: ::IsWindow(hWnd); където hWnd е хендъла на прозореца. ако искаш да затвориш прозорец - най-сигурно е с ::SendMessage (WM_CLOSE, hWnd, 0, 0); ... в противен случай - трябва да си направиш комуникация м/у прозорците ! това dlg->DestroyWindow(); мисля че се дублира с delete dlg; - тъй че и то май е проблем! това дето в таймера проверяваш ... също е доста недобър подход ... ама това е друга тема |
||||||||||
| Автор: | Nikola Kirov [ Пет Яну 11, 2008 4:53 pm ] |
| Заглавие: | |
точно от ::IsWindow(hWnd) почнах и аз. И макар първия диалог да е вече затворен си казва че е валиден window. Което много ме учуди. И оттам почнах с шамански похвати като да извиквам функция от несъществуващ вече обект. Интересното е че работи устойчиво. Това ми е другия въпрос. Що така може? а delete не парви нищо ако е приложено към невалиден обект. По нагоре казах защо съм го написал така и че това не е проблем. |
|
| Автор: | ps66 [ Пет Яну 11, 2008 5:00 pm ] | |||||||||
| Заглавие: | ||||||||||
теоретически ::IsWindow не ти гарантира че hWnd е валиден проблема е че ако твоя hWnd вече е умрял ... друго приложение може да създаде друг прозорец и Windows да му присвои същия hWnd като на твоя! така IsWindow(hWnd) ще е true, но за друг прозорец ... затова най-добре е да имаш комуникация м/у прозорците - примерно родителя ако ще мре - вдига флаг в детето че вече то е сираче ... и обратно ако детето ще мре - казва на родителя че е умряло (флаг) ... методи много въпрос на реализация! Що се отнася до: "...като да извиквам функция от несъществуващ вече обект ..." проблема е че класа сочи в свободен блок и резултатите са непредсказуеми - на практика "this" сочи към обекта който е изтрит, но всяко new/delete, malloc, .... може да му скапе съдържанието и бозата е пълна! затова и ползвам BCB - там CodeGuard е невероятно полезна - лови 99.9% от подобни проблеми (0.01% остават за програмиста:) )! |
||||||||||
| Автор: | Nikola Kirov [ Пет Яну 11, 2008 5:26 pm ] |
| Заглавие: | |
Не е е към друг прозорец този хендъл. Точно към този изтрития е проверих. И аз се замислих за варианта с комуникация. Но използването става сложно по този начин. Трябва в класа на диалога който извиква 2 рия диалог да направя указател към диалога който отварям /2рия/ и чрез него от функцията OnClose на първия да затворя 2 рия. Пълна боза. Има ли начин да изпратя Мessage на 2 рия прозорец без да имам указател към него. Тоест OnClose на първия диалог да праща Message към евентулано отворен модален диалог. Нещо като изпращане на Message на всички child window на диалога. То модалния диалог е малко странен child window също и нямам идея каква ще е хавата при такава ситуация. |
|
| Автор: | ps66 [ Пет Яну 11, 2008 5:57 pm ] | |||||||||
| Заглавие: | ||||||||||
не е боза - просто така трябва да се прави - и двата класа да си имат указателите един друг и при някое събитие да си се разбират! без hWnd - няма как да прaтиш съобщение - просто SendMessage/PostMessage си иска hWnd а и обработката на съощенията е асихронна (PostMessage) - и може да доведе до други проблеми ... така че първия метод е за предпочитане. |
||||||||||
| Автор: | Nikola Kirov [ Пет Яну 11, 2008 6:35 pm ] |
| Заглавие: | |
Май трябва да отворя тема "Ах как мразя MFC" Що всичко трябва да става с много писане ...... В последно време поусвоявам по малко QT. Там нещата си личи че са мислени,не като при тия тъпаци от Мокрософт. |
|
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|