1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Office VBA 64/32Bit共用 Win32 API MsgWaitForMultipleObjects 待機関数

Last updated at Posted at 2020-04-08

#VBAのフォーム間のやりとり
https://web.archive.org/web/20120522222109/http://homepage1.nifty.com/MADIA/vb/vb_bbs2/200706/200706_07060026.html
という記事を見つけました。

Sleep している間は、ウィンドウメッセージを処理できなくなりますので、
ウィンドウを持つアプリは、そのメインスレッドから Sleep API を
呼ぶべきでは無いとされています。

限定的にであれば、Sleep 呼び出しをごく短時間にして、DoEventsとあわせて
繰り返し呼び出すという対処方法もありますが、できれば、
http://msdn.microsoft.com/library/ja/jpdllpro/html/_win32_sleep.asp
にも書かれているように、MsgWaitForMultipleObjects API もしくは、
MsgWaitForMultipleObjectsEx を使った方が安全でしょう。

そうすれば、待機中にもメッセージ(再描画要求、マウスやキー入力等)を
DoEvents等で処理できますので。

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function MsgWaitForMultipleObjects Lib "user32" _
(ByVal Count As Long, ByVal HandlesPointer As Long, _
ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
ByVal WakeMask As Long) As Long



これをVBAで使えるのか、さらに64bit 32 bit共用で使えるのか。
結論から言うと簡単に使えます


```vb

#If VBA7 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
Private Declare PtrSafe Function MsgWaitForMultipleObjects Lib "user32" _
   (ByVal Count As Long, ByVal HandlesPointer As Long, _
    ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
    ByVal WakeMask As Long) As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function MsgWaitForMultipleObjects Lib "user32" _
   (ByVal Count As Long, ByVal HandlesPointer As Long, _
    ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
    ByVal WakeMask As Long) As Long
#End If
Public Sub WaitAPI6432(ByVal msec As Long)
' msec ミリセカント(千分の一秒)単位
If msec <= 0 Then
msec = 1
End If
Dim Interval As Long
Dim tickBegin As Long
Interval = msec
tickBegin = GetTickCount()
Do
  If MsgWaitForMultipleObjects(0, 0, 0, Interval, &HFF&) = 0 Then
     DoEvents
  End If
  Interval = msec + tickBegin - GetTickCount()
Loop Until Interval < 0
End Sub
Sub test_WaitAPI6432()
' Test 用 Sub プロシージャ
Debug.Print Timer
Call WaitAPI6432(3000)
Debug.Print Timer
End Sub

このプロシージャの機能はSleepのように停止するのではなく、待機するという点が違うようです。
http://tokovalue.jp/function/MsgWaitForMultipleObjects.htm

指定したオブジェクトのいずれか1つまたはすべてがシグナル状態になったとき、またはタイムアウト時間が経過したとき制御を戻す。

http://chokuto.ifdef.jp/urawaza/api/MsgWaitForMultipleObjects.html
Windows 95時代からある

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?