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

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

Автор: psa1974
Дата сообщения: 06.11.2009 14:58
volser
там в примере, приведенном DmitryKz неверно объявлены многие локальные переменные, например htkThread, cbTokenGroups... Тип PTOKEN_GROUPS = TOKEN_GROUPS^; это что это за оно? в Windows.pas есть нормальное объявление этого типа , только называется он PTokenGroups... Ну и дальше по тексту...

Свой вариант, в предыдущем посте я проверил, работает.
Автор: DmitryKz
Дата сообщения: 06.11.2009 15:00
psa1974
Спасибо, будем посмотреть)

volser
Начиная с определения типа:
type
PTOKEN_GROUPS = TOKEN_GROUPS^; здесь говорит, что ожидается ; а стоит ^
затем на недекларированные идентификаторы: SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS
и в этом коде:
while iGroup < ptg^.GroupCount do // check administrator group
begin
if EqualSid(ptg^.Groups[iGroup].Sid, psidAdmin) then
на GroupCount и Groups


Добавлено:
psa1974
Пока писал свой ответ, Вы все разъяснили, спасибо.
Автор: data man
Дата сообщения: 06.11.2009 15:13
psa1974
Может выдаваться неправильный результат из-за маленького размера буфера под группы.
Сначала бы определить размер буфера:

Код: GetTokenInformation(hAccessToken, TokenGroups, nil, 0, dwInfoBufferSize);
GetMem(ptgGroups, dwInfoBufferSize);
Автор: psa1974
Дата сообщения: 06.11.2009 15:23
data man

Цитата:
GetTokenInformation(hAccessToken, TokenGroups, nil, 0, dwInfoBufferSize);

Согласен, в моем примере тупо застолблено под это дело 1 кбайт, так будет правильнее (собственно так и было написано в примереDmitryKz).
Спасибо за уточнение
Автор: DmitryKz
Дата сообщения: 06.11.2009 23:00
Ребята, помогите с такое проблемой:
моя программа использует некий блок данных; первоначально он находится в 7zip архиве, в сжатом виде, со своим расширением, и будет доступен для скачивания из Интернета (сейчас этот блок данных в архиве занимает 17 мб, в разархивированном виде (около 200 файлов - 125 мегабайт, самый большой файл - БД, объемом 101 Мб). Этот архив в то же время своего рода инсталлятор - то есть по двойном клике он устанавливается в программу. А точнее говоря - перегоняется в Single File System без компрессии, но с шифрованием, и служит своего рода контейнером, куда программа обращается за данными. Просто мне так удобнее - это пока еще 200 файлов, а дальше будет больше. Но удручает время перегонки - около 3-х минут.
Вот код:

Код: with CreateInArchive(CLSID_CFormat7z) do
begin
SFS_File:=TSingleFileSystem.Create('c:\sfs.bkp', fmCreate);
OpenFile(fn); //открываем 7-zip архив
for i:=0 to NumberOfItems-1 do
begin
mstr:=TMemoryStream.Create;
SFS_Stream:=TSFSFileStream.Create(SFS_File, ItemPath[i], fmCreate);
ExtractItem(i, mstr, false); //Извлечение файла из 7зип архива в TMemoryStream;
SFS_Stream.LoadFromStream(mstr);
FreeAndNil(mstr);
FreeAndNil(SFS_Stream);
end;
end;
Автор: psa1974
Дата сообщения: 07.11.2009 12:59
DmitryKz

Цитата:
Получается, что TMemoryStream тормозит?

Ниже простой тест потоков. Файл Test0.exe взято на угад и весит 64 514 590 байт. Дык вот время выполнения цикла - 20 сек:

Код:
procedure TForm9.Button1Click(Sender: TObject);
var
mstr: TMemoryStream;
i: Integer;
Dat: TDateTime;
begin
Dat:= Now;
for I := 0 to 199 do
begin
mstr:= TMemoryStream.Create;
mstr.LoadFromFile('t:\TEMP\Test0.exe');
mstr.Free;
end;
Label1.Caption:= TimeToStr(Now - Dat);
end;
Автор: ppkp
Дата сообщения: 07.11.2009 16:09
Подскажите, как из одного модуля(компонент), в котором есть программа с долгим вычислением передать значение для ProgressBar ? Пишу так

unit Calc;
const
WM_MYPROCESS = WM_USER + 100;
...

for I:=0 to 100000000000000000000 do begin
// Здесь пробовал SendMessage и пр.
PostMessage(HWND_BROADCAST, WM_MYPROCESS, WPARAM(I), 0);
(Можно, конечно
MainForm.ProgressBar.Position := I;
но не хотелось бы, чтобы в компоненте была ссылка на Main)
end;

-----------------
unit Main;
procedure CMDProcess(var Message: TMessage); message WM_MYPROCESS;

procedure TMainForm.CMDProcess(var Message: TMessage);
begin
ProgressBar.Position := Message.WParam;
end;

А в CMDProcess не попадает никогда. Почему?
Автор: VitaliM
Дата сообщения: 07.11.2009 16:22
ppkp
Ну поставил ты сообщение в очередь, а надо чтобы кто-то начал быстренько обрабатывать эту очередь. Постаь после PostMessage вызов Application.ProcessMessages и должно заработать.
Автор: ppkp
Дата сообщения: 07.11.2009 17:33
Application.ProcessMessages стоит в главной (вызывающей) программе, а в компоненте-то зачем его ставить ?
ЗЫ Не помогло это. Похоже, в компоненте нужно Handle вызывающей пр-мы вместо HWND_BROADCAST передавать в PostMessage. Но как его узнать?
Автор: VitaliM
Дата сообщения: 07.11.2009 17:51

Цитата:
Application.ProcessMessages стоит в главной (вызывающей) программе

ну пока идет цикл, Application.ProcessMessages не вызывается, значит некому обрабатывать очередь сообщений.
Автор: ppkp
Дата сообщения: 07.11.2009 18:00
Дык, он вызывается перед началом цикла в главной программе !

Application.ProcessMessages;
CallMyComponentProc;//отсюда он попадает в цикл

Почему не попадает в CMDProcess?

Добавлено:
Поставил
SendMessage(MainForm.Handle, WM_PROCESS, WPARAM(row), 0);
и все работает. Как и было. Как же мне не привязываться к Main ?
Автор: Odysseos
Дата сообщения: 07.11.2009 18:40
ppkp

Если это длительное вычисление производится в том же потоке, что и остальная программа - зачем там вообще сообщениями пользоваться? Просто добавить в список параметров CallMyComponentProc ProgressBar: TProgressBar, и передавать туда нужный ProgressBar. Только не забыть раз в сколько-то проходов по циклу вызывать Application.ProcessMessages().
Автор: ppkp
Дата сообщения: 07.11.2009 18:52
Тогда и получается, что не привязанный к форме компонент написать нельзя. Ведь для того, чтобы строка
ProgressBar: TProgressBar
компилировалась, нужно в компоненте писать uses MainUnit. Какая здесь независимость от формы?
Автор: DmitryKz
Дата сообщения: 07.11.2009 18:59
psa1974
Ну вот пошел по пути распаковки 7зип архива в папку и упаковки из папки в SFS - 10 секунд. Дисковые операции, однако
Автор: psa1974
Дата сообщения: 07.11.2009 19:24
ppkp
Насчет компонента. А что мешает воспользоваться стандартной практикой и реализовать в компоненте событие, скажем OnProgress, а в форме, где используешь этот компонент - написать обработчик события? Имхо, зачем придумывать лисапед, когда уже все давно придумано.

Но если все же надо через сообщения...

Цитата:
Application.ProcessMessages стоит в главной (вызывающей) программе, а в компоненте-то зачем его ставить ?

Затем, что в компоненте любые методы в конечном счете отрабатывают, как реакция на то или иное событие. И если на какое-то событие реакция весьма длительна (скажем твой цикл), то само собой, никакие другие сообщения не выбираются из очереди и не обрабатываются, пока не закончится обработка этого текущего сообщения, как следствие, твоя форма физически не получает твоего сообщения, пока не закончится цикл.
Весь смысл метода Application.ProcessMessages - организовать локальный цикл выборки сообщений. Т.е., на пальцах: в текущий момент времени выбрать из очереди сообщений накопившиеся там сообщения и обработать. Всё. Смысл его вызывать перед началом цикла в главной программе??? Когда у тебя работает цикл, то, опять же , на пальцах, пока этот цикл не закончится, никакие сообщения из очереди сообщений не выбираются и не обрабатываются. Application.ProcessMessages надо вызывать не перед и не после, а ИМЕННО В ЦИКЛЕ! Тогда при каждом вызове Application.ProcessMessages выполнение цикла приостановится, сообщения из очереди выберутся и обработаются, после чего цикл продолжится.

DmitryKz
Учитывая что у вас на данный момент 200 файлов общим распакованным размером 125 мб при использовании TMemoryStream обрабатывалось 3 минуты, а в моем тесте 200 файлов по 62 мб, т.е. общим объемом 12305 мб (или 12 гб) обрабатывалось в течение 3-х с половиной минут ...
Автор: ppkp
Дата сообщения: 07.11.2009 20:42
Попробовал через создание обработчика OnBlaBlaBla - заработало. Давно надо было додуматься. Большое спасибо.

А Application.ProcessMessages я все время использовал перед большим циклом и в основной программе - для освобождения мыши и прочих ресурсов - и все нормально. Но тогда мне не нужно было получать значение из цикла. И, насколько я рыл по компонентам, нигде не видел этого вызова. ИМХО. И сейчас я его вызвал не из цикла в компоненте, а в обрабочике из главной программы.

Спасибо большое еще раз.
Автор: DmitryKz
Дата сообщения: 07.11.2009 21:24
psa1974
Да убедили-убедили конечно...
Просто теряюсь в догадках, но тоже склоняюсь к выводу насчет
Цитата:
SFS_Stream.LoadFromStream(mstr), т.е. у SFS_Stream какой-то тормоз включен...

Автор: Frodo_Torbins
Дата сообщения: 07.11.2009 21:42
DmitryKz
Может профилировщиком его?
ppkp
Отличная статья на тему сообщений: http://delphikingdom.com/asp/viewitem.asp?catalogid=169
Автор: TechnoDreamer
Дата сообщения: 08.11.2009 03:29
Такая проблема, есть TTrackBar, максимальное значение на нем большое (тысячи), шаг 1. Значение можно выбрать перетягивая ползунок, но это не совсем удобно для пользователя. Хотелось бы что бы он кликнув куда то сразу поменял позицию на то место (типа как перемотка в медиаплеерах). Можно это как то реализовать используя данный компонент (TProgressBar тоже бы подошел, бегунок не так важен как возможность выбрать позицию одним кликом), или возможно какие то сторонние компоненты...
Автор: psa1974
Дата сообщения: 08.11.2009 10:19
TechnoDreamer
при такомколличестве значений с помощью ползунка точно никогда не угадаешь... Я бы чуть ниже или рядом предусмотрел бы еще окно для ввода пальцами точного значения, например, как в диалоге выбора цвета при нажатой клавише "определить цвет" (когда появляется палитра цветов). Там справа есть вертикальный ползунок, а под ним 6 окон ввода для ввода точного значения. Или как в фотошопе во многих диалогах редактирования, скажем, "яркость/контраст"...
Можно по правой кнопке реализовать контекстное меню с зарезервированными похициями перехода (как в тоталкоммандере при щелчке правой кнопкой на сплиттере между панелями...)
Автор: data man
Дата сообщения: 08.11.2009 10:38
TechnoDreamer
Очень хорошие "ползунки" c редакторами значений, есть в библиотеке Pegtop Common Components http://pegtop.net/delphi/components/common/screenshots.htm
См. самый нижний скриншот. Все с исходниками.
Автор: psa1974
Дата сообщения: 08.11.2009 11:14
data man
Ухты, классные компаноиды! Себе забрал, спасибо
Автор: TechnoDreamer
Дата сообщения: 08.11.2009 13:06
psa1974, так и есть, есть едит с числовым значением и стрелочками вверх\вниз, а подним трэк бар.

data man, спасибо, именно то что нужно.
Автор: data man
Дата сообщения: 08.11.2009 13:19
psa1974
TechnoDreamer
Да не за что.
Там еще есть очень интересный компилятор математических выражений в машинный код. Над ним поработать и PaxCompiler станет не нужен

P.S. А вообще хорошо бы создать отдельный топик по OpenSource компонентам.
С разбивкой по категориям, по поддерживаемым версиям Delphi и т.д.
Как идея, кто поддержит ?
Поддержка заключается не в "Да ! Да !!! Я - за !" Топик нужно будет пополнять.
Автор: V1s1ter
Дата сообщения: 08.11.2009 15:01
data man
Спасибо за ползунки - сидел писал собственные, теперь скачал посмотрел оставил, свои недописанные в мусорку.

Цитата:
P.S. А вообще хорошо бы создать отдельный топик по OpenSource компонентам.

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

Добавлено:
В догонку.
Может стоит сделать некий шаблон, например, как предложил xMesSir для "Анонсы компонент и утилит для Delphi/BCB ", да простит он меня за плагиат.

Предлагаю в шапке написать так:

Правила оформления постов


Анонс компонента или библиотеки постить ТОЛЬКО в указанном виде и ТОЛЬКО о тех компонентах, которые не были анонсированы в данном топе ранее:
1. Название компонента или библиотеки.
2. Основное назначение (буквально до десяти слов).
3. Поддерживаемые версии Delphi/Builder
4. Ссылка на официальный сайт

Дополнительно можно постить свое мнение о компоненте или библиотеке в виде:
1. Название компонента или библиотеки.
2. Пара-тройка слов о том чем понравилась.
3. Пара-тройка слов о том чем НЕ понравилась.
Автор: data man
Дата сообщения: 08.11.2009 16:57
V1s1ter + всем заинтересованным
Пока так:
Нужен ли топик по Open Source-компонентам для Delphi ?
Голосуем, обсуждаем оформление шапки, правила оформления постов и т.п.
Автор: Vinidimka
Дата сообщения: 08.11.2009 17:22
Подскажите, пожалуйста, как можно воспроизвести звук mp3 из файла ресурса при запуске приложения? Интересуют разные способы.
Автор: DmitryKz
Дата сообщения: 08.11.2009 19:05
Ребята, что не так делаю:
разархивирую из архива текстовый файл в TFileStream, затем чтобы загрузить (LoadFromStream) его в TStringList (нужно кое-что найти в нем) - успешно загружается;
разархивирую из архива тот же текстовый файл в TMemoryStream для тех же целей - ничего не получается - в TStringList ничего не загружается (в TMemoryStream файл есть);
Никаких нюансов работы с TMemoryStream в доках не вижу.

Добавлено:
так, нашел - добавил к мемористрим.Seek(0, soFromBeginning);
и все заработало. блин, как очевидно-то))))
Автор: psa1974
Дата сообщения: 08.11.2009 19:35
DmitryKz
хм... а Дельфи какая? Юникодовая или обычная? в 2007-й такой код работает:

Код: procedure TForm9.Button2Click(Sender: TObject);
var
mstr: TMemoryStream;
ts: TStringList;
begin
mstr:= TMemoryStream.Create;
ts:= TStringList.Create;
mstr.LoadFromFile('t:\Temp\manifest.xml');
mstr.Position:= 0;
ts.LoadFromStream(mstr);
ShowMessage(ts.Text);
mstr.Free;
ts.Free;
end;
Автор: ValidolX
Дата сообщения: 08.11.2009 23:12
Ребята, есть вопрос по дебагеру Дельфи Lite (Delphi10_Lite_v4.1_SP2_Integrated.rar)
не работает подсказка дебагера (маленькое желтое окошко, оно же hint-window)
у кого то бывало такоке? мож есть способ починки

дебагать без оного ну совсем не в кайф (можно конечно добавлять в Watch переменные - так работает, но ето не то!!!!!)


ПОж-та напишите у кого такое было, кто как фискал

Или (мучает меня идея ета) дело в том что дельфи - лайт?

Спасибо

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

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


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