Delphi RSS Resources, Delphi Components, Delphi Sites, Articles, Dynamic XML Feeds, Tutorials, Sources
 
 
 
Google
 
Web delphirss.com
| Server-Scripts.com | Informations for JAVA | Informations for PHP | SEO Web Links | Borland Delphi
 

Windows

Detecting Win95 Vs W3.X
Getting large text from TClipboard
Long file names from Win95 DirListbox
Application.Title font color
Application to tile on windows desktop
Change wallpaper bitmap
Obtaining Windows Version
Creating and selecting palettes
Loading a listbox with program groups
System colors
Under Win95?
Knowing that Windows is exiting
Screen Saver Register
Hiding apps from taskbar
Reading from Registry
User Name in Windows95 with Delphi 2.0
How to Draw Template Thumbnails
List of opened applications and files
Screen Resolution
Registry and TStrings
Get Windows directory


Detecting Win95 Vs W3.X

Question

Does anyone know a quick way of detecting whether or not an application si
running on win 95 or Win3.x?

Answer

A:
I don't have Win 95 so I can't say what it will return, but the Windows API
function GetVersion returns the Windows (and DOS) version number (it's in
Delphi help). I'm running Windows for Workgroups under DOS 6.22, and this is
what I get back (Windows 3.1 gives me the same thing, I don't know how to
distinguish between 3.1 and 3.11):

var
   x: longint;
begin
   x := GetVersion;
   integer(x shr 24) --> gives me 6, the DOS major version
   integer((x shr 16) and $ff) --> gives me 22, the DOS minor version
   integer((x shr 8) and $ff)  --> gives me 10, the Windows minor version
   integer(x and $ff) --> gives me 3, the Windows major version

A:
Here's a unit I whipped together the other day in an attempt to do this. It
just checks the WINVER.EXE file for the version of the product it is shipped
with. If there's an "official" way to detect Win 3.x/95, I'd like to know.

unit Testvsn;

interface

uses
  SysUtils, WinTypes, WinProcs, VER;

procedure DoIt;

implementation

procedure DoIt;
var
  VIHandle : LongInt;
  VSize : LongInt;
  VData : Pointer;
  VVers : Pointer;
  Len : Word;
  OutStr : String;

begin
  VSize := GetFileVersionInfoSize('WINVER.EXE', VIHandle);
  If VIHandle = 0
    Then OutStr := 'Windows Version : Unknown L1'
    Else
      Begin
        GetMem(VData, VSize);
        Try
          If not GetFileVersionInfo('WINVER.EXE', VIHandle, VSize, VData)
            Then OutStr := 'Windows Version : Unknown L2'
            Else
              If not VerQueryValue(VData,'\',VVers,Len)
                Then OutStr := 'Windows Version : Unknown L3'
                Else
                  With TVS_FIXEDFILEINFO(VVers^) do
                    OutStr := 'Windows Version : ' +
                      IntToStr((dwProductVersionMS and $FFFF0000) shr 16) +
                      '.' +
                      IntToStr(dwProductVersionMS and $0000FFFF);
        Finally
          FreeMem(VData, VSize);
        End;
      End;
    OutStr := OutStr + chr(0);
    MessageBox(0,@OutStr[1],'Windows Version Test',MB_OK or MB_ICONINFORMATION);
end;

begin
  DoIt;
end.

A:
Uses the GetVersion API to determin the version of windows.

TYPE ver = RECORD
             wmaj : byte;
             wmin : byte;
             dmin : byte;
             dmaj : byte;
           END;
VAR Version : ver;

BEGIN
  Version:=getversion;
  {for windows 95 Version.wmaj = 3
                         Version.wmin = 95;}


Getting large text from TClipboard

Question

How get a large text from TClipboard?

Answer

A:
var
  Buffer: PChar;
  MyHandle : THandle;
 TextLength : Integer;
begin
MyHandle := Clipboard.GetAsHandle(CF_TEXT);
Buffer := GlobalLock(MyHandle);
If Buffer = Nil then
 begin
  GlobalUnlock(MyHandle);
  exit;
 end;

TextLength := StrLen(buffer);  {since buffer is of type PChar,
   all the functions applicable to PChar can be applied}

Long file names from Win95 DirListbox

Question

How do I get the long path string from a TDirectoryListbox in Win95 instead
of the 'hybrid' string that includes a tilde (~) character and a number?

Answer

A:
Delphi 16 in principle doesn't deal with longfilenames. But you can do it
yourself.
If you are familiar with assembly language get the M$ book "Programmer's
Guide to Microsoft Windows 95". Look in page 520 for the new DOS function
Find First File (with long filenames). It returns a  WIN32_Find_Data record with
the long and short filenames.
From what I see you can pass either one and you get back both. You have to
code it as a simple
assembler routine into your code.

It's too much to give you an example here, but if you get the book you should be
on your way. Please keep in mind that you send and receive ASCIIZ strings,
not pascal strings.

Application.Title font color

Question

Is there a way to change the color of the application's title font?

Answer

A:
You can change all windows title font colors, but not your windows title font
color. This is a windows limitation.

It is possible to create a hot spot caption and add a label to it.
If you would like to create a custom captionless and borderless form that is
movable and resizable at runtime.

Application to tile on windows desktop

Question

How can I get my Application to tile with the other windows app's currently on
the Windows Desktop? (ie using the Tile button of Task Manager).  Delphi apps
don't behave the way they should).

Answer

A:
type
  TForm1 = class(TForm)
{ ..... }
     procedure AppOnMessage(var Msg: TMsg; var Handled: Boolean);
     procedure FormCreate(Sender: TObject);
  private
	 { Private declarations }
  public
	 { Public declarations }
  end;

var
  Form1: TForm1;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
	Application.OnMessage := AppOnMessage;
	ShowWindow(Handle, CmdShow);
end;

procedure TForm1.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
var
     WindowPosp	: ^TWindowPos;
begin
     with Msg do
          if Message = WM_WINDOWPOSCHANGED then begin
		WindowPosP := pointer(lparam);
		with WindowPosP^ do begin
                    left := X;
                    Top := Y;
                    width := cx;
                    Height := cy;
                    end;
		end;
     end; { AppOnMessage }
end.

I tried it with Tile and Cascade in my Window 95 setup and it works great.

By the way the ShowWindow call that you mention is not to fix a bug. Delphi,
like Visual Basic has an invisible application form, distinct from the
main form.

Change wallpaper bitmap

Question

I want to change wallpaper (win95 desktop) bitmaps run-time.
How can i do it?

Answer

A:
The same way as in Win31 - using the SystemParametersInfo API call.

SystemParametersInfo(SPI_SETDESKWALLPAPER,0,pBitMap,SPIF_UPDATEINIFILE +
                        SPIF_SENDWININICHANGE);

This I do in one of my apps, and the app has quite successfully run
under Win31 and Win95

Obtaining Windows Version

Question

Does anyone have any code handy for determining the version
of Windows?   I'm pretty sure it's got something to do with
the GetVersion API,  but I can't seem to figure out the
bitwise operations in Delphi to determine it in a LongInt!

Answer

A:
Here's a short program that demonstrates GetVersion.

 program Winvrsn;

 uses
   WinTypes,
   WinProcs,
   SysUtils;

 var
   WinVersion : Word;
   DosVersion : Word;
   VersionString : String;

 begin
   WinVersion := GetVersion and $0000FFFF;
   DosVersion := (GetVersion and $FFFF0000) shr 16;
   VersionString := 'DOS : ' + IntToStr(Hi(DOSVersion)) + '.' + IntToStr(Lo(DOSVersion)) + #13 +
                    'Windows : '+ IntToStr(Lo(WinVersion)) + '.' + IntToStr(Hi(WinVersion)) + #0;
   MessageBox(0, @VersionString[1],'Version Information', MB_ICONINFORMATION or MB_OK)
 end.

A:
I don't know for certain what result to expect since WfW is not on my machine
anymore, but how about giving this snippet a try and let me know what
happens? It "cheats" by getting the version info from WINVER.EXE. For
Windows 95 it reads "4.00", for Windows 3.1 it says "3.10".

var
  VIHandle : LongInt;
  VSize : LongInt;
  VData : Pointer;
  VVers : Pointer;
  Len : Word;
  OutStr : String;

begin
  VSize := GetFileVersionInfoSize('WINVER.EXE', VIHandle);
  If VIHandle = 0
    Then OutStr := 'Windows Version : Unknown L1'
    Else
      Begin
        GetMem(VData, VSize);
        Try
          If not GetFileVersionInfo('WINVER.EXE', VIHandle, VSize, VData)
            Then OutStr := 'Windows Version : Unknown L2'
            Else
              If not VerQueryValue(VData,'\',VVers,Len)
                Then OutStr := 'Windows Version : Unknown L3'
                Else
                  With TVS_FIXEDFILEINFO(VVers^) do
                    OutStr := 'Windows Version : ' +
                      IntToStr((dwProductVersionMS and $FFFF0000) shr 16) +
                      '.' +
                      IntToStr(dwProductVersionMS and $0000FFFF) + #0;
        Finally
          FreeMem(VData, VSize);
        End;
      End;
    MessageBox(0,@OutStr[1],'Windows Version Test',MB_OK or MB_ICONINFORMATION);
end;

Creating and selecting palettes

Question

How do you create and use a Palette in Delphi. According to the help fn I
think you should use the CreatePalette and SetPaletteEntries and RealizePalette
but how?

Answer

A:
Below are functions that help to create a palette (an identity
palette, BTW) from an array of RGBQuads (such as you would find in 
the palette section of a .BMP file). I stole this from the WinG 
documentation, and converted it to Delphi. First call 
ClearSystemPalette, then you can get an identity palette by calling 
CreateIdentityPalette.

 If you plan to try palette animation, work in a 256-color mode, and 
change all the PC_NOCOLLAPSE entries below to PC_RESERVED.

Besides creating the palette, the other pieces to the puzzle are 

1. Override the form's GetPalette method, so that it returns the 
new palette.

2. Select and realize the new palette just before you paint.

  OldPal := SelectPalette(Canvas.Handle, NewPalette, False);
  RealizePalette(Canvas.Handle);  
  { Do your painting here }
  SelectPalette(Canvas.Handle, OldPal, False);

3. Remember to release the palette when you are done using 
DeleteObject

4. If you are used to using the RGB function to get color values, use 
the PaletteRGB function in its place.

function CreateIdentityPalette(const aRGB; nColors : Integer) : HPALETTE;
type
  QA = Array[0..255] of TRGBQUAD;
var
  Palette : PLOGPALETTE;
  PalSize : Word;
  ScreenDC : HDC;
  I : Integer;
  nStaticColors : Integer;
  nUsableColors : Integer;
begin
  PalSize := SizeOf(TLOGPALETTE) + SizeOf(TPALETTEENTRY) * 256;
  GetMem(Palette, PalSize);
  try
    with Palette^ do
      begin
        palVersion := $0300;
        palNumEntries := 256;
        ScreenDC := GetDC(0);
        try
          { For SYSPAL_NOSTATIC, just copy the color table into a PALETTEENTRY
            array and replace the first and last entries with black and white }
          if (GetSystemPaletteUse(ScreenDC) = SYSPAL_NOSTATIC)
            then
              begin
	        { Fill in the palette with the given values, marking each
                  with PalFlag }
                {$R-}
                for i := 0 to (nColors-1) do
                with palPalEntry[i], QA(aRGB)[I] do
                  begin
                    peRed := rgbRed;
                    peGreen := rgbGreen;
                    peBlue := rgbBlue;
                    peFlags := PC_NOCOLLAPSE;
                  end;

                { Mark any unused entries with PalFlag }
                for i := nColors to 255 do
                  palPalEntry[i].peFlags := PC_NOCOLLAPSE;

                { Make sure the last entry is white --
                  This may replace an entry in the array!}
                I := 255;
                with palPalEntry[i] do
                  begin
                    peRed := 255;
                    peGreen := 255;
                    peBlue := 255;
                    peFlags := 0;
                  end;

                { And the first is black --
                  This may replace an entry in the array!}
                with palPalEntry[0] do
                  begin
                    peRed := 0;
                    peGreen := 0;
                    peBlue := 0;
                    peFlags := 0;
                  end;
                {$R+}
              end
            else
              begin
	        { For SYSPAL_STATIC, get the twenty static colors into the
                  array, then fill in the empty spaces with the given color
                  table }

                { Get the static colors from the system palette }
                nStaticColors := GetDeviceCaps(ScreenDC, NUMRESERVED);
                GetSystemPaletteEntries(ScreenDC, 0, 256, palPalEntry);

                {$R-}
                { Set the peFlags of the lower static colors to zero }
                nStaticColors := nStaticColors shr 1;
                for i:= 0 to (nStaticColors-1) do
                  palPalEntry[i].peFlags := 0;

                { Fill in the entries from the given color table}
                nUsableColors := nColors - nStaticColors;
                for I := nStaticColors to (nUsableColors-1) do
                  with palPalEntry[i], QA(aRGB)[i] do
                    begin
                      peRed := rgbRed;
                      peGreen := rgbGreen;
                      peBlue := rgbBlue;
                      peFlags := PC_NOCOLLAPSE;
                    end;

                { Mark any empty entries as PC_NOCOLLAPSE }
                for i := nUsableColors to (255-nStaticColors) do
                  palPalEntry[i].peFlags := PC_NOCOLLAPSE;

                { Set the peFlags of the upper static colors to zero }
                for i := (256 - nStaticColors) to 255 do
                  palPalEntry[i].peFlags := 0;
              end;
        finally
          ReleaseDC(0, ScreenDC);
        end;
      end;
    { Return the palette }
    Result := CreatePalette(Palette^);
  finally
    FreeMem(Palette, PalSize);
  end;
end;


procedure ClearSystemPalette;
var
  Palette : PLOGPALETTE;
  PalSize : Word;
  ScreenDC : HDC;
  I : Word;
const
  ScreenPal : HPALETTE = 0;
begin
  PalSize := SizeOf(TLOGPALETTE) + SizeOf(TPALETTEENTRY) * 255; {256th = [0] }
  GetMem(Palette, PalSize);
  try
    FillChar(Palette^, PalSize, 0);
    Palette^.palVersion := $0300;
    Palette^.palNumEntries := 256;
{$R-}
    For I := 0 to 255 do
      With Palette^.palPalEntry[I] do
        peFlags := PC_NOCOLLAPSE;
{$R+}
    { Create, select, realize, deselect, and delete the palette }
    ScreenDC := GetDC(0);
    try
      ScreenPal := CreatePalette(Palette^);
      if ScreenPal <> 0
        then
          begin
            ScreenPal := SelectPalette(ScreenDC,ScreenPal,FALSE);
            RealizePalette(ScreenDC);
            ScreenPal := SelectPalette(ScreenDC,ScreenPal,FALSE);
            DeleteObject(ScreenPal);
          end;
    finally
      ReleaseDC(0, ScreenDC);
    end;
  finally
    FreeMem(Palette, PalSize);
  end;
end;

Loading a listbox with program groups

Question

So my question is,  how can I load a list box with all existing
program groups on a system?

Answer

A:
I am not sure if this approach will be helpful if the application
that ran before yours added any  groups.  i.e. whether groups get 
written to disk immediately, or only on exit from Windows....  You 
can try it out... if it works, great.... if not, and if you would 
like some programmatic control, here is some code that I pulled out 
of one of my programs...

------code---------
Procedure TProgMan.ReadGroups;
Var
  GroupData : PChar;
  TmpStr : String;
  i : integer;
begin
 GroupData := FDDEClient.RequestData('Groups');
 FGroupsList.Clear;
 FNumGroups := 0;  {assume there are no groups! }
 if GroupData = nil then
   exit
 else
   begin
     i := 0;
     TmpStr := '';
     While GroupData[i] <> #0 do
       begin
         if GroupData[i] = #13 then
           begin
             FGroupsList.Add(TmpStr);
             TmpStr := '';
             i := i + 1;  {skip the #10 char}
           end
         else
           TmpStr := TmpStr + GroupData[i];
           i := i + 1;
       end;
   end;
 StrDispose(GroupData);
end;
------------code ends-----------------

Here, FGroupsList is of type TStringlist.... therefore, you may
substitute it with Listbox.Items as easily.

A:
....
var
  Groups: PChar;
begin
   if not DDEClient.SetLink('ProgMan','PROGMAN') then
      MessageDlg('Link with ProgMan NOT established.', mtInformation, [mbOK], 0);

      DDEClient.OpenLink;

      Groups:=DDEClient.RequestData('GROUPS');

      ComboBox1.Items.SetText(Groups);

      strDispose(groups);
      DDEClient.CloseLink;


end;
.....

this code will get existing progMan groups names. and put it into a comboBox ( to let the
user select...)
Note, you don't have to allocate memory for the Groups variable, the API function
RequestData is doing this. but you have to dispose of it when through.

Of course you have to put a DDEClient component on your form.

System colors

Question

I need to emulate the color selection options of control panel... I looked
up the setsyscolor procedure, but though it seems to cause a global repaint,
it seems to have no effect... is it no longer supported? should I instead
change the win.ini (or is it system.ini - sorry - can't remember right now.)
If I change these values will programs update - or do they have to be
notified in some way?

Answer

A:
procedure TMainForm.Button4Click(Sender: TObject);
var
nColorIndex: array [1..2] of integer;
nColorValue: array [1..2] of longint;
begin
    nColorIndex[1]:=COLOR_ACTIVECAPTION;
    nColorIndex[2]:=COLOR_BTNFACE;
    nColorValue[1]:=clBlue;
    nColorValue[2]:=clRed;
    SetSysColors(2,nColorIndex,nColorValue);
    PostMessage(HWND_BROADCAST,WM_SYSCOLORCHANGE,0,0);
end;

Under Win95?

Question

How do I know if I am under Windows95?

Answer

A:
Try the windows function "getversion". Here is an example:

     versNr := LoWord(GetVersion);           {Windows-Versionsnr}
     str(lobyte(versNr),Version);
     str(hibyte(versNr), Dummy);
     if (version = '3') and (dummy = '10') then
       version := '3.10/3.11'
     else
    	 version := version + '.' +Dummy;

If Win95 is installed dummy returns 95. Version returns 3.


A:
Use the getVersion API call as follows:

   vers: longint;

   vers := GetVersion;

   {if you're certain you're running Windows 3.xx or 95, then use this:}
   if ((vers shr 8) and $ff) = 95 then
       Win 95
   else
       Win 3.xx;

   {if you could be running Windows 2.xx or 1.xx, then use this first:}
   if ((vers and $ff) = 3) then
       Win 3.xx or Win 95
   else
       Win 2.xx or Win 1.xx;

You might want to use ">=" instead of "=" to cover Win 96, etc.

Knowing that Windows is exiting

Question

I have been looking for a way to know how to differentiate between my app
closing on the users request and when Windows is closing my app because of
Windows shutting down.
Is there an easy way out, or do I have to write an event handler for the
TApplication object to look at the messages from Windows ?

Answer

A:
Windows sends a message (WM_QUERYENDSESSION) to every active
application when the user tries to shut down Windows.  If your 
program responds with a non-zero value, then Windows will close it.  
If you program returns a 0, that tells Windows not to shut down.  The 
DefWindowProc returns a non-zero value for you.  You can write a 
message handler for this message for this message that will keep 
Windows from shutting down if your program is active.

Screen Saver Register

Question

How do I register my Screen saver so Windows picks it up in the control
panel Desktop Dialog. The Application Name begins with SCRNSAVE and it
still does not register.

Answer

A:
a) In the project file (*.dpr) add '{$D SCRNSAVE } after the
uses clause.

b) On the main form, turn off the border and icon controls. In the 
activate method set the form left and top to 0, and set the Windowstate 
to wsMaximize.

c) In the form create method, set the application.OnMessage to a method 
that controls the deactivation of the screen saver. Set the 
application.OnIdle method to whatever display method for the saver.

d) In the form create method the command line should be tested for /c and 
/s. These are the command line parameters windows uses to define whether 
the screensaver should run or configure. (/c is for configuration)

e) Compile the program, and rename the .exe to .scr. Move it to the 
windows directory, and it should show up in the control panel.

Hiding apps from taskbar

Question

Anyone can tell me how to remove an Application Icon & Title from the taskbar?

Answer

ShowWindow(Application.Handle, SW_HIDE);

Reading from Registry

Question

I have some problems with reading from registry.
Does any one have a clue about solving this problem?
I get Acces Violation with the following code:

 Var
    Registry: TRegistry;
    Listan:TStrings;
 begin
      Listan.create;
      Registry := TRegistry.Create;
      try
         Registry.RootKey := HKey_Classes_Root;
         Registry.GetKeynames(Listan);
         ComboBox1.Items.AddStrings(Listan);
      finally
          Registry.Free;
      end;
 end;

Answer

Try the following. Important is the OPENKEY!

procedure TForm1.FormCreate(Sender: TObject);
Var
   Registry: TRegistry;
   Listan:TStringList;                                  // **************
begin
     Listan := TStringList.create;                      // **************
     Registry := TRegistry.Create;
     try
        Registry.RootKey := HKey_Classes_Root;
        Registry.OpenKey('',False);                     // **************
        Registry.GetKeynames(Listan);
        ComboBox1.Items := Listan;                      // **************
     finally
         Registry.Free;
     end;
end;

User Name in Windows95 with Delphi 2.0

Question

I am trying to get the username of the active user in a Windows 95, using
Delphi 2.0.

Answer

function GetUserName : string;
var
	sNetUserName	: DbiUserName;
begin

	{ Get the user name. }
	if DbiGetNetUserName(sNetUserName) = DBIERR_NONE then
		Result := StrPas(sNetUserName)
	else
		Result := '';

end;

How to Draw Template Thumbnails

Question

I'm trying to find out how to draw a thumbnail representation of a
word processing template (for example, a WordPerfect .WPT or a
Microsoft Word .DOT) on a form.  When I select an item from a
listbox, I want a thumnail of the corresponding file to be displayed on the
form.

Answer

If you mean associated icon, then you can use this:
IconIndex := 0;
Image1.Picture.Icon.Handle := ExtractAssociatedIcon( hInstance, PChar(
'c:\FileName.doc' ), IconIndex );

List of opened applications and files

Question

How to get a list of registered files and their extensions?

Answer

To get a list of the applications and their extensions for opening up
files in Windows95 do the following:

1. Open new application
2. Put a Memo component on the form, about 3 inches wide or so
3. Clear out the memo1 lines

4. Add a FormShow event and put in the following code:

procedure TForm1.FormShow(Sender: TObject);
var K: TRegIniFile;
    i: Integer;
    Extensions: TStringList;
begin
  K := TRegIniFile.Create('');
  K.RootKey := HKEY_LOCAL_MACHINE;
  K.OpenKey('SOFTWARE\MicroSoft\Windows\CurrentVersion\Extensions',
            False);

  Extensions := TStringList.Create;
  K.GetValueNames(Extensions);

  for i := 0 to Extensions.Count-1 do
    Memo1.Lines.Add(Extensions.Strings[i]
                    + ' = ' +
                    K.ReadString('', Extensions.Strings[i], ''));

  Extensions.Free;
  K.Free;
end;

Screen Resolution

Question

When I run a program on my computer everything looks fine, but when I
run it on my other computer, with a higher screen resilotion it looks
totaly different. How can I get it to look the same in any resolution.

Answer

Borland's document ti2861 gave some mileage..and I give it to you with
some of my modifications..here is:

TI2861 - Form display with different screen resolutions.

     Product: Delphi
     Version: All
     Platform: Windows/Win32 

When designing forms, it is sometimes helpful to write the code 
so that the screen and all of its objects are displayed at the 
same size no matter what the screen resolution is.  Here is 
some code to show how that is done:

implementation
const
  ScreenWidth: LongInt = 640; {I designed my form in 640x480 mode.}
  ScreenHeight: LongInt = 480;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  scaled := true;
  if (screen.width <> ScreenWidth) then
  begin
    height := longint(height) * longint(screen.height) div ScreenHeight;
    width := longint(width) * longint(screen.width) div ScreenWidth;
    scaleBy(screen.width, ScreenWidth);
  end;
end;

Then, you will want to have something that checks to see that 
the font sizes are OK.  You can iterate over each child
control's font to adjust its size as necessary.  This can be
done as follows:

type
  TFooClass = class(TControl); { needed to get at protected }
                               { font property } 

var
  i,NewFormWidth,OldFormWidth : integer;
begin
	NewFormWidth := GetsystemMetrics(0); <-- gives you your window's width
	OldFormWidth := 640;                 <-- This is my resolution
  for i := ControlCount - 1 downto 0 do
    TFooClass(Controls[i]).Font.Size := 
        (NewFormWidth div OldFormWidth) * 
        TFooClass(Controls[i]).Font.Size;
end;

This will calculate all your fonts, objects that are on your forms...

Note:  The following are issue to bear in mind when scaling 
Delphi applications (forms) on different screen resolutions:

  * Decide early on in the form design stage whether you're 
going to allow the form to be scaled or not.  The advantage of 
not scaling is that nothing changes at runtime.  The 
disadvantage of not scaling is that nothing changes at runtime 
(your form may be far too small or too large to read on some 
systems if it is not scaled).


  * If you're NOT going to scale the form, set Scaled to False.

  * Otherwise, set the Form's Scaled property to True.

  * Set AutoScroll to False.  AutoScroll = True means 'don't 
change the form's frame size at runtime' which doesn't look 
good when the  form's contents do change size.

  * Set the form's font to a scaleable TrueType font, like 
Arial.   MS San Serif is an ok alternate, but remember that it 
is still a  bitmapped font.  Only Arial will give you a font 
within a pixel of the desired height.  NOTE: If the font used 
in an application is not installed on the target computer, then 
Windows will select an  alternative font within the same font 
family to use instead.  This font may not match the same size 
of the original font any may cause problems.

  * Set the form's Position property to something other than 
poDesigned.  poDesigned leaves the form where you left it at 
design time, which for me always winds up way off to the left
on my 1280x1024 screen -  and completely off the 640x480 screen.

  * Don't crowd controls on the form - leave at least 4 pixels 
between  controls, so that a one pixel change in border 
locations (due to  scaling) won't show up as ugly overlapping 
controls.

  * For single line labels that are alLeft or alRight aligned, 
set AutoSize to True.  Otherwise, set AutoSize to False.

  * Make sure there is enough blank space in a label component 
to allow for font width changes - a blank space that is 25% of 
the length of the current string display length is a little too 
much, but safe. (You'll need at least 30% expansion space for 
string labels if you  plan to translate your app into other 
languages) If AutoSize is  False, make sure you actually set 
the label width appropriately.  If AutoSize is True, make sure 
there is enough room for the label  to grow on its own.

  * In multi-line, word-wrapped labels, leave at least one line
of blank space at the bottom.  You'll need this to catch the 
overflow when the text wraps differently when the font width 
changes with scaling. Don't assume that because you're using 
large fonts, you don't have to allow for text overflow - 
somebody else's large  fonts may be larger than yours!

  * Be careful about opening a project in the IDE at different 
resolutions.  The form's PixelsPerInch property will be 
modified as soon as the form is opened, and will be saved to 
the DFM if you save the project. It's best to test the app by 
running it standalone, and edit the form at only one 
resolution. Editing at varying resolutions and font sizes 
invites component drift  and sizing problems.

  * Speaking of component drift, don't rescale a form multiple 
times, at design time or a runtime.  Each rescaling introduces 
roundoff errors which accumulate very quickly since coordinates 
are  strictly integral.  As fractional amounts are truncated 
off control's origins and sizes with each successive 
rescaling,  the controls will appear to creep northwest and get
smaller. If you want to allow your users to rescale the form 
any number  of times, start with a freshly loaded/created form 
before each  scaling, so that scaling errors do not accumulate.

  * Don't change the PixelsPerInch property of the form, period.

  * In general, it is not necessary to design forms at any 
particular resolution, but it is crucial that you review their 
appearance at 640x480 with small fonts and large, and at a 
high-resolution with small fonts and large before releasing 
your app.  This should be  part of your regular system 
compatibility testing checklist.

  * Pay close attention to any components that are essentially  
single-line TMemos - things like TDBLookupCombo.  The Windows  
multi-line edit control always shows only whole lines of text 
-  if the control is too short for its font, a TMemo will show  
nothing at all (a TEdit will show clipped text). For such  
components, it's better to make them a few pixels too large 
than to be one pixel too small and show not text at all.

  * Keep in mind that all scaling is proportional to the 
difference  in the font height between runtime and design time, 
NOT the pixel resolution or screen size.  Remember also that 
the origins of your controls will be changed when the form is 
scaled - you can't very  well make components bigger without 
also moving them over a bit.

Registry and TStrings

Question

I want to save the contents of a string list to the registry (and later read
it back).  It looks like the ReadSectionValues method of TRegIniFile may
read back the list.

Answer

If anyone is interested, the code that I used to write (and read) a
TStringList to the Registry is:

{Save a list of strings to the registry.
 It will write each string as a key,value with the key being the index of
 each string element and the value being the key.
}
procedure TDPRegistry.SaveStringListInRegistry(_RootKey: HKEY;
                                     _Localkey: String; Strings: TStrings);
var
  TR: TRegIniFile;
  LStringIndex: Integer;
begin
  TR := TRegIniFile.Create('');
  try
    case _RootKey of { default is RootKey=HKEY_CURRENT_USER }
      HKEY_CLASSES_ROOT,
      HKEY_CURRENT_USER,
      HKEY_LOCAL_MACHINE,
      HKEY_USERS,
      HKEY_PERFORMANCE_DATA,
      HKEY_CURRENT_CONFIG,
      HKEY_DYN_DATA : TR.RootKey := _RootKey;
    end; {end case _RootKey}
    TR.EraseSection(_Localkey); {make sure no entries for this section/key}
    with TRegistry(TR) do begin
      if OpenKey(_Localkey,true) then begin
        try
          for LStringIndex := 0 to Strings.Count - 1 do begin
            WriteString (IntToStr(LStringIndex), Strings[LStringIndex]);
          end; {for each string in the list}
        finally
          CloseKey;
        end; {try finally}
      end; {if OpenKey}
    end; {with TRegistry(TR)}
  finally
    TR.Free;
  end; {try finally}
end;

{Get list of strings from registry.}
procedure TDPRegistry.GetStringListFromRegistry(_RootKey: HKEY;
                                     _Localkey: String; Strings: TStrings);
var
  TR: TRegIniFile;
  LStringIndex: Integer;
  RegKeyInfo : TRegKeyInfo;
begin
  Strings.Clear; {start with no elements in string list}
  TR := TRegIniFile.Create('');
  try
    case _RootKey of { default is  RootKey=HKEY_CURRENT_USER  }
      HKEY_CLASSES_ROOT,
      HKEY_CURRENT_USER,
      HKEY_LOCAL_MACHINE,
      HKEY_USERS,
      HKEY_PERFORMANCE_DATA,
      HKEY_CURRENT_CONFIG,
      HKEY_DYN_DATA : TR.RootKey := _RootKey;
    end;
{   TR.ReadSectionValues(_Localkey, Strings); doesn't work nicely because
returns strings as "1=Value", "2=Value"...}
    with TRegistry(TR) do begin
      if OpenKey(_Localkey,true) then begin
        try
          if (GetKeyInfo(RegKeyInfo)) then begin
            for LStringIndex := 0 to RegKeyInfo.NumValues - 1 do begin
              Strings.Add(ReadString(IntToStr(LStringIndex)));
            end; {for each value associated with this key}
          end; {got key information}
        finally
          CloseKey;
        end; {try finally}
      end; {if OpenKey}
    end; {with TRegistry(TR)}
  finally
    TR.Free;
  end; {try finally}
end;

Get Windows directory

Question

How to retrieve Windows directory?

Answer

{this code finds the windows directory on the click of a button}

procedure TForm1.Button1Click(Sender: TObject);
var
   buf : array[0..200] of char;
   pc : Pchar;
   str : string;
   x : integer;
begin
   pc := @buf[0];
   x := getwindowsdirectory(pc, 199);
   str := strpas(pc);
   writeln(str); { output c:\windows}
   writeln(x);   { output 10}
end;










© DelphiRSS.com. All Rights Reserved.