:: Visual Foxpro, Foxpro for DOS
Поиск объектов в форме
Rifat
Автор

Сообщений: 32
Дата регистрации: 06.02.2012
Привет форумчанам.
Существует ли простой способ перебрать в форме, например, все гриды, включая вложенные в различные контейнеры на этапе исполнения формы? Или без рекурсии не обойтись?
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Только рекурсия
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
akvvohinc

Сообщений: 4203
Откуда: Москва
Дата регистрации: 11.11.2008
Если под рекурсией вы буквально понимаете вызов чего-то из себя самого, то без этого обойтись, конечно, можно.
Ratings: 0 negative/1 positive
Re: Поиск объектов в форме
Vedmak

Сообщений: 5949
Откуда: CiTY
Дата регистрации: 30.10.2003
В данном случае самого понятия "рекурсия" пугаться не стоит. Достаточно тривиальный метод повторного вызова функции. Есть ограничения по уровню вложенности. Надаеюсь на вашей форме не больше 32-х уровней вложенности объектов. Быстродействие метода приемлемое.

Можно использовать sys(1272), но что это меняет ?

Например,

[attachment 31868 Joxi.jpg]

Большинство базовых классов моего framework имеют свойство lock, т.е. блокировка возможности редактирования. В примере метод контейнера в котором перебираются дочерние объекты к которым применяется тоже значение lock.

Обращаю внимание, что это не явная рекурсия, а наследование методов.


------------------
Говорить стоит лишь для тех, кто слушает.




Исправлено 3 раз(а). Последнее : Vedmak, 10.09.19 23:07
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Можно пойти от обратного - сделать класс грида, который при инициализации пропишет путь к себе в какое-то свойство-массив (или объект-коллекцию) формы. Прямую объектную ссылку не стоит прописывать, т.к. она будет мешать разгрузке (закрытию/уничтожению) формы.
Ну а вообще начинать стоит с формулировки задачи, а не способа её решения Т.е. для чего пытаешься перебирать все гриды. Может быть и не нужен там перебор вовсе.

P.S. где-то тут в решениях должен быть SetAllX - расширенная функция рекурсивного обхода объектов - можно посмотреть код или просто использовать как готовый вариант - онять же зависит от задачи, для чего ходить по объектам.


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 10.09.19 23:05
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Vedmak

Сообщений: 5949
Откуда: CiTY
Дата регистрации: 30.10.2003
Igor Korolyov
...

Стараюсь избегать "рассказывания" ) дочернему объекту его роли с среде "родителя". Лишние синтетические связи поверх родных. Не стоит создавать почву для конфликта и оный не возникнет.


------------------
Говорить стоит лишь для тех, кто слушает.




Исправлено 1 раз(а). Последнее : Vedmak, 10.09.19 23:23
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Rifat
Автор

Сообщений: 32
Дата регистрации: 06.02.2012
Спасибо за советы, наверное воспользуюсь идеей Игоря Королева, так как задача касается именно гридов - запомнить ширины колонок при закрытии формы.
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
pasha_usue

Сообщений: 3647
Откуда: Е-бург
Дата регистрации: 06.10.2006
Rifat
Спасибо за советы, наверное воспользуюсь идеей Игоря Королева, так как задача касается именно гридов - запомнить ширины колонок при закрытии формы.
О чём Игорь сразу и сказал: "Надо начать с формулировки задачи".

Гораздо проще сделать свой класс грида, от которого наследовать гриды в формах. А в классе в методах Init/Destroy восстанавливать/запоминать ширины колонок.
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Полагаю грид должен сам себя сохранять и восстанавливать.
Вот сохранение грида в реестре.
RwRst - функция записи, чтения из реестра
*Работа с реестром
FUNCTION RwRst
PARAMETERS nAct, cSection, cKey, cValue
IF VARTYPE(goapp)="O"
HKEY = "HKCU\SOFTWARE\" + ALLTRIM(goapp.Appname)+'_'+ALLTRIM(goapp.User) + '\' + IIF(!ISNULL(cSection) AND !EMPTY(cSection), ALLTRIM(cSection) + '\','') + ALLTRIM(cKey)
ELSE
RETURN
ENDIF
oWshShell = CREATEOBJECT("Wscript.Shell")
DO CASE
CASE nAct = 1 && Read
TRY
cValue = oWshShell.RegRead(HKEY)
CATCH
TRY
oWshShell.RegWrite(HKEY,ALLTRIM(cValue),"REG_SZ") && cValue в данном случае выступает и как прочее значение при первой записи(при чтении)
CATCH
MESSAGEBOX('Ошибка первичной записи в системный реестр! Раздел: HKCU\SOFTWARE\' + CHR(13) + ALLTRIM(cSection) + '/' + ALLTRIM(cKey) + ;
CHR(13) + 'значение: ' + ALLTRIM(cValue),0,goapp.appcaption)
ENDTRY
ENDTRY
RETURN cValue
CASE nAct = 2 && Write
TRY
oWshShell.RegWrite(HKEY,ALLTRIM(cValue),"REG_SZ")
CATCH
MESSAGEBOX('Ошибка записи в системный реестр! Раздел: HKCU\SOFTWARE\' + CHR(13) + ALLTRIM(cSection) + '/' + ALLTRIM(cKey) + ;
CHR(13) + 'значение: ' + ALLTRIM(cValue),0,goapp.appcaption)
ENDTRY
ENDCASE
ENDFUNC

Сохранение грида
IF This.ColumnCount > 0
* SORT
lcSection = 'Forms_settings\' + ALLTRIM(UPPER(Thisform.name)) + '\' + ALLTRIM(UPPER(This.name))
= rwrst(2,lcSection,'ColumnSort',ALLTRIM(This.ColumnSort))
* HEADER
lnHH = This.HeaderHeight
lnHH = rwrst(2,lcSection,'HeaderHeight',ALLTRIM(STR(lnHH)))
FOR i = 1 TO This.ColumnCount
lcSection = 'Forms_settings\' + ALLTRIM(UPPER(Thisform.name)) + '\' + ALLTRIM(UPPER(This.name)) + '\' + ALLTRIM(This.columns[i].name)
* WIDTH
lnCW = This.columns[i].Width
rwrst(2,lcSection,'Width',ALLTRIM(STR(lnCW)))
* VISIBLE
lnCV = IIF(This.columns[i].visible,1,0)
lnCV = rwrst(2,lcSection,'Visible',ALLTRIM(STR(lnCV)))
* ORDER
lnCO = This.columns[i].ColumnOrder
lnCO = rwrst(2,lcSection,'ColumnOrder',ALLTRIM(STR(lnCO)))
ENDFOR
Return .T.
ELSE
Return .F.
ENDIF

Восстановление
IF This.ColumnCount > 0
* SORT
lcSection = 'Forms_settings\' + ALLTRIM(UPPER(Thisform.name)) + '\' + ALLTRIM(UPPER(This.name))
This.ColumnSort = ALLTRIM(rwrst(1,lcSection,'ColumnSort',ALLTRIM(This.columns[1].name)))
lnHH = This.HeaderHeight
lnHH = VAL(ALLTRIM(rwrst(1,lcSection,'HeaderHeight',ALLTRIM(STR(lnHH)))))
This.HeaderHeight = lnHH
FOR i = 1 TO This.ColumnCount
lcSection = 'Forms_settings\' + ALLTRIM(UPPER(Thisform.name)) + '\' + ALLTRIM(UPPER(This.name)) + '\' + ALLTRIM(This.columns[i].name)
* WIDTH
lnCW = This.columns[i].Width
lnCW = VAL(ALLTRIM(rwrst(1,lcSection,'Width',ALLTRIM(STR(lnCW)))))
This.columns[i].Width = lnCW
* VISIBLE
lnCV = IIF(This.columns[i].visible,1,0)
lnCV = VAL(ALLTRIM(rwrst(1,lcSection,'Visible',ALLTRIM(STR(lnCV)))))
This.columns[i].visible = IIF(lnCV > 0,.T.,.F.)
* ORDER
lnCO = This.columns[i].ColumnOrder
lnCO = VAL(ALLTRIM(rwrst(1,lcSection,'ColumnOrder',ALLTRIM(STR(lnCO)))))
This.columns[i].ColumnOrder = lnCO
ENDFOR
Return .T.
ELSE
Return .F.
ENDIF
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Rifat
Автор

Сообщений: 32
Дата регистрации: 06.02.2012
Аспид
Полагаю грид должен сам себя сохранять и восстанавливать.

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

Спасибо за код работы с реестром.
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
так нет проблем, всю эту хрень переделать под хранение в своих таблицах.
У меня сначала в таблицах было, потом в ini, потом в реестре.
Теперь и реестр не в тренде)))
Но уж точно трогать не буду))
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
В ProgramData можно хранить общее для всех юзеров
В C:\users\user\AppData\Roaming - личное для юзера, кем вошел в ОС

* GETENV("AppData") = 'C:\users\user\AppData\Roaming' - в XP - users\user\Application Data
* GETENV("ALLUSERSPROFILE") = 'C:\ProgramData' - в XP - users\All Users
* GETENV("ProgramData") = 'C:\ProgramData' - в XP - пусто
* GETENV("PUBLIC") = 'C:\users\PUBLIC' - в XP - пусто
Ratings: 0 negative/0 positive
Re: Поиск объектов в форме
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Rifat
задача касается именно гридов - запомнить ширины колонок при закрытии формы.
У большинства разработчиков на фоксе есть свой вариант решения этой задачи (при том место хранения настроек - это уже детали реализации). И, опять же, у большинства он НЕ требует обхода внутренностей формы, а основан на работе методов собственно гридов - для чего они и субклассируются
Получать полный иерархический путь для грида можно используя SYS(1272,...) - и на его основании (дополнительно используя имя формы) точно идентифицировать каждый из гридов в приложении - как бы глубоко он не был запрятан на форме, и как бы не ленив был разработчик при именовании этих гридов - да хоть бы он их все называл Grid1 - пока они в разных контейнерах находятся, их можно без проблем различать.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 22 akvvohinc  (Гостей: 21)

© 2000-2024 Fox Club 
Яндекс.Метрика