[リストへもどる]
一括表示

投稿時間:2002/08/28(Wed) 05:50
投稿者名:MS
URL :
タイトル:
タスクバー「自動的に隠す」の設定/解除
Windows98のタスクバーのプロパティダイアログ「自動的に隠す」
の設定/解除と同じことをVB6からコードでやりたいのですが、
SHAppBarMessageでABM_SETAUTOHIDEBARメッセージを送っても
WindowsのTaskBarは反応しない様です。何か方法ないでしょうか?

投稿時間:2002/08/28(Wed) 10:26
投稿者名:K.J.K.
Eメール:akiya@koalanet.ne.jp
URL :
タイトル:
Re: タスクバー「自動的に隠す」の設定/解除
# 回答ではありません。

RegMonとSPY++を使って、レジストリのキー及び通知メッセージを調べてみるとか。

投稿時間:2002/08/28(Wed) 11:27
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re: タスクバー「自動的に隠す」の設定/解除
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/t
askbar.asp

によれば、ABM_SETSTATE で設定できるそうです。(未検証)

このURLを拾った海外サイトのDelphiフォーラムでは不可能という回答がついていて、
その根拠として示されていたURLが上記です。上記URLの引用部分に確かに
「プログラム上からは設定できない」とあったので、新しく追加された機能かもしれませんので、
dllのバージョンに依存するかもしれません。

投稿時間:2002/08/28(Wed) 11:38
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^2: タスクバー「自動的に隠す」の設定/解除
#すいません。パスワードの設定を忘れて投稿してしまったので、修正できません(T T)

少し意味不明な文章になっているので、訂正します。

> このURLを拾った海外サイトのDelphiフォーラムでは不可能という回答がついていて、
> その根拠として示されていたURLが上記です。上記URLの引用部分に確かに
> 「プログラム上からは設定できない」とあったので、新しく追加された機能かもしれませんので、
> dllのバージョンに依存するかもしれません。

このURLを拾った海外サイトのDelphiフォーラムでは、
「自動的に隠す」の設定変更は不可能という回答が何度かついており、
その根拠として示されていたURLが上記です。
フォーラムの中で上記URLの一部が引用されていて、内容としては、
「自動的に隠す等の設定は、プログラム上からは設定できない」という文章でした。

しかし、実際に今、上記URLを覗いて見て、引用されていた該当部分を探すと、
「プログラム上からは設定できない」という内容だった部分が、「ABM_SETSTATE で設定できる」という
内容に変わっていたので、文章が修正されたと思われます。そのため、
新しく追加された機能かもしれませんので、dllのバージョンに依存するかもしれません。

・・・ということを書きたかったのですが、変な文章になっていてすいません。

投稿時間:2002/08/28(Wed) 15:10
投稿者名:MS
URL :
タイトル:
Re^3: タスクバー「自動的に隠す」の設定/解除
回答ありがとうございます。

自分なりに少し調べてみたんですが、ABM_SETSTATEは、WinNT用
みたいなことが書いてありました。
でも、Win98で実際に確認したいと思っていますが、手持ちの
shellapi.h が旧いのでABM_SETSTATEの定数値が載っていません。
ご存知でしたら教えて下さい。

投稿時間:2002/08/28(Wed) 15:36
投稿者名:あき☆彡
Eメール:
URL :
タイトル:
Re^4: タスクバー「自動的に隠す」の設定/解除
> shellapi.h が旧いのでABM_SETSTATEの定数値が載っていません。
> ご存知でしたら教えて下さい。

VC.NETのShellAPI.hより

#define ABM_SETSTATE      0x0000000a

投稿時間:2002/08/28(Wed) 17:47
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^5: タスクバー「自動的に隠す」の設定/解除
> > shellapi.h が旧いのでABM_SETSTATEの定数値が載っていません。
> > ご存知でしたら教えて下さい。

私の方でもABM_SETSTATEの値がわからず困っていたので、

> VC.NETのShellAPI.hより
>
> #define ABM_SETSTATE      0x0000000a

助かります。m(_ _)m
#調べる手段がなかったので、For文で第一引数をぐるぐる回して総当たりしてみたりしてました(^^;

で、私の環境(VB5+SP3、WinNT4.0SP5、IE5.5)で試した範囲でうまくいきません。
やり方がまずいのか、そもそも無理なのか・・・うーむ。
MSサイトのABM_SETSTATEの説明では、戻り値は常にTRUEとあるのですが、
戻り値が0になっています・・・。

Private Const ABM_SETSTATE = &HA

Private Sub Command1_Click()
    Dim a As APPBARDATA
    Dim ret As Long
    
    a.cbSize = Len(a)
    a.hwnd = FindWindow("Shell_TrayWnd", vbNullString)
    a.lParam = ABS_AUTOHIDE
    
    ret = SHAppBarMessage(ABM_SETSTATE, a)
    Debug.Print "ret=", ret
End Sub

#APIの宣言と他の定数宣言は省略。

投稿時間:2002/08/28(Wed) 18:36
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^6: タスクバー「自動的に隠す」の設定/解除
    Dim uAppBarData  As APPBARDATA
    Dim Ret As Long
    uAppBarData.cbSize = Len(uAppBarData)
    uAppBarData.hWnd = FindWindow("Shell_TrayWnd", vbNullString)
    uAppBarData.uEdge = ABE_BOTTOM
    uAppBarData.lParam = ABS_AUTOHIDE
    Ret = SHAppBarMessage(ABM_SETSTATE, uAppBarData)

ABE_BOTTOM で タスクバーの位置を指定すればどうでしょう
(上記なくてもOKですね)

私の環境では上記で設定できました。\(-o-)/
WinXP VB6.0(SP5)

やはり、Win98 SE VB6.0(SP5) の環境では出来ませんでした。

投稿時間:2002/08/28(Wed) 20:10
投稿者名:MS
URL :
タイトル:
Re^7: (お礼)タスクバー「自動的に隠す」の設定/解除
> VC.NETのShellAPI.hより
> #define ABM_SETSTATE      0x0000000a

あき☆彡 さん ありがとうございます
。助かりました。

よねKEN さん 花ちゃん さん ありがとうございます。
レス遅れてごめんなさい。教えて戴いたMSDNの和訳に手間どって
しまいました。
お二方の方法をWiindows98で試させて戴きました。
やはり、MSDNに
 Windows NT/2000: Requires Windows NT 3.51 or later.
あるとおりで、うまくいきませんでした。

何か他の方法を模索してみたいと思います。
いろいろと、ありがとうございました。

投稿時間:2002/08/29(Thu) 13:45
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^7: タスクバー自動的に隠す
> ABE_BOTTOM で タスクバーの位置を指定すればどうでしょう
> (上記なくてもOKですね)

これを設定するのも(花ちゃんのコードで)試してみましたが、うまくいきませんでした。
ものすごく基本的な確認ですが、ABS_AUTOHIDEの設定でうまくいった場合、
タスクバーが自動的に隠れるようになるんですよね?

そう思っていろんなパターン(rcも設定してみるとか)を試してますが、
VB5SP3で、WinNT4.0SP5とWin2000SP2とでうまくいきません。
WinXPでうまくいくんだったら、Win2000の方ぐらいは少なくともうまくいくと思ったんですが・・・。

SHAppBarMessage、FindWindowの定義、各ユーザ定義型、定数の定義はAPIビューワから取ってきて、
宣言はFormにすべてPrivateで宣言しています。
ABM_SETSTATEの定義は、あき☆彡さんの情報より以下のように定義してます。
Private CONST ABM_SETSTATE=&HA

タスクバーを「自動的に隠す」に設定する処理はCommand1_Clickに書いてます。
実行環境から、EXEにしてから、両方で試しましたが、どちらも駄目でした。
この処理を行って、すぐに反映されて、タスクバーが隠れるようになったのでしょうか?

投稿時間:2002/08/29(Thu) 14:32
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: タスクバー「自動的に隠す」のサンプル
Option Explicit     'SampleNo=198 WindowsXP VB6.0(SP5) 2002.08.29

'タスクバーの矩形を示す RECT 構造体(P689)
Private Type RECT
    left   As Long
    top    As Long
    right  As Long
    bottom As Long
End Type

'データを格納する APPBARDATA 構造体(P689)
Private Type APPBARDATA
    cbSize As Long              '構造体のサイズ
    hWnd   As Long              'タスクバーのウインドウのハンドル
    uCallbackMessage As Long    'コールバック関数へのポインタ
    uEdge  As Long              'タスクバーの位置を示す次の定数
    rc     As RECT              'タスクバーの矩形を示す RECT 構造体
    lParam As Long              'メッセージのパラメータ
End Type

'アプリケーションバーのメッセージをシステムに送る(P687)
Private Declare Function SHAppBarMessage Lib "shell32.dll" _
    (ByVal dwMessage As Long, pData As APPBARDATA) As Long
'クラス名、又は、キャプションタイトルを与えてウインドウのハンドルを取得(P81)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Const ABM_GETSTATE = &H4    '自動的に隠す・常に手前に表示の状態を取得
Private Const ABM_SETSTATE = &HA    '自動で隠すに設定する(P688)
Private Const ABS_AUTOHIDE = &H1    '自動で隠す(P688)
Private Const ABS_ALWAYSONTOP = &H2 '常に手前に表示(P688)

Private Sub Command1_Click()
    Dim pData  As APPBARDATA
    Dim Ret    As Long
    Dim Flag   As Boolean
    
    With pData
        .cbSize = Len(pData)    '構造体のサイズを取得
        'タスクバーのクラス名を与えてハンドルを取得
        .hWnd = FindWindow("Shell_TrayWnd", vbNullString)
        '現在の設定状態を取得
        Ret = SHAppBarMessage(ABM_GETSTATE, pData)
        Flag = Ret And ABS_AUTOHIDE
        If Flag Then    '自動で隠すの設定の場合
            .lParam = ABS_ALWAYSONTOP   '常に手前に表示設定
        Else            '常に手前に表示設定の場合
            .lParam = ABS_AUTOHIDE      '自動で隠すの設定
        End If
    End With
    'タスクバー自動で隠す/手前に表示設定
    Ret = SHAppBarMessage(ABM_SETSTATE, pData)
    DoEvents
End Sub

WindowsXP(Home) VB6.0(SP) IE6.0
以上の設定と環境で自動で隠す/手前に表示の設定ができ動作しています。
EXE ではまだ試していませんが、このままの状態でOKで終了後も設定が有効のままです。

同じの Windows98SE VB6.0(SP5) で試すと設定が有効(できない)になりません。
サンプル中問題点等ありましたら、ご教授下さい。

投稿時間:2002/08/29(Thu) 14:59
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^2: (実行結果)タスクバー「自動的に隠す」のサンプル
サンプルありがとうございます。
以下の環境ですが、やはり動作しませんでした。
となると私の環境で動かないのは、コードの問題ではないのかもしれません。

WinNT4.0 Workstation(SP5)、VB5(SP3)、IE5.5
Shell32.dll ver4.00

投稿時間:2002/08/29(Thu) 15:09
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: (実行結果)タスクバー「自動的に隠す」のサンプル
Windows2000 の方も動かないのでしょうか?

shell32.dll のバージョンの関係でしょうか
バージョン6.0以上でないとだめとか
 
WinXP = 6.0.2600
Win98SE = 4.72

他のOS等でも動作確認された方おられましたら、教えてください。
Windows95 は勿論だめでした。

投稿時間:2002/08/29(Thu) 20:42
投稿者名:あき☆彡
Eメール:
URL :
タイトル:
Re^4: (実行結果)タスクバー「自動的に隠す」のサンプル
> Windows2000 の方も動かないのでしょうか?
> 他のOS等でも動作確認された方おられましたら、教えてください。

私の環境も動作しませんでした。

Windows2000Server(SP2)
VB6(SP5)
IE6.0
shell32.dll(5.0.3315.2902)

投稿時間:2002/08/29(Thu) 22:12
投稿者名:よねKEN
Eメール:
URL :
タイトル:
Re^4: (実行結果)タスクバー「自動的に隠す」のサンプル
> Windows2000 の方も動かないのでしょうか?

Windows2000 Pro(SP2)、VB5(SP3)、IE6.0
Shell32.dll ver5.00.3502.4718
の環境で動きませんでした(T T)

後、ME、XPの情報は含まれませんが、
OSとIEとShell32.dllの関係の情報があったので参考までに。
http://www.runan.net/program/tips/sdk_11_define_WINVER.shtml

投稿時間:2002/08/29(Thu) 20:45
投稿者名:NAO★
Eメール:
URL :
タイトル:
Re^2: (実行結果)タスクバー「自動的に隠す」のサンプル
Windows2000 Proではうまく機能しませんでした。

XPではうまく行きました。

投稿時間:2002/08/29(Thu) 22:23
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
(お礼)(実行結果)タスクバー「自動的に隠す」のサンプル
> Windows2000 Proではうまく機能しませんでした。
>
> XPではうまく行きました。

よねKENさん、NAO★さん、あき☆彡さん ありがとうございます。

やはり、WindowsXP だけのようですね

投稿時間:2002/09/02(Mon) 15:13
投稿者名:MS
URL :
タイトル:
Re: (続)タスクバー「自動的に隠す」の設定/解除
Win98で実現する方法をいろいろと模索してみんですが、いい手が見つか
らず、結局、ダイアログ設定の操作手順をコードに置換えてみました。
以下がWin98限定のコードです。
この方法の問題は、ダイアログ設定の終了後、Formがアクティブになり
ません。フォアグラウンドウィンドウのスレッドとインプット状態を
共有する方法でアクティブになると思ったのですが。
回避策をご指導下さい。宜しくお願いします。

' Form Code
Option Explicit
Private Type RECT
    Left   As Long
    Top    As Long
    Right  As Long
    Bottom As Long
End Type
Private Type APPBARDATA
    cbSize           As Long
    hwnd             As Long
    uCallbackMessage As Long
    uEdge            As Long
    rc               As RECT
    lParam           As Long
End Type
Private Declare Function SHAppBarMessage Lib "shell32.dll" _
        (ByVal dwMessage As Long, pData As APPBARDATA) As Long
Private Const ABM_GETSTATE = &H4
Private Const ABS_AUTOHIDE = &H1

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
         ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Sub Sleep Lib "kernel32" _
        (ByVal dwMilliseconds As Long)
Private Declare Function GetDlgItem Lib "user32" _
        (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
' Private Const ID_ALWAYSONTOP = 1101
Private Const ID_AUTOHIDE = 1102
Private Const ID_OK = 1
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Long, ByVal wMsg As Long, _
         ByVal wParam As Long, lParam As Any) As Long
Private Const BM_CLICK = &HF5
Private Const BM_SETCHECK = &HF1
Private Const BST_UNCHECKED = 0
Private Const BST_CHECKED = 1

Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetForegroundWindow Lib "user32" _
        (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
        (ByVal uAction As Long, ByVal uParam As Long, _
         ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Private Const SPI_GETFOREGROUNDLOCKTIMEOUT = 2000
Private Const SPI_SETFOREGROUNDLOCKTIMEOUT = 2001
' Private Const SPIF_UPDATEINIFILE = 1
' Private Const SPIF_SENDWININICHANGE = 2
Private Declare Function AttachThreadInput Lib "user32" _
        (ByVal idAttach As Long, ByVal idAttachTo As Long, _
         ByVal fAttach As Long) As Long

Private Sub Command1_Click()
    Static fChkState As Boolean
    fChkState = Not fChkState
    Call SetTaskBarAutoHide(fChkState)
    DoEvents
    Call SetForegroundWnd(Me.hwnd)
End Sub

Private Sub SetTaskBarAutoHide(ByVal fChkState As Boolean)
    Dim hwndTask As Long
    Dim pbd As APPBARDATA
    Dim fIsAutoHide As Boolean
    Const sDlgTitle As String = "タスク バーのプロパティ"  ' Win98
    Dim oShell As Object
    Dim hwndDlg As Long
    Dim hwndChild As Long
    Dim hwndChk As Long
    ' [自動的に隠す]の状態を得る
    hwndTask = FindWindowEx(0, 0, "Shell_TrayWnd", vbNullString)
    pbd.cbSize = Len(pbd)
    pbd.hwnd = hwndTask
    fIsAutoHide = CBool(SHAppBarMessage(ABM_GETSTATE, pbd) And ABS_AUTOHIDE)
    If (fIsAutoHide And Not fChkState) Or (Not fIsAutoHide And fChkState) Then
        Call SetForegroundWindow(hwndTask)
        ' [タスク バーのプロパティ]ダイアログの起動
        Set oShell = CreateObject("Shell.Application")
        oShell.TrayProperties
        Set oShell = Nothing
        ' ダイアログ表示まで待機
        Do
            hwndDlg = FindWindowEx(0, 0, "#32770", sDlgTitle)
        Loop While (hwndDlg = 0)
        ' [自動的に隠す]チェックボックスの操作
        Call Sleep(100) ' 念のため
        hwndChild = FindWindowEx(hwndDlg, 0, "#32770", vbNullString)
        hwndChk = GetDlgItem(hwndChild, ID_AUTOHIDE)
        If (fIsAutoHide And Not fChkState) Then ' Check OFF
            Call SendMessage(hwndChk, BM_SETCHECK, BST_UNCHECKED, ByVal 0&)
        ElseIf (Not fIsAutoHide And fChkState) Then ' Check ON
            Call SendMessage(hwndChk, BM_SETCHECK, BST_CHECKED, ByVal 0&)
        End If
        ' [OK]ボタンでダイアログを閉じる
        Call SendMessage(GetDlgItem(hwndDlg, ID_OK), BM_CLICK, 0, ByVal 0&)
    End If
End Sub

Private Sub SetForegroundWnd(ByVal hwnd As Long)
    Dim dwCurThreadID As Long
    Dim dwThreadID As Long
    Dim dwLockTime As Long
    dwCurThreadID = GetWindowThreadProcessId(GetForegroundWindow(), ByVal 0)
    dwThreadID = GetWindowThreadProcessId(hwnd, ByVal 0)
    If (dwThreadID <> dwCurThreadID) Then
        Call AttachThreadInput(dwThreadID, dwCurThreadID, 1)
        Call SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, dwLockTime, 0)
        Call SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0)
        Call SetForegroundWindow(hwnd)
        Call SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, dwLockTime, 0)
        Call AttachThreadInput(dwThreadID, dwCurThreadID, 0)
    Else: Call SetForegroundWindow(hwnd)
    End If
End Sub

投稿時間:2002/09/02(Mon) 16:17
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^2: (続)タスクバー「自動的に隠す」の設定/解除
> この方法の問題は、ダイアログ設定の終了後、Formがアクティブになり
> ません。

これって、このプログラムを起動したフォームがアクティブになって
いればいいのですよね?

Windows95・Windows98(A)・Windows98(SE) でOKでした。

それとも、私の見当違いですか?

投稿時間:2002/09/02(Mon) 17:03
投稿者名:MS
URL :
タイトル:
Re^3: (続)タスクバー「自動的に隠す」の設定/解除
回答ありがとうございます。

> これって、このプログラムを起動したフォームがアクティブになって
> いればいいのですよね?

その通りです。

> Windows95・Windows98(A)・Windows98(SE) でOKでした。

EXEの場合、一旦フォームとそのタスクボタンがアクティブになってから直ぐ
非アクティブ表示に変わってしまいます。
IDEの場合はアクティブになったり、非アクティブになったりで一定しません。
これは私だけなんでしょうか?

投稿時間:2002/09/02(Mon) 17:25
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^4: (続)タスクバー「自動的に隠す」の設定/解除
念のためEXEにして試して見ましたが同じです。
タスクバーのプロパティが表示している間は非アクティブですが
それ以外はフォームはアクティブ状態です。
只、EXEの時にアプリをいくつか表示させていると?、偶に戻らない時が
あるようです。メモ帳1個位なら、なりません。なかなか、再現ができないので!!

投稿時間:2002/09/03(Tue) 00:22
投稿者名:MS
URL :
タイトル:
Re^5: (続)タスクバー「自動的に隠す」の設定/解除
レスありがとうございます。
再現性に乏しい現象の様で申し訳ありません。

その後、呼び出し側フォームがアクティブにならない現象について
分析してみました。
どうやら、[OK]ボタンでプロパティダイアログを閉じた後もWindows
が関連処理を継続しているらしく、その途中のアクティブウィンドウ
にアタッチしても、直ぐアクティブウィンドウが変更されてしまうた
めと思われます。
回避策ですが、関連処理の終了イベントを検出するか、監視できれば
確実なのですが、とりあえず、[OK]ボタンでダイアログを閉じた後に
Sleep関数で適当な時間(私の場合は500ms)だけ実行を中断することで
終了を待つ様にしたらうまくいきました。
これは、私の場合だけに有効なのかも知れません。

投稿時間:2002/09/03(Tue) 00:54
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^6: (続)タスクバー「自動的に隠す」の設定/解除
> Sleep関数で適当な時間(私の場合は500ms)だけ実行を中断することで

私も同様に Call Sleep(200) で試してはいたのですが、それが効いているのか
たまたま、現象が発生しないの区別がつかなかったので報告をためらっていたのですが
原因が特定できてなによりですね。

投稿時間:2002/09/03(Tue) 01:20
投稿者名:MS
URL :
タイトル:
Re^7: (お礼&解決)(続)タスクバー「自動的に隠す」の設定/解除
花ちゃん さん いろいろお世話になり、ありがとうございました。
これで、解決とさせて戴きます。