こんばんはです。win10&D7で拡大率?の100%、125%、150%を取得するには
どのような手法になるでしょうか?
ここと同じ事をD7で行いたいと思っています。
https://okwave.jp/qa/q8972028.html
下記が参考になるかなと思ったのですが
https://www.petitmonte.com/bbs/answers?question_id=8212
レジストリは
HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI は144になっているのですが、
コントロールパネルで変更しても、ここの値に反映されないようです。
> コントロールパネルで変更しても、ここの値に反映されないようです。
> AppliedDPI は ( 以下,略 )
DPI は,私が知る限りでは拡大率のことではありません.
[ dpi - Wikipedia ]
https://ja.wikipedia.org/wiki/Dpi
procedure TForm1.Button1Click(Sender: TObject);
var
LValue : integer;
begin
LValue := Trunc(144 / USER_DEFAULT_SCREEN_DPI * 100.0);
ShowMessage(IntToStr(LValue));
end;
お返事ありがとうございます。
>DPI は,私が知る限りでは拡大率のことではありません.
たぶん、回答いただいた物のUSER_DEFAULT_SCREEN_DPIは96を入れると150が返るので
環境の値を入れろと言うことだと思いますが、その場合だとUSER_DEFAULT_SCREEN_DPI を得るにはどうすれば的な方向性になると思いますが、
そこら辺を突き進めるとまた違っているという感じになるとおもうので、DPIが何を]意味するかとかは突き進めずにコントロールパネルの「拡大縮小とレイアウト」の部分で100%125%150%175%の切り替えを行うと、どれが選択されているかを得るのが目的という感じで、逆に、この値を切り替えても上記の%が反映されていないモニターサイズを得られれば、そこから逆算という手法もあるかもなど思っています。
残念ながら,目的 ( 文章 ) が理解できません .以下は,もしかしたら参考になるかも知れない記事です.
[ WM_DPICHANGED メッセージ (WinUser.h) - Win32 apps Microsoft Docs ] - 注釈
https://docs.microsoft.com/ja-jp/windows/win32/hidpi/wm-dpichanged#remarks
コントロールパネルのディスプレーで、てきすと、あぷり、その他の項目サイズの設定で
100%/125%/150%/175%のどれかが選べますよね。
DPIのpixelを指定したいという感じでは無く。その選ばれた物が上のどれを選択されているかを取得したいのです。
(sendkeyやhandle経由で調べるというのでは無く、レジストリだったり、何かのコマンドだかで得られれが
)
目的としては、TPOINTを得るときに100%と150%では座標の返り値が変わりますよね?
それを100%で利用しているモニターでも、150%で利用しているモニターでも、自動で%を認識し
切り替えさせるのが目的になります。
以前調べた時に ShellScaling.pas がクサいと思ったのですが邪魔くさかったので
DwmGetWindowAttribute と GetWindowRect の比率でお茶を濁しました
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
//DPIが変更された時
procedure DPIChanged(var msg:TMessage);message WM_DPICHANGED;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var h:THandle;
dc:HDC;
dpi,rate:Integer;
begin
h:=GetDesktopWindow();
dc:=getdc(h);
dpi:=GetDeviceCaps(dc,LOGPIXELSX);
ReleaseDC(h,dc);
Memo1.Lines.Add(inttostr(dpi)+'dpi');
//96dpiで100%、120dpiで125%、144dpiで150%、192dpiで200%
//よって96で割れば拡大率が出るらしい
rate:=dpi*100 div 96;
Memo1.Lines.Add(IntToStr(rate)+'%');
end;
procedure TForm1.DPIChanged(var msg: TMessage);
var dpi,rate:Integer;
begin
dpi:=msg.WParam shr 16;
Memo1.Lines.Add(inttostr(dpi)+'dpi');
//96dpiで100%、120dpiで125%、144dpiで150%、192dpiで200%
//よって96で割れば拡大率が出るらしい
rate:=dpi*100 div 96;
Memo1.Lines.Add(IntToStr(rate)+'%');
end;
end.
ではダメでしょうか。外していたらすいません。
て、さん。mamさんありがとうございます。
>て、さん
私も ShellScaling.pas のにおいをかぎつけたの調べていたのですが ShellScaling.pasはD7にはないようでした。
DwmGetWindowAttribute と GetWindowRect の代替案をいただいたので、どちらとも初見なので今から調べてみたいと思います。
>mamさん
やりたいことの意図が伝わっているようでよかったです。
WM_DPICHANGED; はD7では来ないようでしたが、deko様のページを見たところリアルタイムで切り替えを得るものとのことなので
https://ht-deko.com/ft1601.html
リアルタイムでは無くてもいいのでButton1にしたら出来るかなとおもい試してみました。
ところ。ここが同じ値しか返らないのようなので調べてみたところ
これが理由なんだと思うのですが、環境が違うので代用無理でした。
https://gist.github.com/retorillo/4e0c4a3cf4c7096e05ac
マニフェストファイルを埋め込む方法は簡単だと思います。
delphi10.4などが吐き出すリソース内のマニフェストの真似をしてみるのが1番簡単だと思います。適用の仕方は検索すればすぐ出てきます。
-----書き足す内容、ご指定のサイトより
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"
manifestVersion="1.0">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
-----参考(マニフェストの埋め込み方法ではないですが)
>あ。さん
ありがとうございます。
調べてみましたが、DWMAPIをusesし WindowsXP.resの</assembly>の上に追加すればいいと、みたページに書いてあったので上記を差し込んでみましたが、どう反映するのかが不明でしたので</assembly>の下に差し込んだり、全部入れ替えてみましたが反映確認できませんでした。
初物過ぎて私には簡単じゃやいっぽいです。
>て 。さん
す。スバラシイ!!
て。さんの方法で無事取得できました。わかりやすい方法でたすかりました。
皆さんありがとうございました。無事解決させていただきました♪
Windows 8.1 以降限定、Shcore.dll の GetScaleFactorForMonitor を使う。
type
TGetScaleFactorForMonitor = function (hMon: HMONITOR; out Scale: Integer): HRESULT; stdcall;
var
hProc81: TGetScaleFactorForMonitor;
@hProc81 := GetProcAddress(hLib, PChar('GetScaleFactorForMonitor'));
hProc81(Screen.Monitors[0].Handle, hogehoge)
125%であれば hogehoge = 125 が返る。
という仕様と思って作った自作関数があったけど、使ってないので、使えるものかわからない。
自分で使っているのは、EnumDisplaySettingsExAでTDevModeを取得し、
その幅と、Screen.Monitors[xxx].Width との差を使っていた。
テストしてみました.
[ ディスプレイの DPI を取得 ]
http://mrxray.on.coocan.jp/Delphi/Others/GetDisplayDPI.htm
> DwmGetWindowAttribute と GetWindowRect の比率でお茶を濁しました
もサンプルを作成したかったのですが,残念ながら・・・
追記ありがとうございます。
のちほど一段落しましたら試さしていただこうと思います。
ありがとうございました。
> のちほど一段落しましたら試さしていただこうと思います。
すでに解決しているのて,必要ないと思いますよ.
リンクの記事は,もし,検索でこのスレッドにきた方のためです.
ついでに,このスレッドで話題がでた関数類も,と思ったのです.
[ 04_コミュニティの場は give & take ( ギブ・アンド・テイク ) ]
http://mrxray.on.coocan.jp/Delphi/Others/013.htm#04
ツイート | ![]() |