Come posso determinare in modo affidabile l'handle di una determinata finestra di ispezione di Outlook con WordMail attivato da un componente aggiuntivo COM (Outlook < = 2003)?

StackOverflow https://stackoverflow.com/questions/298466

  •  08-07-2019
  •  | 
  •  

Domanda

[Questo codice viene chiamato dall'interno del gestore di eventi Inspector.Activate (prima chiamata), vale a dire proprio prima che venga effettivamente visualizzata la finestra di ispezione.]

Per " nativo " ispettori di posta Posso semplicemente QI l'interfaccia Inspector su IOleWindow e chiamare il suo metodo GetWindow . Tuttavia, ciò non funzionerà per gli ispettori di Word che in realtà sono istanze di Word con una barra degli strumenti speciale e non implementano IOleWindow .

(Temporaneamente) impostare Inspector.Caption su un valore univoco e quindi cercare una finestra con quella didascalia non funziona poiché l'accesso alla maggior parte delle proprietà di Inspector ha semplicemente nessun effetto (immediato) sulla finestra di ispezione effettiva quando si utilizza l'opzione WordMail. Né chiamare Attiva e quindi eseguire immediatamente la query su GetForegroundWindow funziona in modo affidabile: quando ci sono più ispettori già aperti o quando sono presenti finestre di Word effettive, questo spesso restituirà semplicemente " più vecchio " istanza anziché la più recente.

Ho provato diversi altri approcci nel corso degli anni, ma alla fine tutti si sono rivelati difettosi in un modo o nell'altro. Esiste una soluzione moderatamente semplice a questo o dovrò optare per un approccio molto più elaborato come tenere il mio elenco di maniglie di finestre conosciute tramite un hook di sistema e provare a confrontarle con gli ispettori noti in qualche modo? (cappello a P Daddy per il suggerimento sull'uso dei ganci CBT)

È stato utile?

Soluzione

Ora ho escogitato qualcosa di nuovo che non sono stato ancora in grado di spezzare, ma sembra ancora molto simile al voodoo. Per osservazione ho scoperto che la finestra che desidero sembra sempre essere la prima restituita da < codice> EnumWindows che non è (ancora) visibile, ovvero IsWindowVisible restituisce False (ricorda che sto chiamando questo codice dall'interno della prima occorrenza di Inspector.Activate evento immediatamente prima che l'ispettore venga visualizzato per la prima volta).

Se qualcuno conosce una soluzione migliore o ha una spiegazione fondata del perché funziona (preferibilmente con collegamenti a documenti autorevoli), si prega di inviare una risposta.

Aggiornamento: Quindi, su richiesta, ecco un vero codice (Delphi). Nota che questo non è il mio codice di lavoro, che contiene un paio di altre cose, non pertinenti a questa domanda, che sono state eliminate qui.

function GetWindowClassName(const AHandle: HWND): String;
var
  lClass: array[0..255] of Char;
begin
  if GetClassName(AHandle, lClass, SizeOf(lClass)) > 0 then
    Result := lClass
  else
    Result := '';
end;

type
  TWordSearchInfo = record
    Result: HWND;
  end;
  PWordSearchInfo = ^TWordSearchInfo;

function CheckWnd(AWnd: HWND; ASearchInfo: PWordSearchInfo): Boolean; stdcall;
begin
  Result := True;
  try
    if GetWindowClassName(AWnd) = 'OpusApp' then
      if not IsWindowVisible(AWnd) then
        begin
          ASearchInfo.Result := AWnd;
          Exit(False);
        end;
  except
    //plop!
  end;
end;

function GetNewestWordHandle: Cardinal;
var
  lSearchInfo: TWordSearchInfo;
begin
  lSearchInfo.Result := 0;
  EnumWindows(@CheckWnd, Integer(@lSearchInfo));
  Result := lSearchInfo.Result;
end;

Nota: utilizzo questa funzione solo all'interno dell'evento Attiva dell'ispettore e quando la versione principale di Outlook è < 12 e la proprietà IsWordMail dell'ispettore è True .

Altri suggerimenti

Ho scoperto che sul costruttore dell'ispettore personalizzato è possibile utilizzare il seguente metodo per trovare l'ispettore di nuova costruzione.

C #

inspectorWindow = Win32.FindWindowEx (IntPtr.Zero, IntPtr.Zero, " OpusApp " ;, " Microsoft Word ");

Devi farlo sul costruttore, successivamente la didascalia diventa il titolo del messaggio ("Messaggio senza titolo" sui nuovi messaggi). Suppongo che se hai già aperto un messaggio di nome Microsoft Word, potrebbe esserci un errore a causa dell'ambiguità, ma le probabilità che ciò accada sono piuttosto basse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top