たびたびお世話になります。VC++6.0 MFCで開発を行っています。
今、デスクトップ上にWindows付属の電卓が起動されている状態で 電卓のハンドルを
取得は取得できたのですが、電卓の中にあるボタン( 数字 英字、など)やエディット
ボックスのハンドルを取得して 各コントロールのハンドルからスクリーン座標を取得し
たいのですが、どうようにすればよろしいでしょうか??
EnumWindowみたいに コントロールの一覧を取得するような関数とかあるのでしょう
か??
ご教授よろしくお願いします。
EnumChildWindows。
>EnumWindowみたいに コントロールの一覧を取得するような関数とかあるのでしょうか??
EnumChildWindows()で子ウィンドウの列挙が可能かと。
Win32APIですが…
シャノンさん。瀬戸っぷさん。ありがとうございます。
EnumWindows( )と組み合わせて使うことで うまくデスクトップ上に表示させている
ウィンドウの各コントロールの座標を取得することができました。
しかしながら ここで質問があります。デスクトップ上に表示させているウィンドウ
のみ対して 、EnumChildWindows()で取得したハンドルの中に コントロールとまったく
関係のない位置の座標が含まれてしまいます。
※デスクトップ上に表示させているウィンドウのハンドルの取得条件は デスクトップ
のハンドルでない かつ 最小化されていないという判別で処理をしています。
上記の条件であるフォルダのみを表示させ、フォルダのウィンドウの位置を左上隅に
もっているにも関わらず ウィンドウが表示されていない、まったく違う場所の座標
(デスクトップの真ん中あたり)を取得しているのです。
これは何か判別式が足りていないのでしょうか??それとも 何か処理が抜けているの
でしょうか??ご教授よろしくお願いします
コントロールの位置をGetClientRectで取得しているなら、その位置は親ウィンドウのク
ライアント領域との相対位置ではなかったかしら。
つまりたとえばクライアント領域の左上隅に貼り付けていたら、その位置は(0,0)となる
んでは?
非表示の窓は排除できてます
か。
επιστημη さん。Banさん。ありがとうございます。
>コントロールの位置をGetClientRectで取得しているなら
EnumChildWindow()で取得したウィンドウに対しては GetWindowRect() で位置を取得
しています。この場合は ClientToScreen() を使用する必要はありませんよね??
>非表示の窓は排除できてますか
EnumWindow()の処理としては取得したハンドルに対して以下のように判別をしていま
す
i) デスクトップのハンドルでない
ii) IsWindowVisible() == true である
iii) IsIconic() != true
そして これら3つの条件をすべて満たしているものに対してEnumChildWindo
w()を呼び出しています。EnumChildWindow()内で何かもっと処理を増やしてやらないと
いけないでしょうか??
内部用のウィンドウを裏に放置しているのでは?
# メッセージ受信等で意味があってやっているのかも知れませんが、
# 単に消し忘れコントロールがリソースに残ってるとか…。
> i) デスクトップのハンドルでない
> ii) IsWindowVisible() == true である
> iii) IsIconic() != true
見返したら、これは EnumWindows の条件なのですね。
現状、EnumChild~の方は完全にチェック無しですか?
表示されているウィンドウ上の、非表示の子ウィンドウとかもありえるはずですが、
それは排除できていますか。
Spy++で調べることが出来る結果と見比べてみるとか。
非表示のコントロール(というか子ウィンドウ)なんてのはそこそこあるかと。
> i) デスクトップのハンドルでない
> ii) IsWindowVisible() == true である
> iii) IsIconic() != true
問題ないかもしれないけど
IsWindowVisible
指定したウィンドウとその親ウィンドウが表示状態のときは (WS_VISIBLE スタイルを
持つときは) 、0 以外の値が返ります。
IsIconic
ウィンドウが最小化されているときは、0 以外の値が返ります。
ということなので、bool型のtrueか、falseが帰るわけではないです。
(戻り値はBOOL型。BOOL型はint型の#define)
よって、0か0以外かという判定をすべきなわけで、trueと比較するのは正しくなさそう
です。
IsWindowVisible() != FALSE
IsIconic() == FALSE
といった具合に、FALSEと比較しましょう。
------------------------------------------------------------------
#include <windows.h>
int main( void )
{
BOOL b = 10;
::MessageBox( NULL, ( b == true ) ? OK : NG, ", MB_OK );
return 0;
}
warning C4805: '==' : 演算中の 'int' 型と 'const bool' 型の混用は安全ではありま
せん
追記
> といった具合に、FALSEと比較しましょう。
なぜ、FALSEと比較するかは、TRUEの定義がどうなっているのかを調べてみればすぐにわ
かります。
# この話過去ログにあったと思うけど、検索キーワードがわからないので見つけにく
い、、、
>なぜ、FALSEと比較するかは、TRUEの定義がどうなっているのかを調べてみればすぐにわ
>かります。
># この話過去ログにあったと思うけど、検索キーワードがわからないので見つけにく
>い、、、
過去ログ探してませんが一応補足です。
http://www.cmagazine.jp/src/kinjite/c/coding.html#index28
>ドルドルさん
ウィンドウの位置だけでなくウインドウクラス名や
スタイルなども調べてみると問題を特定しやすいかもしれません。
Banさん。瀬戸っぷさん。Blueさん。subaruさん。
丁寧な解説と親切なご指摘。ありがとうございましたm(_ _)m。
>Banさん
>表示されているウィンドウ上の、非表示の子ウィンドウとかもありえるはずですが、
>それは排除できていますか。
EnumChildWindow() に関してはまったく条件判別処理を行っていませんでした。
EnmuWindow()のIsVisible()処理で完全に処理できていたと勘違いしていましたの
で・・・。
>瀬戸っぷさん
>非表示のコントロール(というか子ウィンドウ)なんてのはそこそこあるかと
ここでの判別処理は ”Banさん”、”瀬戸っぷさん” がご指摘されておられるよう
に、非表示の処理でいいのですかね?? 他にやるべきことってありますでしょうか??
>Blueさん。
>IsWindowVisible() != FALSE
>IsIconic() == FALSE
>といった具合に、FALSEと比較しましょう。
たしかにコンパイルが完了すると 警告がでているのが確認できていましたが、特に
今まで意識していなかったです。このことは今回の質問のみならず今後も大切なことだ
と痛感しました。今後気をつけていきたいと思います。
>subaruさん。
>ウィンドウの位置だけでなくウインドウクラス名やスタイルなども調べてみると
まったく ご指摘された方法の観点から見ることができていませんでした。
GetClassName() とか GetWindowLong() メソッドを使って調べてみます。
みなさん、手数をおかけしましてすいませんが よろしくお願いします。
前述のように、非表示の子ウィンドウのほかにも、
> 内部用のウィンドウを裏に放置しているのでは?
なども考えられます。ボタンの裏に何か隠れてるとか…。
# 警告は、Level4にして全部つぶす(or確認する)くらいが妥当だと
# 私は思ってます。