Question about certain delare

G

Guest

I need to call CreateEvent, but I am getting a runtime error

An unhandled exception of type 'System.DllNotFoundException' occurred in
aa.exe
Additional information: Unable to load DLL (kernel32.lib).

Did I declare correctly?

Dim hevent As System.UInt32
hevent = CreateEvent(IntPtr.Zero, True, False, "abc")

Declare Auto Function CreateEvent Lib "kernel32.lib" ( _
ByRef lpEventAttributes As IntPtr, _
ByVal bManualReset As Boolean, _
ByVal bInitialState As Boolean, _
ByVal lpName As String) As System.UInt32
 
C

Cor Ligthert

Hi,

To create an event you do just in a global part of your class (form)
Public (or whatever) event MyEvent

Than by instance in the form load
addhandler MyEvent, addressof MyEventSub

And in a method
raiseevent MyEvent

I hope this helps?

Cor
 
G

Guest

Cor,
Thanks for your reply. Can you explain what I need to do to get
a handle of an event. I need the handle to use in

Declare Auto Function RegNotifyChangeKeyValue Lib "Advapi32.lib" ( _
ByVal hKey As System.UInt32, _
ByVal bWatchSubtree As Boolean, _
ByVal dwNotifyFilter As System.UInt32, _
ByVal hEvent As System.UInt32, _
ByVal fAsynchronous As Boolean) As System.UInt32

I hope this gives you a better idea of my problem.
Hopefully you or someone have some knowledge with declare's

Andy.
 
T

Tom Shelton

Cor,
Thanks for your reply. Can you explain what I need to do to get
a handle of an event. I need the handle to use in

Declare Auto Function RegNotifyChangeKeyValue Lib "Advapi32.lib" ( _
ByVal hKey As System.UInt32, _
ByVal bWatchSubtree As Boolean, _
ByVal dwNotifyFilter As System.UInt32, _
ByVal hEvent As System.UInt32, _
ByVal fAsynchronous As Boolean) As System.UInt32

I hope this gives you a better idea of my problem.
Hopefully you or someone have some knowledge with declare's

Andy.

Andy... First of all I would declare the above like this:

Declare Auto Function RegNotifyChangeKeyValue Lib "Advapi32.dll" ( _
ByVal hKey As IntPtr, _
ByVal bWatchSubtree As Boolean, _
ByVal dwNotifyFilter As Integer, _
ByVal hEvent As IntPtr, _
ByVal fAsyncronous As Boolean) As Integer

You don't need to use CreateEvent, since you could create a
ManualResetEvent (or AutoResetEvent) from System.Threading and pass in
it's Handle property - which is the native os handle, returned correctly
as an IntPtr.

You can declare the constants for hKey like this:

Public Shared ReadOnly HKEY_CLASSES_ROOT As IntPtr = New IntPtr
(TheValue)

Sorry, I'm not on windows to actually look up the value, but you get the
idea I'm sure :)
 
H

Herfried K. Wagner [MVP]

Tom Shelton said:
Public Shared ReadOnly HKEY_CLASSES_ROOT As IntPtr = New IntPtr
(TheValue)

Sorry, I'm not on windows to actually look up the value, but you get the
idea I'm sure :)

The value is '&H80000000'.
 
G

Guest

Declare Auto Function RegNotifyChangeKeyValue Lib "Advapi32.lib" ( _
Andy... First of all I would declare the above like this:

Declare Auto Function RegNotifyChangeKeyValue Lib "Advapi32.dll" ( _
ByVal hKey As IntPtr, _
ByVal bWatchSubtree As Boolean, _
ByVal dwNotifyFilter As Integer, _
ByVal hEvent As IntPtr, _
ByVal fAsyncronous As Boolean) As Integer

Hi Tom, I have many questions :)
Why are you using an intptr for HKEY, HKEY as all win32 HANDLEs is
a DWORD, which is the same as int32?

Also, assuming Integer and UInt32 are the same, why do you prefer to use
Integer?

Also, any ideas why my CreateEvent api is not found?

Also, do you know if LPCTSTR lpName can be declared as byref String

Finally, I already have hkey which I opend using
Dim reg As RegistryKey
reg = Registry.ClassesRoot
r = reg.OpenSubKey(s, False)
so why do I need the public shared below?
You don't need to use CreateEvent, since you could create a
ManualResetEvent (or AutoResetEvent) from System.Threading and pass in
it's Handle property - which is the native os handle, returned correctly
as an IntPtr.

You can declare the constants for hKey like this:

Public Shared ReadOnly HKEY_CLASSES_ROOT As IntPtr = New IntPtr
(TheValue)

I don't understand this?
 
T

Tom Shelton

Hi Tom, I have many questions :)
Why are you using an intptr for HKEY, HKEY as all win32 HANDLEs is
a DWORD, which is the same as int32?

Handle should be declared as IntPtr because IntPtr is the system pointer
size, and generally Handles are really pointers. In other words, a
HANDLE on a 64-bit system is not going to be 32-bit.
Also, assuming Integer and UInt32 are the same, why do you prefer to use
Integer?

UInt32 and Integer are not the same. They are the same size, but UInt32
is an unsigned 32-bit number and Integer is signed. To be honest it
doesn't really matter in this case... It's just that in general,
unsigned values are harder to work with in VB.NET since they are not
directly supported.
Also, any ideas why my CreateEvent api is not found?

Not sure... I didn't really look at that particular declare because it
isn't really needed. The framework already has an equivalent -
System.Threading.ManualResetEvent and System.Threading.AutoResetEvent.
If you need to pass them to an API call, they both provide a Handle
property.
Also, do you know if LPCTSTR lpName can be declared as byref String

No. You would pass it ByVal.

As a side note, if you're passing strings as buffers to be modified by
the API call you shouldn't pass them as strings at all. You should pass
them as System.Text.StringBuilder. VB.NET cheats, and actually lets you
use string - but there is overhead involved. In C#, you have to use
StringBuilder, so I think it pays to get into the habbit in case you
ever have to work in C#.
Finally, I already have hkey which I opend using
Dim reg As RegistryKey
reg = Registry.ClassesRoot
r = reg.OpenSubKey(s, False)
so why do I need the public shared below?

Well, you can't pass that regkey to your declare. It requires a handle.
So, if you plan on using this function, you'll need to open your
registry key with RegOpenKeyEx...

The declare is really a constant value that represents a predefined key
value. You can pass one of the following ot RegNotifyChangeKeyValue:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
I don't understand this?

Which? The use of the Manual/AutoResetEvent or the declaring of the
constants..

' maybe in a class or form
Private myEvent As New ManualResetEvent (false)

' calling your function

RegNotifyChangedKeyValue (...., ...., ...., myEvent.Handle, ....)

It is a way of creating the possible constant values that can be passed
to RegNotifyChangeKeyValue. You cant declare them as const, but the by
making them Shared ReadOnly in a class (or just public readonly in a
module) you get the same effect.

Admitedly, the Shared ReadOnly maybe sort of a c#'ism... I actually use
C# much more then VB.NET, so sometimes I tend to think that way :)
 
G

Guest

I almost understand, some more question to conclude (if possible?)
No. You would pass it ByVal.

O.k. so String works for C's strings.
Well, you can't pass that regkey to your declare. It requires a handle.
So, if you plan on using this function, you'll need to open your
registry key with RegOpenKeyEx...

Do you mean that vb's OpenSubKey is not useful to obtain a handle ?
The declare is really a constant value that represents a predefined key
value. You can pass one of the following ot RegNotifyChangeKeyValue:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS


Which? The use of the Manual/AutoResetEvent or the declaring of the
constants..

' maybe in a class or form
Private myEvent As New ManualResetEvent (false)

' calling your function

RegNotifyChangedKeyValue (...., ...., ...., myEvent.Handle, ....)

It is a way of creating the possible constant values that can be passed
to RegNotifyChangeKeyValue. You cant declare them as const, but the by
making them Shared ReadOnly in a class (or just public readonly in a
module) you get the same effect.

Admitedly, the Shared ReadOnly maybe sort of a c#'ism... I actually use
C# much more then VB.NET, so sometimes I tend to think that way :)

Thanks for the sample code, it does explain how I should do it. At
the moment I am considering abandoning my project. I wanted to
write a reg-mon program like the one in www.sys internals.com , but now
I realise that just enumerating the keys is a 2 minutes ordeal or vb.
reg-mon seems not to have this problem, maybee they are not using
RegNotify... api.
 
T

Tom Shelton

I almost understand, some more question to conclude (if possible?)


O.k. so String works for C's strings.

LPCTSTR is pointer to a constant TSTR. TSTR is nice way of saying it
can be Unicode or Ansi depending on the system :)
Do you mean that vb's OpenSubKey is not useful to obtain a handle ?

Well it returns a RegistryKey object - and I don't see a way of geting
at it's native handle, which is what you would need to pass to the API
call.
Thanks for the sample code, it does explain how I should do it. At
the moment I am considering abandoning my project. I wanted to
write a reg-mon program like the one in www.sys internals.com , but now
I realise that just enumerating the keys is a 2 minutes ordeal or vb.
reg-mon seems not to have this problem, maybee they are not using
RegNotify... api.

I wouldn't abandon it... It sounds like a good learning experience.
 
G

Guest

I almost understand, some more question to conclude (if possible?)
LPCTSTR is pointer to a constant TSTR. TSTR is nice way of saying it
can be Unicode or Ansi depending on the system :)

Indeed yes, but vb strings are BSTR?
Well it returns a RegistryKey object - and I don't see a way of geting
at it's native handle, which is what you would need to pass to the API
call.
Reflection?


I wouldn't abandon it... It sounds like a good learning experience.

Yes it is :)
thanks for the assistance :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top