⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows.htm

📁 对于学习很有帮助
💻 HTM
📖 第 1 页 / 共 4 页
字号:
identifier). They are normally accessed using pointers to item
identifiers list (PIDL). To get the PIDL of a special folder, you can
use the SHGetSpecialFolder function. The physical location of the
corresponding directory can then be obtained by passing the PIDL to the
GetPathFromIDList function. If the folder is part of the file system,
the function will return the path as a string (which can be used as
InitialDir). But if you want the OpenDialog to start in a folder that is
only virtual (like 'my computer'), you'll have to make it accept a PIDL
as InitialDir, which I don't think it will. My guess is that the
TOpenDialog uses PIDLs when browsing, but only accepts physical
directories as InitialDir.<p>

Here is an example that shows how to get the 'recent documents' path and
use it as InitialDir:<p>

<HR><PRE>procedure TForm1.Button1Click(Sender: TObject);
var
PIDL: Pointer;
Path: LPSTR;
const
CSIDL_RECENT = $0008;
begin
Path := StrAlloc(MAX_PATH);
SHGetSpecialFolderLocation(Handle, CSIDL_RECENT, @PIDL);
if SHGetPathFromIDList(PIDL, Path) then // returns false if folder isn't
part of file system
  begin
  OpenDialog1.InitialDir := Path;
  OpenDialog1.Execute;
  end;
StrDispose(Path);
end;
</PRE><HR>

I think you'll have to write a wrapper for these API calls. They are
found in shell32.dll. The best advice I can give you if you want to dig
into this is to study the ShlObj.h file. I don't program in C myself,
but I found it very useful.<p>

Some constants you may need:<p>

<HR><PRE>  CSIDL_DESKTOP            = $0000;
  CSIDL_PROGRAMS           = $0002;
  CSIDL_CONTROLS           = $0003;
  CSIDL_PRINTERS           = $0004;
  CSIDL_PERSONAL           = $0005;
  CSIDL_STARTUP            = $0007;
  CSIDL_RECENT             = $0008;
  CSIDL_SENDTO             = $0009;
  CSIDL_BITBUCKET          = $000a;
  CSIDL_STARTMENU          = $000b;
  CSIDL_DESKTOPDIRECTORY   = $0010;
  CSIDL_DRIVES             = $0011;  // My Computer
  CSIDL_NETWORK            = $0012;
  CSIDL_NETHOOD            = $0013;
  CSIDL_FONTS              = $0014;
  CSIDL_TEMPLATES          = $0015;
</PRE><HR>


<P><H1><A NAME="windows13">Determining which font (Large or Small) is in use</P></A></H1>
<P><I>"Greg Peterson" &lt;maxint@cwnet.com&gt;</I></P>

  Try this:


<HR><PRE>
FUNCTION SmallFonts : BOOLEAN;
{returns TRUE if  small fonts are set, FALSE if using Large Fonts }
VAR
  DC : HDC; { used to check for number of colors available }
BEGIN
  DC := GetDC(0);
  Result :=   (GetDeviceCaps(DC, LOGPIXELSX) = 96); 
  { LOGPIXELSX will = 120 if large fonts are in use }
  ReleaseDC(0, DC);
END;
</PRE><HR>

<P><H1><A NAME="windows14">Large/Small Fonts?</P></A></H1>
<P><I>Gene Eighmy &lt;eighmy@scott.net&gt;</I></P>

<PRE>> 
> When my programs run on systems with small fonts, I
> often get strange output.  Labels too small to hold all
> the text, leaving the right, or the bottom, unshown, for
> instance.  StringGrid's which don't align as expected.
> 
</PRE>

Try this.  This will rescale both the form size and also reform small 
vs. large fonts.  Call it in Form.FormCreate.  Hope this helps. <p>

<HR><PRE>unit geScale;

interface
uses Forms, Controls;

procedure geAutoScale(MForm: TForm);

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


procedure geAutoScale(MForm: TForm);
const
     cScreenWidth :integer = 800;
     cScreenHeight:integer = 600;
     cPixelsPerInch:integer= 96;
     cFontHeight:integer   = -11;  {Design-time value of From.Font.Height}

var
  i: integer;

begin
     {
     IMPORTANT!! : Set Scaled Property of TForm to FALSE with Object Inspector.

     The following routine will scale the form such that it looks the same
     regardless of the screen size or pixels per inch.  The following section
     determines if the screen width differs from the design-time screen size.
     If it differs, Scaled is set true and component positions are rescaled such
     that they appear in the same screen location as the design-time location.
     }
     if (Screen.width &;lt> cScreenWidth)or(Screen.PixelsPerInch &lt;> cPixelsPerInch) then
     begin
          MForm.scaled := TRUE;
          MForm.height := MForm.height * screen.Height DIV cScreenHeight;
          MForm.width  := MForm.width  * screen.width DIV cScreenWidth;
          MForm.ScaleBy(screen.width, cScreenWidth);

     end;

     {
      This section determines if the run-time font size differs from the design-
      time font size.  If the run-time pixelsperinch differs form the design-time
      pixelsperinch, the fonts must be rescaled in order for the form to appear
      as designed.  Scaling is calculated as the ratio of the design-time font.height
      to run-time font.height.  Font.size will not work as it may equal the design-
      time value yet appear physically larger crowding and overrunning other
      components.    For instance, a form designed in 800x600 small fonts
      has a font.size of 8.  When you run the form on in 800x600 large fonts,
      font.size is also 8 but the text is noticably larger than when run in small
      font mode. This scaling will make them both appear to be the same size.
     }

     if (Screen.PixelsPerInch &lt;&gt; cPixelsPerInch) then
     begin

         for i := MForm.ControlCount - 1 downto 0 do
              TFooClass(MForm.Controls[i]).Font.Height :=
               (MForm.Font.Height div cFontHeight) *
                 TFooClass(MForm.Controls[i]).Font.Height;

     end;

end;

end.
</PRE><HR>


<P><H1><A NAME="windows15">How can I restore a window to its last state when I run it again?</P></A></H1>

A: Here is WindowRestorer - a window size and state restorer <P>

DESCRIPTION:  Ever notice how professional programs seem to remember in what condition 
and location you left them and their child windows?  
Ever notice how most RAD apps don't?  You can take that ragged edge off your program with this unit.  
It Allows apps to save the location, size, and state of windows so that when the user reopens them, they will look as the user left them.<P>


USE: Put WINRSTOR in the uses of clause of your main form and any forms 
that will be saving or restoring their own state, size, or location.  
(If you will be doing all the saving and restoring using WinSaveChildren and WinRestoreChildren from the main form, 
you only need reference it in the main form's uses clause.) <p>

In MainForm.Create, initialize the global WinRestorer object as follows (it's already declared in this file, but needs to be allocated): 

<HR><PRE>
	GlobalWinRestorer := TWinRestorer.create( Application, TRUE, WHATSAVE_ALL); 
</PRE><HR>
Which is the same as: 
<HR><PRE>
	GlobalWinRestorer := TWinRestorer.create( Application, TRUE, [location, size, state]); 
</PRE><HR>
Then, in MainForm.Destroy, deallocate the global WinRestorer object as follows: 
<HR><PRE>GlobalWinRestorer.free; </PRE><HR>


A good place to save a form's status is in the queryclose event or else attached to a button or menu item.  
I usually create an item in the File Menu captioned 'Save &Workspace' which does: 

<HR><PRE>
	GlobalWinRestorer.SaveChildren(Self, [default]); 
</PRE><HR>
And under main form's Close event I put: 

<HR><PRE>
	GlobalWinRestorer.SaveWin(Self, [WHATSAVE_ALL]); 
</PRE><HR>
I have tended to restore the children's status in their own show events like this: 
<HR><PRE>
	GlobalWinRestorer.RestoreWin(Self, [default]); 
</PRE><HR>
though I am moving toward putting in the main form's show event: 

<HR><PRE>
	GlobalWinRestorer.RestoreWin(Self, [default]); 
	GlobalWinRestorer.RestoreChildren(Self, [default]);
</PRE><HR>

HINTS:  If you set TForm.Position to poScreenCenter or anything fancy, 
this unit won't do what you expect.  poDesigned seems to work fairly well.  I 
could have raised an exception if you try to set top and left of a poScreenCentere'd form, but then you have to 
be careful using WinRestoreChildren.  I opted not to check the position property and leave that up to individual developers. <p>
<HR><PRE>
unit WinRstor;

INTERFACE

USES SysUtils, Forms;

TYPE {=============================================================}


{------------------------------------------------------------------
Windows restorer object class and related types.
-------------------------------------------------------------------}
EWinRestorer = class( Exception);
TWhatSave = (default, size, location, state);
STWhatSave = set of TWhatSave;
TWinRestorer = class(TObject)
 protected
  mIniFile: string;
  mIniSect: string[80];
  mIsInitialized: boolean;
  mDefaultWhat: STWhatSave;
 public
  constructor Create( TheApp: TApplication;

    LocalDir: boolean; DefaultWhatSave: STWhatSave);
    {If localDir is true, ini dir is the app dir.  Else, ini dir is the windows dir.}
  procedure SaveWin(TheForm: TForm; What: STWhatSave);
  procedure SaveChildren(TheMDIForm: TForm; What: STWhatSave);
  procedure RestoreWin( TheForm: TForm; What: STWhatSave);
  procedure RestoreChildren(TheMDIForm: TForm; What: STWhatSave);
  property IniFileName: string  read mIniFile;
end;

CONST
  WHATSAVE_ALL = [size, location, state];


VAR
GlobalWinRestorer: TWinRestorer;

IMPLEMENTATION

Uses IniFiles;

constructor TWinRestorer.create;
var fname, path: string[100];
begin
  inherited create;
{Calculate ini file name}
  if default in DefaultWhatSave then
    raise EWinRestorer.create(
     'Attempt to initialize default window position paramaters with set ' +
     ' containing [default] item.  ' +
     'Default params may contain only members of [size, location, state].  ')
  else mDefaultWhat := DefaultWhatSave;

  fname := ChangeFileExt( ExtractFileName( TheApp.exeName), '.INI');
  if LocalDir then begin {parse out path and add to file name}
    path := ExtractFilePath(TheApp.exeName);
    if path[length(path)] <> '\' then
      path := path + '\';
    fname := path + fname;
  end;
{fill object fields}
  mIniFile := fname;
  mIniSect := 'WindowsRestorer';
{It'd be nice to write some notes to a section called [WinRestorer Notes]}
end;

procedure TWinRestorer.RestoreWin;

var FormNm, SectionNm: string[80];   ini: TIniFile;
  n,l,t,w,h: integer; {Left, Top Width, Height}
begin
  ini := TIniFile.create( mIniFile);
  TRY
    SectionNm := mIniSect;
    FormNm := TheForm.classname;
    if default in What then What := mDefaultWhat;
{Update Window State if Necessary}
    if state in What then
      n := ini.ReadInteger( SectionNm, FormNm + '_WindowState', 0);
      case  n of
        1:   TheForm.WindowState := wsMinimized;
        2:  TheForm.WindowState := wsNormal;

        3:   TheForm.WindowState := wsMaximized;
      end;
{Update Size and Location if necessary.}
    with TheForm do begin l:=left; t:=top; h:=height; w:=width; end; {Save current vals.}
    if size in What then begin
      w := ini.ReadInteger( SectionNm, FormNm + '_Width', w);
      h := ini.ReadInteger( SectionNm, FormNm + '_Height', h);
    end;
    if location in What then begin
      t := ini.ReadInteger( SectionNm, FormNm + '_Top', t);
      l := ini.ReadInteger( SectionNm, FormNm + '_Left', l);

    end;
    TheForm.SetBounds(l,t,w,h);
  FINALLY
    ini.free;
  END;
end;

procedure TWinRestorer.RestoreChildren;
var i: integer;
begin
  if TheMDIForm.formstyle &lt;&gt; fsMDIForm then
    raise EWinRestorer.create('Attempting to save window sizes of children for a non MDI parent window.')
  else
    for i := 0 to TheMDIForm.MDIChildCount - 1 do
      RestoreWin( TheMDIForm.MDIChildren[i], what);
end;

procedure TWinRestorer.SaveWin;
var FormNm, SectionNm: string[80];   w : STWhatsave; ini: TIniFile;

begin
  ini := TIniFile.create( mIniFile);
  TRY
    SectionNm := mIniSect;
    FormNm := TheForm.ClassName;
    if default in What then w := mDefaultWhat else w := mDefaultWhat;
    if size in w then begin
      ini.WriteInteger( SectionNm, FormNm + '_Width', TheForm.Width);
      ini.WriteInteger( SectionNm, FormNm + '_Height', TheForm.Height);
    end;
    if location in w then begin
      ini.WriteInteger( SectionNm, FormNm + '_Top', TheForm.Top);
      ini.WriteInteger( SectionNm, FormNm + '_Left', TheForm.Left);

    end;
    if state in w then
      case TheForm.WindowState of
        wsMinimized:   ini.WriteInteger( SectionNm, FormNm + '_WindowState', 1);
        wsNormal:     ini.WriteInteger( SectionNm, FormNm + '_WindowState', 2);
        wsMaximized:   ini.WriteInteger( SectionNm, FormNm + '_WindowState', 3);
      end;
  FINALLY

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -