Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Smalltalk
Перезагрузить страницу Как программно описать простейшее окно с кнопкой закрытия
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию Как программно описать простейшее окно с кнопкой закрытия - 04.04.2008, 20:25

Люди добрые, помогите разобраться. Берем VW7.5

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

Код:
openWindow
    | components |
    mainWindow := EventEnabledApplicationWindow new label: 'Привет !'.
    components := CompositePart new.
    b1 := (Win95ActionButtonView new)
        labelString: 'Закрыть';
        model: ValueHolder newBoolean;
        controller: WidgetController new beButton;
        when: #pressed send: #close to: self.    
    components add: b1
        in: (LayoutFrame 
            leftFraction: 0
            offset: 40
            rightFraction: 1
            offset: -40
            topFraction: 0
            offset: 40
            bottomFraction: 1
            offset: -40).
    mainWindow
        component: components;
        openIn: (100 @ 100 extent: 200 @ 200) withType: #normal
Открываем окно сообщением MyWindow new openWindow. Программа хорошо работает до попытки закрытия окна. Как только нажимаем на кнопку весь VW вешается и не отвечает на мышь и клавиатуру. Метод закрытия следующий.

Код:
close
    mainWindow close
    b1 controller release.
   "mainWindow release"
Интуитивно я понимаю, что проблема вроде бы в том, что контроллер кнопки не вернул управление главному диспетчеру… Но как это сделать мне пока не ясно.

Большое спасибо.
Ответить с цитированием
  (#2 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 16.04.2008, 22:09

Что же, видимо мне никто не поможет. Даже Andrei N.Sobchuck...
Ответить с цитированием
  (#3 (permalink)) Старый
Andrei N.Sobchuck Andrei N.Sobchuck вне форума
Member
 
Сообщений: 88
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.06.2005
По умолчанию 21.05.2008, 17:26

Извини за задержку. Если вопрос всё еще актуальный, то...

В чистом образе твой код выполняться не хочет. Например у меня нет класса EventEnabledApplicationWindow . Однако, ты можешь попробовать вызвать отладчик (Ctrl-"Y" или Ctrl-"\"). Возможно по стек-трейсу ты легко поймёшь в чем проблема.
Ответить с цитированием
  (#4 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 23.05.2008, 20:28

Еще как актуален!
Спасибо за рекомендации. Обе указанные комбинации клавиш позволяют разблокировать систему и работать дальше. Однако, я так и не понял в чем проблема моего кода. Собственно, если использовать класс ApplicationWindow вместо EventEnabledApplicationWindow , то легче не становится... Не могли бы Вы предложить альтернативный вариант программного создания окна с кнопкой?
Ответить с цитированием
  (#5 (permalink)) Старый
berkgaut berkgaut вне форума
Новичок
 
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.09.2007
По умолчанию 24.05.2008, 12:28

Добрый день!

Я никогда особенно не занимался чисто-программным формированием интерфейса (за исключением простейших вещей по образцу Bezier class>>demoFlatness). Поэтому не встревал.

Однако у меня есть предположение. У ApplicationModel есть метод сloseRequest, который, собственно, и служит для закрытия окна приложения. Так вот, этот метод создает CloseEvent и ставит его в очередь WindowManager. Сравните это с методом ApplicationWindow>>close, который создает CloseEvent и немедленно диспатчит его контроллеру. Я думаю, что верный и правильный способ закрывать окна для клиентского кода -- всё таки первый (через очередь), а не второй (напрямую). Ведь жизненным циклом окна с момента его открытия заведуете уже не вы, а WindowManager.

Далее, если вы хотите на закрытии окна сделать ещё что-нибудь (скорее всего -- освободить какие-нибудь ресурсы), то по-хорошему это нужно делать не там, где вы зовете closeRequest, а в методе noticeOfWindowClose у вашего класса-потомка ApplicationModel. Обоснование: в момент, когда вы поставили CloseEvent в очередь событий, у вас нет гарантий, что окно закроется прямо сейчас; вполне может быть, что перед этим окно попросят еще разок перерисоваться, а если вы освободите ресурсы, то с этой перерисовкой могут быть проблемы (либо придется писать все свои гуи в стиле defensive programming, с постоянными проверками ifNotNil, что некрасиво).

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

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

С уважением,
Борис Беркгаут
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Andrei N.Sobchuck Andrei N.Sobchuck вне форума
Member
 
Сообщений: 88
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.06.2005
По умолчанию 24.05.2008, 22:03

Цитата:
Не могли бы Вы предложить альтернативный вариант программного создания окна с кнопкой?
Я - нет. Тут еще могут быть проблемы в удобстве, например нету layout manager-а. В конечном итоге может получится, что создание более сложного интерфейса чем "поле ввода и две кнопки" является очень многословным процессом. Обрати внимание, что сама среда хранит описание интерфейса в спеках. Напр. смотри CodeProbeEditor class>>testEditorSpec:
Код:
^#(#{UI.FullSpec} 
        #window: 
        #(#{UI.WindowSpec} 
            #label: 
            #(#{Kernel.UserMessage} 
                #key: #ProbeEditor 
                #defaultString: 'Probe Editor' 
                #catalogID: #pdp ) 
            #min: #(#{Core.Point} 462 301 ) 
            #bounds: #(#{Graphics.Rectangle} 730 422 1326 849 ) ) 
        #component: 
        #(#{UI.SpecCollection} 
            #collection: #(
                #(#{UI.ActionButtonSpec} 
                    #layout: #(#{Graphics.LayoutFrame} -220 1 -35 1 -120 1 -10 1 ) 
                    #model: #accept 
                    #label: 
                    #(#{Kernel.UserMessage} 
                        #key: #OK 
                        #defaultString: 'OK' 
                        #catalogID: #pdp ) 
                    #defaultable: true ) 
                #(#{UI.ActionButtonSpec} 
                    #layout: #(#{Graphics.LayoutFrame} -110 1 -35 1 -10 1 -10 1 ) 
                    #model: #cancel 
                    #label: 
                    #(#{Kernel.UserMessage} 
                        #key: #Cancel 
                        #defaultString: 'Cancel' 
                        #catalogID: #pdp ) 
                    #defaultable: true ) 
                #(#{UI.SubCanvasSpec} 
                    #layout: #(#{Graphics.LayoutFrame} 10 0 0 0 -10 1 -45 1 ) 
                    #flags: 0 
                    #majorKey: #{CraftedSmalltalk.ProbeTestExpressionEditor} 
                    #minorKey: #testEditorSpec 
                    #clientKey: #testEditor ) ) ) )
Можно генерить такую спеку и скармливать её билдеру из среды. Возможно это не то, что ты хочешь, но в качестве "обходного манёвра"...

Касательно же диагностики проблемы - скопируй сюда в форум стек-трейс (или его топ, если стек-трейс очень большой). Как это сделать:
1. Через отладчик. Нажать Ctrl-Y, открывается отладчик, потом выбираешь пункт меню "Stack"->"Copy Stack Report".
2. Через монитор процессов. Нажать Ctrl-\, выбрать в списке процессов "залипшее" окно, нажать правую кнопку мыши и выбери "View Stack", или "Dump Stack...".
По стек-трейсу можно будет еще что-то сказать.
Ответить с цитированием
  (#7 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 28.05.2008, 21:53

Цитата:
По стек-трейсу можно будет еще что-то сказать.
Вот стек-трейс...

Код:
User Interrupt
Semaphore>>wait
EventQueue>>next
WindowManager>>processNextEvent
optimized [] in [] in WindowManager>>newProcess
BlockClosure>>on:do:
optimized [] in WindowManager>>newProcess
BlockClosure>>on:do:
optimized [] in Process class>>forBlock:priority:</P> 

----------------------------------------------------------------------
Semaphore>>wait
Receiver:
 a Semaphore
Instance Variables:
 firstLink = a Process in Semaphore>>wait
 lastLink = a Process in Semaphore>>wait
 excessSignals = 0
Context PC = 4</P> 

----------------------------------------------------------------------
EventQueue>>next
Receiver:
 an EventQueue
Instance Variables:
 contents = an OrderedCollection[1]
 accessProtect = a Semaphore[0]
 readSynch = a Semaphore[1]
Temporaries:
 isEmpty = nil
 value = nil
Context PC = 8</P> 

----------------------------------------------------------------------
WindowManager>>processNextEvent
Receiver:
 a WindowManager
Instance Variables:
 windows = an OrderedCollection[2]
 activeController = nil
 interruptLock = false
 outstandingMetaOrDamage = false
 openInProgress = false
 eventQueue = an EventQueue
 baseProcess = a Process in Semaphore>>wait
 dontFilterEvents = false
Temporaries:
 event = nil
Context PC = 4</P> 

----------------------------------------------------------------------
optimized [] in [] in WindowManager>>newProcess
Receiver:
 an UndefinedObject
Temporaries:
 .self = a WindowManager
Context PC = 13</P> 

----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
 a BlockClosure
Instance Variables:
 method = CompiledBlock [] in [] in WindowManager>>newProcess
 outerContext = nil
 copiedValues = a WindowManager
Arguments:
 anExceptionSelector = TerminateException
 handlerBlock = BlockClosure [] in [] in WindowManager>>newProcess
Context PC = 18</P> 

----------------------------------------------------------------------
optimized [] in WindowManager>>newProcess
Receiver:
 an UndefinedObject
Temporaries:
 .self = a WindowManager
Context PC = 15</P> 

----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
 a BlockClosure
Instance Variables:
 method = CompiledBlock [] in WindowManager>>newProcess
 outerContext = nil
 copiedValues = a WindowManager
Arguments:
 anExceptionSelector = TerminateException
 handlerBlock = BlockClosure [] in [] in Process class>>forBlock:priority:
Context PC = 18</P> 

----------------------------------------------------------------------
optimized [] in Process class>>forBlock:priority:
Receiver:
 an UndefinedObject
Temporaries:
 .aBlock = BlockClosure [] in WindowManager>>newProcess
Context PC = 9
Ответить с цитированием
  (#8 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 28.05.2008, 21:59

Цитата:
попробуйте, чтобы кнопка слала closeRequest.
Добрый день. Спасибо за совет.

Кнопка шлет self closeRequest, однако это абсолютно никак не сказывается на программе. Т.е. программа работает дальше, но не закрывается и не повисает. Куда прислать пакедж с программой?

С уважением, все еще Lamer
Ответить с цитированием
  (#9 (permalink)) Старый
berkgaut berkgaut вне форума
Новичок
 
Сообщений: 11
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.09.2007
По умолчанию 30.05.2008, 13:00

Цитата:
Куда прислать пакедж с программой?
berkgaut at gmail точка com
Ответить с цитированием
  (#10 (permalink)) Старый
Andrei N.Sobchuck Andrei N.Sobchuck вне форума
Member
 
Сообщений: 88
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.06.2005
По умолчанию 02.06.2008, 22:30

Цитата:
Не могли бы Вы предложить альтернативный вариант программного создания окна с кнопкой?
Кстати, нашел тут у себя в загашнике. Может поможет: http://groups.google.com/group/comp.lang.s...a091b8ead79f12f
Ответить с цитированием
  (#11 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 20.06.2008, 20:36

Цитата:
berkgaut at gmail точка com
Я уже давно написал Вам..
Ответить с цитированием
  (#12 (permalink)) Старый
SorryImLamer SorryImLamer вне форума
Новичок
 
Сообщений: 7
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 28.03.2008
По умолчанию 20.06.2008, 20:38

Цитата:
По стек-трейсу можно будет еще что-то сказать.
Так что можно по нему сказать?
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
При выключении компьютера появляется окно с названием оaisjdnoifj. Что это за окно? Polzovatel_2010 Любые вопросы от новичков 4 21.03.2010 01:34
Повернуть окно программно Olejek WinAPI 10 07.12.2007 01:43
Помогите с кнопкой PhantomM Visual Basic 0 27.08.2007 14:57
Народ помогите с кнопкой empy PHP 2 24.05.2007 22:00
Как программно с помощью WinAPI развернуть окно на полный экран imported_Gremmio Delphi 5 10.05.2007 18:17
Выход из программы кнопкой Крест new_programer Visual C++ 2 21.06.2006 15:21
Как остановить цикл кнопкой Andrey_tchaikovsky Delphi 3 14.02.2006 15:48
Как программно заграбить полноэкранное DOS окно _Андрей_ Delphi 0 29.12.2005 13:57
Как программно заграбить полноэкранное DOS окно _Андрей_ Delphi 0 27.10.2005 14:51
Как чтобы по щелчку левой кнопкой мыши окно переводилось в полноэкранный режим LR Visual C++ 5 18.06.2004 19:23
Управление програмно созданной кнопкой Templar C++ Builder 12 26.11.2003 15:48



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов