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

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

Автор: Odysseos
Дата сообщения: 12.05.2010 02:43
eddoc

1. Едва ли TransWrite и DSet - глобальные переменные, скорей всего - это поля класса TForm1 (ну, или еще какого) - и обращаться к ним из потока надо как к Form1.TransWrite и Form1.DSet;

2. Если речь идет о TIBTransaction и TIBDataSet (или о TpFIBTransaction и TpFIBDataSet) - то так работать оно будет только с fbclient.dll версии 2.5 и позже, более ранние версии fbclient.dll не позволяют работать с одним коннектом из разных потоков, на кажый поток надо создавать отдельный коннект (то есть - в терминах Delphi - отдельный TIBDatabase).
Автор: Frodo_Torbins
Дата сообщения: 12.05.2010 10:48
eddoc
Лучше бы вы сплеш в поток запихнули: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1169
Автор: jonikDk
Дата сообщения: 12.05.2010 12:41

Цитата:
Решил при сохранении данных в БД показывать заставку-сплэш в основном потоке, а сами данные сохранять в треде

мягко говоря странное решение, обычно делают наоборот
Автор: Varenik
Дата сообщения: 12.05.2010 13:30
Odysseos
Цитата:
Если речь идет о TIBTransaction и TIBDataSet (или о TpFIBTransaction и TpFIBDataSet) - то так работать оно будет только с fbclient.dll версии 2.5 и позже, более ранние версии fbclient.dll не позволяют работать с одним коннектом из разных протоков, на кажый поток надо создавать отдельный коннект (то есть - в терминах Delphi - отдельный TIBDatabase).
Вот интересно! А через BDE - позволяют
Автор: eddoc
Дата сообщения: 12.05.2010 16:17
jonikDk

Цитата:
обычно делают наоборот

пытался, сплэш не рисуется

Вообще-то, я потоки только начал осваивать, поэтому просьба: можно показать (хотя бы схематично), как отрисовать сплэш в дополнительном потоке?

Odysseos

Цитата:
на кажый поток надо создавать отдельный коннект

у меня фибы и клиентская либа от 2.1.3
Коль вопрос стоИт так, то в отдельный поток, конечно же, совать БД не стОит (простите за каламбур). Спасибо за замечание.

Frodo_Torbins
за линку спасибо.

Читал, с автором компоненты общался на скруле. Хочу понять принцип работы треда (в целях самообучения), увы, на все случаи жизни компонент не напасешься.
Автор: Frodo_Torbins
Дата сообщения: 12.05.2010 16:42
eddoc
Хм, там в отдельном потоке идет работа с окнами посредством винапи, т к с помощью VCL этого делать нельзя.
Автор: jonikDk
Дата сообщения: 12.05.2010 19:07
eddoc
кстати поищи SplashMsg от softwarera на sql.ru готовая реализция splash окна.
Автор: eddoc
Дата сообщения: 12.05.2010 23:38
Frodo_Torbins, jonikDk
камрады, все любезно указанные вами способы я уже пробовал. Кстати, от softwarer'a сплэш тоже просто так не отрисовывается. Потому и просил помочь.

Суть одна: пока в основном потоке данные сохраняются в базу, хотелось бы в дополнительном потоке (треде) крутить перед носом юзера окошко. Пробовал отрисовывать его в методе TThread.Execute примерно так (пишу по памяти, не обращайте внимание на мелочи - важна суть)
[more=код]
Цитата:

var FrmSpl: TFrmSplash;//предположим добавим к проекту внешнюю сплэш-форму
begin
FrmSpl:= TFrmSplash.Create(nil);

try
while not Terminated do
begin
//имитируем циклическую деятельность, пока тред не прибьют из основного потока
FrmSpl.Show;
beep;
sleep (1000);
end;
finally
FrmSpl.Free;
end;
end;
[/more]

Заметил, что сплэшик рисуется один раз сразу после окончания работы основного VCL-потока (основной поток запускается стандартно, сразу же после запуска доп.потока). Вот я и пытаюсь понять, почему код в треде не работает параллельно основному (в отладчике Дельфей это видно).

Камрады, подмогните. Что-то втупляю.

Автор: Varenik
Дата сообщения: 13.05.2010 06:49
eddoc
После создания потока нужно дать ему запуститься:
begin
....
MyThread.Create;
Application.ProcessMessages;
...
end;
иначе поток стартует только после вот этого end
Автор: Man_Without_Face
Дата сообщения: 13.05.2010 09:08
Доброго времени суток. Скажите пож как передать в Tquery значение поля? Спасибо.
Автор: Frodo_Torbins
Дата сообщения: 13.05.2010 10:17
eddoc
Еще раз напомню, что работать с VCL из потока нельзя. Если вам нужно показать из потока окно, то писать его нужно полностью на винапи. Кроме того, в вашем потоке отсутствует петля сообщений, поэтому ваше окошко и не работает.
Автор: delover
Дата сообщения: 13.05.2010 10:40
Man_Without_Face
Написать SQL для апдейта - то есть Вам необходимо как минимум два значения передавать - ID по которому запись изменять плюс значение поля. К тому не ясно почему кверь, если гораздо симпатичнее датасетом пользоваться. Об ускорении Query даже лучше не думать.
Автор: Man_Without_Face
Дата сообщения: 13.05.2010 10:57
delover
Спасибо, вопрос снят. Решил свой вопрос через калькулируемое поле.
Автор: eddoc
Дата сообщения: 13.05.2010 22:22
Varenik
Спасибо, собственно работало и так, и так Единственное НО: окошко сплэш-прекрасно отображается (я использую сплэш от softwarer'a, немного доработанное собственным напильником), только все равно в некоторые моменты оно не успевает прорисоваться [more=код]MessageForm.Show('Начали...');//запускаем сплэш с начальным сообщением
try
TransWrite.Start;//запустили пишущую транзакцию
MessageForm.Text('Пишем данные...');//меняем надпись на сплэше
DataSet.Edit;
// тут в коде присвоение значений полям
DataSet.Post;

MessageForm.Text('Коммитимся...');//меняем надпись на сплэше
TransWrite.Commit; //вот тут, похоже, обработка очереди сообщений приостанавливается и сплэш не перерисовывается
finally
MessageForm.Close;//уничтожаем сплэшик
end; [/more]

Похоже, придется изучать АПИ

Frodo_Torbins
Да, я уже понял, что кавалерийским наскоком в моем случае не обойдешься. Ладно, пойду читать Григорьева, благо эту книгу я в свое время прикупил "про запас"
Автор: YuriyRR
Дата сообщения: 13.05.2010 23:28
eddoc


Добавлено:
eddoc
Создаешь окно в основном потоке а его перерисовку из трэда делаешь при помощи метода Synchronize.

Добавлено:
А в основном потоке
Call the CheckSynchronize routine periodically within the main thread
Автор: svs123456789
Дата сообщения: 14.05.2010 08:55
не будет ли проблем с работой старой Delphi 7 в среде Windows Seven ?
Автор: ShIvADeSt
Дата сообщения: 14.05.2010 10:12
Я под семеркой (Win7) Дельфи 5 поставил и компилял проекты. Проблем не было, думаю с Дельфи 7 тем более.
Автор: ppkp
Дата сообщения: 14.05.2010 14:06
Прошу прощения за возможно очень простой вопрос. Никогда не работал с TreeView (ну не довелось). У меня TreeView состоит только из одного корня и нескольких ветвей. Как менять какие-то данные при движении по TreeView вроде бы понятно - через OnChange. А как, наоборот, менять фокус у TreeView при изменении данных - запутался. Подскажите, пожалуйста, на примере. Спасибо.
Автор: eddoc
Дата сообщения: 14.05.2010 15:32
YuriyRR
уже по-всякому пытался. В тестовых проектах все прекрасно отображается и рисуется, а вот в реале на WriteTrans.Commit происходит "замораживание" подлежащего сплэша и подлежащего окна, т.е. [more=вот тут приложил скрины]
должно быть так



а получается так (красной рамкой место, где не перерисовывается сплэш)

[/more]

Цитата:
А в основном потоке
Call the CheckSynchronize routine periodically within the main thread

как-то смущает справка

Цитата:
It is not necessary to call CheckSynchronize in a GUI application. The call to CheckSynchronize is made automatically by the application object. In a non-GUI application, you must call CheckSynchronize if you use the Synchronize method of TThread. To do this, set the WakeMainThread variable to a procedure that calls CheckSynchronize.

а не могли бы показать, где в моем коде надо воткнуть эту функцию?
Автор: Bonivur
Дата сообщения: 14.05.2010 17:48
У меня на форме есть Memo. При вставке в него текста, происходит обработка и результат опять пишется в этом Мемо. Как заставить его работать с Uncode? То есть,

var
s: WideString;
...

s := Memo.Text;

далее невозможно сделать проверку типа

if s[23] in ['a'..'z'] then...

пишет что типы не совпадают WideChar и Char. Какой может быть выход в данном случае?
Автор: psa1974
Дата сообщения: 14.05.2010 19:10
Bonivur
не воспроизводится. Пробовал в Д2007. Компиилятор предупреждает что "WideChar reduced to byte char in set expressions", но компилирует.
Автор: Bonivur
Дата сообщения: 14.05.2010 19:16
psa1974
У меня Delphi 7. И там пишет Error: Incompatible types "WideChar" and "Char".
Автор: psa1974
Дата сообщения: 14.05.2010 19:46
Bonivur
Кстати, в Д2007 хоть и компилируется, но если в s[23] будет символ кириллицы то это if s[23] in ['а'..'я'] then... вернет ложь, потому что компилятор при сравнении WideChar c набором "Set of char" (который может адресовать только 256 символов - размер байта) от двухбайтового символа WideChar берет только один байт.

Не знаю, есть ли в Delphi 7 ф-ция WideCharToString, но если есть, то как вариант:
if (WideCharToString(@s[23])[1] in ['a'..'z']) then
Автор: Frodo_Torbins
Дата сообщения: 14.05.2010 20:16
eddoc
Цитата:
только все равно в некоторые моменты оно не успевает прорисоваться
Попробуйте потоку со сплешем приоритет поднять. Возможно основной поток просто сильно нагружает процессор.

Bonivur
Поищите в теме про D2009, там несколько раз обсуждали варианты решения этой проблемы. Вроде даже ссылки на готовые решения были.
Автор: eddoc
Дата сообщения: 14.05.2010 23:25
Frodo_Torbins

Цитата:
Попробуйте потоку со сплешем приоритет поднять. Возможно основной поток просто сильно нагружает процессор.

увы... Поднял приоритет до критического - тот же результат. Щас попробую поюзать Рощинский WindowThread...

добавлено позже: а компонент С.Рощина ваапче ничего не отрисовывает. Ы-ы-ы-ы ....

Bonivur
Как-то понадобилась проверка наличия символов кириллицы в строке (для D2007), пришлось написать [more=свою функцию]

Цитата:
//----------------------------------------------------------------------------
// функция, позволяющая определить, имеются ли в переданной строке кириллические символы
// Возвращает 3 значения:
// - строка пуста или содержит только пробелы (-1)
// - в строке не содержится ни одного символа кириллицы (0)
// - в строке содержится хотя бы один кириллический символ (1)

function TFrmConnect.CyrChrPresents(const AText: string): Integer;
var i, counter: Integer;
TmpStr: string;
begin
Result:= -1;
TmpStr:= Trim(AText);
if Length(TmpStr) = 0 then Exit;//выйдем, если строка пустая

counter:= 0;//обнулим счетчик

for i:= 1 to Length(TmpStr) do
//(ord('A') = 192, т.е. #192 возращает строку 'А'; ord('я') = 255, т.е. #255 возращает строку 'я')
if (TmpStr[i] >= #192) and (TmpStr[i] <= #255) then //если очередной символ строки - кириллический
counter:= counter + 1;//то наращиваем счетчик

if counter = 0
then
Result:= 0
else
Result:= 1;
end;
[/more]
помятуя о том, что стандартные дельфевые функции не очень жалуют кириллицу.

Может, стоит попробовать сделать свой велосипед?
Автор: YuriyRR
Дата сообщения: 15.05.2010 03:20
eddoc

Цитата:
а не могли бы показать, где в моем коде надо воткнуть эту функцию?

Цитата:
It is not necessary to call CheckSynchronize in a GUI application

ее не обязательно конечно вставлять в чистом виде т.к. она вызывается в цикле
обработки сообщений.Но программа то должна в него входить.
while not EndProcFlag do
begin
Beep;//вместо кода отрисовки заставки-сплэша
Sleep(500);
end;
В этом цикле такого входа нет, а чтобы появился добавляем
в него Application.ProcessMEssages



Добавлено:
А вообще я к примеру пишу процедуры которые делают расчеты или обновления и возвращают в ходе этого кол-ва записей или проценты в цикле в селекте считываем из нее возвращаемые записи и выводим прогресбар или еще чего
Очень эффективно.
Автор: Bonivur
Дата сообщения: 15.05.2010 08:02
eddoc
Кстати, Ваша функция не находит буквы "Ё" и "ё". Для этого надо проверять также символы 168 и 184.
Автор: eddoc
Дата сообщения: 15.05.2010 08:56
Bonivur
ОК, [more=подправил]
Код: //----------------------------------------------------------------------------
// функция, позволяющая определить, имеются ли в переданной строке кириллические символы
// Возвращает 3 значения:
// - строка пуста или содержит только пробелы (-1)
// - в строке не содержится ни одного символа кириллицы (0)
// - в строке содержится хотя бы один кириллический символ (1)

function CyrChrPresents(const AText: string): Integer;
var i, counter: Integer;
TmpStr: string;
begin
Result:= -1;
TmpStr:= Trim(AText);
if Length(TmpStr) = 0 then Exit;//выйдем, если строка пустая

counter:= 0;//обнулим счетчик

for i:= 1 to Length(TmpStr) do
//(ord('A') = 192, т.е. #192 возращает строку 'А'; ord('я') = 255, т.е. #255 возращает
//строку 'я'), #168 строку 'Ё', # 184 строку 'ё'
//если очередной символ строки - кириллический
if ((TmpStr[i] >= #192) and (TmpStr[i] <= #255)) or (TmpStr[i] = #168) or (TmpStr[i] = #184) then
counter:= counter + 1;//то наращиваем счетчик

if counter = 0
then
Result:= 0
else
Result:= 1;
end;
Автор: Man_Without_Face
Дата сообщения: 15.05.2010 14:06
Доброго времени суток. Есть модуль Dll с отчетами. Скины в DevExpress (v4.8) в рантайме не поддерживаются. В опциях выставляю галочку Run with runtime puckages, тогда поддерживаются. Вопрос1: можно ли только часть пакетов скомпилировать таким образом? Вопрос2: какие тогда нужны Dll'ки для поддержки скинов? И еще главная суть проблемы: моя dll скомпилирована под Delhi 2009, а exe под Delphi 5.

Добавлено:
Второй вопрос не актуален, их нужно слишком много. Есть другой вопрос: можно ли указать экзешнику другую папку для этих bpl (devexpress), кроме как корневой каталог программы и system32. Например папку в корневом каталоге программы?

Добавлено:
Экзешник для которого нужно указать папку скопмилирован под Delphi 5
Автор: Frodo_Torbins
Дата сообщения: 15.05.2010 17:47
Man_Without_Face
Чтобы опция "Build with runtime puckages" работала, все должно быть скомпилено в одной версии делфей. По поводу остального - пакеты можно загружать и динамически, но понятное дело не все.

Bonivur
Все же приведу ссылку на один из своих прошлых постов:
http://forum.ru-board.com/topic.cgi?forum=33&topic=9383&start=1400#18

eddoc
Цитата:
а компонент С.Рощина ваапче ничего не отрисовывает.
Примерчик плиз в студию.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Clipper 5


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