Tom,
I had found a similar sample online, but yours does not work either. But I
feel as if I'm close.
This is the code I'm now using in my calling program:
Sub Outlook_Startup
Dim cb As New EnumWindowCallbackDelegate(AddressOf MyProject.Main)
EnumWindows(cb, IntPtr.Zero)
Call ReturnContact 'code to process after the .dll is finished running
End Sub
This is the code called in the .dll
Public Function Main(ByVal hwnd As Integer, ByVal lParam As Integer)
As Boolean
objOutlook = New Outlook.Application()
ns = objOutlook.Session
Dim MyContactFolders As Outlook.MAPIFolder =
(ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFo lderContacts))
Dim MyDefaultProfile As RegistryKey
Dim MyKey As String
Try
MyDefaultProfile =
Registry.CurrentUser.OpenSubKey("Software\Microsof t\Windows
NT\CurrentVersion\Windows Messaging Subsystem\Profiles", False)
MyKey = MyDefaultProfile.GetValue("DefaultProfile", "")
ns.Logon("Outlook", , False, False)
Call GetAllContactFolders()
MyContacts.Show()
MyContacts.BringToFront()
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Function
The behavior I'm getting is different from the code you sent me that I
tested. The code execution runs through the .dll and then returns to the
calling program and then tries to run that 'ReturnCode' sub. It never stops
to allow the .dll to do it's job.
I was able to call the Main sub in the .dll using this code:
Dim caller As New AsyncMethodCaller(AddressOf MyProject.Main)
threadId = Thread.CurrentThread.ManagedThreadId()
caller.Invoke(3000, threadId)
This code was giving full control to the .dll. The only problem is, I'm not
able to return back to my .dll.
Do you have any ideas on what I may be doing wrong? Thanks!
"Tom Shelton" wrote:
On 2008-06-10, Joemanc <jm****@cl-law.com.donotspamwrote:
Hi,
I'm trying to figure out the Callback method. I have a .dll that I call from
a sub in my unmanaged code/calling program. That works just fine. But I'd
like to have the .dll finish doing it's thing before returning to my calling
program. Right now, with the code I've been testing with, the calling program
goes to the .dll and then returns back to the calling program without letting
the .dll do it's thing. Just having a hard time figuring out the callback
routine. If someone could lead me to a good example, that would be great.
Thanks!
Ok... Here you go a simple example that calls the EnumWindows api:
Option Strict On
Option Explicit On
Option Infer Off
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Module Module1
' callback delegate
Private Delegate Function EnumWindowCallbackDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
' EnumWindows declare
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowCallbackDelegate, ByVal lParam As IntPtr) As Boolean
Private Declare Auto Function GetWindowTextLength Lib "user32" (ByVal hWnd As IntPtr) As Integer
Private Declare Auto Function GetWindowText Lib "user32" (ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
Sub Main()
Dim cb As New EnumWindowCallbackDelegate(AddressOf EnumWindowsCallbackFunction)
EnumWindows(cb, IntPtr.Zero)
End Sub
Private Function EnumWindowsCallbackFunction(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Dim bufferLength As Integer = GetWindowTextLength(hWnd)
If (bufferLength 0) Then
Dim buffer As New StringBuilder(bufferLength + 1)
If GetWindowText(hWnd, buffer, buffer.Capacity) 0 Then
Console.WriteLine(buffer.ToString())
End If
End If
Return True
End Function
End Module
Now, the trick here is that the EnumWindows api takes a function pointer - so,
we declare a delegate type with the same signature - and that is what we pass.
A delegate is, after alll, a object oriented function pointer :)
--
Tom Shelton