Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using CreateEvent in a VB context.. 1

Status
Not open for further replies.

mattKnight

Programmer
May 10, 2002
6,238
GB
Hi all,

I have a question regards CreateEvent...

I wish to capture a event signal from the system so I need to create an event something like

Code:
dim hHandle as handle
'create event
hHandle = CreateEvent(NULL,true,false, "myEvent")
'register event
NotifyEventLogChange(hEvHandle,hHandle)

'then do a waitforsingle object

My problem comes with, somewhat obviously, the WaitforSingleObject bit...
As VB is essentially single threaded, the whole system will freeze until the event is signalled!

Does anyone understand my problem?
Can anyone suggest a potential solution framework?

The only one I can think of is a free-threaded com server that raises a VB event on the signal, but that seems to be a large overhead for a simple (ish) operation.

Thanks for your thoughts


Matt
 
Yep, just spawn a seperate thread to wait for the signal.
 
strongm

Thanks for the suggestion! This is the code I have tried.

I've omitted the API declares for clarity, but if you want to see them...

Code:
Private Sub Command1_Click()
'click to start thread
Dim SA As SECURITY_ATTRIBUTES
'Really want NULL Security Attributes
'but can't work out how!
hThread = CreateThread(SA, 0, ThreadProc, 0, 0, lThread)
End Sub

Private Function ThreadProc() As Long
'Thread start Procedure
WaitForSingleObject hEvent, 10000
MsgBox "EventSignalled", , App.Title

End Function

Private Sub Command2_Click()
'Click to signal event
SetEvent hEvent
End Sub

Private Sub Form_Load()

'Create event
Dim SA As SECURITY_ATTRIBUTES

'hEvent is a form level variable

hEvent = CreateEvent(SA, 0, 0, "Event1")
If hEvent Then
    Debug.Print "EventCreated"
Else
    Debug.Print "Event Not Created"
End If


End Sub

Guess what It don't work

The thread start procedure starts, waits and times out after 2.5s. however, I can't click the other button.

I get an exeception after the timeout, which I am sure is due to the lack of cleanup code (end thread etc)

2 questions then,
1) I want to use NULL security, how do I do that?

2) Why can't I click the other command button to set the event?

> As VB is essentially single threaded I guess I need some magic then!

Thanks again

Matt
 
Having thought about it, I have another question (more theoretical than anything else)

Code:
hThread = CreateThread(SA, 0, ThreadProc, 0, 0, lThread)

How does VB resolve ThreadProc into a long when ThreadProc in this context is symbolic only?

Thanks again

Matt
 
I#ll pop an answer up to this in a few hours, when I get back to my primary development machine.
 
>I#ll pop an answer up to this in a few hours, when I get back to my primary development machine.

Superb, Thank you (and which Timezone are you in cos your last post was notfied at 02:30 GMT - almost above the call of duty!)

Matt
 
Ok, I've modified my code to more closely match the code you tried. Here's the code that goes in your form (you'll require two command buttons):
[tt]
Option Explicit

Private Sub Command1_Click()
Dim hThread As Long
hThread = CreateThread(ByVal 0&, ByVal 0&, AddressOf ThreadProc, ByVal 0&, ByVal 0&, 0&) ' hThreadID)
' Don't need handle, so dispose of it cleanly
CloseHandle hThread
End Sub

Private Sub Command2_Click()
'Click to signal event
SetEvent hEvent
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
' Ensure we terminate thread when closing. This is particularly important in IDE,
' as otherwise we WILL crash
' This still isn't perfect, as there is still the possibility that the thread
' is in a wait state when we exit
EndThread = True
End Sub

[/tt]
And the following goes in a module:
[tt]
Option Explicit

Public Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long
Public Declare Function SetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Public Declare Function ResetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Public Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type

Private Const WAIT_OBJECT_0 = 0
Public EndThread As Boolean
Public hEvent As Long

Public Sub ThreadProc()
Dim SA As SECURITY_ATTRIBUTES
Dim result As Long

EndThread = False

SA.nLength = Len(SA)
hEvent = CreateEvent(SA, False, False, "")

' Encapsulated in a do loop so we can terminate the thread if necessary
' by setting EndThread to TRUE
Do Until EndThread = True
result = WaitForSingleObject(hEvent, 1000)
If result = WAIT_OBJECT_0 Then MsgBox "EventSignalled", , App.Title
ResetEvent hEvent
Loop

End Sub
[/tt]
Note: To use threads spawned in this fashion reliably in a compiled application, you need to compile to P-Code rather than to native code.
 
strongm

That works well for me, I have one final question to confirm
Does the thread terminate (neatly) on the end sub of the ThreadProc? I assume it does!

Thanks again and *

Matt
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top