矢印型 Form をこの位置に置いてクリックすると・・・予め設定した範囲を、指定した倍率で、図のように枠のない別窓に拡大表示します。 別窓を指定時間後に自動で閉じる設定も可能です。 (デフォルト設定では、幅640×高さ320ピクセル、倍率2倍で、2.5秒間表示後、自動で閉じます)
追記(20250715)
初期バージョンにあった不具合を解消しました。主な改善点は以下の通りです。
(1)矢印型 Form の画面上の位置に応じて、矢印の向きとキャプチャ範囲を自動設定します。 (2)矢印形状(方向)のリアルタイム描画で、より直感的なキャプチャ範囲設定を可能としました。 (3)キャプチャ画面を指定時間後に自動で閉じる機能を追加しました(0.5秒刻みで設定可)※。
※ 指定時間経過後に拡大表示画面が自動で閉じる機能はデフォルト ON になっています。
また、上記改善を行った後、マルチモニター環境で行ったテストにおいて、プログラムの設計時、設定 Form の Scaled プロパティの確認を怠り、これを「 True のまま」としたため(なぜ、そうなっているのか、わかりませんが、 Delphi では Form の Scaled プロパティはデフォルト True なのです)、設定 Form に配置した VCL コントロールの配置がモニタの解像度によっては乱れてしまうことを確認し、一旦公開を中止して当該箇所の不具合を修正し、再度公開しました。
プログラムにはバージョン番号の表記等は一切ありませんので、矢印型 Form を右クリックすると表示されるサブメニューから「設定」をクリックして選択し、表示される設定画面が正常でない場合は、当記事のダウンロードリンクより、最新版の KindLens.exe をダウンロードしていただけますよう、伏してお願い申し上げます。
PCの画面を拡大表示できるツールは Windows の拡大鏡をはじめとしてさまざまなものがありますが、各種設定変更の必要性がなく、単一の実行形式ファイルのダブルクリックで起動し、マウス操作(ドラッグ&ドロップと左ボタンクリック)のみで画面の拡大表示を実現できる無料ツールはおそらくないのではないかと思います。
使い方は・・・
【初期バージョン】※ 現在、ダウンロードできません。
(1)矢印型の Form を拡大表示したい領域の右下へドラッグして移動します。 (2)ドロップした矢印型 Form 上をクリック(マウスの左ボタンを押し下げ)します。 (3)ドロップした位置の左上方向の画面が、拡大表示されます。
また、矢印型の Form は、常に最前面に表示されますので、動画等を全画面表示している場合でも問題なく動作します。拡大表示は矢印型の Form 上をクリックすることで実行されますので、動画アプリの操作と干渉することはありません(動画を流したまま、その一部の拡大表示が「静止画」として可能※です)。
※ 私のPC環境では、TEAMSで配信した動画や、YouTube の動画は静止画として拡大表示できましたが、PC環境や通信方法によっては動画を静止画として取得できない場合があるかもしれません。また、このプログラムは Microsoft 社の Windows11 で開発し、同 OS 上で動作確認を行っています。他社製 OS 上での動作は未確認ですので、間接的な方法やエミュレーション技術を利用されて本プログラムを Windows 以外の OS 上で実行される場合は、プログラムそのものが動作しない可能性があることに十分ご注意ください。
【プログラムの開発環境(ご参考まで)】
・デバイスの仕様
デバイス名 XXX
プロセッサ 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz (3.00 GHz)
実装 RAM 32.0 GB (31.7 GB 使用可能)
デバイス ID
プロダクト ID
システムの種類 64 ビット オペレーティング システム、x64 ベース プロセッサ
ペンとタッチ 10 タッチ ポイントでのペンとタッチのサポート
・Windowsの仕様
エディション Windows 11 Pro
バージョン 24H2
インストール日 2024/10/05
OS ビルド 26100.4652
エクスペリエンス Windows 機能エクスペリエンス パック 1000.26100.128.0
・開発環境
Embarcadero® Delphi 12.3 (バージョン 29.0.55362.2017)
Professional with Mobile
矢印の色に「白」を設定した場合は、矢印の輪郭を黒で描画して白背景の画面でも矢印 Form の位置がわかるように工夫してあります。ただし、白以外の淡色を指定した場合は、このような黒い輪郭の描画は行われません。くれぐれもご注意ください※。
色を「白」に設定した場合、矢印の輪郭が黒い線で描画されます。
※ もし、矢印 Form の色を白以外のごく薄い淡色に設定して、矢印型 Form の表示位置がわからなくなった場合は、タスクバーに表示されている KindLens のアイコンを右クリックして表示されるメニューから「ウィンドウを閉じる」を選択(クリック:マウスの左ボタン押し下げ)する方法で、プログラムを終了することができます。
設定状態を保存していない場合は、次回起動時には矢印型 Form の色は以前の状態に戻ると思いますが、ごく薄い淡色の設定状態を保存した場合は、KindLens.exe と同じ場所にある KindLens.ini を削除してから KindLens.exe を起動してください。矢印型 Form は初期設定の赤い状態で表示されます。その後、必要に応じて各種設定を変更してください。設定変更後、「保存」ボタンをクリックすれば、拡張子が ini のイニシャライズファイルが再作成され、新しい設定がこのファイルに保存されます。
プログラムの起動に成功すると、初期状態では赤い矢印型 Form がお使いの PC の画面中央に表示されますが、ダウンロード&展開直後の最初の実行(プログラム起動)時には Windows の保護機能が働いて、次に示す Windows Defender SmartScreen による警告画面が表示されます。
AV は「初めて見る未知の DLL」をロードしようとした時に、ファイル全体をディスクから読み込み、サンドボックス(外部と隔離された仮想環境:ITやセキュリティの分野では、主に怪しいプログラムを安全に試すための実験室として使われる)や、クラウドサービスに投げて解析(インターネット接続が出来ない環境である場合には、一定時間のタイムアウトを設け、その後ローカル判定にフォールバックする:なのでインターネット接続環境がないPCで実行してもいつまでもフリーズしたような状態が続くわけではない → 待機時間は Windows Defender の場合、既定で数秒~数十秒程度)し、ハッシュをキャッシュに登録という処理を行うため、この「初回スキャン」が終わるまで、DLL ロードは OS レベルでブロックされてしまい、アプリケーション側から見ると フリーズ、すなわち「固まった」ようにしか見えない状態になるわけです。一度、このスキャンを通過すれば「このファイルは安全」とキャッシュされるので、以後は高速にロードできるようになります。
自動採点の初回実行時のみ PC がフリーズしたようになり、2回目以降は何の問題もなかったかのように動作するのは、このスキャンが実行されている証拠だと思われます(このスキャンが実行されていることを直接確認する方法はないようです: AV が検査状態を外部に直接公開すると、逆にマルウェアに悪用される可能性が高まるため)。
さらに「実行形式ファイルを別の場所にコピーすると再びフリーズする」のは、 AV によっては ファイルパスや場所ごとにキャッシュが分かれるためです(同じファイルでもデスクトップに置いたら「未知扱い」になる)。
procedure TFormCollaboration.FormCreate(Sender: TObject);
var
・・・ 省略 ・・・
begin
//embPythonの存在の有無を調査(条件コンパイル)
{$IFDEF WIN32}
//32bit環境での処理
AppDataDir:=ExtractFilePath(Application.ExeName)+'Python39-32';
{$ELSE}
//64bit環境での処理
AppDataDir:=ExtractFilePath(Application.ExeName)+'Python39-64';
{$ENDIF}
if DirectoryExists(AppDataDir) then
begin
//フォルダが存在したときの処理
PythonEngine1.AutoLoad:=True;
PythonEngine1.IO:=PythonGUIInputOutput1;
PythonEngine1.DllPath:=AppDataDir;
PythonEngine1.SetPythonHome(PythonEngine1.DllPath);
PythonEngine1.LoadDll;
//PythonDelphiVar1のOnSeDataイベントを利用する
PythonDelphiVar1.Engine:=PythonEngine1;
PythonDelphiVar1.VarName:=AnsiString('var1');
//初期化
PythonEngine1.Py_Initialize;
end else begin
PythonEngine1.AutoLoad:=False;
end;
//Splashフォームを表示
theSplashForm:=TSplashForm.Create(Application);
try
theSplashForm.Show;
theSplashForm.Refresh;
theSplashForm.TimeLabel.Caption :=
'ライブラリをロード中...(スキャンにより数分かかる場合があります)';
theSplashForm.Update;
Sleep(1500);
LoadAllPythonModules; //Pythonのモジュールを読み込み
theSplashForm.TimeLabel.Caption := '準備が整いました!';
theSplashForm.Update;
Sleep(500);
FadeOutForm(theSplashForm);
theSplashForm.Close;
finally
theSplashForm.Free;
end;
・・・ 省略 ・・・
end;
上記コードを実行した結果、初回起動時、私の環境では約2分5秒間 PC が待機状態になりました。また、自動採点機能の初回使用時は、私の環境では 15 秒間待機状態が続きました。2回目のアプリケーション起動時、自動採点実行時は、いずれも待機時間は大幅に短縮され、ほとんど気にならないレベル(個人差はあると思いますが)になりました。
(2)について
(1)ではユーザーへの案内が「’ライブラリをロード中…(スキャンにより数分かかる場合があります)’」のみとなってしまい、処理の経過状況がうまく伝わらない可能性があると考え、当初、別スレッドで AV スキャンを監視し、UI (theSplashForm.TimeLabel.Caption)に進捗状況を表示できないかと考えました。そこで、.pyd ファイル(=Python モジュール)のロードと同時に監視を自動で開始し、スキャンが収束するまで待機するユーティリティ関数を作成してみたのですが、PC の環境によりインストールされている AV は異なっていて当然ですので、この AV プロセスをどうすれば確実に取得できるかという部分が、まず大きな問題となりました。
type
TAVInfo = record
Name: string;
Path: string;
end;
function DetectAVProcesses: TArray<TAVInfo>;
implementation
const
AVCandidates: array[0..4] of TAVInfo = (
(Name: 'MsMpEng'; Path: '') //動的に取得する
);
function GetProcessPath(const ProcName: string): string;
var
Snapshot: THandle;
ProcEntry: TProcessEntry32;
hProcess: THandle;
PathBuffer: array[0..MAX_PATH - 1] of Char;
begin
Result := '';
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Snapshot = INVALID_HANDLE_VALUE then Exit;
ProcEntry.dwSize := SizeOf(TProcessEntry32);
if Process32First(Snapshot, ProcEntry) then
begin
repeat
if SameText(ProcEntry.szExeFile, ProcName + '.exe') then
begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcEntry.th32ProcessID);
if hProcess <> 0 then
begin
if GetModuleFileNameEx(hProcess, 0, PathBuffer, Length(PathBuffer)) > 0 then
Result := PathBuffer;
CloseHandle(hProcess);
end;
Break;
end;
until not Process32Next(Snapshot, ProcEntry);
end;
CloseHandle(Snapshot);
end;
function DetectAVProcesses: TArray<TAVInfo>;
var
i: Integer;
L: TList<TAVInfo>;
Path: string;
Info: TAVInfo;
begin
L := TList<TAVInfo>.Create;
try
for i := Low(AVCandidates) to High(AVCandidates) do
begin
Path := GetProcessPath(AVCandidates[i].Name);
if Path <> '' then
begin
Info := AVCandidates[i];
Info.Path := Path;
L.Add(Info);
end;
end;
Result := L.ToArray;
finally
L.Free;
end;
end;
var
AVProcesses: TArray<string>;
begin
theSplashForm.TimeLabel.Caption := 'AV監視開始…';
AVProcesses := DetectAVProcesses;
if Length(AVProcesses) = 0 then
begin
theSplashForm.TimeLabel.Caption := '対象AVが見つかりません';
Exit;
end;
AVThread := TAVScanThread.Create(
AVProcesses, 10, 3, 60000,
procedure(const Msg: string)
begin
theSplashForm.TimeLabel.Caption := Msg;
end
);
AVThread.Start;
end;
(1)「ウォームアップ import」をアプリ起動時に実行だけで十分な気がしてきました!
なので、ここは潔く・・・
撤退します!
(追記_20250825 ここまで)
また、このプログラムの動作には「Microsoft Visual C ++ ランタイムライブラリ」のインストールが必要です。お使いのPCに「Microsoft Visual C ++ ランタイムライブラリ」が入っていない場合は、下記 Web サイトから「VisualCppRedist_AIO_x86_x64.exe」をダウンロードし、ダウンロードしたプログラムを管理者権限で実行し、動作に必要なライブラリをPCにインストールしてください。なお、インストール時には Windows のユーザーアカウント制御(UAC) が起動し、管理者用のID とパスワードの入力を求められます。インストールでは、exe の名称からわかるように 32 ビット版と 64 ビット版それぞれの VC++ランタイムライブラリがお使いの PC にセットアップされます。なお、インストール後は(僕のPC環境では)再起動なしで、そのまますぐに AC_Reader.exe を実行できました。
ダウンロードした zip ファイルを展開すれば、すぐにお試しいただけるよう、次に紹介する採点サンプルデータを同梱してあります。記事の説明を参照しながら、操作していただけますよう、お願い申し上げます。
この記事の冒頭にも書きましたが、プログラムの動作には「Microsoft Visual C ++ ランタイムライブラリ」のインストールが必要です。お使いのPCに「Microsoft Visual C ++ ランタイムライブラリ」が入っていない場合は、下記 Web サイトから「VisualCppRedist_AIO_x86_x64.exe」をダウンロードし、ダウンロードしたプログラムを管理者権限で実行し、動作に必要なライブラリをPCにインストールしてください。なお、インストール時には Windows のユーザーアカウント制御(UAC) が起動し、管理者用のID とパスワードの入力を求められます。インストールでは、exe の名称からわかるように 32 ビット版と 64 ビット版それぞれの VC++ランタイムライブラリがお使いの PC にセットアップされます。なお、インストール後は(僕のPC環境では)再起動なしで、そのまますぐに AC_Reader.exe を実行できました。