Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: krapotkin
Дата сообщения: 29.04.2013 21:53
OOD
Пишу на Java/Eclipse для планшета, но связь с БД идет через промежуточный сервер, который взаимодействует с планшетами посредством т.н. Datasnap Mobile Connectors
Так что delphi тоже участвует
Автор: Vitus_Bering
Дата сообщения: 30.04.2013 11:29
OOD
_http://tmssoftware.com/site/tmsiwiphone.asp
Автор: MoLnuS
Дата сообщения: 24.05.2013 19:51
Здравия вам, люди!=)

Есть задание, связанное с анкетами. Всё его излагать не буду, т.к. вопрос пока лишь по одной части. Пытаюсь сделать более менее удобный конструктор анкет. Добавление вопросов, вариантов ответов, удаление вариантов и вопросов целиком. Пока лишь "скелет" программы.
Для ясности программу прилагаю, качать здесь.
Работает пока только "Создать анкету", туда и жмите) Исходники целиком скину по надобности.

И сами вопросы по порядку:
1. Не могу понять, как корректно удалить весь вопрос целиком, т.е. как видно из программы - каждый вопрос на отдельной панельке. При нажатии на "Удалить вопрос" выполняется след.код:
[more]

Код:
...
var i,k:integer;
begin
k:=0;
pnl:=TPanel(TButton(Sender).Owner);
for i := 0 to pnl.Componentcount-1 do
if not (pnl.Components[k]=Sender) then
pnl.Components[k].Free else inc(k);
TButton(Sender).Hide;
end;
Автор: XPerformer
Дата сообщения: 24.05.2013 20:39
по первому вопросу. нельзя из обработчика объекта удалить сам объект, т.к. управление после завершения выполнения обработчика некуда вернуть. это как спилить сук, на котором сидишь

Добавлено:
по второму вопросу - удаленные он видеть не может. Наверное, это скрытые объекты
Автор: MoLnuS
Дата сообщения: 25.05.2013 07:11

Цитата:
по первому вопросу. нельзя из обработчика объекта удалить сам объект, т.к. управление после завершения выполнения обработчика некуда вернуть. это как спилить сук, на котором сидишь

Добавлено:
по второму вопросу - удаленные он видеть не может. Наверное, это скрытые объекты

По первому, это я уже понял. А как иначе можно ее удалить, не подскажете? Вопрос был в этом + если он таки может найти удаленный компонент через findcomponent, значит метод free их не удаляет?? И как их тогда убить?
Автор: miwa
Дата сообщения: 25.05.2013 09:11
MoLnuS
По поиску динамических объектов - ничего сверх тупого нет, все нормально.

По удалению объектов - их надо удалять из внешнего обработчика. Метод Free его удаляет, можно не сомневаться (лично я использую FreeAndNil, но это уже кому как нравится); а чтобы он работал, его надо вызывать не из OnClick удаляемого объекта. Как вариант - по клику только помечать на удаление, а реально удалять по нажатию кнопки типа «Удалить отмеченные элементы». Вариант сложнее - по клику прятать (Visible := False) и как-то отмечать (Tag := 1234) неугодные объекты, а удалять позже (раз в минуту запускать очищающую процедуру).
Автор: MoLnuS
Дата сообщения: 25.05.2013 10:31
miwa,

Цитата:
Вариант сложнее - по клику прятать (Visible := False) и как-то отмечать (Tag := 1234) неугодные объекты, а удалять позже (раз в минуту запускать очищающую процедуру).

Ну это же доп нагрузка будет..=(( Плюс, тут такой косяк получится, если хоть один объект на панели есть - панель существует, а у меня в обходе по панелям и сбору от туда вопросов\вариантов тогда сломается всё...хотя там можно в принципе проверять, есть ли там вообще едиты, тогда все ок будет..

В общем, если таки не выйдет..придется делать по таймеру очистку да.. По выходу из программы ведь оно само должно очистится, или же нет - и тоже придется запускать процедуру очистки по событию Close?

Я сумел сделать более менее работающий алгоритм удаления всего и вся, вот такой:
[more]

Код: var i,k:integer; com:TComponent;
begin
k:=0;
pnl:=TPanel(TButton(Sender).Owner);
for i := 0 to pnl.Componentcount-1 do
if not (pnl.Components[k]=Sender) then begin
pnl.Components[k].free;
end
else inc(k);
pnl.Components[0].free;
pnl.Free;
Автор: miwa
Дата сообщения: 25.05.2013 10:54
MoLnuS

Цитата:
Ну это же доп нагрузка будет.

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

При выходе из программы все объекты и так уничтожаются, так что по Close можно ничего не делать.

У твоего «более-менее работающего алгоритма» есть один недостаток - переход по объектам с целью удаления всегда делается в обратом порядке:

for i := ComponentCount - 1 downto 0

Почему - сам подумай
Автор: MoLnuS
Дата сообщения: 25.05.2013 11:21

Цитата:
Если серьезно - при отсутствии явных ошибок в коде нагрузка будет в пределах статистической погрешности.

Ну ок тогда=) Просто на всякий случай уж..%))


Цитата:
У твоего «более-менее работающего алгоритма» есть один недостаток - переход по объектам с целью удаления всегда делается в обратом порядке:

for i := ComponentCount - 1 downto 0

Почему - сам подумай

Ммм..не понял, а какая разница? У меня же там всегда удаляется нулевой, кроме случая, когда нулевой =sender, затем удаляется первый, оставляя sender в нулевых. Разве есть разница от куда начинать отсчет?) Не понимаю, объясните, пожалуйста..
И таки не доработать этот алгоритм, чтобы он работал в 100% случаев..?

Добавлено:
Кстати, вот еще вопрос какой.
Как лучше всего сохранять анкету? У меня в идеях пока только excel-файлы.. Может есть варианты получше?
Автор: LadyOfWood
Дата сообщения: 25.05.2013 21:08

Цитата:
Разве есть разница от куда начинать отсчет?) Не понимаю, объясните, пожалуйста..

Есть, раскрутка с начала приводит с тому что в конце получаешь AV.
Автор: XPerformer
Дата сообщения: 26.05.2013 14:39
MoLnuS
for i := ComponentCount - 1 downto 0
удалил первый элемент, ComponentCount уменьшилось на 1 единицу, а паскале границы цикла вычисляются один раз. Усек идею?
Автор: miwa
Дата сообщения: 27.05.2013 09:48
MoLnuS

Цитата:
Как лучше всего сохранять анкету? У меня в идеях пока только excel-файлы.. Может есть варианты получше?

Зависит от того, что дальше с ней планируется делать. Если только смотреть - я бы PDF генерировал; если анкету будет анализировать еще какая-то программа, тогда я бы сохранял в XML. А для внутреннего пользования - так как удобно мне (типизированные файлы/встроенная база данных/etc). Самый правильный вариант, как по мне - хранить во внутреннем формате с возможностью експорта.
Автор: XPerformer
Дата сообщения: 29.05.2013 20:27
Скажите, как грамотно делаются такого рода подсказки в меню


Можно, конечно, задисейблить этот пункт меню... но, может, надо по-другому?
Автор: miwa
Дата сообщения: 30.05.2013 11:47
XPerformer
Ну, как по мне, задисейблить - вполне себе решение. Если играться с цветами-шрифтами, тогда надо учитывать что у пользователя может быть другая тема оформления, что более геморройно и не факт что элегантнее/красивее.
Автор: Frodo_Torbins
Дата сообщения: 31.05.2013 20:37
MoLnuS
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=40427
Автор: MoLnuS
Дата сообщения: 01.06.2013 09:21
XPerformer

Цитата:
MoLnuS
for i := ComponentCount - 1 downto 0
удалил первый элемент, ComponentCount уменьшилось на 1 единицу, а паскале границы цикла вычисляются один раз. Усек идею?

Вообще не усек. И какая разница, если оно таки вычитается единожды?
Допустим, есть 5 элементов - цикл прошагает от 4 до 0 раз или же от 0 до 4-ых раз и там и там выйдет 5 шагов. Разница-то в чем в итоге?)))

В любом случае от того, в какую сторону шагать - ничего не сменилось. Абстракт Ерроры так и летят.


Добавлено:
Frodo_Torbins

Цитата:
MoLnuS
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=40427

Спасибо большое, полезно и подробно.
Но вот даже в таком случае у меня ошибка доступа к памяти=((( Ну как там написано, в некоторых случаях может все же не работать и останется только прятать..

Думаю, вариантов больше нет или же их просто бессмысленно искать. Решил, спрячу злополучную кнопку, а потом буду ловить и удалять каждые n-секунд\минут - как предлагалось выше.

Спасибо всем, кто поучаствовал в решении данной проблемы=)
Автор: miwa
Дата сообщения: 01.06.2013 11:34

Цитата:
Вообще не усек. И какая разница, если оно таки вычитается единожды?

В том, что единожды вычислилось что у тебя ЧЕТЫРЕ объекта. Потом ты один удалил. У тебя осталось ТРИ. А цикл-то до ЧЕТЫРЕХ. Соотвественно, при обращении к четвертому элементу, который перестал существовать, у тебя вылезает ошибка доступа к памяти.


Цитата:
В любом случае от того, в какую сторону шагать - ничего не сменилось. Абстракт Ерроры так и летят.

Значит, у тебя есть еще одна ошибка в коде. Надо смотреть код дальше.
Автор: Frodo_Torbins
Дата сообщения: 01.06.2013 14:30
MoLnuS
При использовании этого подхода у меня никогда проблем не было. Так что показывайте новый код, может еще чего найдем.
Автор: LadyOfWood
Дата сообщения: 02.06.2013 19:06

Цитата:
Абстракт Ерроры так и летят.

Он возникает при обращение к абстрактному методу, смотри call stack.
Автор: Grande
Дата сообщения: 06.06.2013 13:16
Уважаемые знатоки, возникла необходимость написания сетевой проги. Все бы ничего, но заспорили мы вот о чем:
что лучше использовать - асинхронный режим, основанный на событиях или асинхронный режим, основанный на сообщениях.
Не поделится ли кто опытом?
Спасибо.
Автор: miwa
Дата сообщения: 06.06.2013 13:49
Grande
Как всегда, зависит от реализации. «Дьявол в мелочах» © Плюс нам отсюда не видно, что лучше для вас в ваших условиях.
Автор: Grande
Дата сообщения: 06.06.2013 14:06
Думаю
Цитата:
Как всегда, зависит от реализации.

Думаю, на событиях лучше подходит для безоконных программ, а с окнами лучше использовать сообщения.
Автор: miwa
Дата сообщения: 06.06.2013 15:09
Grande
Ну вот и говорю - отсюда не видно, что у вас там и как: является ли слушатель сервисом, или оконным приложением; в трее висит или отдельным потоком в основной программе крутится.

Так что - на общие вопросы получите общие ответы
Автор: Grande
Дата сообщения: 07.06.2013 06:31
miwa
Вы правы
Спасибо.
Автор: Grande
Дата сообщения: 24.07.2013 08:07
Имеется прцедура для приема инфы из сокета:

Код:
case WSAGetSelectEvent(Msg.LParam) of
FD_Read:
begin
ioctlsocket(FrameSocket, FIONREAD, LenOfBuf);
SetLength(Local, LenOfBuf);
Recv(FrameSocket, PChar(Local)^, LenOfBuf, 0);
ReceiveBuffer := ReceiveBuffer + Local;
SendMessage...
...
Автор: vavavol
Дата сообщения: 28.08.2013 17:08
Ребята, помогите! Delphi5, обычная SpeedButton. Свойство Glyph загружена картинка. У соседа форма открывается нормально. У меня с теми же исходниками формы пишет: "SpeedButton.Glyph: Stream read error". Винда одинакова - Win7(64)
Автор: MGAlex
Дата сообщения: 28.08.2013 17:25
vavavol
У соседа тоже Delphi5?
Попробуйте заново загрузить картинку в Glyph.
Автор: vavavol
Дата сообщения: 28.08.2013 17:35

Цитата:
У соседа тоже Delphi5?
Попробуйте заново загрузить картинку в Glyph.


В том то и дело, что такая же Delphi5. Он берёт форму с VSS, как и я. Оба убиваем у себя - и берём с сервера. Менять что-то на форме не имею право. Нужно просто собрать проект
Автор: MGAlex
Дата сообщения: 28.08.2013 18:19
Так менять ничего и не нужно. Просто загрузите по новой ту же самую картинку.
Если Вы заходите в Glyph, картинка видна?
Автор: A_V
Дата сообщения: 28.08.2013 23:09
vavavol
dfm в текстовом виде сохранена? выложите ее сюда что-ли, что гадать )

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.