Не работает SetBkColor.Нужна помощь.
От: urban1981  
Дата: 14.01.11 06:06
Оценка:
Здравствуйте. Есть "свой" Control TABCONTROL. Хочу задать цвет фона таким способом:

        [DllImport("coredll.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("coredll.dll")]
        private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

        public override Color BackColor
        {
            get
            {
                return this.BackColor;
            }
            set
            {
                if (hwndTab != IntPtr.Zero)
                {
                    IntPtr hdc = GetDC(hwndTab);
                    SetBkColor(hdc, value.ToArgb());
                    ReleaseDC(hwndTab, hdc);
                }
            }
        }

Не работает. Подскажите пожалуйста в чем дело.Маленько накопал инфрмации не знаю верной ли:
        public static ReversibleHandle Create(Color backColor, FrameStyle style)
        {
            ReversibleHandle ret = new ReversibleHandle();
            int mixmode;
            Color color;
            if (backColor.GetBrightness() < 0.5)
            {
                mixmode = 10;
                color = Color.White;
            }
            else
            {
                mixmode = 7;
                color = Color.Black;
            }
            ret.HDC = new HandleRef(null, GetDCEx(new HandleRef(null, GetDesktopWindow()), new HandleRef(null, IntPtr.Zero), 0x403));
            ret.MixMode = SetROP2(ret.HDC, mixmode);

            ret.ptr2 = (style == FrameStyle.Dashed)
                ? new HandleRef(null, CreatePen(2, 1, ColorTranslator.ToWin32(backColor)))
                : new HandleRef(null, CreatePen(0, 2, ColorTranslator.ToWin32(backColor)));

            ret.ptr3 = new HandleRef(null, SelectObject(ret.HDC, new HandleRef(null, GetStockObject(5))));
            ret.ptr4 = new HandleRef(null, SelectObject(ret.HDC, ret.ptr2));
            SetBkColor(ret.HDC, ColorTranslator.ToWin32(color));//!!!!!!!!!!!!!!!!!
            return ret;
        }

Может нужно спортировать функцию аналог методу ColorTranslator.ToWin32(переводит указанную структуру Color в цвет Windows).Если ДА то подскажите пожалуйста название функции.
Заранее благодарю.


14.01.11 14:25: Перенесено модератором из '.NET' — TK
Re: Не работает SetBkColor.Нужна помощь.
От: aloch Россия  
Дата: 14.01.11 11:45
Оценка:
Здравствуйте, urban1981, Вы писали:

Вот скажи мне, как ты думеешь, если ты задащь цвет фона в некотором только что созданном и сразу уничтоженном контексе устройства, то как это повлияет на то, какой цвет фона будет использован, когда контрол будет рисовать сам себя в ответ на WM_PAINT (в совершенно другом контексе устройства)? Ведь он даже и не узнет, что ты что то такое делал с ним когда-то.


Re: Не работает SetBkColor.Нужна помощь.
От: Pavel Dvorkin Россия  
Дата: 14.01.11 11:49
Оценка:
Здравствуйте, urban1981, Вы писали:

U> {

U> IntPtr hdc = GetDC(hwndTab);
U> SetBkColor(hdc, value.ToArgb());
U> ReleaseDC(hwndTab, hdc);
U> }

Ну и что ты от этого кода хочешь ? Получить контекст, установить цвет, выбросить контекст. Все именно так и работает.

Вот если бы класс окна был со стилем CS_OWNDC или CS_WINDOWDC, тогда бы работало. Но это значит, что класс окна надо самому регистрировать.

А теперь посмотри как это сделано в System.Windows.Forms.Control.BackColor : Color



public virtual Color BackColor
{
    get
    {
        Color rawBackColor = this.RawBackColor;
        if (!rawBackColor.IsEmpty)
        {
            return rawBackColor;
        }
        Control parentInternal = this.ParentInternal;
        if ((parentInternal != null) && parentInternal.CanAccessProperties)
        {
            rawBackColor = parentInternal.BackColor;
            if (this.IsValidBackColor(rawBackColor))
            {
                return rawBackColor;
            }
        }
        if (this.IsActiveX)
        {
            rawBackColor = this.ActiveXAmbientBackColor;
        }
        if (rawBackColor.IsEmpty)
        {
            AmbientProperties ambientPropertiesService = this.AmbientPropertiesService;
            if (ambientPropertiesService != null)
            {
                rawBackColor = ambientPropertiesService.BackColor;
            }
        }
        if (!rawBackColor.IsEmpty && this.IsValidBackColor(rawBackColor))
        {
            return rawBackColor;
        }
        return DefaultBackColor;
    }
    set
    {
        if ((!value.Equals(Color.Empty) && !this.GetStyle(ControlStyles.SupportsTransparentBackColor)) && (value.A < 0xff))
        {
            throw new ArgumentException(SR.GetString("TransparentBackColorNotAllowed"));
        }
        Color backColor = this.BackColor;
        if (!value.IsEmpty || this.Properties.ContainsObject(PropBackColor))
        {
            this.Properties.SetColor(PropBackColor, value);
        }
        if (!backColor.Equals(this.BackColor))
        {
            this.OnBackColorChanged(EventArgs.Empty);
        }
    }
}


Так что можешь пойти по этому пути. Но можно и проще. См. SetClassLongPtr с параметром GCL_HBRBACKGROUND.
With best regards
Pavel Dvorkin
Re[2]: Не работает SetBkColor.Нужна помощь.
От: urban1981  
Дата: 17.01.11 11:38
Оценка:
PD>Так что можешь пойти по этому пути. Но можно и проще. См. SetClassLongPtr с параметром GCL_HBRBACKGROUND.
А может быть такое что SetClassLongPtr нет в "coredll.dll"

        [DllImport("coredll.dll", EntryPoint = "SetClassLongPtr")]
        private static extern IntPtr SetClassLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

Ругается , говорит что нет такой...Может я портирую неправильно или она по другому называется, потомучто во всех хелпах там ни одного упоминания про Windows ce...
Re[3]: Не работает SetBkColor.Нужна помощь.
От: Pavel Dvorkin Россия  
Дата: 17.01.11 12:29
Оценка:
Здравствуйте, urban1981, Вы писали:

PD>>Так что можешь пойти по этому пути. Но можно и проще. См. SetClassLongPtr с параметром GCL_HBRBACKGROUND.

U>А может быть такое что SetClassLongPtr нет в "coredll.dll"

U>
U>        [DllImport("coredll.dll", EntryPoint = "SetClassLongPtr")]
U>        private static extern IntPtr SetClassLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
U>

U>Ругается , говорит что нет такой...Может я портирую неправильно или она по другому называется, потомучто во всех хелпах там ни одного упоминания про Windows ce...

Она в user32.dll. Если в CE ее нет, замени на SetClassLong — в 32-битной не отличается.
With best regards
Pavel Dvorkin
Re[4]: Не работает SetBkColor.Нужна помощь.
От: urban1981  
Дата: 18.01.11 08:58
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Она в user32.dll. Если в CE ее нет, замени на SetClassLong — в 32-битной не отличается.
Функция портируется все ровно, но результата нет... Да под цветом фона я имел в виду цвет вкладок...На RSDN некоторые рекомендуют: "Смотри в сторону TCS_OWNERDRAWFIXED". Смотрел — не помогло. Может у вас есть ещё советы?
Re[5]: Не работает SetBkColor.Нужна помощь.
От: Аноним  
Дата: 20.01.11 09:54
Оценка:
Здравствуйте, urban1981, Вы писали:

U>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>Она в user32.dll. Если в CE ее нет, замени на SetClassLong — в 32-битной не отличается.
U>Функция портируется все ровно, но результата нет... Да под цветом фона я имел в виду цвет вкладок...На RSDN некоторые рекомендуют: "Смотри в сторону TCS_OWNERDRAWFIXED". Смотрел — не помогло. Может у вас есть ещё советы?

1. поиграться c WM_ERASEBKGND
2. забить на backgroundcolor и заполнять фон нужным цветом в WM_PAINT
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.