Invoke Required but not working?

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
hi folks
I have a VB6 app migrated to VB.NET / VS2010 currently under test. Issue is with integration between the app and Outlook (2003). In summary the app opens an Outlook Explorer window to let the user view a calendar and update appointment items,
any changes made are validated and if OK written to a db.
There are two methods here, one handles event Item_Change and does the validation / updates, the other handles Explorer_Close and tidies up all the Outlook objects. There is a condition in the Item_Change method ("<span style="white-space:pre If
rs.RecordCount = 0 Then") which if detected needs the Outlook Explorer to be closed programmatically.
If I break execution at the top of the Explorer_Close method, InvokeRequired at the top of the Explorer_Close method tests True, but when the following Invoke line is executed, program execution just seems to stop - none of the code in the Else block is
executed.
If I break execution within the Item_Change method and step through the code from there, execution never seems to even get to the Explorer_Close method, it stops immediately after executing the Explorer.Close() line.
NB if the user closes the Explorer window manually, InvokeRequired tests false and the Explorer_Close method completes satisfactorily.
Code is below, would be grateful for any thoughts?
Item_Change:

<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; Private <span style="color:Blue; Sub myItems_ItemChange(<span style="color:Blue; ByVal Item <span style="color:Blue; As <span style="color:Blue; Object) <span style="color:Blue; Handles myItems.ItemChange
<span style="color:Green; user has changed an item - maybe validated in myExplorer_SelectionChange()
<span style="color:Green; that the item is of the correct type, and exists on our db -
<span style="color:Green; if so this routine just calls the Method on the AsstAppoint object
<span style="color:Green; to modify the db accordingly

<span style="color:Green; however a drag and drop does not trigger selectionChange until after the drop
<span style="color:Green; which is too late becaus it is after this event - so need to have same checks here

<span style="color:Blue; Dim Response <span style="color:Blue; As <span style="color:Blue; Integer
<span style="color:Blue; Dim rs <span style="color:Blue; As ADODB.Recordset

<span style="color:Blue; On <span style="color:Blue; Error <span style="color:Blue; GoTo ErrorHandler

<span style="color:Green; this check exits the Sub if the update has been completed already
<span style="color:Green; and the event is firing a second time; avoids an endless loop
<span style="color:Blue; If mblnEndLoop = <span style="color:Blue; True <span style="color:Blue; Then
mblnEndLoop = <span style="color:Blue; False
<span style="color:Blue; Exit <span style="color:Blue; Sub
<span style="color:Blue; End <span style="color:Blue; If

myAppoint = Item
<span style="color:Blue; If myAppoint.Start < Now <span style="color:Blue; Then
<span style="color:Green; bring Main App form to front so as to display message box
BringToFront_Renamed()
Response = MsgBox(<span style="color:#A31515; "You have moved the appointment to be in the past." & Chr(13) & <span style="color:#A31515; "If this is incorrect, please move it to the correct date.")
myExplorer.Display()
<span style="color:Blue; End <span style="color:Blue; If

<span style="color:Green; check whether Assessment object set in selectionchange are present
<span style="color:Blue; If mobjAssessment <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
<span style="color:Green; set up Assessment object now
mdsrDE.cmdGetAssessWithCIID(VB.Left(myAppoint.EntryID, 250), Mid(myAppoint.EntryID, 251))
rs = mdsrDE.rscmdGetAssessWithCIID
<span style="color:Blue; If rs.RecordCount = 0 <span style="color:Blue; Then
<span style="color:Green; no record of this appointment on db
BringToFront_Renamed()
Response = MsgBox(<span style="color:#A31515; "The Outlook Item which you selected " & Chr(13) & <span style="color:#A31515; "is not an Assessment Appointment. " & Chr(13) & <span style="color:#A31515; "The Outlook Calendar will now close.")
rs.Close()
rs = <span style="color:Blue; Nothing
myExplorer.Close()
<span style="color:Blue; Exit <span style="color:Blue; Sub
<span style="color:Blue; Else
<span style="color:Green; check that the db record has no outcome recorded - if it has
<span style="color:Green; why are they changing it?
<span style="color:Blue; If rs.Fields(<span style="color:#A31515; "Assessment Outcome").Value <> <span style="color:#A31515; "" <span style="color:Blue; Then
BringToFront_Renamed()
MsgBox(<span style="color:#A31515; "The Outlook Item which you selected " & Chr(13) & <span style="color:#A31515; "already has an Outcome recorded, and " & Chr(13) & <span style="color:#A31515; "therefore should not be edited." & Chr(13) & Chr(13) & <span style="color:#A31515; "The change which you made will not" & Chr(13) & <span style="color:#A31515; "be recorded in the application database" & Chr(13) & <span style="color:#A31515; "- please undo it in the Calendar", MsgBoxStyle.Exclamation)
rs.Close()
rs = <span style="color:Blue; Nothing
<span style="color:Blue; Exit <span style="color:Blue; Sub
<span style="color:Blue; Else
<span style="color:Green; potentially valid appointment - keep a track of the db IDs
mintAssessID = rs.Fields(<span style="color:#A31515; "Assessment ID").Value
mintClientID = rs.Fields(<span style="color:#A31515; "Client ID").Value
rs.Close()
rs = <span style="color:Blue; Nothing
<span style="color:Green; set up instance of the objects
mobjClient.ClientID = mintClientID
mobjClient.RetrieveClient()
mobjAssessment = <span style="color:Blue; New AsstAppoint
<span style="color:Blue; With mobjAssessment
.ClientID = mintClientID
.AssessID = mintAssessID
.EntryID = myAppoint.EntryID
<span style="color:Blue; End <span style="color:Blue; With
<span style="color:Blue; If mobjClient.FirstContact > myAppoint.Start <span style="color:Blue; Then
MsgBox(<span style="color:#A31515; "You moved the Outlook Item prior to the " & Chr(13) & <span style="color:#A31515; "First Contact Date for the client." & Chr(13) & Chr(13) & <span style="color:#A31515; "The change which you made will not" & Chr(13) & <span style="color:#A31515; "be recorded in the application database" & Chr(13) & <span style="color:#A31515; "- please undo it in the Calendar", MsgBoxStyle.Exclamation)
rs.Close()
rs = <span style="color:Blue; Nothing
<span style="color:Blue; Exit <span style="color:Blue; Sub
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; Else
<span style="color:Green; Create Object and set ID from previous db read
mobjAssessment = <span style="color:Blue; New AsstAppoint
<span style="color:Blue; With mobjAssessment
.ClientID = mintClientID
.AssessID = mintAssessID
.EntryID = myAppoint.EntryID
<span style="color:Blue; End <span style="color:Blue; With
<span style="color:Blue; End <span style="color:Blue; If

<span style="color:Green; call the object method to validate and persist the new details
mobjAssessment.PersistAppoint(<span style="color:#A31515; "U", myAppoint)
mobjAssessment = <span style="color:Blue; Nothing
mobjClient = <span style="color:Blue; Nothing
<span style="color:Green; this sets a variable to prevent the ItemChange event firing
<span style="color:Green; continuously - as the PersistAppoint sub includes an update
<span style="color:Green; to the Outlook Item, which triggers another ItemChange
mblnEndLoop = <span style="color:Blue; True
ExitHere:
<span style="color:Blue; Exit <span style="color:Blue; Sub
ErrorHandler:
mobjError = <span style="color:Blue; New cError
mobjError.GetActiveControlValue(<span style="color:Blue; Me.ActiveControl)
<span style="color:Blue; Call LoadErrorInformation(mobjError, mstrRecID, mstrProcedureName, mstrClass)
<span style="color:Green; Process the error with a Message Box, Email message,
<span style="color:Green; or write to an error table in a database.
mobjError.ProcessError(<span style="color:Blue; True)
myExplorer.Close()
<span style="color:Blue; Resume ExitHere
<span style="color:Blue; End <span style="color:Blue; Sub
[/code]

<br/>
Explorer_Close:


<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; Private <span style="color:Blue; Sub myExplorer_Close() <span style="color:Blue; Handles myExplorer.Close
<span style="color:Green; this code handles form running on different thread from
<span style="color:Green; current and resolves - see http://www.vbforums.com/showthread.php?t=498387
<span style="color:Blue; If <span style="color:Blue; Me.InvokeRequired <span style="color:Blue; Then
<span style="color:Blue; Me.Invoke(<span style="color:Blue; New MethodInvoker(<span style="color:Blue; AddressOf myExplorer_Close))
<span style="color:Blue; Else
<span style="color:Green; tidy up
myOlApp.Quit()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()

<span style="color:Blue; If <span style="color:Blue; Not myAppoint <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myAppoint)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myItem <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myItem)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not mySecondItem <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(mySecondItem)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myItems <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myItems)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myDeletedItems <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myDeletedItems)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myInspector <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myInspector)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not my2ndInspector <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(my2ndInspector)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myInspectors <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myInspectors)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myFolder <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myFolder)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myTopFolder <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myTopFolder)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myDeletedFolder <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myDeletedFolder)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myNameSpace <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myNameSpace)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myExplorer <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myExplorer)
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; If <span style="color:Blue; Not myOlApp <span style="color:Blue; Is <span style="color:Blue; Nothing <span style="color:Blue; Then
Marshal.FinalReleaseComObject(myOlApp)
<span style="color:Blue; End <span style="color:Blue; If
SharedForms.MainForm.enableMe()
<span style="color:Blue; Me.Close()
<span style="color:Blue; End <span style="color:Blue; If
<span style="color:Blue; End <span style="color:Blue; Sub
[/code]

Thanks!

View the full article
 
Back
Top