按照此处发布的Helmut Oberdan示例,我正在为Outlook 2010开发自定义地址对话框
http://www.codeproject.com/Articles/21288/Customize-the-built-in-Outlook-Select-Names-dialog
我已经使用框架4.5将项目迁移到VS2015但是 我在使用findwindow函数时遇到了麻烦
IntPtr hBuiltInDialog = WinApiProvider.FindWindow("#32770","");
某些计算机(我的)运行良好,而另一些(客户)运行不好。 似乎该函数找到了另一个不是Outlook的窗口的32770窗口,我试图枚举所有32770窗口但是当InspectorWrapper_Deactivate函数启动时,我的32770窗口不在列表中。 出现奇怪的行为,如果我将一个消息框放在去激活功能中,它会弹出两次,然后第二次右边的窗口被捕获,我的自定义对话框就会打开。这是InspectorWrapper_Deactivate函数
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;
}
}
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;
}
}
任何建议都会非常感激。 谢谢 弗拉维奥
遵循德米特里的建议 但仍然无法找到32770窗口,因为它有空窗口名称(即使它存在)
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 :(得分:0)
您需要找到托管该控件的Outlook窗口(为FindWindow
和cal Inspector
强制转换IOleWindow
),而不是使用lIOelWindow.GetWindow
,然后查找该窗口的子项(EnumChildWindows
)具有给定的类名称/标题/等。如果有多个具有该类名称的窗口,您可能需要使用父/子/对等窗口的唯一组合来确保您有正确的。
答案 1 :(得分:0)
经过几天的测试和尝试后,解决方案(由Microsoft建议)一直是插入一个单独的线程,从检查器启动并在找到窗口时自动终止。
在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();
}
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();
}
并在线程内部
public Worker(Outlook.Inspector insp)
{
Inspector = insp;
_shouldStop = false;
}
public void DoWork()
{
while (!_shouldStop)
{
SubstituteWindow();
}
}