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)?
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)
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.