TOpenDialog(TSaveDialog)上にある各コントロールのIDは不変でしょうか

解決


km  2020-07-18 19:16:29  No: 148940

 先日より大変お世話になっております。
 今回は久しぶりにDelphiの質問をさせていただきます。

 現在、自作のテキストエディタのメンテナンスを行っているのですが、
その中で、TSaveDialogにコンボボックスを2つ追加するカスタマイズを
行っています。

(イメージ図)http://s.kota2.net/1595066353.png

 自分のパソコンの解像度は1920×1080なのですが、拡大率を100%
で使うと、アプリの文字やボタンが小さくなりすぎますので、125%の
状態で使用しています。

このとき、100%で使ったときと125%で使ったときで、二つのコンボ
ボックスの間隔が、大きく異なってしまうのです。

そのため、

  Rect1 := GetDlgItemRect(1148); // ファイル名のコンボボックス
  Rect2 := GetDlgItemRect(1136); // ファイルの種類のコンボボックス

として、2つのコンボボックスの位置を取得し、この高さの差を基準
に、Showイベントの中でコントロールを再配置することを考えました。
(一応成功しています。)

ここで、このID(1148や1136)は、どんな環境でも不変なものなのか、
それとも、変わってもおかしくないものなのかを知りたいと思いました。
大変恐縮ですが、以下の2点について確認させてください。

①もしのIDについて不変か否かをご存じの方がいらっしゃいましたら、
 ご教示をお願いいたします。
②もし、このIDをコンスタントに示す変数などの存在があれば、併せて
 ご教示をお願いいたします。

※環境は以下のとおりです。
 Windows10 home + Delphi10.3.3 community edition
※IDの存在及び探索には、Mr.Xray様の公開ツールを使用させていただき
 ました。あのような有用なツールをさりげなく公開されていることに、
 大変感銘を受けました。今後も愛用させていただきたいと思います。


km  2020-07-18 19:41:41  No: 148941

 自己レスです。

 ソースを見ると、ファイル名のダイアログのIDを「cmb1」として指定している
ように見える箇所があり、定数としては「$0470」が割り振られていました。これ
は1136に相当します。
 また、その付近には「cmb13」として「$047c」=1148が割り振られていました。
(ユニットはWinapi.Dlgs)です。

なんとなく、この定数で正解のようですが、もし何か情報をお持ちの方がいらっしゃい
ましたらお願いいたします。


Mr.XRAY  2020-07-19 14:05:24  No: 148944

何と書いていいのか,どう表現していいのか分かりませんが,
多分,おそらく,少なくとも,この掲示板を見ている方が,km さんの質問に対して,
満足する回答ができる方はいないと思います.


Mr.XRAY  2020-07-19 14:06:24  No: 148945

私も,どうレスしていいのか分かりません.
判断の材料となることを書いてみます.後は自分で判断してください.

フォームに複数の TButton を配置した EXE を作成します.
EXE を起動して TButton のウィンドウハンドルの値と ID の値を調べます.
EXE を終了して,また EXE を起動します.
同じ様に,TButton のウィンドウハンドルの値と ID の値を調べます.
それらの値は,前と違っているハズです.

ウィンドウ (ウィンドウコントロール) が生成されると,ウィンドウハンドルと ID が割り振られます.
それらの値は Windows が決めています.
おそらく規則性はないと考えて差支えありません. 

ウィンドウハンドルの値は変更できません.
ウィンドウコントロールの ID の値はコードで変更できます.
つまり,ID の値はそのアプリ,プログラムの仕様です.
私が,あるいは km さんが開発するアプリやプログラムの仕様の一部みたいなものです.

極端な話,Windows のバージョンやリビジョン,PC の特定の値によって,
あるいは日付によっても ID の値を変えることもできるわけです.
km さんがそのようなアプリを作成したとします.
そのアプリを使用した方が同じ様な質問をした時,答えられるのは km さんだけです.
何故なら,その ID の値を決めたのは km さんだからです.


km  2020-07-19 17:13:40  No: 148948

 ご回答ありがとうございます。言葉が足りず、申し訳ありません。

 このIDというのは、自分が割り振ったわけではありません。Delphiでは、
Vcl.ExtDlgsというユニットで、TOpenTextFileDialogという、コンボボックス
が1つだけついたダイアログがあります。

 このダイアログでは、コンボボックスの位置決めをする際、DoShow処理
において

 R := GetDlgItemRect(cmb1); // "ファイルの種類" comboxbox

という関数を使い、このRの幅に合わせてコンボボックスの横幅を決めてい
ます。

 ここで引数となっているcmb1というのは完全に決め打ちで指定していた
ため、おそらくこのID値は変わらないのだろうなと推測しました。

 別のPCでも、

 Rect1 := GetDlgItemRect(cmb1); // ファイル名のコンボボックス
 Rect2 := GetDlgItemRect(cmb13); // ファイルの種類のコンボボックス

の高さの差をとれば、2つのコンボボックスを望む形で配置できましたの
で、おそらくこれが正解なのだろうと思いました。

 このIDというのがそもそもわからなかったのですが、作る際にプログラム
側で任意に指定できるものだというのはあまり認識していませんでした。
(いつもウインドウハンドルしか相手にしていなかったので…)
もう少しほかの端末で使ってみたり、IDというものの特性を調べて勉強して
みたいと思います。


Mr.XRAY  2020-07-19 18:38:30  No: 148949

> このIDというのは、自分が割り振ったわけではありません。

私も Delphi を使用しています.
それらの ID の値を,km さんが設定したわけではないことは知っています (^^;
間違いなく km さん以外の方が設定しています.
と言うことは・・・・ 


au  2020-07-20 09:59:18  No: 148950

https://docs.microsoft.com/en-us/windows/win32/dlgbox/open-and-save-as-dialog-boxes
リンク先のExplorer-Style Control Identifiers で説明がありますが、
WindowsSDKで定義されているIDですので現状のWindows環境であれば同じ値であることが期待出来ると思います。


Mr.XRAY  2020-07-20 11:49:46  No: 148951

https://docs.microsoft.com/en-us/windows/win32/dlgbox/open-and-save-as-dialog-boxes
> リンク先のExplorer-Style Control Identifiers で説明がありますが、
> WindowsSDKで定義されているIDですので現状のWindows環境であれば同じ値であることが期待出来ると思います。 

おそらく km さんはこういう「保証」が欲しかったんだと思います
私のレスはちょっと面倒で歪んでいました.「不変」に反応してしまいました.

アプリやコンポーネントのプロパティやメソッドの仕様について「それは不変ですか ?」
という状況を想定してしまいました.


Mr.XRAY  2020-07-21 22:05:50  No: 148952

アプリ,プログラム,コンポーネント,あるいはそれらで使用しているコントロールの仕様が,
「不変」で「絶対」である保証は一般的にはありません.

String 型の変数のコードページは Delphi 2007 までは「不変」でした.
それは AnsiString 型 (日本ではコードページ 932) の文字列でした.
Delphi 2009 では UTF-16 になりました.

Indy というコンポーネントは,バージョンによってイベントの引数の形式が変わることがあります.

Windows Vista では管理者権限での実行の仕様が変わりました.
Windows 8 では Windows のバージョン取得用の関数の仕様が変更されました.
こういうことを書き出すときりがありません.

原発は絶対安全 (不変) と電力会社が言い続けていました.
実際には大変な事故が発生しました.想定外の津波が原因だそうです.

コントロールの ID 値も同じです.
それらの ID の値を設定した人 (マイクロソフトのプログラマでしょう) は,それらの ID の値を,
基本的には変更するつもりもないし,変更もしたくないでしょう.多分.
ID の値を変えてしまうと,それらの値を使用したプログラムも変更しなければなりません.
しかし,ダイアログの仕様変更の関係で変更することがあるかも知れません.
それこそ想定外のことが発生するかも知れません.

km さんのいう「環境」が何を意味するのかは不明ですが,
Windows のバージョンであるとすれば,ID の値の設定方法が,
Windows のバージョン依存でなければ問題ないと思われます ( これも絶対とは言い切れません) 
それでも,おそらく,多くのプログラマは実際に自分で確認して使用していると思われます.
私もそうです.

> WindowsSDKで定義されているIDですので現状のWindows環境であれば同じ値であることが期待出来ると思います。 

というレスがあるように,ほとんどのプログラマは,
たとえ不変という保証がなくても,「暗黙の了解事項」として受け入れて利用しているわけです.
au さんのレスも「期待」となっています.
「暗黙の了解」なんてとんでもない !! 不変かどうかハッキリしろ !!,というのであれば,
コントロールの ID を設定 (決めた) 人を探し出して問いただすしかありません.
そんなこと訊かれても困るとは思いますが.もちろん掲示板等で訊かれても困ってしまいます.
不変とは言い切れないし,不定とも言えません.かと言って使えないとも言えません.


Mr.XRAY  2020-07-21 22:07:43  No: 148953

> Windows のバージョンであるとすれば,ID の値の設定方法が,
> Windows のバージョン依存でなければ問題ないと思われます ( これも絶対とは言い切れません)  

コントロールの ID の値は,ウィンドウコントロールのウィンドウ生成時に設定できます.
コントロールの ID の値は,SetWindowLong 関数で変更できます.
マイクロソフトもどちらかの方法で設定していると思われます.
SetWindowLong 関数は Windows 98 時代から使用していますが,Windows 10 で使用しても結果は同じです.

※ ウィンドウコントロールのウィンドウ生成時というのは TButton.Create 等のことではありません.


km  2020-07-22 07:54:58  No: 148954

 すみません。現状、なかなか検証に着手できず、このままだと遅くなってしまいそうなので、まずはお礼を申し上げたく書かせていただきます。
自分が検証したかったのは、まさにau様にご提示いただいた内容です。いくら検索しても、ここには行きつきませんでしたので、大変助かりました。ありがとうございます。
Mr.XRAY、この変数が未来永劫変わらないとは思いませんが、このコードは、turbo delphi explorer 2006のソースを引用して作成していることもあり、かなり安定性の高いコードであるとは考えておりました。
ただ、全く仕組みもわからず、コピーして作成したのでは、今後どんなトラブルがあるかもわかりません。
また、エンバカデロ様が使用されているのはcmb1という変数の方だけで、cmb13というのは使用されていませんでした。au様のご提示いただいたサイトを見ると、cmb13の部分の注釈に、edt1と比較せよ、などといった記述があり、ここが気になっています。そのため、後でrectの範囲がどう違うのか、検証してみようと思っています。


km  2020-07-22 12:42:29  No: 148955

Mr.XRAY様の敬称が抜けておりました。不愉快な書き込みとなり、大変申し訳ございません。大変失礼いたしました。


mk  2020-07-23 13:44:40  No: 148956

 先ほど、表記の件について、

Rect2 := GetDlgItemRect(cmb13) と
Rect2 := GetDlgItemRect(edt1) 

の結果を取得してみました。

[cmb13]
Top  505
Left  260
Bottom  534
Right  588

[edt1]
Top  -261
Left  -107
Bottom -190
Right  1694074

自分のケースでは、基本的にはcmb13の方で大丈夫そうでした。
逆に、edt1では、範囲外の数値が取得されました。

検索すると、少なくともedt1を使うべきという書き込みはなく、
cmb13を使用している例がいくつか見つかりましたので、
当面、こちらで様子を見つつ、使用していきたいと思います。

今回ご紹介いただいたサイトは、なかなか見つけられなかった
ので、ご教示いただいて本当に助かりました。
ありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加