| Автор |
Съобщение |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
 Проблем с затваряне на модален диалог.
Случая е следния:
Имам един модален диалог който стартира друг модален диалог. Това е извикването на 2 рия модален диалог
Но в първия диалог имам проверка за наличност на един процес която се извиква периодично от таймера. Ако процеса е прекъснат дава OnOK() и по този начин диалога се затваря. Това е извикването на първия диалог от main window Но по този начин 2 рия модален диалог не се затваря. Не намерих при затварянето си първия диалог да праща на 2 рия някакво съобщение. Затова и прецених че мога да проверявам CWnd * укзателя който предавам на 2 рия диалог. След затварянето и изтриването на CPhoneNumbersDlg очаквам указателя към него който имам предаден на 2 рия диалог да е невалиден. А не е така. Получавам си съвсем валиден handle към класа също и не мога по него по нормален начин да установя дали първия диалог съществува. Най накрая написах това в 2 рия диалог и неочаквано си работи съвсем нормално.
Някой може ли да обясни тази мистерия,как така извиквам функция в член на клас който е вече изтрит и това работи и стабилно на това отгоре.
И има ли някакъв по цивилизован метод по който да разбера дали parrent window се е затворил?
|
| Чет Яну 10, 2008 4:16 pm |
|
 |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
Диалозите се затварят единствено и само с OnOK() и OnCancel().
|
| Чет Яну 10, 2008 5:48 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Ами така е. Първия съм написал че го затварям с OnOK(). А втория в сорса се вижда че пак го затварям с OnOK. Но в случая това не е въпроса,с това проблеми няма.
|
| Чет Яну 10, 2008 7:02 pm |
|
 |
|
zaphod
Ранг: Форумен бог
Регистриран на: Нед Юли 24, 2005 10:28 am Мнения: 2658
|
това е проблема, махни го. излизайки от ДоМодал, вече прозореца е утрепан.
а, и още нещо, защо new/delete? просто си декларирай "променлива", както си декларираш инт или флоат, динамичната памет не е за игра 
|
| Чет Яну 10, 2008 8:52 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Това го сложих допълнително като видях че се държи алогично и тръгнах да търся проблема.
Чета тук в Msdn-a че е проблематично да изтривам с delete CWnd обект и било по добре така. Но Разлика нема.
В много книжки за visual C++ съм виждал че се създават диалозите динамично в примерите. И откак програмирам така си ги и създавам и аз. Явно не е съвсем неправилна техника.
|
| Чет Яну 10, 2008 11:26 pm |
|
 |
|
Реконструктор
Ранг: Форумен бог
Регистриран на: Съб Сеп 25, 2004 12:32 pm Мнения: 8382 Местоположение: София
|
Също така е много важно диалога да е направен в основния тред и пак там да е затворен. Иначе стават бози (най-често не се затваря коректно).
|
| Пет Яну 11, 2008 2:08 am |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Така е направено. Не е проблема в това.
|
| Пет Яну 11, 2008 2:56 am |
|
 |
|
zaphod
Ранг: Форумен бог
Регистриран на: Нед Юли 24, 2005 10:28 am Мнения: 2658
|
динамичното създаване не е проблем технически, абсолютно еквивалентно е на директното инстанциране. за това че в книгите така го показват и аз май съм виждал, което ме дразни. както и да е, проблема явно е някъде извън това което си дал. явно още овладяваш нещата, понеже си писал някои забавни неща, например това GetOwner()->IsWindowVisible() == NULL
значи кажи накратко какво трябва да става по замисъл, какво става реално и може да дадеш ключовите парчета код, ако не е твърде много.
|
| Пет Яну 11, 2008 9:25 am |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Виж в първото съобщение. Там детайлно съм описал какво правя и какво става. Друга част от кода не е намесена. Нещо особенно има в работата с динамични обекти което не схващам. А и вероятно това което искам да направя се прави по някакъв по цивилизован начин.
Най синтезирано казано трябва в един модален диалог да правя проверка дали диалога който го е стартирал не е затворен вече.
А какво му е комичното на
GetOwner()->IsWindowVisible() == NULL
освен че трябва да е GetOwner()->IsWindowVisible() == 0 но и така с NULL си работи по същия начин и се интерпретира като 0.
Не че твърдя че съм спец по VC++. По скоро съм аматьор. 
|
| Пет Яну 11, 2008 1:39 pm |
|
 |
|
ps66
Ранг: Форумен бог
Регистриран на: Пет Яну 19, 2007 9:16 am Мнения: 1063 Местоположение: путинофили: "иди н***й"
|
 |  |  |  | Nikola Kirov написа: Виж в първото съобщение. Там детайлно съм описал какво правя и какво става. Друга част от кода не е намесена. Нещо особенно има в работата с динамични обекти което не схващам. А и вероятно това което искам да направя се прави по някакъв по цивилизован начин. Най синтезирано казано трябва в един модален диалог да правя проверка дали диалога който го е стартирал не е затворен вече. А какво му е комичното на GetOwner()->IsWindowVisible() == NULL освен че трябва да е GetOwner()->IsWindowVisible() == 0 но и така с NULL си работи по същия начин и се интерпретира като 0. Не че твърдя че съм спец по VC++. По скоро съм аматьор.  |  |  |  |  |
не ползвам VC ... и без да се задълбавам в проблема ти:
1) това: GetOwner()->IsWindowVisible()
никак не е желателно - ако GetOwner() - е вече невалиден - викаш функция от невалиден клас.
2) най-лесния и сигурен начин да провериш дали един прозорец е валиден е:
::IsWindow(hWnd);
където hWnd е хендъла на прозореца.
ако искаш да затвориш прозорец - най-сигурно е с
::SendMessage (WM_CLOSE, hWnd, 0, 0);
...
в противен случай - трябва да си направиш комуникация м/у прозорците !
това dlg->DestroyWindow();
мисля че се дублира с delete dlg; - тъй че и то май е проблем!
това дето в таймера проверяваш ... също е доста недобър подход ... ама това е друга тема 
_________________ путинофили: "иди н***й"
|
| Пет Яну 11, 2008 4:27 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
точно от ::IsWindow(hWnd) почнах и аз. И макар първия диалог да е вече затворен си казва че е валиден window. Което много ме учуди.
И оттам почнах с шамански похвати като да извиквам функция от несъществуващ вече обект. Интересното е че работи устойчиво. Това ми е другия въпрос. Що така може?
а delete не парви нищо ако е приложено към невалиден обект. По нагоре казах защо съм го написал така и че това не е проблем.
|
| Пет Яну 11, 2008 4:53 pm |
|
 |
|
ps66
Ранг: Форумен бог
Регистриран на: Пет Яну 19, 2007 9:16 am Мнения: 1063 Местоположение: путинофили: "иди н***й"
|
теоретически ::IsWindow не ти гарантира че hWnd е валиден
проблема е че ако твоя hWnd вече е умрял ... друго приложение може да създаде друг прозорец и Windows да му присвои същия hWnd като на твоя!
така IsWindow(hWnd) ще е true, но за друг прозорец ...
затова най-добре е да имаш комуникация м/у прозорците - примерно родителя ако ще мре - вдига флаг в детето че вече то е сираче ... и обратно ако детето ще мре - казва на родителя че е умряло (флаг) ... методи много въпрос на реализация!
Що се отнася до: "...като да извиквам функция от несъществуващ вече обект ..."
проблема е че класа сочи в свободен блок и резултатите са непредсказуеми - на практика "this" сочи към обекта който е изтрит, но всяко new/delete, malloc, .... може да му скапе съдържанието и бозата е пълна!
затова и ползвам BCB - там CodeGuard е невероятно полезна - лови 99.9% от подобни проблеми (0.01% остават за програмиста:) )!
_________________ путинофили: "иди н***й"
|
| Пет Яну 11, 2008 5:00 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Не е е към друг прозорец този хендъл. Точно към този изтрития е проверих. И аз се замислих за варианта с комуникация. Но използването става сложно по този начин. Трябва в класа на диалога който извиква 2 рия диалог да направя указател към диалога който отварям /2рия/ и чрез него от функцията OnClose на първия да затворя 2 рия. Пълна боза.
Има ли начин да изпратя Мessage на 2 рия прозорец без да имам указател към него. Тоест OnClose на първия диалог да праща Message към евентулано отворен модален диалог. Нещо като изпращане на Message на всички child window на диалога. То модалния диалог е малко странен child window също и нямам идея каква ще е хавата при такава ситуация.
|
| Пет Яну 11, 2008 5:26 pm |
|
 |
|
ps66
Ранг: Форумен бог
Регистриран на: Пет Яну 19, 2007 9:16 am Мнения: 1063 Местоположение: путинофили: "иди н***й"
|
не е боза - просто така трябва да се прави - и двата класа да си имат указателите един друг и при някое събитие да си се разбират!
без hWnd - няма как да прaтиш съобщение - просто SendMessage/PostMessage си иска hWnd
а и обработката на съощенията е асихронна (PostMessage) - и може да доведе до други проблеми ... така че първия метод е за предпочитане.
_________________ путинофили: "иди н***й"
|
| Пет Яну 11, 2008 5:57 pm |
|
 |
|
Nikola Kirov
Ранг: Форумен бог
Регистриран на: Нед Окт 31, 2004 9:19 pm Мнения: 4464 Местоположение: Stara Zagora
|
Май трябва да отворя тема "Ах как мразя MFC"
Що всичко трябва да става с много писане ......
В последно време поусвоявам по малко QT.
Там нещата си личи че са мислени,не като при тия тъпаци от Мокрософт.
|
| Пет Яну 11, 2008 6:35 pm |
|
|