?
Solved

Use RegNotifyChangeKeyValue without WaitForSingleObject (Array)

Posted on 2005-03-25
18
Medium Priority
?
1,315 Views
Last Modified: 2007-12-19
Greetings,

I'm using the code suggested by Ark in this message, and it functions great. The problem occurs if I use this method wish a dynamic string array. Error details is given at the bottom.

Ark's method:
http://oldlook.experts-exchange.com:8080/Programming/Programming_Languages/Visual_Basic/Q_21334275.html

====CODE=====

Dim strKeys() As String
Dim i as integer

For ListViewIndex = 1 To ListView1.ListItems.Count
 ReDim Preserve strKeys(i)
 RNumber = ListView1.ListItems(ListViewIndex).Text
 RPath = "Software\MyKey\" & RNumber
 strKeys(i) = RPath
 i = i + 1
Next

Call RegMonitor(HKEY_CURRENT_USER, strKeys, True, REG_NOTIFY_CHANGE_ATTRIBUTES + REG_NOTIFY_CHANGE_LAST_SET + REG_NOTIFY_CHANGE_NAME + REG_NOTIFY_CHANGE_SECURITY)

====End of CODE=====

ERROR:  "ByRef Argument type mismatch" in variable "strKeys"

Perhaps I did something wrong in declaring the Array ? Any help would be appreciated.
0
Comment
Question by:sramesh2k
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 4
  • 3
  • +1
18 Comments
 
LVL 32

Expert Comment

by:Erick37
ID: 13632915
sRegKeyPath is declared as String, you are passing in an array.  That's why there is a Type Mismatch.
I believe you can monitor only one value at a time using this function, so you will have to pass in only one index: strKeys(0) for example.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 13632979
If you need to monitor many different keys simultaneously you probably will need to move the code over to an ActiveX EXE and run a new instance for each key you need to montor.  Each "thread" will then be able to raise an event in your main program when a change occurs.
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13635205
Thanks for the insight, Erick. I noticed (and now removed) a duplicate "sub RegMonitor" and removed the duplicate one. Now, the error "Subscript out of range" error appears.

BTW, the error "ByRef Argument type mismatch" no longer appears now.

>> code over to an ActiveX EXE

Looks interesting, can you give me an example. I've never done an ActiveX Exe yet.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 32

Accepted Solution

by:
Erick37 earned 600 total points
ID: 13636037
"Subscript out of range" means that the index you are using in an array is either too big or too small.
Make sure that i in strKeys(i) is within the bounds of the array.

If in doubt, use x = Lbound(strKeys) for the lower bound, and Ubound(strKeys) to test the upper bound.

Here is a pretty good example of using an ActiveX Exe worker thread:
Multi-Threaded VB Using ActiveX EXEs
http://www.vbaccelerator.com/home/VB/Code/Libraries/Threading/Multi-threading_using_classes_in_ActiveX_EXEs/article.asp
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13636745
Will try that, thanks. Let me reiterate the question again

From this PAQ:
http://oldlook.experts-exchange.com:8080/Programming/Programming_Languages/Visual_Basic/Q_21334275.html

It works perfectly if I use this format:
======================
 Dim strKeys(2) As String
 strKeys(0) = "Software\VB and VBA Program Settings\Registry Notification\Hello"
 strKeys(1) = "Software\VB and VBA Program Settings\Registry Notification\Hello1"
 strKeys(2) = "Software\VB and VBA Program Settings\Registry Notification\Hello2"
======================

In my case, the number of registry keys to monitor, varies (sometimes it's 10 keys, and sometimes it's 45 keys). How can I proceed with that? If that works, it's probably the simplest one that I know of.
0
 
LVL 28

Expert Comment

by:Ark
ID: 13637621
Hi
Just change sRegKeyPath() As String to sRegKeyPath As Variant

Regards
Ark
0
 
LVL 28

Expert Comment

by:Ark
ID: 13637639
PS Which VB version do you use? VB6 allow both ways (either sRegKeyPath() As String or sRegKeyPath As Variant) while VB5 allow Variant only
0
 
LVL 28

Assisted Solution

by:Ark
Ark earned 800 total points
ID: 13637677
PS2: You also can add one more sub, smth like this:
'In a module:

Private Type KeyInfo
   RootKey As ROOT_KEY
   sName As String
   WatchSubTree As Boolean
   dwFilter As NOTIFY_EVENTS
End Type

Dim ki() As KeyInfo
Dim nKeys As Long
Public hEvent() As Long, bExit As Boolean

Public Sub AddKeyToMonitor (ByVal root As ROOT_KEY, ByVal sKey As String, ByVal lFilter As NOTIFY_EVENTS, ByVal bSubTree As Boolean)
   Redim Preserve ki(nKeys)
   ki(nKeys).RootKey = root
   ki(nKeys).sName = sKey
   ki(nKeys).WatchSubTree = bSubTree
   ki(nKeys).dwFilter = lFilter
   nKeys = nKeys + 1
End Sub

Public Sub StartRegMonitor()
   Dim lKeyHandle() As Long, lRet As Long, i As Long  

   If nKeys=0 Then Exit Sub
   ReDim hEvent(nKeys - 1)
   ReDim lKeyHandle(nKeys - 1)
   For i = 0 To nKeys - 1
       hEvent(i) = CreateEvent(0, True, False, vbNullString)
       lRet = RegOpenKey(ki(i).RootKey, ki(i).sName, lKeyHandle(i))
       RegNotifyChangeKeyValue lKeyHandle(i), ki(i).WatchSubTree, ki(i).dwFilter, hEvent(i), True
   Next i
   Do
     DoEvents
     lRet = WaitForMultipleObjects(nKeys, hEvent(0), False, 100)
     If bExit Then Exit Do
     If lRet < nKeys Then
        MsgBox "Key " & ki(lRet).sName & " have been changed!"
        ResetEvent hEvent(lRet)
        RegNotifyChangeKeyValue lKeyHandle(lRet), ki(lRet).WatchSubTree, ki(lRet).Filter, hEvent(lRet), True
     End If
   Loop
   For i = 0 To nKeys - 1
       lRet = RegCloseKey(lKeyHandle(i))
   Next i
   End
End Sub
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13638001
Thanks, Ark for jumping in. Will implement as you suggest.
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13638011
Ark,

>> Which VB version do you use?

I'm using VB6
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13638126
Ark,

Actually, I'm enumerating a registry key, and populating the entries to a listview control. The listview control contains something like this (the number of keys varies):

1
2
3
4
5
6
7

They are the sub-keys of this registry key:
HKCU\Software\MyKey

What I'm trying to do is to is to monitor each sub-key for changes simultaneously.

PS: I could monitor "HKCU\Software\MyKey" alone, but it does not notify which sub-key or value has changed. That's why I dropped that plan, and want to monitor each sub-key individually passing in an array.
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13638217
The error 9: "subscript out of range" occurs only if there are too many keys (more than 65 sub-keys), otherwise it functions great.

I've uploaded my test project here:
http://windowsxp.mvps.org/regmonitor.zip

Thanks!
0
 
LVL 26

Assisted Solution

by:EDDYKT
EDDYKT earned 600 total points
ID: 13643592
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13643659
Hi Eddykt,

Thanks. Is 64 the maximum that I can use?
0
 
LVL 26

Expert Comment

by:EDDYKT
ID: 13643669
according to mx, it is
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13643688
Excellent catch, Eddy. Based on your hint, got this article.
http://www.microsoft.com/msj/0197/win32/win320197.aspx

"Also, WaitForMultipleObjects does not allow you to pass an array of handles that exceeds 64 (MAXIMUM_ WAIT_OBJECTS) entries"

Now, I'll have to think about the workaround.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 13643788
The workaround may be to monitor each key in an ActiveX exe object using WiatForSingleObject.  There will be no limitation on the number of instances of the class that you can create.  The worker object can then notify you in an event when a key has changed.
0
 
LVL 34

Author Comment

by:sramesh2k
ID: 13643794
I'm considering that option, Erick. Thanks again.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question