Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Use RegNotifyChangeKeyValue without WaitForSingleObject (Array)

Posted on 2005-03-25
18
Medium Priority
?
1,320 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
  • 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
Independent Software Vendors: 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…
Suggested Courses
Course of the Month15 days, 13 hours left to enroll

581 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