- PR -

全てのウィンドウを最小化(API使用)

投稿者投稿内容
ほっしゃんラブ
会議室デビュー日: 2005/03/31
投稿数: 5
投稿日時: 2005-03-31 23:43
初めて質問させていただきます。

API関数を使用し、すべてのウィンドウを最小化しようとしています。
が、うまくいきません。最小化されないどころか、無限ループ
してしまいます。
以下のような感じ記述しているのですが・・・
何かご指摘いただけないでしょうか。

使用しているAPI関数:
 CloseWindow (最小化)
 IsIconic (最小化状態かチェック)
 GetDesktopWindow (最上位のウィンドウハンドル取得)
 GetWindow (ウィンドウハンドル取得)


lngWindowHandle = GetDesktopWindow()
lngWindowHandle = GetWindow(lngWindowHandle, GW_CHILD)

Do Until lngWindowHandle = 0
If IsIconic(lngWindowHandle) = False Then
lngRet = CloseWindow(lngWindowHandle)
End If
lngWindowHandle = GetWindow(lngWindowHandle, GW_HWNDNEXT)
Loop


すみません。よろしくお願いします。
ほっしゃんラブ
会議室デビュー日: 2005/03/31
投稿数: 5
投稿日時: 2005-03-31 23:56
すみません。環境を書くの忘れました。

 OS:WindowsXP
 言語:VB.NET
 .NET:var1.1

です。よろしくお願いします。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-04-01 00:22
ウィンドウを列挙する時にGetWindowを使うべきではありません。
途中でZオーダーが変動し正確な列挙ができないどころか無限ループに陥ったりする可能性があります。
EnumWindowsを使用すべきです。
またトップレベルウィンドウ全てに対して(GUIを持たないものまで)CloseWindowするのはまずくないですか?

折角.NETを使ってるのですから、極力APIを使わず、
System.Diagnostics.Processクラスを使いましょう。
GetProcessesでプロセスの配列を取得し、
それぞれのプロセスのMainWindowHandleをチェックしてGUIを持つメインウィンドウを判別して
MainWindowHandleを引数にCloseWindowを実行すれば良いのではないでしょうか。

[ メッセージ編集済み 編集者: Hongliang 編集日時 2005-04-01 00:24 ]
ほっしゃんラブ
会議室デビュー日: 2005/03/31
投稿数: 5
投稿日時: 2005-04-01 00:44
回答ありがとうございます。

>またトップレベルウィンドウ全てに対して(GUIを持たないものまで)CloseWindowするのはまずくないですか?

・・・確かにそんな感じの動きでした。なるほど。
教えていただいたやり方で試してみます。
ありがとうございます。

(サンプルコード、どこかにありませんかね・・・)

ほっしゃんラブ
会議室デビュー日: 2005/03/31
投稿数: 5
投稿日時: 2005-04-01 10:16
Hongliangさんからのアドバイスどおり、やってみました。

どうしてもExplorerがうまく最小化されず、ウィンドウが
残ってしまいます。
以下のようにコーディングしてみたのですが、どこか
おかしいのでしょうか。。。
アドバイスいただけるとありがたいです。

ちなみに、MainWindowHandleを用いて最小化すると、余計なもの
までが最小化されるので、MainWindowTitleに何かセットされている
プロセスを最小化するようにしようかと考えています。

Dim p As System.Diagnostics.Process

For Each p In System.Diagnostics.Process.GetProcesses()
'MainWindowHandleがゼロでないプロセスを探す
If Not IntPtr.Zero.Equals(p.MainWindowHandle) Then
CloseWindow(p.MainWindowHandle.ToInt64)
End If
Next


Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-04-01 11:29
え〜、前回賢しらにProcess使えなどと言いましたが、
プロセスに複数の(トップレベル)ウィンドウがあるようなものに対しては無力ですね。
ろくに検証も考えもせずに書いてすみませんでした。

やはりEnumWindows関数を使うべきでしょう。
コールバックの中で、可視状態か、親ウィンドウを持っていないか、ポップアップウィンドウでないか、辺りをチェックすると。
//どれをチェックすれば「より安全」なのか、私も今一よく分かってません。
//あるところでは可視、トップレベル、ウィンドウテキスト、ウィンドウクラス名が"Progmon"でないか、をチェックしていました。

奥の手として、[Win]+M/Dをエミュレートする方法があります。
直接キーをエミュレートする場合は
http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=5#0174.txt
シェルを使う場合は
http://homepage1.nifty.com/MADIA/vb/vb_bbs2/200308_03080020.html
ほっしゃんラブ
会議室デビュー日: 2005/03/31
投稿数: 5
投稿日時: 2005-04-01 13:21
Hongliangさん

リンクありがとうございます。
Shellを使うやり方があったのですね・・・
これを使った動作で問題ないです。
採用させていただきます。

勉強になりました。
ありがとうございました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-04-02 06:02
「クイックランチにあるんだから、そいつをまねればいいやん」と思って、プロパティを出すも、特に情報無し。メモ帳にドラッグすると…
引用:

[Shell]
Command=2
IconFile=explorer.exe,3
[Taskbar]
Command=ToggleDesktop


シェルを使う方法ですね(--;

_________________

スキルアップ/キャリアアップ(JOB@IT)