0

ich eine benutzerdefinierte Adresse Dialog für Outlook 2010, die Entwicklung nach der Probe von Helmut Oberdan hier veröffentlichtOutlook 2010 Plugin falsch 32770 Fenster

http://www.codeproject.com/Articles/21288/Customize-the-built-in-Outlook-Select-Names-dialog

ich das Projekt migriert haben mit Rahmen VS2015 4.5 aber Ich habe Probleme mit der Funktion findwindow

IntPtr hBuiltInDialog = WinApiProvider.FindWindow ("# 32770", "");

auf einigen Computer (meins) funktioniert gut und auf einige andere (Kunde) tut es nicht. Es scheint, dass die Funktion ein anderes 32770-Fenster findet, das nicht das von Outlook ist. Ich habe versucht, alle 32770-Fenster aufzulisten, aber wenn die InspectorWrapper_Deactivate-Funktion ausgelöst wird, ist mein 32770-Fenster nicht in der Liste vorhanden. Ein seltsames Verhalten tritt auf, wenn ich eine MessageBox in die Deaktivierungsfunktion setze, erscheint sie zweimal und nach dem zweiten Mal wird das rechte Fenster eingefangen und mein benutzerdefinierter Dialog öffnet sich. Hier

ist die InspectorWrapper_Deactivate Funktion

void InspectorWrapper_Deactivate() 
{ 
    _showOwnDialogOnActivate = false; 

    // If there is an invisible ghost Window out there - close it 
    if (_hWndInvisibleWindow != IntPtr.Zero) WinApiProvider.SendMessage(_hWndInvisibleWindow, WinApiProvider.WM_SYSCOMMAND, WinApiProvider.SC_CLOSE, 0); 

    IntPtr hBuiltInDialog = WinApiProvider.FindWindow("#32770", ""); 
    if (hBuiltInDialog != IntPtr.Zero) 
    { 
     // ok, found one 
     // let's see what childwindows are there 
     List<IntPtr> childWindows = WinApiProvider.EnumChildWindows(hBuiltInDialog); 
     // Let's get a list of captions for the child windows 
     List<string> childWindowNames = WinApiProvider.GetWindowNames(childWindows); 

     //MessageBox.Show("Contact"); 

     // now check some criteria to identify the build in dialog.. 
     int languageId = Inspector.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI); 
     switch (languageId) 
     { 
      case 1031: 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       // !!! This part is only valid for German Outlook 2007 Version !!! 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       if (!childWindowNames.Contains("Nur N&ame")) return; 
       if (!childWindowNames.Contains("&Mehr Spalten")) return; 
       if (!childWindowNames.Contains("A&dressbuch")) return; 
       // you can even check more criteria 
       break; 

      case 1033: 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       // !!! This part is only valid for english Outlook 2007 Version !!! 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       if (!childWindowNames.Contains("&Name only")) return; 
       if (!childWindowNames.Contains("Mo&re columns")) return; 
       if (!childWindowNames.Contains("A&ddress Book")) return; 
       break; 

      case 1040: 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       // !!! This part is only valid for italian Outlook 2007 Version !!! 
       // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
       if (!childWindowNames.Contains("Solo n&ome")) return; 
       if (!childWindowNames.Contains("Altre &colonne")) return; 
       if (!childWindowNames.Contains("R&ubrica")) return; 
       break; 
      // TODO: place your language here.... 

      default: 
       return; 
     } 

     // OK - we have the built in Recipient Dialog 
     // Create a new invisible window 
     _hWndInvisibleWindow = WinApiProvider.CreateWindowEx(0, "Static", "BriaSOFT", 0, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); 

     // use this window as new Parent for the original Dialog 
     WinApiProvider.SetParent(hBuiltInDialog, _hWndInvisibleWindow); 

     WinApiProvider.SendMessage(hBuiltInDialog, WinApiProvider.WM_SYSCOMMAND, WinApiProvider.SC_CLOSE, 0); 
     // When our INspector becomes active again, we should show our own Dialog 
     _showOwnDialogOnActivate = true; 
    } 
} 

jeder Vorschlag zu schätzen sein, wirklich wird. Dank Flavio

Nach Dmitry Vorschlag aber nach wie vor nicht in der Lage, die 32770-Fenster zu finden, weil es leer Fensternamen hat (auch wenn es vorhanden ist)

string windowName; 
    IntPtr outlookHandle = (IntPtr)0; 
    IOleWindow window = Inspector as IOleWindow; 
    if (window != null) 
    { 
     window.GetWindow(out outlookHandle); 
     List<IntPtr> subWindows = WinApiProvider.EnumChildWindows(outlookHandle); 
     foreach (IntPtr hand in subWindows) 
     { 
      StringBuilder ClassName = new StringBuilder(256); 
      int nRet = WinApiProvider.GetClassName(hand, ClassName, ClassName.Capacity); 
      if (nRet != 0) 
      { 
       if (ClassName.ToString().Contains("#32770")) 
       { 
        windowName = WinApiProvider.GetWindowName(hand); 
        if (windowName.Contains("Seleziona nomi")) 
        { 
         hBuiltInDialog = hand; 
         break; 
        } 
       } 
      } 
     } 
    } 

+0

Das ist ziemlich typisch Codeproject.com Code, es funktioniert immer nur richtig durch reinen Zufall. Du musst es wegwerfen. Verwenden Sie den System.Windows.Automation-Namespace, da gibt es ein bisschen eine Lernkurve, aber die Investition ist es wert und wird sich in Zukunft gut zurückzahlen. –

Antwort

0

Nach Tagen von Test und Versuchen wurde die Lösung (vorgeschlagen von Microsoft), einen separaten Thread einzufügen, aus dem Inspektor gestartet und automatisch beendet, wenn das Fenster gefunden wird.

Im Innern der inspector_deactivate

if (workerThread.ThreadState == ThreadState.Unstarted) 
    { 
     // Start the worker thread. 
     workerThread.Start(); 

     while (!workerThread.IsAlive) ; 

     // Put the main thread to sleep for 1 millisecond to 
     // allow the worker thread to do some work: 
     Thread.Sleep(1); 
    } 
    else if (!workerThread.IsAlive) 
    { 
     workerObject = new Worker(Inspector); 
     workerThread = new Thread(workerObject.DoWork); 
     workerThread.Start(); 
    } 

und im Gewinde

public Worker(Outlook.Inspector insp) 
    { 
     Inspector = insp; 
     _shouldStop = false; 
    } 

    public void DoWork() 
    { 
     while (!_shouldStop) 
     { 
      SubstituteWindow(); 
     } 
    } 

0

Statt FindWindow verwenden, werden Sie muss das Outlook-Fenster finden, das dieses Steuerelement hostet (cast Inspector für IOleWindow und cal lIOelWindow.GetWindow), dann suchen Sie nach einem Kind dieses Fensters (EnumChildWindows) mit dem gegebenen Klassennamen/caption/etc. Wenn es mehrere Fenster damit Klassenname, müssen Sie möglicherweise eine eindeutige Kombination der Eltern/Kind/Peer-Fenster verwenden, um sicherzustellen, dass Sie die richtige haben.

+0

Hallo Dmitry vielen Dank für die Antwort, ich habe Ihre Anweisungen gefolgt, aber die Schleife durch die Liste findet nicht das richtige Fenster, der Titel scheint leer zu sein, werde ich die Funktion Name des Fensters –

+0

mit spielen testen Spioniere zuerst mit ++ die richtige Fensterhierarchie. –

+0

Verwenden von Spy ++ Ich sehe, dass das Fenster, nach dem ich suche, unter Desktop-Root ist. Das Problem scheint zu sein, dass das Fenster in der Liste immer noch nicht in der Liste –