From: "Mark Goodrich" <mgood@ns.net>
uses Registry, Windows; var TheReg: TRegistry; KeyName: String; ValueStr: String; begin TheReg := TRegistry.Create; try TheReg.RootKey := HKEY_CURRENT_USER; KeyName := 'Software\MyTinyApp\StartUp; if TheReg.OpenKey(KeyName, False) then begin ValueStr := TheReg.ReadString('WorkPath'); TheReg.CloseKey; end; finally TheReg.Free; end; end;
Also note, the correct place to store the path to your application's EXE under the Win95 registry is in:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\AppPaths\MYAPP.EXE
Store the complete path to your app as the default value under that key.
Regstr.pas defines a constant for this path up through ...\App Paths\ as REGSTR_PATH_APPPATHS.
Storing the path to your application's EXE here will allow a user to simply type MYAPP (or whatever its name is) in Start|Run on the taskbar and your application will launch. Here's an example of how to create it:
uses Registry, Regstr; var TheReg: TRegistry; KeyName: String; begin TheReg := TRegistry.Create; try {Check AppPath setting, update if necessary} TheReg.RootKey := HKEY_LOCAL_MACHINE; KeyName := REGSTR_PATH_APPPATHS + ExtractFileName(Application.ExeName); if TheReg.OpenKey(KeyName, True) then begin if CompareText(TheReg.ReadString(''), Application.ExeName) <> 0 then TheReg.WriteString('', Application.ExeName); TheReg.CloseKey; end; finally TheReg.Free; end; end;
You are right: before an OCX can be used, it must be registered with the System Registry.
Suppose the OCX you want to use is called "test.ocx".
Try this code:
var OCXHand: THandle; RegFunc: TDllRegisterServer; //add OLECtl to the uses clause begin OCXHand:= LoadLibrary('c:\windows\system\test.ocx'); RegFunc:= GetProcAddress(OCXHand, 'DllRegisterServer'); //case sensitive? if RegFunc <> 0 then ShowMessage('Error!'); FreeLibrary(OCXHand); end;
You can the same way unregister the OCX: all you have to do is to replace 'DllRegisterServer' by 'DllUnregisterServer'.
You should add some validation code: "Does the file exist", "Was the call to LoadLibrary successful?", ...
Some explanations:
An OCX is a special form of dll, so you can load it in memory with a call to the LoadLibrary() API function. An OCX exports two functions to register and unregister the control. You then use GetProcAddress to obtain the address of these functions. You just have then to call the appropriate function. And that's it! You can explore the Registry (with regedit.exe) to verify that the OCX is registered.
From: "None of your Business" <someone@someplace.org>
function FindWindowsDir : string; var pWindowsDir : array [0..255] of Char; sWindowsDir : string; begin // GetWindowsDirectory(LPTSTR,UINT); // LPTSTR lpBuffer, // address of buffer for Windows directory // UINT uSize // size of directory buffer GetWindowsDirectory (pWindowsDir, 255); sWindowsDir := StrPas (pWindowsDir); Result := sWindowsDir ; end;
From: rds@melbpc.org.au (Robert Small)
> >HKEYLocal Machine/Software/Microsoft/Windows/CurrentVersion/TimeZones/ > >is the place where Timezone infos are stored in the registry. The >binary 'TZI' entry should be the info for start and end times of >daylight saving times. Anyone has an idea how to extract the dates >from this value? >
The TZI entry seems to be structured as follows:
int32 Bias; // Minutes from GMT // (Sydney -600; 0xfffffda8; // or a8, fd, ff, ff) int32 StandardBias; // Bias for Standard time (0) int32 DaylightBias; // Bias for Daylight time (-60 // or 0xffffffc4 ) int16 ?? // 0 int16 StandardStartMonth; // 3 => March int16 StandardStartDayOfWeek??; // 0 => Sun int16 StandardStartDOWoccurrence; // 1 => 1st int16 StandardStartHour; // 2 => 02:00:00.00 int16 StandardStartMins??; // 0 => 02:00:00.00 int16 StandardStartSecs??; // 0 => 02:00:00.00 int16 StandardStartHunds??; // 0 => 02:00:00.00 int16 ?? // 0 int16 DaylightStartMonth; // 0x0a (10) => October int16 DaylightStartDayOfWeek??; // 0 => Sun int16 DaylightStartDOWoccurrence; // 5 => last int16 DaylightStartHour; // 2 => 02:00:00.00 int16 DaylightStartMins??; // 0 => 02:00:00.00 int16 DaylightStartSecs??; // 0 => 02:00:00.00 int16 DaylightStartHunds??; // 0 => 02:00:00.00
From: Vito Palmisano <vi.palmisano@area.ba.cnr.it>
From "Visual Developer Journal" June/July 1996 page 108, unit IniStr written by Ed Jordan:
unit IniStr; {Written by Ed Jordan} interface uses Classes; type TIniStringlist = class( TStringList ) public procedure LoadFromIni( const FileName, Section: string); procedure SaveToIni( const FileName, Section: string); end; implementation uses IniFiles, SysUtils; procedure TIniStringList.LoadFromIni( const FileName,Section: string); var Index: Integer; Line: string; begin with TIniFile.Create( FileName ) do try ReadSectionValues( Section, Self); for Index:= 0 to Count - 1 do begin { Remove the identifier name ...} Line:= Values[ IntToStr( Index ) ]; { Delete the tilde ... } System.Delete( Line, 1, 1); Strings[ Index ]:= Line; end; finally Free; end; end; procedure TIniStringList.SaveToIni( const FileName, Section: string); var Index: Integer; Line: string; begin with TIniFile.Create( FileName ) do try EraseSection( Section ); for Index:= 0 to Count - 1 do begin { Preserve leading white space, blank lines ...} Line:= '~' + Strings[ Index ]; WriteString( Section, IntToStr( Index ), Line); end; finally Free; end; end; end. Usage: var L: TIniStringList; begin L:= TIniStringList.Create; L.LoadFromIni('MyFile.Ini', 'Alati'); {process L..} L.Free; end.
From: jxidus@aol.com (JXidus)
My solution: (to store the entire font, actually)
function FontToStr(font: TFont): string; procedure yes(var str:string); begin str := str + 'y'; end; procedure no(var str:string); begin str := str + 'n'; end; begin {encode all attributes of a TFont into a string} Result := ''; Result := Result + IntToStr(font.Color) + '|'; Result := Result + IntToStr(font.Height) + '|'; Result := Result + font.Name + '|'; Result := Result + IntToStr(Ord(font.Pitch)) + '|'; Result := Result + IntToStr(font.PixelsPerInch) + '|'; Result := Result + IntToStr(font.size) + '|'; if fsBold in font.style then yes(Result) else no(Result); if fsItalic in font.style then yes(Result) else no(Result); if fsUnderline in font.style then yes(Result) else no(Result); if fsStrikeout in font.style then yes(Result) else no(Result); end; procedure StrToFont(str: string; font: TFont); begin if str = '' then Exit; font.Color := StrToInt(tok('|', str)); font.Height := StrToInt(tok('|', str)); font.Name := tok('|', str); font.Pitch := TFontPitch(StrToInt(tok('|', str))); font.PixelsPerInch := StrToInt(tok('|', str)); font.Size := StrToInt(tok('|', str)); font.Style := []; if str[0] = 'y' then font.Style := font.Style + [fsBold]; if str[1] = 'y' then font.Style := font.Style + [fsItalic]; if str[2] = 'y' then font.Style := font.Style + [fsUnderline]; if str[3] = 'y' then font.Style := font.Style + [fsStrikeout]; end; function tok(sep: string; var s: string): string; function isoneof(c, s: string): Boolean; var iTmp: integer; begin Result := False; for iTmp := 1 to Length(s) do begin if c = Copy(s, iTmp, 1) then begin Result := True; Exit; end; end; end; var c, t: string; begin if s = '' then begin Result := s; Exit; end; c := Copy(s, 1, 1); while isoneof(c, sep) do begin s := Copy(s, 2, Length(s) - 1); c := Copy(s, 1, 1); end; t := ''; while (not isoneof(c, sep)) and (s <> '') do begin t := t + c; s := Copy(s, 2, length(s)-1); c := Copy(s, 1, 1); end; Result := t; end;
Note that you can keep stuff like this really handy by creating your own subclass of the TIniFile class, and adding routines like this.
From: Stefan.Hoffmeister@Uni-Passau.De (Stefan Hoffmeister)
>I will like to know how to find the program (exe) associated with >one file extension from register (not win.ini).
const BufferSize = {$IFDEF Win32} 540 {$ELSE} 80 {$ENDIF}; var Buffer : PChar; StringPosition : PChar; ReturnedData: Longint; begin Buffer := StrAlloc(BufferSize); try { get the first entry, don't bother about the version !} ReturnedData := BufferSize; StrPCopy(Buffer, '.xls'); RegQueryValue(hKey_Classes_Root, Buffer, Buffer, ReturnedData); if StrLen(Buffer) > 0 then begin
does anybody know a way to save a total Font setting of a form/panel/listbox etc. etc. to the registry, it's not so dificult doing it line by line, but with the FontStyle it becomes a lot of lines, so is there and easy/shorter way ?Secrets of Delphi 2 has some code that recursively saves any object's published properties to the registry. The example specifically shows how it works for TFont.
uses TypInfo; { Define a set type for accessing an integer's bits. } const BitsPerByte = 8; type TIntegerSet = set of 0..SizeOf(Integer)*BitsPerByte - 1; { Save a set property as a subkey. Each element of the enumerated type is a separate Boolean value. True means the item is in the set, and False means the item is excluded from the set. This lets the user modify the configuration easily, with REGEDIT. } procedure SaveSetToRegistry(const Name: string; Value: Integer; TypeInfo: PTypeInfo; Reg: TRegistry); var OldKey: string; I: Integer; begin TypeInfo := GetTypeData(TypeInfo)^.CompType; OldKey := '\' + Reg.CurrentPath; if not Reg.OpenKey(Name, True) then raise ERegistryException.CreateFmt('Cannot create key: %s', [Name]); { Loop over all the items in the enumerated type. } with GetTypeData(TypeInfo)^ do for I := MinValue to MaxValue do { Write a Boolean value for each set element. } Reg.WriteBool(GetEnumName(TypeInfo, I), I in TIntegerSet(Value)); { Return to the parent key. } Reg.OpenKey(OldKey, False); end; { Save an object to the registry by saving it as a subkey. } procedure SaveObjToRegistry(const Name: string; Obj: TPersistent; Reg: TRegistry); var OldKey: string; begin OldKey := '\' + Reg.CurrentPath; { Open a subkey for the object. } if not Reg.OpenKey(Name, True) then raise ERegistryException.CreateFmt('Cannot create key: %s', [Name]); { Save the object's properties. } SaveToRegistry(Obj, Reg); { Return to the parent key. } Reg.OpenKey(OldKey, False); end; { Save a method to the registry by saving its name. } procedure SaveMethodToRegistry(const Name: string; const Method: TMethod; Reg: TRegistry); var MethodName: string; begin { If the method pointer is nil, then store an empty string. } if Method.Code = nil then MethodName := '' else { Look up the method name. } MethodName := TObject(Method.Data).MethodName(Method.Code); Reg.WriteString(Name, MethodName); end; { Save a single property to the registry, as a value of the current key. } procedure SavePropToRegistry(Obj: TPersistent; PropInfo: PPropInfo; Reg: TRegistry); begin with PropInfo^ do case PropType^.Kind of tkInteger, tkChar, tkWChar: { Store ordinal properties as integer. } Reg.WriteInteger(Name, GetOrdProp(Obj, PropInfo)); tkEnumeration: { Store enumerated values by name. } Reg.WriteString(Name, GetEnumName(PropType, GetOrdProp(Obj, PropInfo))); tkFloat: { Store floating point values as Doubles. } Reg.WriteFloat(Name, GetFloatProp(Obj, PropInfo)); tkString, tkLString: { Store strings as strings. } Reg.WriteString(Name, GetStrProp(Obj, PropInfo)); tkVariant: { Store variant values as strings. } Reg.WriteString(Name, GetVariantProp(Obj, PropInfo)); tkSet: { Store a set as a subkey. } SaveSetToRegistry(Name, GetOrdProp(Obj, PropInfo), PropType, Reg); tkClass: { Store a class as a subkey, with its properties as values of the subkey. } SaveObjToRegistry(Name, TPersistent(GetOrdProp(Obj, PropInfo)), Reg); tkMethod: { Save a method by name. } SaveMethodToRegistry(Name, GetMethodProp(Obj, PropInfo), Reg); end; end; { Save an object to the registry by storing its published properties. } procedure SaveToRegistry(Obj: TPersistent; Reg: TRegistry); var PropList: PPropList; PropCount: Integer; I: Integer; begin { Get the list of published properties. } PropCount := GetTypeData(Obj.ClassInfo)^.PropCount; GetMem(PropList, PropCount*SizeOf(PPropInfo)); try GetPropInfos(Obj.ClassInfo, PropList); { Store each property as a value of the current key. } for I := 0 to PropCount-1 do SavePropToRegistry(Obj, PropList^[I], Reg); finally FreeMem(PropList, PropCount*SizeOf(PPropInfo)); end; end; { Save the published properties as values of the given key. The key is relative to HKEY_CURRENT_USER. } procedure SaveToKey(Obj: TPersistent; const KeyPath: string); var Reg: TRegistry; begin Reg := TRegistry.Create; try if not Reg.OpenKey(KeyPath, True) then raise ERegistryException.CreateFmt('Cannot create key: %s', [KeyPath]); SaveToRegistry(Obj, Reg); finally Reg.Free; end; end;