1

我正在尝试使用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 中有一些限制导致回调使系统内爆?

4

2 回答 2

2

您注册的回调函数RegisterWaitForSingleObject()在另一个线程(http://msdn.microsoft.com/en-us/library/ms685061.aspx)上调用:

当对象的状态变为信号或超时间隔过去时,回调例程由工作线程执行。

我对 RealBasic 的线程支持一无所知,但至少 Windows 上的 GUI 操作通常需要在特定线程上进行,而不仅仅是任何旧的工作线程。所以对该MsgBox()工作线程的调用可能是一个问题。

您可以尝试的一个简单方法是调用PostMessage()(或任何 RealBasic 等效项)将自定义消息发布到您的应用程序可以响应的窗口消息队列(例如通过调用MsgBox())。

于 2011-04-08T18:29:44.887 回答
0

也许不相关,但 MyCallBackFn() 在哪里声明?如果它是一个实例方法,您应该使用 Wea​​kAddressOf 而不是 AddressOf。

于 2011-04-08T21:43:24.743 回答