Советы по Delphi. Версия 1.4.3 от 1.1.2001 - Валентин Озеров
- Дата:20.06.2024
- Категория: Компьютеры и Интернет / Программирование
- Название: Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Автор: Валентин Озеров
- Просмотров:5
- Комментариев:0
Шрифт:
Интервал:
Закладка:
X := 350;
Y := 250;
end;
end;
end;
end.
TIniFile
Проблемы ini-файла
Кто-нибудь имел какие-нибудь проблемы при использовании модуля TIniFile? Я думаю здесь какая-то детская проблема с кэшированием!!!
Вот что я делал:
(* c:test.ini уже существует *)
myIni := TIniFile.Create('c:test.ini');
With myIni do begin
…. (добавляем новую секцию в test.ini
end;
myIni.Free;
RenameFile('c:test.ini', 'c:test1.ini');
Что я получил:
1. test1.ini НЕ ИМЕЕТ добавленной мною секции;
2. всякий раз при создании или открытии нового файла в том же самом каталоге с помощью File Manager, 'c:test.ini' появляется вновь, и у него СУЩЕСТВУЕТ секция, которую я добавлял.
Я решил эту проблему добавлением следующей строки перед IniFile.Free:
WritePrivateProfileString(nil, nil, nil, PChar(IniFileName));
Для получения дополнительной информации обратитесь к электронной справке к разделу 'WritePrivateProfileString'.
– Tony Chang
Как создать Ini-файл в директории программы?
По умолчанию ini-файл создается в Windows-директории (например: TIniFile.Create('MFile.ini')), что приводит к «захламлению» оной. Более (эко-)логично (за исключением случаев, когда программа делается для CD-ROM) если ini-файл создается в той же директории что и главная программа. Вот пример чтения и записи ini файла из директории программы:
function ReadIni(ASection, AString : String) : String;
var
sIniFile: TIniFile;
sPath : String[60];
begin
GetDir(0,sPath);
sIniFile := TIniFile.Create(sPath + 'Name.INI');
Result := sIniFile.ReadString(ASection, AString, S);
sIniFile.Free;
end;
procedure WriteIni(ASection, AString, AValue: String);
var
sIniFile: TIniFile;
sPath : String[60];
begin
GetDir(0,sPath);
sIniFile := TIniFile.Create(sPath + 'Name.INI');
sIniFile.WriteString(ASection, AString, AValue);
sIniFile.Free;
end;
TRegistry
Дополненный TRegistry, умеет работать с значениями типа REG_MULTI_SZ (Windows NT, Windows 2000)
Кондратюк Виталий советует:
unit Reg;
{$R-,T-,H+,X+}
interface
uses Registry, Classes, Windows, Consts, SysUtils;
type TReg = class(TRegistry)
public
procedure ReadStringList(const name : string; list : TStringList);
procedure WriteStringList(const name : string; list : TStringList);
end;
implementation
//*** TReg *********************************************************************
//------------------------------------------------------------------------------
// Запись TStringList ввиде значения типа REG_MULTI_SZ в реестр
//------------------------------------------------------------------------------
procedure TReg.WriteStringList(const name : string; list : TStringList);
var
Buffer : Pointer;
BufSize : DWORD;
i, j, k : Integer;
s : string;
p : PChar;
begin
{подготовим буфер к записи}
BufSize := 0;
for i:=0 to list.Count-1 do inc(BufSize, Length(list[i])+1);
inc(BufSize);
GetMem(Buffer, BufSize);
k := 0;
p := Buffer;
for i:=0 to list.Count-1 do begin
s := list[i];
for j:=0 to Length(s)-1 do begin
p[k] := s[j+1];
inc(k);
end;
p[k] := chr(0);
inc(k);
end;
p[k] := chr(0);
{запись в реестр}
if RegSetValueEx(CurrentKey, PChar(name), 0, REG_MULTI_SZ, Buffer, BufSize) <> ERROR_SUCCESS then raise ERegistryException.CreateResFmt(@SRegSetDataFailed, [name]);
end;
//------------------------------------------------------------------------------
// Чтение TStringList ввиде значения типа REG_MULTI_SZ из реестра
//------------------------------------------------------------------------------
procedure TReg.ReadStringList(const name : string; list : TStringList);
var
BufSize,DataType: DWORD;
Len, i: Integer;
Buffer: PChar;
s: string;
begin
if list = nil then Exit;
{чтение из реестра}
Len := GetDataSize(Name);
if Len < 1 then Exit;
Buffer := AllocMem(Len);
if Buffer = nil then Exit;
try
DataType := REG_NONE;
BufSize := Len;
if RegQueryValueEx(CurrentKey, PChar(name), nil, @DataType, PByte(Buffer), @BufSize) <> ERROR_SUCCESS then raise ERegistryException.CreateResFmt(@SRegGetDataFailed, [name]);
if DataType <> REG_MULTI_SZ then raise ERegistryException.CreateResFmt(@SInvalidRegType, [name]);
{запись в TStringList}
list.Clear;s := '';
for i:=0 to BufSize-2 do begin
// BufSize-2 т.к. последние два нулевых символа
if Buffer[i] = chr(0) then begin
list.Add(s);
s := '';
end else s := s + Buffer[i];
end;
finally
FreeMem(Buffer);
end;
end;
end.
Как я могу определить доступные сервера приложений на этой машине через Registry?
Nomadic советует:
Прочитайте ключ под HKEY_CLASSES_ROOTCLSID*, просматривая его насчёт ключей, которые имеют подключ "Borland DataBroker". Эти вхождения и являются серверами приложений.
Ниже пример, который загружает имена доступных серверов приложений в Listbox:
uses Registry;
procedure TForm1.FormCreate(Sender: TObject);
var
I: integer;
TempList: TStringList;
begin
TempList := TStringList.Create;
try
with TRegistry.Create do try
RootKey := HKEY_CLASSES_ROOT;
if OpenKey('CLSID', False) then GetKeyNames(TempList);
CloseKey;
for I := 1 to TempList.Count - 1 do
if KeyExists('CLSID' + TempList[I] + 'Borland DataBroker') then begin
if OpenKey('CLSID' + TempList[I] + 'ProgID', False) then begin
Listbox1.Items.Add(ReadString(''));
CloseKey;
end;
end;
finally
Free;
end;
finally
TempList.Free;
end;
end;
OLE+
ActiveX
Ошибка 'EOLESYS..OPERATION UNAVAILABLE' (операция недоступна) при использовании GETACTIVEOLEOBJECT
Delphi 3
Это происходит при использовании сервера автоматизации Delphi, или когда сервер автоматизации (например, word.basic) не запущен.
procedure TForm1.Button1Click(Sender: TObject);
var V: OleVariant;
begin
V := GetActiveOleObject('Word.Basic');
V.FileNew;
V.Insert('тест');
end;
GetActiveOleObject определен в ComObj.pas. Он преобразует имя класса в guid и передает его при вызове Windows api функции GetActiveObject.
function GetActiveOleObject(const ClassName: string): IDispatch;
var
ClassID: TCLSID;
Unknown: IUnknown;
begin
ClassID := ProgIDToClassID(ClassName);
OleCheck(GetActiveObject(ClassID, nil, Unknown));
OleCheck(Unknown.QueryInterface(IDispatch, Result));
end;
GetActiveOleObject использует интерфейс с именем IRunningObjectTable. Мы не регистрируем это автоматически в таблице, поэтому, чтобы воспользоваться его функциональным назначением, вы должны получить этот интерфейс и использовать его методы для регистрации.
Ошибка 'TACTIVEFORMX DECLARATION MISSING OR INCORRECT' (определение TACTIVEFORMX отсутствует или неправильно)
Delphi 3
Обычно это происходит при неправильном порядке изменения имени ActiveForm (смотри README.TXT). Если сначала изменяется имя CoClass, а затем делается обновление (refresh), возникает AV. При дальнейшей попытке изменить имя в Инспекторе Объектов вы получите ошибку «TActiveFormX declaration missing or incorrect» (определение TActiveFormX отсутствует или неправильно). Для решения проблемы откройте .DFM-файл и измените строчку:
object ActiveFormX: TActiveFormX
на
object MyForm: TMyForm
- Основы объектно-ориентированного программирования - Бертран Мейер - Прочая околокомпьтерная литература
- HR-брендинг. Как стать лучшим работодателем в России - Нина Осовицкая - Маркетинг, PR, реклама
- Аквариум. (Новое издание, исправленное и переработанное) - Виктор Суворов (Резун) - Шпионский детектив
- Как учить чужой язык? - Антон Хрипко - Справочники
- Концептуальное проектирование сложных решений - Андрей Теслинов - Психология, личное