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

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

Автор: lorents
Дата сообщения: 08.03.2009 20:40
Frodo_Torbins
спасибо, пойду разбираться

Добавлено:
такой вопрос возник
как можно вызвать вот это вот окно



которое использую почти все программы?
Автор: Frodo_Torbins
Дата сообщения: 08.03.2009 22:38
lorents
Загляните на вкладку Dialogs.
Автор: DmitryKz
Дата сообщения: 09.03.2009 15:29
Подскажите, какой наиболее оптимальный путь хранения настроек программы, если их (опций в форме) много? Вроде как вариант с сохранением всей формы в файл приемлемый, но вот у меня в форме "Опции" есть парочка кнопок, которые вызывают форму настроек параметров прокси и родной Фонтдиалог. Делать два файла настроек, соответствующих каждой форме уже как-то нехочется, да и как хранить результаты выбора пользователем в Фонтдиалоге. В-общем, вопрос, как обычно поступают? Разные места хранения разных настроек - файл, реестр?
Автор: Frodo_Torbins
Дата сообщения: 09.03.2009 19:43
DmitryKz
Мне из джедайского набора очень нравятся компоненты. Кроме того там есть методы для сохранения только published свойств обьектов. Т о можно просто сделать все настройки published полями.
Автор: DmitryKz
Дата сообщения: 09.03.2009 20:42
Frodo_Torbins
Понял, спасибо за подсказку
Автор: V1s1ter
Дата сообщения: 09.03.2009 23:18
DmitryKz
В библиотеке EhLib есть TPropStorageEh.
В библиотеке DevExpress есть TPropertiesStore.
Ну и я когдато на заре писал? удобно, чем, что:
- легко расширяется
- не требует подробных указаний, что именно сохранять.

Код:
unit VIniValue;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
TIniOption = (ioFormCoordinate, ioGridWidth, ioEditValue);
TSetIniOptions = set of TIniOption;

TVIniValue = class(TComponent)
private
FormOnCreate : TNotifyEvent;
FormOnDestroy: TNotifyEvent;
FIniFileName: String;
FAutomatic: Boolean;
FIniOptions: TSetIniOptions;
procedure NewFormOnCreate(Sender : TObject);
procedure NewFormOnDestroy(Sender : TObject);
procedure SetIniFileName(const Value: String);
protected
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
procedure Load;
procedure Save;
published
property Automatic: Boolean read FAutomatic write FAutomatic default True;
property IniFileName: String read FIniFileName write SetIniFileName;
property IniOptions: TSetIniOptions read FIniOptions write FIniOptions;
end;


procedure Register;

implementation

uses
TypInfo, IniFiles, VVCLUtl, VStrUtl;

procedure Register;
begin
RegisterComponents('Victory Common', [TVIniValue]);
end;

{ TVIniValue }

constructor TVIniValue.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAutomatic := True;
end;

procedure TVIniValue.Loaded;
function EqualAddr(Addr1, Addr2: TNotifyEvent): Boolean;
begin
Result := CompareMem(@TMethod(Addr1), @TMethod(Addr2), 8);
end;
begin
inherited Loaded;
if not (csDesigning in ComponentState) then begin
if FIniFileName = '' then FIniFileName := Name;
FIniFileName := ExtractFilePath(ParamStr(0)) + FIniFileName;
if FAutomatic and (Owner is TForm) and not EqualAddr((Owner as TForm).OnCreate, NewFormOnCreate) then begin
FormOnCreate := (Owner as TForm).OnCreate;
(Owner as TForm).OnCreate := NewFormOnCreate;
FormOnDestroy := (Owner as TForm).OnDestroy;
(Owner as TForm).OnDestroy := NewFormOnDestroy;
end;
end;
end;

procedure TVIniValue.NewFormOnCreate(Sender: TObject);
begin
if Assigned(FormOnCreate) then FormOnCreate(Self);
if FAutomatic then Load;
end;

procedure TVIniValue.NewFormOnDestroy(Sender: TObject);
begin
if FAutomatic then Save;
if Assigned(FormOnDestroy) then FormOnDestroy(Self);
end;

procedure TVIniValue.Load;
var
IniFile: TIniFile;
Prop : PPropInfo;
i,j,V: Integer;
s: String;
begin
IniFile := TIniFile.Create(IniFileName);
try
if ioFormCoordinate in IniOptions then begin
V := IniFile.ReadInteger(Owner.Name, 'FormTop', -1);
if V <> -1 then TForm(Owner).Top := V;
V := IniFile.ReadInteger(Owner.Name, 'FormLeft', -1);
if V <> -1 then TForm(Owner).Left := V;
V := IniFile.ReadInteger(Owner.Name, 'FormHeight', -1);
if V <> -1 then TForm(Owner).Height := V;
V := IniFile.ReadInteger(Owner.Name, 'FormWidth', -1);
if V <> -1 then TForm(Owner).Width := V;
V := IniFile.ReadInteger(Owner.Name, 'WindowState', -1);
if (TForm(Owner).FormStyle <> fsMDIChild) and (V <> -1) and TWinControl(Owner).Showing then TForm(Owner).WindowState := TWindowState(V);
end;
for i := 0 to Owner.ComponentCount -1 do begin
if ioEditValue in IniOptions then begin
Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Text');
if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then begin
s := GetStrProp(Owner.Components[i], Prop);
SetStrProp(Owner.Components[i], Prop, IniFile.ReadString(Owner.Name,Owner.Components[i].Name,s));
end;
Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Value');
if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then begin
s := GetStrProp(Owner.Components[i], Prop);
SetStrProp(Owner.Components[i], Prop, IniFile.ReadString(Owner.Name,Owner.Components[i].Name,s));
end;
if (Prop <> nil) and (Prop^.PropType^.Kind = tkInteger) then begin
j := GetOrdProp(Owner.Components[i], Prop);
SetOrdProp(Owner.Components[i], Prop, IniFile.ReadInteger(Owner.Name,Owner.Components[i].Name,j));
end;
Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Checked');
if (Prop <> nil) then begin
j := GetOrdProp(Owner.Components[i], Prop);
SetOrdProp(Owner.Components[i], Prop, Ord(IniFile.ReadBool(Owner.Name,Owner.Components[i].Name,Boolean(j))));
end;
end;
end;
finally
IniFile.Free;
end;
end;

procedure TVIniValue.Save;
var
IniFile: TIniFile;
Prop : PPropInfo;
i: Integer;
WS: TWindowState;
begin
IniFile := TIniFile.Create(IniFileName);
try
if ioFormCoordinate in IniOptions then begin
WS := TForm(Owner).WindowState;
if TForm(Owner).WindowState <> wsNormal then TForm(Owner).WindowState := wsNormal;
IniFile.WriteInteger(Owner.Name, 'FormTop', TForm(Owner).Top);
IniFile.WriteInteger(Owner.Name, 'FormLeft', TForm(Owner).Left);
IniFile.WriteInteger(Owner.Name, 'FormHeight', TForm(Owner).Height);
IniFile.WriteInteger(Owner.Name, 'FormWidth', TForm(Owner).Width);
IniFile.WriteInteger(Owner.Name, 'WindowState', Integer(WS));
TForm(Owner).WindowState := WS;
end;
for i := 0 to Owner.ComponentCount -1 do begin
if ioEditValue in IniOptions then begin
Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Text');
if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then
IniFile.WriteString(Owner.Name,Owner.Components[i].Name,GetStrProp(Owner.Components[i], Prop));

Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Value');
if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then
IniFile.WriteString(Owner.Name,Owner.Components[i].Name,GetStrProp(Owner.Components[i], Prop));
if (Prop <> nil) and (Prop^.PropType^.Kind = tkInteger) then
IniFile.WriteInteger(Owner.Name,Owner.Components[i].Name,GetOrdProp(Owner.Components[i], Prop));

Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Checked');
if (Prop <> nil) then
IniFile.WriteBool(Owner.Name,Owner.Components[i].Name,Boolean(GetOrdProp(Owner.Components[i], Prop)));
end;
end;
finally
IniFile.Free;
end;
end;

procedure TVIniValue.SetIniFileName(const Value: String);
var
S: String;
begin
FIniFileName := Value;
S := Copy(FIniFileName, Length(FIniFileName)-4, 4);
S := AnsiLowerCase(S);
if S <> '.ini' then FIniFileName := FIniFileName+'.ini';
end;

end.
Автор: ShIvADeSt
Дата сообщения: 10.03.2009 02:03
DmitryKz

Цитата:
Делать два файла настроек, соответствующих каждой форме уже как-то нехочется, да и как хранить результаты выбора пользователем в Фонтдиалоге.

А что вызывают какие то трудности сохранить имя шрифта и данные шрифта в инишку? Насчет много опций - посмотрите как хранит Тотал Коммандер свои настройки, там и прокся и прочее и ничего, все нормально хранится
Автор: DmitryKz
Дата сообщения: 10.03.2009 02:42
ShIvADeSt
Ну наверно да, просто программа развивается, какие-то опции будут добавляться или удаляться, значит, надо править код, с риском что что-то пропустится и т.п.
V1s1ter
Очень интересно! Вообще, у меня мелькала мысль написать свой класс для сохранения и загрузки настроек. Хочется избавиться как можно от большего количества телодвижений в будущем, при развитии программы. В-общем, спасибо за пример и идею

Добавлено:

Цитата:
посмотрите как хранит Тотал Коммандер

Посмотрел... У меня сразу после установки там всего лишь 26 строк - это ведь немного...
Автор: Tantos
Дата сообщения: 10.03.2009 03:23
DmitryKz

Цитата:
Посмотрел... У меня сразу после установки там всего лишь 26 строк - это ведь немного...

Могу скинуть мой конфиг - удивитесь. Есть такое понятие - "по умолчанию". Кто мешает использовать имя формы в качестве имени секции, к примеру?
Автор: bigspoon
Дата сообщения: 10.03.2009 07:27
Есть проект на Turbo Delphi 2006 для работы с MySQL.
Подключаюсь с помощью низкоуровневой библиотеки MySQLClasses (Компоненты для работы с MySQL, Автор: Виталий Лещенко, www.vitaliy.org).
Есть ли к кого-то опыт использования этой библиотеки?

Как обойти проблему отсутствия поддержки DataSource?
Все данные приходится вставлять через запросы...
Автор: greenpc
Дата сообщения: 10.03.2009 13:31
V1s1ter

Код: procedure TVIniValue.SetIniFileName(const Value: String);
var
S: String;
begin
FIniFileName := Value;
S := Copy(FIniFileName, Length(FIniFileName)-4, 4);
S := AnsiLowerCase(S);
if S <> '.ini' then FIniFileName := FIniFileName+'.ini';
end;
Автор: Grande
Дата сообщения: 10.03.2009 18:18
Не знает ли кто, уважаемые знатоки, как программно удалить файлы WinVista (или Win7) из-под WinXP?
Поясню подробнее, чего я хочу:
Имеется WinXP и Win7 на одном диске. Потом Win7 сносится, но после нее на диске остаются несколько папок (например, $RECYCLE.BIN), которые удаляться не хотят. При помощи утилиты UnLocker победить этот трабл удается (при этом, правда, UnLocker признается, что заблокировавший хэндл неизвестен). Однако остается вопрос - как узнать, какой хэндл заблокировал эти файлы и, как следствие, как все же удалить файлы?
Спасибо.
P.S. Надеюсь, понятно объяснил .
Автор: Frodo_Torbins
Дата сообщения: 10.03.2009 19:26
Grande
Подозреваю, что их блокирует сама система. А удалить обычным Shift+Del загрузившись с какого-нибуть загрузочного сиди.
Автор: Grande
Дата сообщения: 10.03.2009 19:31
Frodo_Torbins
Из-под WinPE не удается. Только из-под Linux'a PE либо чего-нибудь еще не Microsoft'овского.
То, что их блокирует система, не вызывает сомнений. Тут Вы правы.
Дело даже не в том - как удалить. Необходимо понять принцип их блокировки системой, дабы в будущем не наступать на эти грабли. Ведь это случилось уже на двух осях, что претендует на продолжение
Автор: V1s1ter
Дата сообщения: 10.03.2009 19:49
greenpc
Это смотря для каких целей.
Допустим я хочу чтобы имя файла было n.1, а другого n.2
в моем коде файлы будут названы n.1.ini и n.2.ini,
причем ошибка, если Вы намекаете на то, что строка имени всего 3 символа, не возникнет.
В Вашем коде будет один файл n.ini, но со смешаным содержанием, и возможным нежелательным перезаписыванием значений переменных.
Хотя на тот момент, я мог и не знать о функции ChangeFileExt
Кстати в Вашем коде совсем не обязательно вызывать AnsiLowerCase.
И на последок, я никогда не предентовал на оптимальный, гениальный, лучший и т.п. код.

Автор: fayzullin
Дата сообщения: 10.03.2009 22:09
Grande
Все дело в настройках прав на NTFS-папки. Из-под Windows у меня также не вышло и поэтому воспользовался самым простым решением - Linux. В Linux'е Вы работали из под root, я так понимаю, иначе не получилось бы и в нем. Сам тоже с этим сталкивался 2 дня назад.
Автор: V1s1ter
Дата сообщения: 10.03.2009 22:14
Grande
Информация на правах флуда
Для некоторых папок дастаточно прав администратора, для некоторых требуется права процесса на уровне ядра.
Алгоритм наверное такой, определяем идентификаторы процессов блокирующих доступ, приостанавливаем их, удаляем, возобновляем процесс.
Автор: Grande
Дата сообщения: 11.03.2009 08:43
V1s1ter

Цитата:
определяем идентификаторы процессов блокирующих доступ

Перерыл все процессы, подозрительные выкинул, результат нулевой. Что-то мелкомягкие придумали
Кстати, из-под WinPE тоже не удаляется! Как он (WinPE) догадался, что эти папки необходимо блокировать? Появился какой-то новый атрибут, который я не вижу? И с правами - выше прав, чам под WinPE, уже и быть не может.
А так хочется написать утилитку, дабы в дальнейшем не было подобных проблем.
Как только что получится - обязательно выложу исходники.
Автор: Frodo_Torbins
Дата сообщения: 11.03.2009 19:08
Grande

Цитата:
И с правами - выше прав, чам под WinPE, уже и быть не может.

Я после переустановки винды не мог получить доступ к некоторым старым папкам. Решилось толко установкой своего нового пользователя владельцем этих папок.
Автор: DmitryKz
Дата сообщения: 12.03.2009 04:46
Такой вопрос по локализации приложений: использую DKLang на 2009 Дельфи. Устраивает всем, но... сталкиваюсь с тем, что иногда из-за разной длины русских и английских слов формы приобретают какой-то корявый вид. Не эстетичный, в-общем. Т.е., по идее, надо бы и сами формы и кантролы (их размеры, высоту, ширину) на них подгонять под каждый новый язык. Есть какие-то способы осуществления этого?
Кто-нибудь использовал встроенный в 2009 Дельфи транслятор? Как он?

Еще есть такой вопрос: как определить в 2009 Дельфи, юникодный текстовый файл или анси? Например, в Tnt компонентах была такой метод у TTntStringList - if TntStringList.LastFileCharSet in [csUnicode, csUnicodeSwapped]. Этот метод определял наличие юникода по BOM. Есть ли что-то подобное в 2009-м? Интересуют именно эти два момента: как определить наличие юникода, загрузив текстовый файл в StringList, или не загружая его в компонент.
Автор: Grande
Дата сообщения: 12.03.2009 06:31
Frodo_Torbins
Здесь нечто похожее: под Vista и Win7 все файлы и папки принадлежат скрытому юзеру System из (скрытого, опять же) домена NT Authority (или что-то похожее). TotalCommander довольно легко все эти безобразия чинит. Осталось поставить WinAPI hook и посмотреть, как он это делает. Ессно, о результатах будет доложено .
Автор: Mandor Sawall
Дата сообщения: 12.03.2009 09:25
DmitryKz
Не знаю как там в Delphi2009, но в общем случае определение формата файла невозможно. Есть, например, UTF-файлы без BOM и т.д.
Как вы сам сказали, LastFileCharSet возвращает только есть ли у файла BOM или нет (т.е. какой у него BOM), но никак не определяет формат файла - например UTF-8 без BOM определяет как ANSI.
Автор: Frodo_Torbins
Дата сообщения: 12.03.2009 12:47
DmitryKz

Цитата:
Еще есть такой вопрос: как определить в 2009 Дельфи, юникодный текстовый файл или анси?

В классе TEncoding реализовано определение кодировки по BOM. Если BOM отсутствует, то считается что у файла дефолтная кодировка (можно установить в свойствах проекта).
Автор: alecksey1984
Дата сообщения: 12.03.2009 18:02
как можно втолкать в системный трей картинку определенного размера. насколько я понимаю действовать нужно как и Chameleon Clock.
но как этого добиться, может кто подскажет
Автор: Frodo_Torbins
Дата сообщения: 12.03.2009 19:06
alecksey1984
Придется работать с чужими окнами через WinAPI: http://delphikingdom.com/asp/answer.asp?IDAnswer=32499
Автор: sergiuz1303
Дата сообщения: 13.03.2009 14:07
Всем привет! Нужна помощь при подключение эл. весов DIGI DS-788 к своей программе, кто сталкивался с таким отзовитесь!
Автор: extasy
Дата сообщения: 14.03.2009 09:25
Подскажите пожалуйста компоненты для создания SFTP-клиента. Пробовал IPWorks SSL V8, но его пример SFTP никак не хочет работать (при соединении пишет "Connection refused")
Автор: murkovich
Дата сообщения: 14.03.2009 18:46
DmitryKz

Цитата:
Еще есть такой вопрос: как определить в 2009 Дельфи, юникодный текстовый файл или анси?

Во первых, Тебе надо определиться, какой именно юникод - UTF-8, UCS-2, или еще другой.

Если UTF-8 против конкретного анси, то определить можно с близкой к 100% вероятностью, анализируя символы 128..255, ибо некоторые байты в UTF-8 недопустимы, другие же в свою очередь очень маловероятны в текстовом анси.
Автор: Arch1S
Дата сообщения: 14.03.2009 20:40

Цитата:
Подскажите пожалуйста компоненты для создания SFTP-клиента

знаю только SecureBlackbox 6 VCL
Автор: Aleksoid1978
Дата сообщения: 16.03.2009 10:18
Ребята, помогите с проблемой такой :

Есть проигрыватель Media Player Classic Home Cinema(написан на С++ в Visual Studio), у него есть свой API, общение с ним идет посредством SendMessage с параметром WM_COPYDATA, в свою очередь проигрыватель в ответ шлет тоже SendMessage c WM_COPYDATA.

Все вробе отлично, пример на С++ работает на ура. Сдела тестовую прогу на Delphi - она отсылает сообщения, все нормально. А вот принятие сообщений не работает, вернее сообщения приходят от проигрываетлся в программу только после закрытия самого проигрыватеся.

за принятие сообщений отвечает данная процедура :

private
{ Private declarations }
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;

...

procedure TForm1.WMCopyData(var Msg: TWMCopyData);
begin
ShowMessage('WMCopyData'+#10#13+IntToStr(Msg.CopyDataStruct.dwData)); // Это временно для проверки.
end;


Так вот Сообщение показывается после того как проигрыватель закрыть, причем приходят все кучей.

З.Ы. - все, всем спасибо - разобрался, дело было в самом MPC

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

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


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