No.1ベストアンサー
- 回答日時:
>WinXPとVB.NETで休止やスタンバイのイベントを受け取るには?
WndProc (WindowsProcとも言われたりします)
を利用します。
ただ、これはシステムフックをする事になるので、ここでは
1・重い負荷を与える処理
2・ユーザからの入力を待機する処理
はご法度です!!
もしそのような処理を入れた場合、
1・システムが次の処理を走らすことができず、動作が不安定になる
2・システムが次の処理を走らすために、アプリ側で捕まえられた処理をタイムアウトとして扱い、アプリ側の変更を受け付けなくなる
という事がありえます。
これを回避するには処理を分割しましょう。↓にまとめます。
1.休止orサスペンド要求イベントを認識する
2.休止orサスペンド要求イベントの継続を破棄する
3.ユーザに休止orサスペンドがあったことを通知する
4.ユーザに休止orサスペンドを行うかを問い合わせをする
5.ユーザへの問い合わせ結果によって、処理を行う
参考[休止状態/サスペンドの破棄]を応用
http://www.microsoft.com/japan/msdn/vbasic/migra …
参考[休止状態/サスペンドの実行]を応用
http://www.vbvbvb.com/jp/gtips/0301/gSetSystemPo …
そこで問題となるのが、休止orサスペンドのどちらの要求が送られてきているのかがわからないということです。こればかりは仕方がありません。
なので、どのような処理にするかはユーザに任せてしまうか、サスペンド限定するなどの対応が必要になります。
電源イベント通知を即座に行わず、後で通知する方法は、私の場合であれば、タイマを利用する方法しか思いつきませんが、もっとよい方法があるかも知れません。
以下が、サンプルです。
WindowsApplication1.vbproj
├Form1.vb(コントロールは、何も置かないでいいです)
└Class1.vb
※Form1.vb
--------------------------------------------------------------------------------
Public Class Form1
Inherits System.Windows.Forms.Form
Private WithEvents m_obj休止 As New 休止監視()
Private m_objListデバッグ用 As New ListBox()
#Region " Windows フォーム デザイナで生成されたコード "
~~~ここは略します~~~
#End Region
'イベント/フォーム/ロード
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'デバッグ用のリストボックスの初期設定
Me.Controls.Add(m_objListデバッグ用)
m_objListデバッグ用.Size = Me.ClientSize
End Sub
'イベント/休止オブジェクト/発生処理
Private Sub obj休止_発生処理(ByVal モード As 休止監視.処理モード) Handles m_obj休止.発生処理
'発生したイベント内容をデバッグ用リストボックスに追加
Dim l_strワーク As String = IIf(モード = 休止監視.処理モード.再開, "再開", "休止")
m_objListデバッグ用.Items.Add(System.DateTime.Now.ToString & " " & l_strワーク)
m_objListデバッグ用.SelectedIndex = m_objListデバッグ用.Items.Count - 1
End Sub
'イベント/休止オブジェクト/発生通知
Private Sub obj休止_発生通知(ByRef モード As 休止監視.休止モード) Handles m_obj休止.発生通知
'サスペンドor休止状態が起ころうとしたことを通知
'さらに、遂行する処理を返却する
Dim l_msgRet As Microsoft.VisualBasic.MsgBoxResult
Dim l_strMsg As String = ""
l_strMsg &= "は い: サスペンド" & vbCrLf
l_strMsg &= "いいえ: 休止状態" & vbCrLf
l_strMsg &= "CANCEL: 何もしない" & vbCrLf
l_msgRet = MsgBox(l_strMsg, MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Question, "休止モード継続お知らせ")
Select Case l_msgRet
Case MsgBoxResult.Yes
モード = 休止監視.休止モード.サスペンド
Case MsgBoxResult.No
モード = 休止監視.休止モード.休止状態
Case MsgBoxResult.Cancel
モード = 休止監視.休止モード.未処理
End Select
End Sub
'イベント/システム/WindowsProc
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If Not m_obj休止.メッセージ処理(m) Then
Return
End If
MyBase.WndProc(m)
End Sub
End Class
※Class1.vb
--------------------------------------------------------------------------------
Imports System
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Public Class 休止監視
#Region "属性"
Public Event 発生通知(ByRef モード As 休止モード)
Public Event 発生処理(ByVal モード As 処理モード)
#Region "定数"
Private Const WM_POWERBROADCAST As Integer = &H218
Private Const PBT_APMQUERYSUSPEND As Integer = &H0
Private Const BROADCAST_QUERY_DENY As Integer = &H424D5144
#End Region
#Region "型"
Private Structure tagLUID
Dim LowPart As Integer
Dim HighPart As Integer
End Structure
Private Structure LUID_AND_ATTRIBUTES
Dim Luid As tagLUID
Dim Attributes As Integer
End Structure
Private Structure TOKEN_PRIVILEGES
Dim PrivilegeCount As Integer
Dim Privileges As LUID_AND_ATTRIBUTES
End Structure
#End Region
#Region "列挙"
Public Enum 休止モード
未処理
サスペンド
休止状態
End Enum
Public Enum 処理モード
再開
休止
End Enum
#End Region
#Region "API"
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function OpenProcessToken( _
ByVal ProcessHandle As IntPtr, _
ByVal DesiredAccess As Integer, _
ByRef TokenHandle As IntPtr _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function LookupPrivilegeValue( _
ByVal pSystemName As String, _
ByVal lpName As String, _
ByRef lpLuid As tagLUID _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function AdjustTokenPrivileges( _
ByVal TokenHandle As IntPtr, _
ByVal DisableAllPrivileges As Boolean, _
ByRef NewState As TOKEN_PRIVILEGES, _
ByVal BufferLength As Integer, _
ByVal PreviousState As IntPtr, _
ByVal ReturnLength As IntPtr _
) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function SetSystemPowerState( _
ByVal fSuspend As Boolean, _
ByVal fForce As Boolean _
) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function ExitWindowsEx( _
ByVal flag As Integer, _
ByVal reserved As Integer _
) As Boolean
End Function
#End Region
#End Region
#Region "メソッド"
#Region "メソッド_PUBLIC"
'サスペンドを行う
Public Sub 実行_サスペンド()
Call 実行_休止処理(True)
End Sub
'休止状態を行う
Public Sub 実行_休止状態()
Call 実行_休止処理(False)
End Sub
'WindowsProc処理
Public Function メッセージ処理(ByRef m As Windows.Forms.Message) As Boolean
Dim l_blnRet As Boolean = True
If (m.Msg = WM_POWERBROADCAST) And (m.WParam.ToInt32 = PBT_APMQUERYSUSPEND) Then
l_blnRet = False
'休止イベントの破棄
m.Result = New IntPtr(BROADCAST_QUERY_DENY)
'この中でイベントを発生させず、タイマを生成し、そのタイマイベント内部で処理を行う
Dim l_objタイマ As New tmpタイマ()
AddHandler l_objタイマ.Elapsed, AddressOf objタイマ_Elapsed
End If
Return l_blnRet
End Function
#End Region
#Region "メソッド_PRIVATE"
'休止処理メイン
Private Sub 実行_休止処理(ByVal l_blnサスペンド As Boolean)
Const TOKEN_QUERY As Integer = &H8
Const TOKEN_ADJUST_PRIVILEGES As Integer = &H20
Const SE_SHUTDOWN_NAME As String = "SeShutdownPrivilege"
Const SE_PRIVILEGE_ENABLED As Integer = &H2
Dim l_blnRet As Boolean
'// プロセスのハンドルを取得する。
Dim l_PronWnd As IntPtr = Diagnostics.Process.GetCurrentProcess().Handle
'// Token を取得する。
Dim l_TpkenWnd As IntPtr = IntPtr.Zero
l_blnRet = OpenProcessToken(l_PronWnd, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), l_TpkenWnd)
'// LUID を取得する。
Dim l_udtLuid As tagLUID
l_blnRet = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, l_udtLuid)
'// 特権をセットする。
Dim tp As TOKEN_PRIVILEGES = New TOKEN_PRIVILEGES()
tp.PrivilegeCount = 1
tp.Privileges = New LUID_AND_ATTRIBUTES()
tp.Privileges.Luid = l_udtLuid
tp.Privileges.Attributes = SE_PRIVILEGE_ENABLED
l_blnRet = AdjustTokenPrivileges(l_TpkenWnd, False, tp, 0, IntPtr.Zero, IntPtr.Zero)
'休止処理実行
'第2引数をTRUEにすることで、強制実行
Call SetSystemPowerState(l_blnサスペンド, True)
End Sub
#End Region
#End Region
#Region "イベント"
#Region "イベント_定義"
'イベント/クラス/生成時
Public Sub New()
'システムの電源状態変化イベントを、内部メソッドへ引き込む
AddHandler SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
End Sub
'イベント/クラス/破棄時
Protected Overrides Sub Finalize()
MyBase.Finalize()
'システムの電源状態変化イベントを、内部メソッドからはずす
RemoveHandler SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
End Sub
#End Region
#Region "イベント_WindowsProc_PowerModeChanged"
'イベント/電源/状態変化時
Private Sub SystemEvents_PowerModeChanged(ByVal sender As Object, ByVal e As PowerModeChangedEventArgs)
Select Case e.Mode
Case PowerModes.Resume
RaiseEvent 発生処理(処理モード.再開)
Case PowerModes.Suspend
RaiseEvent 発生処理(処理モード.休止)
End Select
End Sub
#End Region
#Region "イベント_内部タイマ"
'イベント/タイマ/タイマ
Private Sub objタイマ_Elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs)
Dim l_objタイマ As tmpタイマ = CType(sender, tmpタイマ)
Dim l_休止モード As 休止モード = 休止モード.未処理
'イベントとの関連付けを切り離す
RemoveHandler l_objタイマ.Elapsed, AddressOf objタイマ_Elapsed
l_objタイマ.Dispose()
'問合せ中に、再度休止関連イベントが行われたとき対策
Static s_bln多重問合せ回避フラグ As Boolean = False
If s_bln多重問合せ回避フラグ Then
Return
End If
s_bln多重問合せ回避フラグ = True
'問い合わせを行う
RaiseEvent 発生通知(l_休止モード)
'戻り値によって処理を行う
Select Case l_休止モード
Case 休止モード.サスペンド
Call 実行_サスペンド()
Case 休止モード.休止状態
Call 実行_休止状態()
End Select
s_bln多重問合せ回避フラグ = False
End Sub
#End Region
#End Region
#Region "内部タイマー"
Private Class tmpタイマ
Inherits Timers.Timer
Public Sub New()
Me.Interval = 1
Me.Enabled = True
End Sub
End Class
#End Region
End Class
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 会社・職場 30歳主婦でパートで働いてます。夫の扶養外れてるのでガッツリ働かないと損になるのですが、人間関係が辛 6 2022/08/07 15:00
- 遊園地・テーマパーク 1人ディズニー 3 2023/07/25 19:47
- イベント・祭り ジャンプビクトリーカーニバル、ジャンプ様のイベント当たりました。 仕事休みです。 会場のヲタに話しか 1 2022/07/05 08:40
- 人事・法務・広報 法定休日に出勤し振休をとった場合の休日手当は週40時間を超えたら支給するのかについて。 全社員参加必 1 2023/05/17 00:08
- 事務・総務 2つの事務ならどちらに応募しますか? ①社団法人の事務 175000の給与、ボーナス4.5、昇給あり 4 2023/03/16 12:26
- その他(暮らし・生活・行事) 自治会について 一軒家に引越して不動産屋さんからもゴミ捨ての事などあるから自治会には入った方が良いと 7 2022/04/26 09:24
- イベント・祭り 屋外の大型イベント開催について 1 2022/08/24 13:38
- コスメ・化粧品 最近退院してもらった病院の薬が合わず顔に薬疹が出てしまい、塗り薬を塗ったら顔がギトギトのテカテカに。 1 2022/08/18 12:31
- その他(ビジネス・キャリア) 有給休暇トラブル 3 2023/02/05 15:09
- iPhone(アイフォーン) iphone13 2 2022/07/17 08:32
このQ&Aを見た人はこんなQ&Aも見ています
-
10代と話して驚いたこと
先日10代の知り合いと話した際、フロッピーディスクの実物を見たことがない、と言われて驚きました。今後もこういうことが増えてくるのかと思うと不思議な気持ちです。
-
家・車以外で、人生で一番奮発した買い物
どんなものにお金をかけるかは人それぞれの価値観ですが、 誰もが一度は清水の舞台から飛び降りる覚悟で、ちょっと贅沢な買い物をしたことがあるはず。
-
「覚え間違い」を教えてください!
私はかなり長いこと「大団円」ということばを、たくさんの団員が祝ってくれるイメージで「大円団」だと間違えて覚えていました。
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
【お題】 ・急に朝起こしてきた母親に言われた一言とは?
-
VB2010でスタンバイや休止モードの復帰検出
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
VBSで応答不要のメッセージボッ...
-
処理をとめるキャンセルボタン...
-
ACCESS側からEXCELの書式を設定...
-
「キャンセル」ボタン付きの処...
-
VBA kernel32 の意味
-
MFCのワーカースレッドとUIスレ...
-
探しています~プログレスバー...
-
vb.net イベントが完全に終了...
-
C# 何かキーを押すとことで処理...
-
access 確認メッセージのはい/...
-
WEB上にボタンが押せない
-
実行させた処理の終了を待ちた...
-
Powerクエリーの更新完了までの...
-
エクセルVBAでクリップボード内...
-
Excel VBA で処理中断(DoEvents...
-
キーボード入力、マウス操作を...
-
エクセルが勝手に立ち上がる
-
VB.NETのUsingキーワードの使い方
-
起動後直に実行するコードはど...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
VBA kernel32 の意味
-
ACCESS側からEXCELの書式を設定...
-
VBA、UserFormを前面に出力して...
-
VBSで応答不要のメッセージボッ...
-
VBA メッセージボックスを自動...
-
エクセルVBAでクリップボード内...
-
Application.ScreenUpdating=Fa...
-
ASP.NETでのメッセージ画面を出...
-
Excel VBA で処理中断(DoEvents...
-
【MFC】イベントの無効化について
-
【C#】 あるイベントから別イ...
-
MFCのワーカースレッドとUIスレ...
-
Excel VBA 自動的に閉じるMsgBox
-
VCでウエイトをミリ秒でかけ...
-
[VC++] AfxBeginThreadで生成し...
-
DoEvents
-
InvalidateRectがうまくいかない
-
「キャンセル」ボタン付きの処...
おすすめ情報