• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2341
  • Last Modified:

MsgWaitForMultipleObjects code example

I'm looking for a code example that uses MsgWaitForMultipleObjects correctly. I'm only interested in waiting for one object, but this thread creates windows, so I can't use WaitForSingleObject. Every time I've tried doing it, it doesn't return before the timeout, even if the thread's window receives messages. I am passing a pointer to the object I am waiting for (a mutex) as the pHandles parameter. I am using QS_ALLEVENTS as the dwWakeMask parameter.
  • 7
  • 5
  • 2
1 Solution
I haven't used it so I don't have an example for U.  Have U seen Appleman's Win32 API book discussion of it's use?  I'm looking at it, and it  doesn't appear to discuss any bizarre requirements - just a thought.

covingtonAuthor Commented:
That's why I'm asking - I have looked in his book, and it seems simple to use, but I can't get it to work.

BTW, I'm using VB 5.0, SP3.
covingtonAuthor Commented:
Bueller? Bueller?
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

I found this in the samples for McKinney's Hardcore VB book.  Let me know if it works.

Attribute VB_Name = "MFileNotify"
Option Explicit

Public Type TConnection
    sDir As String
    fSubTree As Boolean
    notifier As IFileNotifier
End Type

' Actually cLastNotify + 1 allowed
Public Const cLastNotify = 28
' One extra blank item in each array for easy compacting
Public ahNotify(0 To cLastNotify + 1) As Long
Public aconNotify(0 To cLastNotify + 1) As TConnection
Public aerr(errFirst To errLast) As String
' Count of connected objects managed by class
Public cObject As Long

Sub Main()

    Dim i As Integer
    For i = 0 To cLastNotify
        ahNotify(i) = hInvalid
    aerr(errInvalidDirectory) = "Invalid directory"
    aerr(errInvalidType) = "Invalid notification type"
    aerr(errInvalidArgument) = "Invalid argument"
    aerr(errTooManyNotifications) = "Too many notifications"
    aerr(errNotificationNotFound) = "Notification not found"
    BugMessage "Initialized static data"

    ' Start the wait loop and return to the caller
    Call SetTimer(hNull, 0, 200, AddressOf WaitForNotify)
    BugMessage "Started Timer"
End Sub

Sub WaitForNotify(ByVal hWnd As Long, ByVal iMsg As Long, _
                  ByVal idTimer As Long, ByVal cCount As Long)
    ' Ignore all parameters except idTimer
    ' This one-time callback is used only to start the loop
    KillTimer hNull, idTimer
    BugMessage "Killed Timer"

    Dim iStatus As Long, f As Boolean
    ' Keep waiting for file change events until no more objects
        '  Wait 100 milliseconds for notification
        iStatus = WaitForMultipleObjects(Count, ahNotify(0), _
                                         False, 100)
        Select Case iStatus
        Case WAIT_TIMEOUT
            ' Nothing happened
            BugMessage "Waited for timeout"
        Case 0 To Count
            BugMessage "Got a notification"
            ' Ignore errors from client; that's their problem
            On Error Resume Next
            ' Call client object with information
            With aconNotify(iStatus)
                .notifier.Change .sDir, .efn, .fSubTree
            End With
            ' Wait for next notification
            f = FindNextChangeNotification(ahNotify(iStatus))
            BugAssert f
        Case WAIT_FAILED
            ' Indicates no notification requests
            BugMessage "No notification requests"
        Case Else
            BugMessage "Can't happen"
        End Select
    ' Class Initialize and Terminate events keep reference count
    Loop Until cObject = -1
End Sub

Private Property Get Count() As Long
    Dim i As Long
    For i = 0 To cLastNotify
        If ahNotify(i) = INVALID_HANDLE_VALUE Then Exit For
    Count = i
End Property

Public Sub RaiseError(iErr As Integer)
    Err.Raise vbObjectError + iErr, "FileNotify.CFileNotify", aerr(iErr)
End Sub

covingtonAuthor Commented:
Sorry, but that's an example with WaitForMultipleObjects. I'm looking for MsgWaitForMultipleObjects.

From the SDK:
"If you have a thread that uses a wait function with no time-out interval, the system will deadlock. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjects."

I've tried using WaitForMultipleObjects in a loop with a short timeout, but the tasks I'm waiting for won't execute when WaitForMultipleObjects is waiting, which defeats the purpose.
I'm assuming You have seen the documents about MsgWait... and that You know how to issue some API calls, the main difference in MsgWait... is that it can check the message queue for the waited object, so if You specify your own process as one of the objects to be waited and set the dwWakeMask parameter to a usable value (say QS_ALLINPUT) whenever a message is into the message queue of Your app the wait will return allowing You to process it and avoiding Your app to hang, oviously in this case You should check the reason of the Wait termination and, if it's the case restart waiting.

I hope it's clear, if not let me know

covingtonAuthor Commented:
Fairly clear...

Let me try to restate this in my own words...tell me if I get it right.

I was passing just one handle (the mutex) into the MsgWait.. call. I thought that I would also automatically be waiting on any messages that the waiting thread received. You're saying that I won't get these messages unless I pass in both the handle to the mutex and the handle to the waiting thread. Is that right?

I understand the part about checking to see why the wait released, and looping again if it wasn't the mutex.

I'll try it out this weekend and let you know how it works.

You got the point pal, it's exactly as explained into MS docs

covingtonAuthor Commented:
I'll still try it this weekend, but I'm not sure what MS docs you're referring to. In the SDK for MsgWait... it says:

"The state of a thread object is set to signaled when the thread terminates."

So I imagine that if I wait on a thread, it won't return until the thread terminates. This defeates the purpose, since I can't have a thread wait on itself. Should I be including the thread handle in the array, or the handle of the window (created in the thread) that I expect to receive the posted messages?
Yes I just wrote this, sorry for the misunderstanding, You MUST include Your own process in the wait list to get signaled whenever a message is in Your (main) process queue !!

I got to go now it's 19.24 here (Italy)

covingtonAuthor Commented:
I haven't forgotten this question - I've just been too swamped to try it recently.
No Prob ... but let me know please !

covingtonAuthor Commented:
Still haven't tried it, but I don't want this to expire without giving you a decent grade.

Please let me know when You test it, You can reach
me via e-mail at anzen@geocities.com

Bye and ...thank You !

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

  • 7
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now