powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как (самому) нарисовать заливку в стиле Vista-Explorer?
10 сообщений из 10, страница 1 из 1
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37010046
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник

Нарисовать надо "самому", т.к. нужно применить независимо от тек. стиля, не говоря о том, что волшебное слово
Код: plaintext
 SetWindowTheme g_hwndRebar, StrPtr(<стиль Explorer>),  0  'стиль для Висты
конкретно для такой заливки до сих пор не найдено.

Пытаюсь делать это с помощью CreateGradientBackground
(спасибо Бенедикту, исходник ф-ции напр. тут: http://www.sql.ru/forum/actualfile.aspx?id=8878628 )
Код: plaintext
1.
2.
3.
4.
5.
Public Function CreateGradientBackground( _
   ByVal hwndRef As Long, _
   ByVal Width As Long, ByVal Height As Long, _
   Optional ByVal Color1 =  14454852 , _
   Optional ByVal Color2 =  7747602 , _
   Optional ByVal Color3 =  9067836 ) As IPictureDisp
Как видно из картинки(слева), применение
Код: plaintext
1.
    Set g_picBackground = _
CreateGradientBackground(Form1.Picture2.hWnd, Form1.Picture2.Width, Form1.Picture2.Height,  12695690 ,  7824148 ,  11247700 )
дает ну не совсем как в оригинале (справа)
Т.е. либо цвета напутал, либо все же там 4 цвета, а не три.

Анализировал цвета спец. программой:
Верхняя полоска:
12695690
10456648
Нижняя полоска:
7824148
11247700
Т.е. так понимаю в центре переход не градиентом, а ступенькой:
10456648=>7824148

Есть еще пример как это рисовать:
http://www.vbforums.com/showthread.php?t=547618
Но он не на vb6 и там цвета указаны так:
Код: plaintext
1.
2.
3.
4.
5.
6.
    'Main background
    Public clrBGTop1 As Color = Color.FromArgb( 255 ,  127 ,  166 ,  191 )
    Public clrBGTop2 As Color = Color.FromArgb( 255 ,  4 ,  72 ,  117 )
    Public clrBGBottom1 As Color = Color.FromArgb( 255 ,  57 ,  117 ,  156 )
    Public clrBGBottom2 As Color = Color.FromArgb( 150 ,  255 ,  255 ,  255 )
    Public clrBGBorder As Color = Color.FromArgb( 200 ,  176 ,  200 ,  216 )
    Public clrBGGreen As Color = Color.FromArgb( 100 ,  57 ,  161 ,  133 )
Очевидно верхние 4 строчки это основа для двух градиентов.
Пытался мудрить:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
Option Explicit

Function Get4ByteHex(val)
    Dim s As String
    s = Hex(val)
    Do While Len(s) <  8 
        s = "0" & s
    Loop
    Get4ByteHex = Right(s,  8 )
End Function

Function Get1ByteHex(val)
    Dim s As String
    s = Hex(val)
    Do While Len(s) <  2 
        s = "0" & s
    Loop
    Get1ByteHex = Right(s,  2 )
End Function

Function GetAlpha(val)
    Dim s As String
    s = Get4ByteHex(val)
    GetAlpha = CLng("&h" & Left(s,  2 ))
End Function

Function GetRed(val)
    Dim s As String
    s = Get4ByteHex(val)
    GetRed = CLng("&h" & Mid(s,  3 ,  2 ))
End Function

Function GetGreen(val)
    Dim s As String
    s = Get4ByteHex(val)
    GetGreen = CLng("&h" & Mid(s,  5 ,  2 ))
End Function

Function GetBlue(val)
    Dim s As String
    s = Get4ByteHex(val)
    GetBlue = CLng("&h" & Right(s,  2 ))
End Function

Function GetARGB(a, r, g, b) As Long
    Dim s As String
    s = "&h" & Get1ByteHex(a) & Get1ByteHex(r) & Get1ByteHex(g) & Get1ByteHex(b)
    GetARGB = CLng(s)
End Function

Function GetMyColor(a, r, g, b) As Long
    Dim ARGBval As Long
    Dim RGBval As Long
    ARGBval = GetARGB(a, r, g, b)
    RGBval = RGB(GetRed(ARGBval), GetGreen(ARGBval), GetBlue(ARGBval))
    GetMyColor = RGBval
End Function
Мудрил вот так:
Код: plaintext
1.
2.
    Set g_picBackground = CreateGradientBackground(Form1.Picture2.hWnd, _ 
    Form1.Picture2.Width, Form1.Picture2.Height, GetMyColor( 255 ,  127 ,  166 ,  191 ), _
GetMyColor( 255 ,  4 ,  72 ,  117 ), GetMyColor( 255 ,  57 ,  117 ,  156 ))
Но цвета вообще какие-то непохожие и в голубизну отдают.

Т.е. вопрос как бы правильно этот стиль нарисовать?
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37010051
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, на картинке справа, крайне модный последние пару лет стиль, состоящий из двух градиентов.

"Анализирую цвета спец. программой" - это Gimp или Photoshop вы так обозвали?
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37010058
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.Dragonэто Gimp или Photoshop вы так обозвали?
Всего лиль какой-то ColorPic 4.1.
Но вопрос как нарисовать и какие все же правильные 4 цвета. Функция предложенная Бенедиктом 3-х ступенчатая.
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37010074
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Edd.Dragonэто Gimp или Photoshop вы так обозвали?
Всего лиль какой-то ColorPic 4.1.
Но вопрос как нарисовать и какие все же правильные 4 цвета. Функция предложенная Бенедиктом 3-х ступенчатая.
Правильные цвета берем конечно же на концах градиентов.

Код: plaintext
1.
Верхний: с 0x84AEC0 к 0x42839D
Нижний: с 0x0D5876 к 0x509AAA

а как нарисовать - не знаю. WinAPI и подобные ему API для стилизации форм не помню. Если отдельно два градиента нарисовать некак, а на весь контрол бекграунд рисуется одной функцией, то никак. Тогда как варианты:
- растянутая картинка (как обычно и делается или делалось в XP);
- готовите картинку нужного размера во время работы проги один раз и в качестве бекграунда используете ее (какими функциями - это уже к знатокам API бейсика).
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37010466
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, вот так то получше.

Как я это сделал, прилагается.
Сначала было попытался содрать отсюда.
Apply a Gradient to Any Control that Has an hDC
Но быстро послал этот пример, т.к. он рисует на hdc напрямую, что влечет кучу безобразий с перерисовками, эффектом ластика и т.п.
Поэтому переделал 3-ч ступенчатую конструкцию "от Бенедикта", упомянутую выше в 2-х ступенчатую (ломать не строить). 4-х ступенчатая оказалась не позубам, хотя не сомневаюсь это не очень сложно если шаришь.
Так что два Picturebox друг под другом
Ваши цвета из hex в long перевести не сумел.
Совет AntonariyНа будущее, 0х = &H. данный когда-то
/topic/757817&hl=%ef%e5%f0%e5%e2%e5%f1%f2%e8
чего-то не прокатил, так что брал "свои наработки".

Но, на самом деле, недаром лучше вызывать родной стиль, если это возможно...
Во-первых в нижней полоске градиент нелинейный, т.е. в оригинале темного больше.
Во-вторых там еще есть градиент по горизонтали, и любая прога-анализатор вам это покажет.

Но, если это "просто полоска", а не тулбар, то сгодится и так.
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37014441
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

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

P.S. Если когда-либо имели дело с DirectX, то методика подготовки данных очень похожа на таковую для вызова Direct3DDevice.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, ...).
P.P.S. Если будете сильно мучить GradientFill(), то функция, будучи аппаратно ускоренной, при некоторых условиях способна обрушить ОС, имейте ввиду (как и DirectX-ные).
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37014885
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бенедикт,

Энто все красиво, но озвученную задачу хотя бы из четырех цветов (без учета горизонтали), но одной функцией сделать можно? Т.е. наложить 2 градиента на один битмап. Приведенные 2 полоски это конечно сойдет, но два кулбара под один тулбар подкладывать же не выйдет например.
С кнопкой кстати ничего не посоветуете?
Как облагородить кнопку которая поверх картинки?
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37015820
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

ну есть же инструментарий. Прямая сетка, две полосы, линейная интерполяция цвета в точках сетки. Конечно, 100%-ного попадания не получится, в оригинале, кстати, ещё и граница осветлена, но довольно близко к.

По кнопке ничего не скажу, ибо конец года, не до экспериментов. Попробуйте посмотреть, будет ли тот же эффект, если кнопку создавать через CreateWindowEx().
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37015828
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

а, ну и Кэп Очевидность подсказывает: если где видите хорошую, годную кнопку, натравите на неё Spy++. Вдруг что найдётся.
...
Рейтинг: 0 / 0
Как (самому) нарисовать заливку в стиле Vista-Explorer?
    #37017257
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бенедиктну есть же инструментарий. Прямая сетка, две полосы, линейная интерполяция цвета в точках сетки...
Это для Вас инструментарий. Для меня - хождение по мукам.
Несколько часов ушло чтоб сделать из Вашего примера функцию CreateGradientBackComplex(), кот. относительно легко применима чтоб заполнить любой контрол в размер....как смог (результат прилагается).
Долго думал что есть
Код: plaintext
1.
 Static bSetup As Boolean
 If bSetup Then Exit Sub
Потом таки прочел, типа внутри ф-ции живет и помнит свое значение при каждом ее вызове, но недоступна во вне -школьнику бы поставили двойку.
Но не понял зачем оно там.
Из-за этого bSetup вторая картинка никогда не нарисуется.
Не знаю зачем она там, убрать не рискнул, пристукнул ее частично путем добавления ложных вызовов перед вызовом функций
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private Sub SetupVertices(v0() As TRIVERTEX, v1() As TRIVERTEX, _
  ByVal b As Long, ByVal u As Long, ByVal s As Long, _
  disablestatic As Boolean)  'установка координат узлов сетки
 Dim i As Long, x As Long
 Static bSetup As Boolean
 If disablestatic Then
    bSetup = False
    Exit Sub
 End If
 If bSetup Then Exit Sub
...

БенедиктP.P.S. Если будете сильно мучить GradientFill(), то функция, будучи аппаратно ускоренной, при некоторых условиях способна обрушить ОС, имейте ввиду (как и DirectX-ные)....
Задумался над Вашими словами, уже ведь тупо "наловчился" применять где не лень:
Код: plaintext
1.
2.
3.
4.
Private Sub Form_Paint()
    Set g_picBackground = CreateGradientBackground _
      (Form1.Picture1.hWnd, Form1.Picture1.Width, Form1.Picture1.Height, vbWhite,  7747602 ,  9067836 )
    Form1.Picture1.Picture = g_picBackground
End Sub
То бишь градиент.битмэп создается всякий раз. Случаев сбоя ОС правда не наблюдал, но пореределывал на типа вот так (один раз создали, в конце на всяк. случай убили):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Option Explicit
Dim g_picBackground As IPictureDisp

Private Sub Form_Load()
    Set g_picBackground = CreateGradientBackgroundSimple_ 
      (Me.Picture1.hWnd, Me.Picture1.Width, Me.Picture1.Height,  12628871 ,  10389829 ) '12695690, 7824148, 11247700
End Sub

Private Sub Form_Paint()
    Me.Picture1.Picture = g_picBackground
End Sub

Private Sub Form_Unload(Cancel As Integer)
    DeleteObject g_picBackground
End Sub

По идее Form_Paint не нужен если AutoRedraw, но мне понравилось рисовать еще большие полноцветные иконки на hdc поверх фона:
Код: plaintext
1.
2.
3.
Private Sub Form_Paint()
   Me.Picture1.Picture = g_picBackground
   DrawIconEx Picture1.hDC,  10 ,  0 , lngIconPICT,  0 ,  0 ,  0 ,  0 , DI_NORMAL 'перерисовываем иначе сотрется как ластиком
 End Sub

По хорошей идее иконку думаю можно сразу нарисовать на виртуальное hdc при создании битмапа, т.е. внутрь функции CreateGradientBackground, но это как нибудь потом.

Единственное, в одном месте я таки оставил изначальный вариант с перегенерацией картинки, потому что размер PictureBox меняется при изменении размера формы и фон-подложку надо регенерировать. И даже не убиваю в конце. Вроде фурычит и через сутки-двое не падает.

Кстати вопрос. Надо ли делать?
Код: plaintext
1.
2.
Private Sub Form_Unload(Cancel As Integer)
    DeleteObject g_picBackground
End Sub
Тема как то обсуждалась. Просто в крайнем варианте с перегенерацией убивать надо думаю постоянно и можно нарваться на ситуацию когда g_picBackground не существует. Думаю лучше не создавать доп. проблем и положиться на удачу.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как (самому) нарисовать заливку в стиле Vista-Explorer?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]