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.olFolderContacts))
Dim MyDefaultProfile As RegistryKey
Dim MyKey As String
Try
MyDefaultProfile =
Registry.CurrentUser.OpenSubKey("Software\Microsoft\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 <(E-Mail Removed)> wrote:
> > 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
>