0

我正在尝试使用 SetParent 设置对 Outlook Mailgrid 的控制并调整大小(MoveWindow),并在 Mailgrid 更改时使其无效。

这有效,但在调整大小时,控件会开始闪烁。

我的控件是 Outlook 的 Mailgrid 的替代品。要更改邮件预览,我只需通过我的控件更改原始邮件网格的选择。

我的控件的父级是 Outlook 主窗口。我已经尝试关闭 Mailgrid 窗口,但这没有帮助。

如果我将 Mailgrid 设置为父级,则闪烁停止,但在这种情况下,如果我更改选择,它会闪烁,并且无法控制邮件搜索窗口。

有人知道如何阻止极端闪烁吗?

处理 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);
    }
}

创建事件侦听器和控件并将其设置为父级

//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));

改变事件

//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();

我的控制绘画

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)
}

/// 编辑

将 a 添加Thread.Sleep(1000)到 DoPaint 方法后,我能够看到绘制顺序。调整大小后,我的控件会立即显示,然后 Outlook 邮件网格会覆盖我的控件。我试过设置base.WndProc(ref m);OnChange();但没有任何改变。我希望这有助于解决问题。

/// 编辑

经过一些测试后,我尝试收听所有 Outlook 窗口,Graphics.Clear它们都是橙色的。我不知道为什么,但即使这样也行不通。在调整大小时,几乎所有内容都是由前景绘制的。

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();
    }               

}
4

1 回答 1

0

我通过将侦听器添加到 Outlook“分帧器”解决了这个问题。由于某种原因,Outlook 将 Mailgrid 设置为不可见并直接在主窗口上绘制。(主窗口没有收到任何窗口消息)

我现在也在WM_WINDOWPOSCHANGING WM_WINDOWPOSCHANGED WM_SETREDRAW我对主窗口的控制上作画。

于 2010-12-08T12:54:20.520 回答