KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Валентин Озеров, "Советы по Delphi. Версия 1.4.3 от 1.1.2001" бесплатно, без регистрации.
Перейти на страницу:

   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 

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*