views:

32

answers:

1

I'm using p/invoke to call EnableScrollBar from user32.dll (MSDN reference). I noticed that when the scrollbar is enabled, it seems to draw as though no theme is applied and then re-drawn with the theme applied. I've only tested with Windows 7 so far. Is there any way to stop this from happening?

EDIT: Here's some code to show what happens (dump into a form with scrollbars):

private class Native
{
    [DllImport("user32.dll")]
    public static extern bool EnableScrollBar(IntPtr hWnd, uint wSBflags, uint wArrows);

    public static class SBArrows
    {
        public const uint ESB_ENABLE_BOTH = 0;
        public const uint ESB_DISABLE_BOTH = 3;
        public const uint ESB_DISABLE_LEFT = 1;
        public const uint ESB_DISABLE_RIGHT = 2;
        public const uint ESB_DISABLE_UP = 1;
        public const uint ESB_DISABLE_DOWN = 2;
        public const uint ESB_DISABLE_LTUP = 1;
        public const uint ESB_DISABLE_RTDN = 2;
    }

    public static class SBFlags
    {
        public const uint SB_HORZ = 0;
        public const uint SB_VERT = 1;
        public const uint SB_CTL = 2;
        public const uint SB_BOTH = 3;
    }
}


private bool Switch = false;

protected override void OnMouseDown(MouseEventArgs e)
{
    Native.EnableScrollBar(this.Handle, Native.SBFlags.SB_HORZ, this.Switch ? Native.SBArrows.ESB_DISABLE_BOTH : Native.SBArrows.ESB_ENABLE_BOTH);
    this.Switch = !this.Switch;
}


Final Solution

Native.SendMessage(this.Handle, Native.WindowMessages.WM_SETREDRAW, new IntPtr(0), IntPtr.Zero);
Native.EnableScrollBar(this.Handle, Native.SBFlags.SB_HORZ, Native.SBArrows.ESB_ENABLE_BOTH);
Native.SendMessage(this.Handle, Native.WindowMessages.WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
+1  A: 

I don't like this solution much. It does however work:

    protected override void OnMouseDown(MouseEventArgs e) {
        Native.LockWindowUpdate(this.Handle);
        Native.EnableScrollBar(this.Handle, Native.SBFlags.SB_HORZ, this.Switch ? Native.SBArrows.ESB_DISABLE_BOTH : Native.SBArrows.ESB_ENABLE_BOTH);
        //this.Invalidate();
        Native.LockWindowUpdate(IntPtr.Zero);
        this.Switch = !this.Switch;
    }
Hans Passant
@Hans - That does the trick. Could you enlighten me as to why you don't like this solution? I'm trying to learn as much as possible about native methods. Thanks!
TheCloudlessSky
Link: http://blogs.msdn.com/b/oldnewthing/archive/2007/02/22/1742084.aspx?wa=wsignin1.0
Hans Passant
Thanks! I just found that link and the others blog series on it, too. So sending the `WM_SETREDRAW` message would obviously be better, correct?
TheCloudlessSky
I doubt that works.
Hans Passant
@Hans - After some tests, I'm sure that sending the `WM_SETREDRAW` message does seem to work.
TheCloudlessSky
Okay, that's better then.
Hans Passant
Thanks for your help.
TheCloudlessSky