Je crée un fil qui cherche une fenêtre. Quand il trouve la fenêtre, il remplace son windowproc et gère WM_COMMAND et WM_CLOSE.Sous-classe d'une fenêtre d'un fil dans C#
Voici le code qui recherche la fenêtre et sous-il:
public void DetectFileDialogProc()
{
Window fileDialog = null;
// try to find the dialog twice, with a delay of 500 ms each time
for (int attempts = 0; fileDialog == null && attempts < 2; attempts++)
{
// FindDialogs enumerates all windows of class #32770 via an EnumWindowProc
foreach (Window wnd in FindDialogs(500))
{
IntPtr parent = NativeMethods.User32.GetParent(wnd.Handle);
if (parent != IntPtr.Zero)
{
// we're looking for a dialog whose parent is a dialog as well
Window parentWindow = new Window(parent);
if (parentWindow.ClassName == NativeMethods.SystemWindowClasses.Dialog)
{
fileDialog = wnd;
break;
}
}
}
}
// if we found the dialog
if (fileDialog != null)
{
OldWinProc = NativeMethods.User32.GetWindowLong(fileDialog.Handle, NativeMethods.GWL_WNDPROC);
NativeMethods.User32.SetWindowLong(fileDialog.Handle, NativeMethods.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(new WindowProc(WndProc)).ToInt32());
}
}
Et le WindowProc:
public IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
lock (this)
{
if (!handled)
{
if (msg == NativeMethods.WM_COMMAND || msg == NativeMethods.WM_CLOSE)
{
// adding to a list. i never access the window via the hwnd from this list, i just treat it as a number
_addDescriptor(hWnd);
handled = true;
}
}
}
return NativeMethods.User32.CallWindowProc(OldWinProc, hWnd, msg, wParam, lParam);
}
Tout cela fonctionne bien dans des conditions normales. Mais je vois deux cas de mauvais comportement afin de badness:
Si je ne ferme pas la boîte de dialogue dans une minute, les accidents de l'application. Est-ce parce que le fil récupère les ordures? Cela aurait un sens, dans la mesure où GC peut dire que le fil est fait? Si c'est le cas, (et je ne sais pas si c'est le cas), comment puis-je faire en sorte que le fil reste tant que la boîte de dialogue est ouverte? Si je ferme immédiatement la boîte de dialogue avec le bouton 'X' (WM_CLOSE), l'application se bloque. Je crois que c'est crash dans le windowproc, mais je ne peux pas obtenir un point d'arrêt là-bas. Je reçois une exception AccessViolationException, l'exception dit "Tentative de lecture ou d'écriture de la mémoire protégée, ce qui indique souvent qu'une autre mémoire est corrompue". C'est une condition de course, mais de ce que je ne sais pas. Pour info, j'avais remis à jour l'ancien windowproc une fois que j'avais traité les commandes, mais ça se brisait encore plus souvent!
Des idées sur la façon dont je peux résoudre ces problèmes?
il est appelé un «crochet d'accessibilité», ils sont différents des crochets de fenêtres ordinaires –