Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2010年07月07日] [更新 2013年11月09日] Delphi サンプルプログラム集
   
SystemParametersInfo 関数サンプル
S01_ユーザー補助関係
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
S01_SystemParametersInfo_User.zip [4,908 KB] 2013年11月09日版 (EXE 同梱)







ユーザ補助関係 概要


アクセシビリティに関する設定です.
Windows XP まではコントロールパネルの [ユーザ補助] の設定ですが,Windows Vista 以降では [コンピューターの簡単操作センター] になっています.本ページでは [ユーザ補助] の設定での用語を使用しています.
設定フラグに [インジケータに表示] というのがあります.これをチェックするとタスクトレイ (通知領域) にアイコンが登録されます.また,各々の機能でホットキーを有効にすると,他の常駐アプリケーションのホットキー類が動作しなくなることがあります.フラグの中には無効だったり,重複するものもあるようです.




01_ユーザ補助を無効にするまでの時間


コンピュータに対して一定時間操作がない時間 (アイドル時間) 経過すると,有効にしたユーザ補助の機能を自動的にオフにします.この情報の取得と設定のサンプルです.


表1
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETACCESSTIMEOUT 取得
ACCESSTIMEOUT 構造体を使用
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ
実行後,この構造体に情報が格納される
SPI_SETACCESSTIMEOUT 設定
ACCESSTIMEOUT 構造体に新しいパラメータを設定する
構造体の cbSize をこの構造体のサイズとする
uiParam もこの構造体のサイズ
pvParam はこの構造体のポインタ


図1
起動すると現在の設定を表示

リスト1
ユーザ補助を無効にするまでの時間の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    SpinEdit1: TSpinEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
    OrignalRecord : TAccessTimeout;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  OrignalRecord.cbSize := SizeOf(OrignalRecord);
  SystemParametersInfo(SPI_GETACCESSTIMEOUT,
                       SizeOf(OrignalRecord),
                       @OrignalRecord,
                       0);

  //取得した結果を表示
  CheckBox1.Checked := (ATF_TIMEOUTON and (OrignalRecord.dwFlags)) > 0;
  CheckBox2.Checked := (ATF_ONOFFFEEDBACK and (OrignalRecord.dwFlags)) > 0;
  SpinEdit1.Value   := OrignalRecord.iTimeOutMSec div (1000 * 60);
end;

//=============================================================================
//  設定変更
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ARecord : TAccessTimeout;
begin
  Screen.Cursor  := crHourGlass;
  ARecord.cbSize := SizeOf(ARecord);

  //設定内容をTAccessTimout構造体にセット
  ARecord.dwFlags := 0;
  ARecord.dwFlags := (Ord(CheckBox1.Checked) * ATF_TIMEOUTON) or
                     (Ord(CheckBox2.Checked) * ATF_ONOFFFEEDBACK);
  ARecord.iTimeOutMSec := SpinEdit1.Value * 1000 * 60;

  SystemParametersInfo(SPI_SETACCESSTIMEOUT,
                       SizeOf(ARecord),
                       @ARecord,
                       SPIF_SENDCHANGE);
  Screen.Cursor  := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor  := crHourGlass;

  SystemParametersInfo(SPI_SETACCESSTIMEOUT,
                       SizeOf(OrignalRecord),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);
  Screen.Cursor  := crDefault;
end;

end.




02_ユーザ補助のフィルターキー機能


[ユーザ補助] [キーボード] タブの [フィルタキー機能] の取得と設定のサンプルです.
Vista 以降では [コンピュータの簡単操作センター] の [キーボードを使いやすくします] で [フィルターキー機能を有効にします] で設定する項目に相当します.


表2
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETFILTERKEYS 取得
FILTERKEYS 構造体を使用
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam は構造体へのポインタ
実行後,構造体に情報が格納される
SPI_SETFILTERKEYS 設定
FILTERKEYS 構造体に新しいパラメータを設定する
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ


図2
起動すると現在の設定を表示
  • Windows XP の時間表示は現在の設定値
  • Vista 以降では,無効な機能の設定は0
    有効にすると現在の設定値を表示
図3
有効にすると通知領域にアイコン
  • インジケータ表示Falseで非表示

リスト2
フィルターキー機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    ComboBox3: TComboBox;
    ComboBox4: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  private
    { Private 宣言 }
    OrignalRecord : TFilterKeys;
    NewRecord     : TFilterKeys;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//
//  キーの待機時間関係の設定は,WindowsXPではフィルタキーが無効でも現在の設定
//  値が表示される.Windows 7では無効の時は0となる
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //WinXPでは[キー入力の速度]の[キーを認識するまでの時間](秒)に相当
  with ComboBox1.Items do begin
    Clear;
    Add('0.0');
    Add('0.3');
    Add('0.5');
    Add('0.7');
    Add('1.4');
    Add('2.0');
    Add('5.0');
    Add('10.0');
    Add('20.0');
  end;

  //同じキーを繰り返すまでの待機時間(リピート)
  //WinXPでは[間隔を長くする]の[表示までの待ち時間](秒)に相当
  //繰り返されたキー入力をすべて無視の場合は0.0
  with ComboBox2.Items do begin
    Clear;
    Add('0.3');
    Add('0.7');
    Add('1.0');
    Add('1.5');
    Add('2.0');
  end;

  //次のキーを繰り返すまでの待機時間
  //WinXPでは[間隔を長くする]の[表示の間隔](秒)に相当
  //繰り返されたキー入力をすべて無視の場合は0.0
  with ComboBox3.Items do begin
    Clear;
    Add('0.3');
    Add('0.5');
    Add('0.7');
    Add('1.0');
    Add('1.5');
    Add('2.0');
  end;

  //バウンズ機能(同じキー押下を一定時間無視)をオフにしている場合は0.0(Windows7)
  with ComboBox4.Items do begin
    Clear;
    Add('0.3');
    Add('0.7');
    Add('1.0');
    Add('1.5');
    Add('2.0');
  end;

  OrignalRecord.cbSize := SizeOf(TFilterKeys);
  SystemParametersInfo(SPI_GETFILTERKEYS,
                       SizeOf(TFilterKeys),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;
  //フィルタキー有効
  CheckBox1.Checked := (FKF_FILTERKEYSON and NewRecord.dwFlags) > 0;
  //フィルタキー使用可能
  CheckBox2.Checked := (FKF_AVAILABLE and NewRecord.dwFlags) > 0;
  //dwFlagのその他の値
  CheckBox3.Checked := (FKF_HOTKEYACTIVE  and NewRecord.dwFlags) <> 0;
  CheckBox4.Checked := (FKF_HOTKEYSOUND   and NewRecord.dwFlags) <> 0;
  CheckBox5.Checked := (FKF_INDICATOR     and NewRecord.dwFlags) <> 0;
  CheckBox6.Checked := (FKF_CLICKON       and NewRecord.dwFlags) <> 0;

  //時間関係
  ComboBox1.Text := FormatFloat('#0.0', NewRecord.iWaitMSec   / 1000);
  ComboBox2.Text := FormatFloat('#0.0', NewRecord.iDelayMSec  / 1000);
  ComboBox3.Text := FormatFloat('#0.0', NewRecord.iRepeatMSec / 1000);
  ComboBox4.Text := FormatFloat('#0.0', NewRecord.iBounceMSec / 1000);
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  NewRecord.dwFlags := 0;
  NewRecord.dwFlags := (FKF_FILTERKEYSON  * Ord(CheckBox1.Checked)) or
                       (FKF_AVAILABLE     * Ord(CheckBox2.Checked)) or
                       (FKF_HOTKEYACTIVE  * Ord(CheckBox3.Checked)) or
                       (FKF_HOTKEYSOUND   * Ord(CheckBox4.Checked)) or
                       (FKF_INDICATOR     * Ord(CheckBox5.Checked)) or
                       (FKF_CLICKON       * Ord(CheckBox6.Checked));

  NewRecord.iWaitMSec   := Trunc(StrToFloat(ComboBox1.Text) * 1000);
  NewRecord.iDelayMSec  := Trunc(StrToFloat(ComboBox2.Text) * 1000);
  NewRecord.iRepeatMSec := Trunc(StrToFloat(ComboBox3.Text) * 1000);
  NewRecord.iBounceMSec := Trunc(StrToFloat(ComboBox4.Text) * 1000);

  SystemParametersInfo(SPI_SETFILTERKEYS,
                       SizeOf(TFilterKeys),
                       @NewRecord,
                       SPIF_SENDCHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETFILTERKEYS,
                       SizeOf(TFilterKeys),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  マウスホイール使用禁止
//  コンボボックスで予期しない選択をしてしまうため
//  このフォーム上には,他にマウスホイールでスクロールするものはないので
//  コードはHandled := True;たけ
//=============================================================================
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := True;
end;

end.




03_ユーザ補助のハイコントラスト機能


[ユーザ補助] の [画面] タブの [ハイコントラストを使う] の取得と設定のサンプルです.
Windows XP ではレジストリから [ハイコントラストの表示設定] のリストを取得できますが,Vista 以降では取得出来なかったので,あらかじめ OS が用意しているテーマ名をコード内に記述しました.


表3
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETHIGHCONTRAST 取得
HIGHCONTRAST 構造体を使用
構造体の cbSize はこの降雨増体のサイズ
uiParam は Sizeof (HIGHCONTRAST)
pvParam はこの構造体へのポインタ
実行後,この構造体に情報が格納される
SPI_SETHIGHCONTRAST 設定
HIGHCONTRAST 構造体に新しいパラメータを設定する
構造体の cbSize をこの構造体のサイズ
uiParam もこの構造体のサイズとする
pvParam はこの構造体のポインタ


図4
起動すると現在の設定を表示
図5
通常画面
図6
ハイコントラスト画面の例

リスト3
ハイコントラスト機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    ComboBox1: TComboBox;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  private
    { Private 宣言 }
    OrignalRecord : THighContrast;
    NewRecord     : THighContrast;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses Registry;

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得し表示
//
//  確認ダイアログとインジケータ関係は実装していない
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  Reg     : TRegistry;
  ARegKey : String;
  SL      : TStringList;
  i       : Integer;
begin
  //Vista以上の場合
  if CheckWin32Version(6, 0) then begin
    with ComboBox1.Items do begin
      BeginUpdate;
      Clear;
      Add('ハイコントラスト #1');
      Add('ハイコントラスト #2');
      Add('ハイコントラスト 黒');
      Add('ハイコントラスト 白');
      Add('Windows クラシッ');
      EndUpdate;
    end;

  //Windows XPの場合はレジストリからテーマの設定リストを読みだす
  end else begin
    Reg := TRegistry.Create;
    SL  := TStringList.Create;
    try
      Reg.Access  := KEY_READ;
      Reg.RootKey := HKEY_CURRENT_USER;
      ARegKey     := 'Control Panel\Appearance\Schemes\';

      if Reg.OpenKey(ARegKey,False) then begin
        try
          //Reg.GetKeyNames(SL)ではうまくいかない
          Reg.GetValueNames(SL);
          //何故かWindowsXPのユーザ補助のリストとは逆順になっているので...
          ComboBox1.Items.Clear;
          for i := 0 to SL.Count - 1 do begin
            ComboBox1.Items.Add(SL[SL.Count - i - 1]);
          end;
        finally
          Reg.CloseKey;
        end;
      end;
    finally
      FreeAndNil(Reg);
      FreeAndNil(SL);
    end;
  end;

  //現在の設定値読出し
  OrignalRecord.cbSize := SizeOf(THighContrast);
  SystemParametersInfo(SPI_GETHIGHCONTRAST,
                       SizeOf(THighContrast),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;

  //デフォルトのカラースキーマの値
  ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(NewRecord.lpszDefaultScheme);

  //dwFlagの値
  CheckBox1.Checked := (HCF_HIGHCONTRASTON  and NewRecord.dwFlags) > 0;
  CheckBox2.Checked := (HCF_AVAILABLE       and NewRecord.dwFlags) > 0;
  CheckBox3.Checked := (HCF_HOTKEYACTIVE    and NewRecord.dwFlags) <> 0;
  CheckBox4.Checked := (HCF_HOTKEYSOUND     and NewRecord.dwFlags) <> 0;
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  //デフォルトのカラースキーマの値
  NewRecord.lpszDefaultScheme := PChar(ComboBox1.Text);

  //dwFlagの値
  NewRecord.dwFlags := 0;
  NewRecord.dwFlags := (HCF_HIGHCONTRASTON  * Ord(CheckBox1.Checked)) or
                       (HCF_AVAILABLE       * Ord(CheckBox2.Checked)) or
                       (HCF_HOTKEYACTIVE    * Ord(CheckBox3.Checked)) or
                       (HCF_HOTKEYSOUND     * Ord(CheckBox4.Checked));

  SystemParametersInfo(SPI_SETHIGHCONTRAST,
                       SizeOf(THighContrast),
                       @NewRecord,
                       SPIF_SENDCHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETHIGHCONTRAST,
                       SizeOf(THighContrast),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  マウスホイール使用禁止
//  コンボボックスで予期しない選択をしてしまうため
//  このフォーム上には,他にマウスホイールでスクロールするものはないので
//  コードはHandled := True;たけ
//=============================================================================
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
   Handled := True;
end;

end.




04_ユーザ補助のマウスキー機能


[ユーザ補助] ダイアログの [マウス] タブの [マウスキー機能を使う] の取得と設定のテストです.
この機能を有効にすると,テンキーでマウスカーソル移動ができるようになります.
[NumLock] をオフにすると,テンキーの矢印キーでカーソル (キャレット) の移動ができますが,これをマウスカーソルにしたものです.


表4
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETMOUSEKEYS 取得
MOUSEKEYS 構造体を使用
構造体の cbSize はこの構造体のサイズ)
uiParam もこの構造体のサイズとする
pvParam はこの構造体へのポインタ
実行後,この構造体に情報が格納される 
SPI_SETMOUSEKEYS 設定
MOUSEKEYS 構造体に新しいパラメータを設定する
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ


図7
起動すると現在の設定を表示
図8
有効にすると通知領域にアイコン
  • インジケータ表示 False で非表示

リスト4
マウスキーの取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    CheckBox7: TCheckBox;
    CheckBox8: TCheckBox;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    { Private 宣言 }
    OrignalRecord : TMouseKeys;
    NewRecord     : TMouseKeys;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses Registry, CommCtrl;

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//
//  確認のダイアログボックスをオフにしても,オンにする時は表示するらしい
//  オフの時はフラグに関係なく表示されない
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  AStyle : DWORD;
begin
  //TrackBarの初期設定
  with TrackBar1 do begin
    //Maxを先に設定しないとMinの設定が反映されない(要Max>Min)
    Max := 360;
    Min := 10;
    LineSize  := 35;
    PageSize  := LineSize;
    Frequency := LineSize;
  end;
  with TrackBar2 do begin
    //Maxを先に設定しないとMinの設定が反映されない(要Max>Min)
    Max := 5000;
    Min := 1000;
    LineSize  := 400;
    PageSize  := LineSize;
    Frequency := LineSize;
  end;

  //現在の設定値読出し
  OrignalRecord.cbSize := SizeOf(TMouseKeys);
  SystemParametersInfo(SPI_GETMOUSEKEYS,
                       SizeOf(TMouseKeys),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;

  //矢印キーを押した時のカーソルの最大移動速度
  //WindowsXPのコントロールパネルでは一定以上の値は全て最大値としていらしい
  TrackBar1.Position := NewRecord.iMaxSpeed;
  Label3.Caption     := IntToStr(NewRecord.iMaxSpeed);
  //最大速度に達するまでの時間
  //この表示はWindowsXPのコントロールパネルでは,右が速いになっているが,
  //このサンプルの表示では左端が少ない数値なので速いことになる
  TrackBar2.Position := NewRecord.iTimeToMaxSpeed;
  Label4.Caption     := IntToStr(NewRecord.iTimeToMaxSpeed);

  //dwFlagの値
  CheckBox1.Checked := (MKF_MOUSEKEYSON    and NewRecord.dwFlags) > 0;
  CheckBox2.Checked := (MKF_AVAILABLE      and NewRecord.dwFlags) > 0;
  CheckBox3.Checked := (MKF_HOTKEYACTIVE   and NewRecord.dwFlags) <> 0;
  CheckBox4.Checked := (MKF_CONFIRMHOTKEY  and NewRecord.dwFlags) <> 0;
  CheckBox5.Checked := (MKF_HOTKEYSOUND    and NewRecord.dwFlags) <> 0;
  CheckBox6.Checked := (MKF_INDICATOR      and NewRecord.dwFlags) <> 0;
  CheckBox7.Checked := (MKF_MODIFIERS      and NewRecord.dwFlags) <> 0;
  CheckBox8.Checked := (MKF_REPLACENUMBERS and NewRecord.dwFlags) <> 0;

  //トラックバーの溝の幅を狭くしてみる
  //usesにCommCtrlが必要
  AStyle := GetWindowLong(TrackBar1.Handle, GWL_STYLE);
  AStyle := AStyle and (not TBS_ENABLESELRANGE);
  SetWindowLong(TrackBar1.Handle, GWL_STYLE, AStyle);

  AStyle := GetWindowLong(TrackBar2.Handle, GWL_STYLE);
  AStyle := AStyle and (not TBS_ENABLESELRANGE);
  SetWindowLong(TrackBar2.Handle, GWL_STYLE, AStyle);
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  //矢印キーを押した時のカーソルの最大移動速度
  NewRecord.iMaxSpeed := TrackBar1.Position;
  //最大速度に達するまでの時間
  NewRecord.iTimeToMaxSpeed := TrackBar2.Position;

  //dwFlagの値
  NewRecord.dwFlags := 0;
  NewRecord.dwFlags := (MKF_MOUSEKEYSON   * Ord(CheckBox1.Checked)) or
                       (MKF_AVAILABLE      * Ord(CheckBox2.Checked)) or
                       (MKF_HOTKEYACTIVE   * Ord(CheckBox3.Checked)) or
                       (MKF_CONFIRMHOTKEY  * Ord(CheckBox4.Checked)) or
                       (MKF_HOTKEYSOUND    * Ord(CheckBox5.Checked)) or
                       (MKF_INDICATOR      * Ord(CheckBox6.Checked)) or
                       (MKF_MODIFIERS      * Ord(CheckBox7.Checked)) or
                       (MKF_REPLACENUMBERS * Ord(CheckBox8.Checked));

  SystemParametersInfo(SPI_SETMOUSEKEYS,
                       SizeOf(TMouseKeys),
                       @NewRecord,
                       SPIF_SENDCHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETMOUSEKEYS,
                       SizeOf(TMouseKeys),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  マウスホイール使用禁止
//  このフォーム上には,他にマウスホイールでスクロールするものはないので
//  コードはHandled := True;たけ
//=============================================================================
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
   Handled := True;
end;

//=============================================================================
//  トラックバーを移動したら現在の値を表示
//=============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
  Label3.Caption := IntToStr(TrackBar1.Position);
end;

//=============================================================================
//  トラックバーを移動したら現在の値を表示
//=============================================================================
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
  Label4.Caption := IntToStr(TrackBar2.Position);
end;

end.




05_ユーザ補助のスクリーンリーダ機能


スクリーンリーダー (スクリーンレビューア ユーティリティ) は,文字情報をスピーチシンセサイザや点字ディスプレイなどのデバイスに送信する機能のことです.

マイクロソフトのこのフラグの説明に,
《このフラグが指定されている場合、アプリケーションは、通常はグラフィックで表示される情報を、テキスト形式で提供するべきです。》
とあります.スクリーンリーダ動作のフラグとして使用してもらいたいようですが,Windows 7 のナレーターを動作させても True になりません.実際には利用されていないのかも知れません.

Windows XP では英語版でナレーターがサポートされていましたが,Windows Vista からは日本語版もサポートされました.デフォルトの対応は英語だけですが,設定すれば日本語も利用可能なようです.


表5
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETSCREENREADER 取得
uiParam は 0
pvParam は BOOL 型変数へのポインタ
有効ならば 0 以外の値が,それ以外の場合は 0 が戻ってくる
SPI_SETSCREENREADER 設定
uiParam に,有効にする場合は 0 以外,無効にするは 0
pvParam は nil


図9
起動すると現在の設定を表示

リスト5
スクリーンリーダ動作状態の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    OrignalValue : Integer;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  SystemParametersInfo(SPI_GETSCREENREADER,
                       0,
                       OrignalValue,
                       0);

  CheckBox1.Checked := OrignalValue <> 0;
end;

//=============================================================================
//  設定
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  AValue : Integer;
begin
  Screen.Cursor := crHourGlass;

  AValue := Ord(CheckBox1.Checked);
  SystemParametersInfo(SPI_SETSCREENREADER,
                       AValue,
                       nil,
                       SPIF_SENDCHANGE);
  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETSCREENREADER,
                       OrignalValue,
                       nil,
                       SPIF_SENDCHANGE);
  FormCreate(nil);
  Screen.Cursor := crDefault;
end;

end.




06_ユーザ補助のサウンド解説機能


サウンドを鳴らす場面で,同時にテキスト等でその情報を表示する機能です.この uiAction の各フラグを検出して,これらの機能を実装しているアプリケーションに対してだけ有効となります.

このフラグの状態は,GetSystemMetrics で SM_SHOWSOUNDS を引数にして取得できます.Microsoft ではこちらの使用を推奨しているようです.


表6
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParamは第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETSHOWSOUNDS 取得
uiParam は 0
pvParam は BOO L型変数へのポインタ
この値が有効ならば 0 以外,無効なら 0
SPI_SETSHOWSOUNDS 設定
uiParam は,有効にする時は 0 以外,無効にする場合は 0 とする
pvParam は nil


図10
起動すると現在の設定を表示

リスト6
サウンド解説機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    OrignalValue : Integer;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  SystemParametersInfo(SPI_GETSHOWSOUNDS,
                       0,
                       OrignalValue,
                       0);

  CheckBox1.Checked := OrignalValue <> 0;
end;

//=============================================================================
//  設定
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  AValue : Integer;
begin
  Screen.Cursor := crHourGlass;

  AValue := Ord(CheckBox1.Checked);
  SystemParametersInfo(SPI_SETSHOWSOUNDS,
                       AValue,
                       0,
                       SPIF_SENDCHANGE);
  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETSHOWSOUNDS,
                       OrignalValue,
                       0,
                       SPIF_SENDCHANGE);
  FormCreate(nil);
  Screen.Cursor := crDefault;
end;

end.




07_ユーザ補助のサウンド表示機能


サウンドを鳴らす場面で,同時にキャプションバー等の点滅でそれを知らせる機能です.
この uiAction の各フラグを検出して,これらの機能を実装しているアプリケーションに対してだけ有効となります.


表7
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETSOUNDSENTRY 取得
SOUNDSENTRY 構造体 を使用
構造体の cbSize はこの構造体のサイズとする
uiParam もこの構造体のサイズとする
pvParam はこの構造体へのポインタ
関数実行後,この構造体情報が格納される
SPI_SETSOUNDSENTRY 設定
SOUNDSENTRY 構造体に新しいパラメータを設定する
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ


図11
起動すると現在の設定を表示

リスト7
サウンド表示機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    RadioGroup1: TRadioGroup;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    OrignalRecord : TSoundsEntry;
    NewRecord     : TSoundsEntry;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //現在の設定値読出し
  OrignalRecord.cbSize := SizeOf(TSoundsEntry);
  SystemParametersInfo(SPI_GETSOUNDSENTRY,
                       SizeOf(TSoundsEntry),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;

  //dwFlagの値
  CheckBox1.Checked := (SSF_SOUNDSENTRYON and NewRecord.dwFlags) > 0;
  CheckBox2.Checked := (SSF_AVAILABLE     and NewRecord.dwFlags) > 0;

  //iWindowsEffectの値
  if NewRecord.iWindowsEffect = SSWF_NONE    then RadioGroup1.ItemIndex := 0;
  if NewRecord.iWindowsEffect = SSWF_TITLE   then RadioGroup1.ItemIndex := 1;
  if NewRecord.iWindowsEffect = SSWF_WINDOW  then RadioGroup1.ItemIndex := 2;
  if NewRecord.iWindowsEffect = SSWF_DISPLAY then RadioGroup1.ItemIndex := 3;
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  NewRecord.dwFlags := (SSF_SOUNDSENTRYON * Ord(CheckBox1.Checked)) or
                       (SSF_AVAILABLE     * Ord(CheckBox2.Checked));

  if RadioGroup1.ItemIndex = 0 then NewRecord.iWindowsEffect := SSWF_NONE;
  if RadioGroup1.ItemIndex = 1 then NewRecord.iWindowsEffect := SSWF_TITLE;
  if RadioGroup1.ItemIndex = 2 then NewRecord.iWindowsEffect := SSWF_WINDOW;
  if RadioGroup1.ItemIndex = 3 then NewRecord.iWindowsEffect := SSWF_DISPLAY;



  SystemParametersInfo(SPI_SETSOUNDSENTRY,
                       SizeOf(TSoundsEntry),
                       @NewRecord,
                       SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETSOUNDSENTRY ,
                       SizeOf(TSoundsEntry),
                       @OrignalRecord,
                       SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

end.




08_ユーザ補助の固定キー機能


[固定キー機能] を利用すると,2 つ以上のキーを同時に押す代わりに,各キーを1つづつ順番に押すようにできます.


表8
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETSTICKYKEYS 取得
STICKYKEYS 構造体を使用
構造体の cbSize をこの構造体のサイズとする
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ
実行後この構造体に情報が格納される
SPI_SETSTICKYKEYS 設定
STICKYKEYS 構造体 に新しいパラメータを設定する
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ


図12
起動すると現在の設定を表示

リスト8
固定キー機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    CheckBox7: TCheckBox;
    CheckBox8: TCheckBox;
    CheckBox9: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    OrignalRecord : TStickyKeys;
    NewRecord     : TStickyKeys;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //現在の設定値読出し
  OrignalRecord.cbSize := SizeOf(TStickyKeys);
  SystemParametersInfo(SPI_GETSTICKYKEYS,
                       SizeOf(TStickyKeys),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;

  //dwFlagの値
  CheckBox1.Checked := (SKF_STICKYKEYSON and NewRecord.dwFlags) <> 0;
  CheckBox2.Checked := (SKF_AVAILABLE    and NewRecord.dwFlags) <> 0;

  CheckBox3.Checked := (SKF_HOTKEYACTIVE    and NewRecord.dwFlags) <> 0;
  CheckBox4.Checked := (SKF_CONFIRMHOTKEY   and NewRecord.dwFlags) <> 0;
  CheckBox5.Checked := (SKF_HOTKEYSOUND     and NewRecord.dwFlags) <> 0;
  CheckBox6.Checked := (SKF_INDICATOR       and NewRecord.dwFlags) <> 0;
  CheckBox7.Checked := (SKF_AUDIBLEFEEDBACK and NewRecord.dwFlags) <> 0;
  CheckBox8.Checked := (SKF_TRISTATE        and NewRecord.dwFlags) <> 0;
  CheckBox9.Checked := (SKF_TWOKEYSOFF      and NewRecord.dwFlags) <> 0;
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  //dwFlagの値
  NewRecord.dwFlags := 0;
  NewRecord.dwFlags := (SKF_STICKYKEYSON    * Ord(CheckBox1.Checked)) or
                       (SKF_AVAILABLE       * Ord(CheckBox2.Checked)) or
                       (SKF_HOTKEYACTIVE    * Ord(CheckBox3.Checked)) or
                       (SKF_CONFIRMHOTKEY   * Ord(CheckBox4.Checked)) or
                       (SKF_HOTKEYSOUND     * Ord(CheckBox5.Checked)) or
                       (SKF_INDICATOR       * Ord(CheckBox6.Checked)) or
                       (SKF_AUDIBLEFEEDBACK * Ord(CheckBox7.Checked)) or
                       (SKF_TRISTATE        * Ord(CheckBox8.Checked)) or
                       (SKF_TWOKEYSOFF      * Ord(CheckBox9.Checked));

  SystemParametersInfo(SPI_SETSTICKYKEYS,
                       SizeOf(TStickyKeys),
                       @NewRecord,
                       SPIF_SENDCHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETSTICKYKEYS,
                       SizeOf(TStickyKeys),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

end.




09_ユーザ補助の切替えキー機能


トグルキー ( [CapsLock] [NuLock] [ScrolLock] ) を押した時に音を鳴らすようにする機能です.キーをオンにすると高い音,オフにすると低い音が鳴るようになります.


表9
uiAction パラメータは SystemParametersInfo 関数の第 1 引数
uiParam は第 2 引数で,pvParam は第 3 引数

uiAction パラメータ uiParam と pvParam パラメータ
SPI_GETTOGGLEKEYS 取得
TOGGLEKEYS 構造体 を使用
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ
実行後,この構造体に情報が格納される
SPI_SETTOGGLEKEYS 設定
TOGGLEKEYS 構造体に新しいパラメータを設定する
構造体の cbSize はこの構造体のサイズ
uiParam もこの構造体のサイズ
pvParam はこの構造体へのポインタ


図13
起動すると現在の設定を表示

リスト9
トグルキー機能の取得と設定
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    OrignalRecord : TToggleKeys;
    NewRecord     : TToggleKeys;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  プログラムを起動したら現在の設定を取得しておく
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  //現在の設定値読出し
  OrignalRecord.cbSize := SizeOf(TToggleKeys);
  SystemParametersInfo(SPI_GETTOGGLEKEYS,
                       SizeOf(TToggleKeys),
                       @OrignalRecord,
                       0);

  NewRecord := OrignalRecord;

  //dwFlagの値
  CheckBox1.Checked := (TKF_TOGGLEKEYSON and NewRecord.dwFlags) <> 0;
  CheckBox2.Checked := (TKF_AVAILABLE    and NewRecord.dwFlags) <> 0;

  CheckBox3.Checked := (TKF_HOTKEYACTIVE  and NewRecord.dwFlags) <> 0;
  CheckBox4.Checked := (TKF_CONFIRMHOTKEY and NewRecord.dwFlags) <> 0;
  CheckBox5.Checked := (TKF_HOTKEYSOUND   and NewRecord.dwFlags) <> 0;
end;

//=============================================================================
//  [設定]ボタン
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  //dwFlagの値
  NewRecord.dwFlags := 0;
  NewRecord.dwFlags := (TKF_TOGGLEKEYSON  * Ord(CheckBox1.Checked)) or
                       (TKF_AVAILABLE     * Ord(CheckBox2.Checked)) or
                       (TKF_HOTKEYACTIVE  * Ord(CheckBox3.Checked)) or
                       (TKF_CONFIRMHOTKEY * Ord(CheckBox4.Checked)) or
                       (TKF_HOTKEYSOUND   * Ord(CheckBox5.Checked));

  SystemParametersInfo(SPI_SETTOGGLEKEYS,
                       SizeOf(TToggleKeys),
                       @NewRecord,
                       SPIF_SENDCHANGE);

  Screen.Cursor := crDefault;
end;

//=============================================================================
//  元に戻す
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;

  SystemParametersInfo(SPI_SETTOGGLEKEYS,
                       SizeOf(TToggleKeys),
                       @OrignalRecord,
                       SPIF_SENDCHANGE);
  FormCreate(nil);

  Screen.Cursor := crDefault;
end;

end.