RegisterWaitForSingleObject Для просмотра каталога с использованием RealBasic - PullRequest
1 голос
/ 08 апреля 2011

Я пытаюсь посмотреть каталог на наличие изменений, используя функцию FindFirstChangeNotification .Это работает, если я возьму дескриптор, возвращенный FindFirstChangeNotification, и вставлю его в WaitForSingleObject.Проблема в том, что WaitForSingleObject блокирует все приложение до тех пор, пока оно не вернется.

Итак, я огляделся и, похоже, RegisterWaitForSingleObject был подходящим путем:

Sub monitorDir(dir As FolderItem)
  Declare Function FindFirstChangeNotificationW Lib "Kernel32" (dirPath As WString, watchChildren As Boolean, eventTypeFilter As Integer) As Integer
  Declare Function RegisterWaitForSingleObject Lib "Kernel32" (ByRef waiterHWND As Integer, HWND As Integer, cllbck As Ptr, _
  context As Integer, wait As Integer, flags As Integer) As Integer
  Dim allFilters As Integer = &h00000001 Or &h00000002 Or &h00000004 Or &h00000008 Or &h00000010_
      Or &h00000100
  Dim monitorHandle As Integer = FindFirstChangeNotificationW(dir.AbsolutePath, True, allFilters)
  If monitorHandle <> 0 Then
  Call RegisterWaitForSingleObject(myCallbackHWND, monitorHandle, AddressOf MyCallbackFn, 0, &hFFFFFFFF, 0)
End Sub

Этот выглядит как для работы, поскольку приложение продолжает нормально работать.Однако, как только MyCallbackFn вызывается (то есть когда происходит изменение в каталоге), все становится ... странным.Приложения начинают зависать или блокироваться, начиная с Process Explorer и Windows Explorer.Я должен выйти из Windows, чтобы восстановить вещи.

На данный момент все, что делает MyCallbackFn, это:

Sub MyCallbackFn()
  Declare Function UnregisterWaitEx Lib "Kernel32" (waitHWND As Integer, eventHandle As Integer) As Integer
  Call UnregisterWaitEx(myCallbackHWND, 0)
  MsgBox("Change Detected")
End Sub

Я лаю неправильное дерево, используя RegisterWaitForSingleObject,Я использовал это неправильно, или есть какое-то ограничение в RealBasic, которое вызывает обратные вызовы, чтобы взорвать систему?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2011

Функция обратного вызова, которую вы регистрируете в RegisterWaitForSingleObject(), вызывается в другом потоке (http://msdn.microsoft.com/en-us/library/ms685061.aspx):

Процедура обратного вызова выполняется рабочим потоком, когда состояние объекта становится сигнальным или истекает интервал времени ожидания.

Я ничего не знаю о поддержке потоков RealBasic, но, по крайней мере, операции с графическим интерфейсом в Windows обычно должны выполняться в определенном потоке, а не в каком-либо старом рабочем потоке. Так что вызов MsgBox() в этом рабочем потоке, вероятно, является проблемой.

Простая вещь, которую вы можете попробовать, это позвонить по номеру PostMessage() (или какому-либо эквиваленту RealBasic), чтобы отправить пользовательское сообщение в очередь сообщений вашего окна, на которое ваше приложение может ответить (например, вызвав MsgBox()).

0 голосов
/ 09 апреля 2011

Может быть не связано, но где объявлен MyCallBackFn ()? Если это метод экземпляра, вы должны использовать WeakAddressOf вместо AddressOf.

...