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

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

Автор: Aleksandr N
Дата сообщения: 24.05.2009 13:06
Frodo_Torbins

Цитата:
даже касперский не позволяет себе такого

Ну это дело самого Касперского. Мне главное узнать как, а там посмотрим. Тем более пользователю можно предоставить выбор.
Автор: mauar
Дата сообщения: 24.05.2009 13:46
Frodo_Torbins

Цитата:
mauar
Наверно стоит еще включить рантаймпакеты.


В смысле?
Автор: RS85
Дата сообщения: 24.05.2009 14:05
V1s1ter

Я имею в виду, дерево или список, состоящий из объектов. Если создавать такие структуры не из записей, а из объектов.

Каждый узел дерева - объект. А объектов этих может быть много...
Автор: V1s1ter
Дата сообщения: 24.05.2009 14:41
RS85
У меня аналогичный список графических объектов, и их тоже много иногода до пол миллиона. Если делаете нечто подобное могу предложить готовый фрагмент кода. Но Вы не ответели в каких ситуациях есть необходимость зарезервировать ветвь для еще не созданного объекта. Или Вы хотели сначала создать необходимое количество вервей и потом в них записывать создаваемые объекты? Если это так, то такое предворительное построение не нужно. Если объекты должны быть отсортированы, допустим по номеру, но создаются не попорядку, то всеравно это решается другим способом. В общем, если Вы узнали все, что хотели, напишите. Если есть еще непонятные моменты - спрашивайте, но помните, что я незнаю что зачем и как Вы делаете, поэтому вопросы чуть по подробнее.
К стати если Вам нужно, чтобы список и отображался, рекомендую сразу использовать компонеты типа TTreeView. Если ветвей много то лучше использовать компоненты VirtualTree (они бесплатные), TeeTree или от DevExpress они будут гораздо шустрее, чем стандартные.
Автор: RS85
Дата сообщения: 24.05.2009 14:52
V1s1ter

Я пишу обыкновенный кодировщик Хоффмана.

Да, в принципе количество узлов известно - 511.
Это максимальное количество узлов, которое может быть в дереве.

Каждый из таких узлов - объект, с весом символа, со ссылкой на узлы-родители и т. д.

Но чтобы мне занести все 511 узлов в Tlist, мне приходиться сначала делать массив объектов, пройтись по нему циклом, и проинициализировать все объекты.
Ведь в Tlist невозможно сначала добавить энное количество объектов, а только потом сделать для каждого из них Object.Create.

Вот я и думаю, возможно ли это как-нибудь обойти, чтобы не создавать дополнительный массив из объектов.





Автор: Frodo_Torbins
Дата сообщения: 24.05.2009 15:06
mauar
Без Run-time packages (надеюсь осилите) очень не рекомендуется обращаться к классам в основной программе из библиотеки. Можно получить кучу весьма странных глюков. И никакой менеджер памяти не спасет.

RS85
А если так написать:

Код: var
f: TList;
o: TObject;
i: Integer;
begin
f := TList.Create;
for i := 0 to 15 - 1 do
begin
o := TObject.Create;
//тут еще что то с ним делаем
f.Add(o);
end;
end;
Автор: PsyNIX
Дата сообщения: 24.05.2009 15:16
простите ламера....
Может такое уже и спрашивали....
Объясните мне пожалуста как в Инди нормально сделать обмен текстовыми сообщениями между сервером и клиентом, и как посылать "Приват"-сообщения от сервера пользователю?
Автор: V1s1ter
Дата сообщения: 24.05.2009 15:21
RS85
Если принимать только то, что Вы написали, то решение простоеб или мы говорим оразных вещах.
Пример без массива, ведь в какой-то момент времени Вы создаете всетаки объект вот и пишите в этом месте f.Add(Object.Create)
Вом модификация Вашего кода:
var
f:TList;
i:Integer;
begin
f:=Tlist.create;
for i:= 0 to 15-1 do
f.Add(Object.Create);

если Вам нужно сначала создать и вставить подчиненный объект с готовой ссылкой на несозданного родителя, пожалуйста:
пример для ссфлок по указателям
N := f.Add(Nil);
M := f.Add(Object.Create);
....
f[N] := Object.Create;
TXXXObject(f[M]).Parent := f[N];

пример для ссфлок по номеру
N := f.Add(Nil);
M := f.Add(Object.Create);
TXXXObject(f[M]).Parent := N;
....
f[TXXXObject(f[M]).Parent] := Object.Create;

Еще вариант использовать TStringList с гтовой сортировкой.
Например List.Add(Символ, TObject(Вес));
где Вес: Integer;
Автор: RS85
Дата сообщения: 24.05.2009 16:29
V1s1ter

Спасибо!

Только мне немного непонятен один момент:
Например

Type
Object = class
a: Integer;
end;

.........................................
procedure TForm1.Button1Click(Sender: TObject);
var
f: TList;
i:Integer;
begin
f:=TList.Create;
for i:= 0 to 10-1 do
f.Add(Object.Create);

То есть получается, мы не создаем дополнительную переменную для объекта, типа:

var
Object2: Object;
begin
Object2:=Object.Create;
f.Add (Object2);

а сразу в метод Add вписываем (Object.Create) ?

В таком случае потом, F.Items[такой-то] уже и будет являться проинициализированной переменной-объектом?
Автор: Grande
Дата сообщения: 24.05.2009 17:10
RS85

Цитата:
В таком случае потом, F.Items[такой-то] уже и будет являться проинициализированной переменной-объектом?


Ну, естественно. Только TList не сработает. Нужно использовать TObjectList.

P.S.Правда, TList сработает, но достучаться к полям экземпляров по индексу вряд ли удастся

Добавлено:
PsyNIX

Вот это и и вот это тебе точно поможет.
Автор: V1s1ter
Дата сообщения: 24.05.2009 17:20
RS85

Цитата:
а сразу в метод Add вписываем (Object.Create) ?
В таком случае потом, F.Items[такой-то] уже и будет являться проинициализированной переменной-объектом?

Да.
Но выигрыш при этом от варианта
Код: Object2:=Object.Create;
f.Add (Object2);
Автор: Andrey128
Дата сообщения: 24.05.2009 17:30
RS85
Ещё такой вариант для коллекции:

Код: begin
List := TList.Create;
List.Count := 511;
for I := 0 to List.Count - 1 do
[no]List[I] := TMyObject.Create;[/no]
end;
Автор: V1s1ter
Дата сообщения: 24.05.2009 17:51
RS85
Прошу прощения, я как-то привык, что вопросы здесь обычно задают более сложные и потому долго не понимал что не так. Если я правильно понял Вы недавно изучаете Object Pascal. Если да, то Ниже приведенные пояснения возможно Вам помогут.

Код: var
A: TObject;
ArrA: array[0..511] of TObject;
L: Tlist;
begin
A := TObject.Create;
for i :=0 to 511 do ArrA := TObject.Create;
L := Tlist.Create;
L.Add(TObject.Create);
Автор: Frodo_Torbins
Дата сообщения: 24.05.2009 19:40
V1s1ter

Цитата:
Естественно что в месте "тут еще что то с ним делаем " стоят несколько операций над вновь созданным объектом, поскольку строка o.Xxx := Yyy легче воспринимается чем TObject(f.[no][i]).Xxx := Yyy.[/no]

У этой конструкции и с точки зрения надежности есть одно преимущество. Если при заполнении полей объекта возникнет исключение, то частично незаполненный объект не попадет в список.
Автор: V1s1ter
Дата сообщения: 24.05.2009 22:25
Frodo_Torbins

Цитата:
У этой конструкции и с точки зрения надежности есть одно преимущество. Если при заполнении полей объекта возникнет исключение, то частично незаполненный объект не попадет в список.

Преимущество - частная штука. Для человека начинающего, главное понять что происходит, а преимущества это удел опыта и частных случаев. Теперь по теме, сразу оговорюсь, что я согласен стем, что такой подход имеет ряд положительных моментов, но преимуществами я бы не назвал, но это философский момент - давай не будем флудить ибо не будет здесь правых. Хочу отметить, что не до конца созданный объект нужно все равно "дорабатывать", в том числе и освобождать память. Прочитав прочитав Ваше, несомненно правильное замечание, начинающий специалист может забыть про "доработку" и получить утечки памяти.
К стали из личного опыта, один мой коллега, при разработки графической подсистемы забыл удалить один объект на пару кило, в итоге 60 кадров в секунду + несколько часов работы и вылет. В чем проблема нашли конечно, но осадок остался...
Автор: AndreyPA
Дата сообщения: 25.05.2009 02:17
Кто-нибудь использует компонент VirtualStringTree (VirtualTreeView). Очень хороший компонент, но у меня небольшая проблема. Со многим разобрался но вот заткнулся на одной фичке. Необходимо в заголовках колонок программно менять цвет текста. Утанавливаю в Header->Options->OwnerDraw=True (т.е. рисовать буду сам) и программирую события OnAdvancedHeaderDraw и OnHeaderDrawQueryElements Вроде все как положено. Но не получается в результате только текст 0 колонки выходит красным и все - что я делаю не так.

Код:
procedure TForm1.VirtualStringTree1AdvancedHeaderDraw(Sender: TVTHeader;
var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements);
begin
if (hpeText in Elements) and (PaintInfo.Column <> nil)then begin
PaintInfo.TargetCanvas.Font.Color:=clRed;
PaintInfo.TargetCanvas.TextOut(PaintInfo.PaintRectangle.Left, PaintInfo.PaintRectangle.Top,IntTostr(PaintInfo.Column.index));
end;
end;

procedure TForm1.VirtualStringTree1HeaderDrawQueryElements(
Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
var Elements: THeaderPaintElements);
begin
Elements := [hpeText];
end;
Автор: Aleksoid1978
Дата сообщения: 26.05.2009 04:54
Народ, подскажите, есть такой трабл небольшой - написал прогу для управвения с помощью пульта от тюнера Beholder проигрывателем MPC-HC. Все хорошо, все работает.
Сам проигрыватель предотвращает включение скринсэйвера и выключение моника во время проигрывания, если надо могу код запостить(но он на С++). Управляю посредством посылания нужных сообщений, примерно так:

SendMessage(mpc_handle, MPCMessage, wParam, lParam);

т.е. во время проигрывания видео ни клавиатура, ни мышка не юзаються. И например по после посылки команды Паузы или вообще закрытия проигрывателся - моник сразу же уходит в спящий режим. Получается пока плейер работат, он не дает монику(системе) это делать, а как только закрыть или пауза(во время паузы MPC не блокирует выключение моника) - он сразу отрубается.

Можно ли как-то без юзания клавы и мыши предотвратить выключение моника ??? Т.е. чтобы таймер, который выставлен в винде(у меня например стоит 20 минут бездействия) не срабатывал.

З.Ы. в MPC юзаеться примерно такой код по таймеру(я на Delphi напишу) :

procedure TMainForm.Timer1Timer(Sender: TObject);
Var
status: Cardinal;
begin
status := 0;
if SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, @status, 0) then begin
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF_SENDWININICHANGE);
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, status, 0, SPIF_SENDWININICHANGE);
end;

status := 0;
if SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, @status, 0) then begin
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, status, 0, SPIF_SENDWININICHANGE);
end;

Self.Caption := DateTimeToStr(Now);
end;
Автор: ShIvADeSt
Дата сообщения: 26.05.2009 06:56
Aleksoid1978
Можно:
1. Так как ты юзаешь свой софт, то при старте МРС выставляй программно настройки отрубаний на false, после выключения опять возвращаешь.
2. Можно эмулировать движения мыши (setcursorpos), клавиатуры (keybd_event) чтобы система думала что есть активность.

ИМХО первое более правильно. Так как если мы собрались смотреть фильм - то не надо чтобы у нас гас моник или отрубалось питание. А вот если закончили, то начиная с этого момента пусть мониторит.
Автор: Aleksoid1978
Дата сообщения: 26.05.2009 07:17
ShIvADeSt

Так смотри, в самом MPC по таймеру идет сброс и возврат настроек, т.е. выставляется Скринсейвер-выключен, и тут же возвращает обратно флаг. Это, видимо, не сбрасывает таймер бездействия, и как только перестается это делать - монитор гаснет. Вот в чем прикол.

Эмулировать действия кнопок или мыши тоже не подходит, т.к. в момент просмотра за компом может ктолибо сидеть, Жена например по инету лазить или детям печатать реферат - это ессно будет очень мешать.

P.S. - хотя нет, переключение режима скринсейвера вкл/выкл сбрасывает таймер бездействия, проверил тестовой прогой - значит какойто баг в самом MPC.
Автор: ShIvADeSt
Дата сообщения: 26.05.2009 07:37
Aleksoid1978

Цитата:
Так смотри, в самом MPC по таймеру идет сброс и возврат настроек, т.е. выставляется Скринсейвер-выключен, и тут же возвращает обратно флаг. Это, видимо, не сбрасывает таймер бездействия, и как только перестается это делать - монитор гаснет. Вот в чем прикол.

вот вроде тут написано как сбросить idle timer у винды http://forum.sysinternals.com/forum_posts.asp?TID=16362
а вот что говорит msdn

Цитата:

Calling SetThreadExecutionState without ES_CONTINUOUS simply resets the idle timer; to keep the display or system in the working state, the thread must call SetThreadExecutionState periodically.

To run properly on a power-managed computer, applications such as fax servers, answering machines, backup agents, and network management applications must use both ES_SYSTEM_REQUIRED and ES_CONTINUOUS when they process events. Multimedia applications, such as video players and presentation applications, must use ES_DISPLAY_REQUIRED when they display video for long periods of time without user input. Applications such as word processors, spreadsheets, browsers, and games do not need to call SetThreadExecutionState.
Автор: Aleksoid1978
Дата сообщения: 26.05.2009 07:41
ShIvADeSt

Спасибо - проверю
Автор: Aleksoid1978
Дата сообщения: 26.05.2009 09:51
ShIvADeSt

Проверил - вызов SetThreadExecutionState не помогает, просто накидал прогу, при создании формы вызываю SetThreadExecutionState, пример взял с MSDN - http://msdn.microsoft.com/en-us/library/aa373208(VS.85).aspx, нифига - всеравно по таймеру включается скринсейвер а далее монитор вырубается(тоже по таймеру). Что-то непонятно.
Хотя по идее, пока программа не вызовет SetThreadExecutionState(ES_CONTINUOUS) не должно.
Автор: ShIvADeSt
Дата сообщения: 26.05.2009 12:56
Aleksoid1978

Цитата:
Проверил - вызов SetThreadExecutionState не помогает, просто накидал прогу, при создании формы вызываю SetThreadExecutionState,

Система у меня ВиндоусХР СП3. Выставил отключение ДИСПЛЕЯ на 1 минуту. Дисплей через минуту отключился.
Склепал программку

Код:
type
EXECUTION_STATE = DWORD;
const
ES_SYSTEM_REQUIRED = $00000001;
ES_DISPLAY_REQUIRED = $00000002;
ES_USER_PRESENT = $00000004;
ES_AWAYMODE_REQUIRED = $00000040;
ES_CONTINUOUS = $80000000;
KernelDLL = 'kernel32.dll';

procedure SetThreadExecutionState(ESFlags: EXECUTION_STATE) ; stdcall; external kernel32 name 'SetThreadExecutionState';

procedure TForm1.Button1Click(Sender: TObject);
begin
SetThreadExecutionState(ES_DISPLAY_REQUIRED or ES_CONTINUOUS);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SetThreadExecutionState(ES_CONTINUOUS);
end;
Автор: RS85
Дата сообщения: 26.05.2009 16:57
Уважаемые спецы, помогите кто сможет.

Пишу я кодировщик Хоффмана. И возникает такая трабла: вот функция, которая записывает в узлы дерева веса встречающихся в файле символов. Суммирует для каждого символа частоты вхождения.
Всё бы хорошо, но только она почему-то работает только для английских букв и цифр. Русские буквы и спец символы не заносит.
Ничего не могу понять. Вроде бы ord даёт коды всех 255 символов ASCII?
Но у меня почему-то веса русских букв остаются нулевыми...

Или я чё-то не то делаю?


Procedure Symbol;
var
a: array [0..511-1] of Object;
num2:Integer;
Strin: AnsiChar;
begin
TFS := TFileStream.Create('C:\ff.txt', fmOpenRead);
while TFS.Position <> TFS.Size do
begin
TFS.Read(Strin, 1);
num2:=ord(Strin);
a[num2].Ves:=a[num2].Ves+1;
end;
TFS.Free;
end;



Добавлено:
Долго не мог понять в чем дело, вываливается Acces Violation и всё.
Потом заметил, что это происходит только если в файле есть русские буквы.

Если файл полностью состоит из английских букв (но без спец символов), то всё жмется замечательно.

Вобщем кодер жмет только "чисто английский текст"
Автор: Aleksoid1978
Дата сообщения: 27.05.2009 00:51
ShIvADeSt

Цитата:
при нажатии на кнопку 1 - монитор не выключался сам 2 минуты. Нажал кнопку 2 - монитор погас через 1 секунду.


Вот в том то и проблема - что мне надо чтобы вов ремя работы программы, не срабатывал таймер бездействия, а как ты сам сказал, после вызова

SetThreadExecutionState(ES_CONTINUOUS);

вырубается моник сразу же, а должен только через минуту, вернее мне надо. Получается эта процедура не дает срабатывать таймеру бездействия, но не обнуляет его.
Автор: ShIvADeSt
Дата сообщения: 27.05.2009 01:02
Aleksoid1978

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

Блин опечатался - через 1 минуту вырубается у меня Не знаю как у тебя, а у меня все отлично отрабатывает. Попробуй написать голую программу. Отключи запуск скринсейвера, настрой только угасание моника через 1 минуту. Запусти прогу. Не нажимай кнопок. По идее через 1 минуту должен погаснуть моник. Нажми кнопку 1. Моник не погаснет никогда. Нажми кнопку 2. Моник должен будет погаснуть через 1 минуту после нажатия. У меня именно так работало. У меня подозрение, что манипуляции МРС с установкой отключения заново активируют данную фичу. Поэтому надо проверять когда он не запущен. В общем отпишись.
Блин данный вопрос надо было в отдельную тему выделить - ибо не типовой
Автор: Aleksoid1978
Дата сообщения: 27.05.2009 01:57
ShIvADeSt

Ага - я проверил, все отлично работает, видимо первый раз в попыхах чето с флагами намутил. ОГРОМНОЕ спасибо за помощь - пошел вносить изменения в MPC-HC и тестить.

З.Ы. - от включения скринсейвера тоже спасает, кстати ...
Автор: V1s1ter
Дата сообщения: 27.05.2009 02:52
RS85
Подсказать трудно. Хотябы не видно как сделано свойство "ves".
Для подобных ситуаций нужен точный код, а не общая идея.
Думаю, что "русские буквы" не причем. Вообще можно смело считать байты, без всяких преобразований типа ord(Strin).
Автор: ShIvADeSt
Дата сообщения: 27.05.2009 03:21
RS85

Цитата:
Долго не мог понять в чем дело, вываливается Acces Violation и всё.
Потом заметил, что это происходит только если в файле есть русские буквы.

вот тестил твой код, немного его поправил - у тебя не было зануление массива в итоге там разный мусор был, прогнал на файле со смешанными русскими и англ буквами (ОЕМ и АНСИ кодировка) - не было ошибок вообще.

Код:
type
_Object=record
ves:word;
end;

Procedure Symbol;
var
a: array [0..511-1] of _Object;
num2:Integer;
Strin: AnsiChar;
TFS :TFileStream;
begin
ZeroMemory(@a,sizeof(a));
TFS := TFileStream.Create('C:\ff.txt', fmOpenRead);
while TFS.Position <> TFS.Size do
begin
TFS.Read(Strin, 1);
num2:=ord(Strin);
a[num2].Ves:=a[num2].Ves+1;
end;
TFS.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Symbol;
end;
Автор: Aleksoid1978
Дата сообщения: 27.05.2009 06:55
ShIvADeSt

Прикол такой - этот метод спокойно работает в ХП СП3, в 7 7127 ... но не пашет в Висте СП2. Почему такое - непонятно.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Глобальные переменные в разных формах с++ builder 'a.


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