{"id":1244,"date":"2024-07-30T08:00:00","date_gmt":"2024-07-30T00:00:00","guid":{"rendered":"http:\/\/www.wyrcad.com\/?p=1244"},"modified":"2024-07-15T10:07:47","modified_gmt":"2024-07-15T02:07:47","slug":"%e5%bb%b6%e8%bf%9f%ef%bc%88%e5%81%9c%e6%bb%9e%ef%bc%89%e8%bf%9b%e7%a8%8b%e4%b8%80%e5%ae%9a%e6%97%b6%e9%97%b4","status":"publish","type":"post","link":"https:\/\/www.wyrcad.com\/?p=1244","title":{"rendered":"\u5ef6\u8fdf\uff08\u505c\u6ede\uff09\u8fdb\u7a0b"},"content":{"rendered":"\n<p>Option Explicit<br>&#8216;\u4e0eSleep\u76f8\u6bd4,\u672c\u6a21\u5757\u7684 Wait \u4e0d\u5360\u7528CPU\u7684\u65f6\u95f4<br>Private Type FILETIME<br>dwLowDateTime As Long<br>dwHighDateTime As Long<br>End Type<\/p>\n\n\n\n<p>&#8216;Private Const WAIT_ABANDONED&amp; = &amp;H80&amp;<br>&#8216;Private Const WAIT_ABANDONED_0&amp; = &amp;H80&amp;<br>&#8216;Private Const WAIT_FAILED&amp; = -1&amp;<br>&#8216;Private Const WAIT_IO_COMPLETION&amp; = &amp;HC0&amp;<br>Private Const WAIT_OBJECT_0&amp; = 0<br>&#8216;Private Const WAIT_OBJECT_1&amp; = 1<br>&#8216;Private Const WAIT_TIMEOUT&amp; = &amp;H102&amp;<\/p>\n\n\n\n<p>Private Const INFINITE = &amp;HFFFF<br>Private Const ERROR_ALREADY_EXISTS = 183&amp;<\/p>\n\n\n\n<p>Private Const QS_HOTKEY&amp; = &amp;H80<br>Private Const QS_KEY&amp; = &amp;H1<br>Private Const QS_MOUSEBUTTON&amp; = &amp;H4<br>Private Const QS_MOUSEMOVE&amp; = &amp;H2<br>Private Const QS_PAINT&amp; = &amp;H20<br>Private Const QS_POSTMESSAGE&amp; = &amp;H8<br>Private Const QS_SENDMESSAGE&amp; = &amp;H40<br>Private Const QS_TIMER&amp; = &amp;H10<br>&#8216;Private Const QS_MOUSE&amp; = (QS_MOUSEMOVE _<br>Or QS_MOUSEBUTTON)<br>&#8216;Private Const QS_INPUT&amp; = (QS_MOUSE _<br>Or QS_KEY)<br>&#8216;Private Const QS_ALLEVENTS&amp; = (QS_INPUT _<br>Or QS_POSTMESSAGE _<br>Or QS_TIMER _<br>Or QS_PAINT _<br>Or QS_HOTKEY)<br>Private Const QS_ALLINPUT&amp; = (QS_SENDMESSAGE _<br>Or QS_PAINT _<br>Or QS_TIMER _<br>Or QS_POSTMESSAGE _<br>Or QS_MOUSEBUTTON _<br>Or QS_MOUSEMOVE _<br>Or QS_HOTKEY _<br>Or QS_KEY)<\/p>\n\n\n\n<p>Private Declare Function CreateWaitableTimer Lib &#8220;kernel32&#8221; _<br>Alias &#8220;CreateWaitableTimerA&#8221; ( _<br>ByVal lpSemaphoreAttributes As Long, _<br>ByVal bManualReset As Long, _<br>ByVal lpName As String) As Long<\/p>\n\n\n\n<p>&#8216;Private Declare Function OpenWaitableTimer Lib &#8220;kernel32&#8221; _<br>Alias &#8220;OpenWaitableTimerA&#8221; ( _<br>ByVal dwDesiredAccess As Long, _<br>ByVal bInheritHandle As Long, _<br>ByVal lpName As String) As Long<\/p>\n\n\n\n<p>Private Declare Function SetWaitableTimer Lib &#8220;kernel32&#8221; ( _<br>ByVal hTimer As Long, _<br>lpDueTime As FILETIME, _<br>ByVal lPeriod As Long, _<br>ByVal pfnCompletionRoutine As Long, _<br>ByVal lpArgToCompletionRoutine As Long, _<br>ByVal fResume As Long) As Long<\/p>\n\n\n\n<p>&#8216;Private Declare Function CancelWaitableTimer Lib &#8220;kernel32&#8221; ( _<br>ByVal hTimer As Long)<\/p>\n\n\n\n<p>&#8216;Private Declare Function CloseHandle Lib &#8220;kernel32&#8221; ( _<br>ByVal hObject As Long) As Long<\/p>\n\n\n\n<p>&#8216;Private Declare Function WaitForSingleObject Lib &#8220;kernel32&#8221; ( _<br>ByVal hHandle As Long, _<br>ByVal dwMilliseconds As Long) As Long<\/p>\n\n\n\n<p>Private Declare Function MsgWaitForMultipleObjects Lib &#8220;user32&#8221; ( _<br>ByVal nCount As Long, _<br>pHandles As Long, _<br>ByVal fWaitAll As Long, _<br>ByVal dwMilliseconds As Long, _<br>ByVal dwWakeMask As Long) As Long<\/p>\n\n\n\n<p>Public Sub Wait(dwMilliseconds As Long)<br>Dim ft As FILETIME<br>Dim lBusy As Long<br>Dim dblDelay As Double<br>Dim dblDelayLow As Double<br>Dim dblUnits As Double<br>Dim hTimer As Long<br>hTimer = CreateWaitableTimer(0, True, App.EXEName &amp; &#8220;Timer&#8221;)<br>If Err.LastDllError = ERROR_ALREADY_EXISTS Then<br>&#8216; If the timer already exists, it does not hurt to open it<br>&#8216; as long as the person who is trying to open it has the<br>&#8216; proper access rights.<br>Else<br>ft.dwLowDateTime = -1<br>ft.dwHighDateTime = -1<br>lRet = SetWaitableTimer(hTimer, ft, 0, 0, 0, 0)<br>End If<br>&#8216; Convert the Units to nanoseconds.<br>dblUnits = CDbl(&amp;H10000) * CDbl(&amp;H10000)<br>dblDelay = CDbl(dwMilliseconds) * 10000<br>&#8216; By setting the high\/low time to a negative number, it tells<br>&#8216; the Wait (in SetWaitableTimer) to use an offset time as<br>&#8216; opposed to a hardcoded time. If it were positive, it would<br>&#8216; try to convert the value to GMT.<br>ft.dwHighDateTime = -CLng(dblDelay \/ dblUnits) &#8211; 1<br>dblDelayLow = -dblUnits * (dblDelay \/ dblUnits &#8211; _<br>Fix(dblDelay \/ dblUnits))<br>If dblDelayLow &lt; CDbl(&amp;H80000000) Then<br>&#8216; &amp;H80000000 is MAX_LONG, so you are just making sure<br>&#8216; that you don&#8217;t overflow when you try to stick it into<br>&#8216; the FILETIME structure.<br>dblDelayLow = dblUnits + dblDelayLow<br>ft.dwHighDateTime = ft.dwHighDateTime + 1<br>End If<br>ft.dwLowDateTime = CLng(dblDelayLow)<br>lRet = SetWaitableTimer(hTimer, ft, 0, 0, 0, False)<br>Do<br>&#8216; QS_ALLINPUT means that MsgWaitForMultipleObjects will<br>&#8216; return every time the thread in which it is running gets<br>&#8216; a message. If you wanted to handle messages in here you could,<br>&#8216; but by calling Doevents you are letting DefWindowProc<br>&#8216; do its normal windows message handling&#8212;Like DDE, etc.<br>lBusy = MsgWaitForMultipleObjects(1, hTimer, False, _<br>INFINITE, QS_ALLINPUT&amp;)<br>DoEvents<br>Loop Until lBusy = WAIT_OBJECT_0<br>&#8216; Close the handles when you are done with them.<br>CloseHandle hTimer<br>End Sub<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Option Explicit&#8216;\u4e0eSleep\u76f8\u6bd4,\u672c\u6a21\u5757\u7684 Wait \u4e0d\u5360\u7528CPU\u7684\u65f6\u95f4Priva &hellip; <a href=\"https:\/\/www.wyrcad.com\/?p=1244\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u201c\u5ef6\u8fdf\uff08\u505c\u6ede\uff09\u8fdb\u7a0b\u201d<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[24,17],"class_list":["post-1244","post","type-post","status-publish","format-standard","hentry","category-bianchengyuandi","tag-vb","tag-biancheng"],"_links":{"self":[{"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/posts\/1244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1244"}],"version-history":[{"count":2,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/posts\/1244\/revisions"}],"predecessor-version":[{"id":1246,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=\/wp\/v2\/posts\/1244\/revisions\/1246"}],"wp:attachment":[{"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wyrcad.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}