Comment définir un contrôle personnalisé sur Mailgrid d'Outlook?
-
09-10-2019 - |
Question
Je suis en train de mettre mon contrôle sur les perspectives Mailgrid avec SetParent et Redimensionner (MoveWindow) et invalide si le Mailgrid a changé.
Cela fonctionne, mais Redimensionner le contrôle commence le scintillement.
Mon contrôle est un remplacement de Mailgrid Outlook. Pour changer le mailpreview je change simplement la sélection du mailgrid d'origine via mon contrôle.
Le parent de mon contrôle est la principale fenêtre Outlook. Je l'ai déjà essayé de fermer la fenêtre Mailgrid, mais cela n'a pas aidé.
Le scintillement arrête si je mets le Mailgrid comme le parent, mais dans ce cas, il scintille si je change la sélection, et ce ne est pas possible de tirer mon contrôle sur la mailsearch-fenêtre.
Quelqu'un sait-il comment arrêter le scintillement extrem?
classe pour gérer les changements des messages Mailgrid d'Outlook
sealed class SubWindow : NativeWindow
{
public event EventHandler Changed;
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)(NativEnums.WindowMessage.WM_SIZE) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_WINDOWPOSCHANGED) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_WINDOWPOSCHANGING) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_ERASEBKGND) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCHITTEST) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCCALCSIZE) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PAINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCPAINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PRINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PRINTCLIENT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_SETREDRAW) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_MOVE)
)
{
OnChanged();
}
base.WndProc(ref m);
//I have already tried to ignore wm_paint, but it still painted
//if (m.Msg != (int)NativEnums.WindowMessage.WM_PAINT)
//{
// base.WndProc(ref m);
//}
}
private void OnChanged()
{
if (Changed != null)
Changed(this, null);
}
}
Créer l'événement-Listener et le contrôle et définissez des parents est tout
//Is the Class above
SubWindow lw = new SubWindow();
lw.AssignHandle(ListHandle);
lw.Changed += new EventHandler(lw_Changed);
//Gets the IntPtr of the Mailgrid
//MainWindow is the Outlook main-window window
IntPtr ListHandle = GetSizes.GetMailFolderIntPtr(MainWindow);
//Gets the Rectangle of the Mailgrid
System.Drawing.Rectangle listsize = GetSizes.GetMailfolderSize(MainWindow, ListHandle);
//mc is the Custom Control
MoveWindow(mc.Handle, listsize.Left, listsize.Top, listsize.Width, listsize.Height, false);
SetParent(mc.Handle, MainWindow);
SetWindowLong(mc.Handle, (int)NativEnums.GetWindowLongConst.GWL_STYLE, (uint)(NativEnums.WindowStyles.WS_CHILD | NativEnums.WindowStyles.WS_VISIBLE));
Changement-événement
//Gets the Rectangle of the Mailgrid
System.Drawing.Rectangle listsize = GetSizes.GetMailfolderSize(MainWindow, ListHandle);
//Move and size the CustomControl to the Mailgrid Rectangle
MoveWindow(mc.Handle, listsize.Left, listsize.Top, listsize.Width, listsize.Height, false);
//Invalidate my Control
mc.Invalidate();
Peinture de mon contrôle
protected override void OnPaint(PaintEventArgs e)
{
DoPaint(e.Graphics);
//base.OnPaint(e);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground(pevent);
}
public void DoPaint(Graphics g)
{
g.Clear(BackColor);
//Here comes the painting of the GridRows (only the visible rows)
}
/// EDIT
Après avoir ajouté un Thread.Sleep(1000)
à l'DoPaint Methode j'ai pu voir l'ordre de peinture.
Après le redimensionnement, mes spectacles de contrôle pour un instant, après Outlook Mailgrid surpeints mon contrôle.
J'ai essayé de mettre base.WndProc(ref m);
befor OnChange();
mais rien n'a changé.
J'espère que cela aide à résoudre le problème.
/// EDIT
Après quelques tests, je l'ai essayé d'écouter toutes les fenêtres de perspectives et les Graphics.Clear
orange.
Je ne sais pas pourquoi, mais même cela ne fonctionne pas. Alors que le redimensionnement presque tout est tirée par les perspectives.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
/////////////////////////////////////////////////////
// Here i clear the complete window (all windows) //
/////////////////////////////////////////////////////
using (Graphics g = Graphics.FromHwnd(m.HWnd))
g.Clear(Color.Orange);
if (m.Msg == (int)(NativEnums.WindowMessage.WM_SIZE) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_WINDOWPOSCHANGED) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_WINDOWPOSCHANGING) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_WINDOWPOSCHANGING) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_ERASEBKGND) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCHITTEST) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCCALCSIZE) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PAINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_NCPAINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PRINT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_PRINTCLIENT) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_SETREDRAW) ||
m.Msg == (int)(NativEnums.WindowMessage.WM_MOVE)
)
{
OnChanged();
}
}
La solution
J'ai résolu le problème en ajoutant l'auditeur à Outlook « Frame Splitter ». Pour une raison Outlook permet d'activer l'invisible Mailgrid et peintures directe dans la fenêtre principale. (La fenêtre principale ne reçoit pas windowmessage)
Je maintenant la peinture sur WM_WINDOWPOSCHANGING
de WM_WINDOWPOSCHANGED
WM_SETREDRAW
mon contrôle sur la fenêtre principale.