Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нарисовать градиент (GDI+) 
V
    Опции темы
suxxor
Дата 18.1.2012, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



Нужно нарисовать градиент как на картинке из .NET на C++ (WINAPI)

Оригинал:
Код

void CCtrlTraffic::OnPaint()
{
    CPaintDC dc(this); // device context for painting

    int iMax = GetMaxSpeed();
    CRect rect;
    GetClientRect(&rect);

    Graphics graphics(dc);

    //Draw background
    LinearGradientBrush lineargradientbrush(
        Point(rect.left, rect.top), 
        Point(rect.right, rect.bottom),
        Color(255, 65, 120, 165),
        Color(255, 0, 0, 0));

    Pen PenDownload(Color(150, 65, 95, 120));
    Pen PenUpload(Color(255, 135, 135, 135)); //230, 155, 55));
    Pen PenWhite(Color(150, 255, 255, 255)); 


    SolidBrush BrushDownload(Color(150, 65, 95, 120));
    SolidBrush BrushUpload(Color(150, 135, 135, 135)); // 185, 125, 55));
    SolidBrush BrushWhite(Color(150, 255, 255, 255));
    
    Gdiplus::Font fFont(L"Segoe UI", 10);

    PointF pointfDown(0.0f, rect.Height()/2 - 10);
    PointF pointfUp(rect.Width()/2 , rect.Height()/2 - 10);
    //DrawBack ground
    graphics.FillRectangle(&lineargradientbrush, rect.left, rect.top, rect.right, rect.bottom);

    graphics.DrawLine(&PenWhite, rect.left, rect.Height()/2 - 10, (int)rect.right, (int)rect.Height()/2 - 10 );
    graphics.DrawLine(&PenWhite, rect.left, rect.Height()/2 + 10, (int)rect.right, (int)rect.Height()/2 + 10 );
    graphics.DrawLine(&PenWhite, rect.Width()/2, rect.Height()/2 - 10, (int)rect.Width()/2, (int)rect.Height()/2 + 10 );

    CString sDonwload;
    sDonwload.Format(L"Down: %.2f kb/s", m_fDownloadSpeed);

    CString sUpload;
    sUpload.Format(L"Up: %.2f kb/s", m_fUploadSpeed );


    graphics.DrawString(sDonwload, sDonwload.GetLength(), &fFont, pointfDown, &BrushWhite);
    graphics.DrawString(sUpload, sUpload.GetLength(), &fFont, pointfUp, &BrushWhite);

    int iSize = m_vDownloads.size();
    int iNumberOfBars = rect.Width() / BAR_SIZE;

    std::vector<int>::iterator iItrDownload;
    std::vector<int>::iterator iItrUpload;

    iItrDownload = m_vDownloads.begin();
    iItrUpload = m_vUploads.begin(); 

    while(iItrUpload!= m_vUploads.end() && iItrDownload!= m_vDownloads.end())
    {

        int iHightUpload = (*iItrUpload)*(rect.Height()/2 - 10) / iMax;
        int iHightDownload = (*iItrDownload)*(rect.Height()/2 - 10) / iMax;
        if (iHightDownload > iHightUpload)
        {
            graphics.FillRectangle(&BrushDownload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2-11) - iHightDownload, BAR_SIZE, iHightDownload);        
            graphics.DrawRectangle(&PenDownload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2-11) - iHightDownload + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightDownload - BAR_FRAME_SIZE*2);

            graphics.FillRectangle(&BrushUpload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2+11) , BAR_SIZE, iHightUpload);
            graphics.DrawRectangle(&PenUpload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2+11) + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightUpload - BAR_FRAME_SIZE*2);            
        }
        else
        {
            graphics.FillRectangle(&BrushUpload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2+11), BAR_SIZE, iHightUpload);
            graphics.DrawRectangle(&PenUpload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2+11) + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightUpload - BAR_FRAME_SIZE*2);            

            graphics.FillRectangle(&BrushDownload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2-11) - iHightDownload, BAR_SIZE, iHightDownload);        
            graphics.DrawRectangle(&PenDownload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2-11) - iHightDownload + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightDownload - BAR_FRAME_SIZE*2);
        }

        iItrDownload++;
        iItrUpload++;
        iSize--;
    }
}


Результат:
user posted image

Источник

Это сообщение отредактировал(а) suxxor - 18.1.2012, 00:28
PM   Вверх
GremlinProg
Дата 18.1.2012, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



на C++ (WINAPI) для этого есть GradientFill
https://www.google.com/search?q=using+GradientFill


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
suxxor
Дата 18.1.2012, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



GremlinProg, как с помощью этой ф-и сделать как на картинке?

Это сообщение отредактировал(а) suxxor - 18.1.2012, 11:16
PM   Вверх
GremlinProg
Дата 18.1.2012, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



как сделать сам градиент на все окно, или разукрасить градиентом график?

Добавлено через 3 минуты и 36 секунд
если первое, то по ссылке есть примеры
если второе, то существует несколько способов, например: отрисовать сначала график в путь, выбрать его в HDC ( SelectClipPath ), после чего, отрисовать серый градиент на фоне синего градиента

Добавлено через 13 минут
по моему, тут даже серого градиента нет, это просто 2 кисти: upload и download,
тогда и путей не надо, просто отрисовка графика на фоне градиента


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
suxxor
Дата 18.1.2012, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



Мне нужен только градиент:

Кажется оно:
Код

    //Draw background
    LinearGradientBrush lineargradientbrush(
        Point(rect.left, rect.top), 
        Point(rect.right, rect.bottom),
        Color(255, 65, 120, 165),
        Color(255, 0, 0, 0));


как это с GradientFill сделать?

Это сообщение отредактировал(а) suxxor - 18.1.2012, 11:48
PM   Вверх
GremlinProg
Дата 18.1.2012, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(suxxor @  18.1.2012,  13:48 Найти цитируемый пост)
Мне нужен только градиент

ну, по первой же ссылке как раз нужный код:
Код

type
  TRIVERTEX = packed record
    X, Y : DWORD;
    Red, Green, Blue, Alpha : Word;
  end;

function GradientFill(DC : hDC; pVertex : Pointer; dwNumVertex : DWORD;
  pMesh : Pointer; dwNumMesh, dwMode: DWORD) : DWord; stdcall;
  external 'msimg32.dll';

The following example shows a horizontal rectangle call.

procedure TForm1.Button1Click(Sender: TObject);
var
 vert : array[0..1] of TRIVERTEX;
 gRect   : GRADIENT_RECT;
begin
  vert [0] .x      := 0;
  vert [0] .y      := 0;
  vert [0] .Red    := $0000;
  vert [0] .Green  := $0000;
  vert [0] .Blue   := $0000;
  vert [0] .Alpha  := $0000;

  vert [1] .x      := 100;
  vert [1] .y      := 32;
  vert [1] .Red    := $0000;
  vert [1] .Green  := $0000;
  vert [1] .Blue   := $ff00;
  vert [1] .Alpha  := $0000;

  gRect.UpperLeft  := 0;
  gRect.LowerRight := 1;
  GradientFill(Form1.Canvas.Handle, @vert,2,@gRect,1,GRADIENT_FILL_RECT_H);
end;

vert [0] .x, vert [0] .y - координата левого-верхнего угла прямоугольника
vert [1] .x, vert [1] .y - координата правого-нижнего угла прямоугольника
стоит только отметить, что цветовые компоненты здесь 16-битные, т.е. чтобы перевести 8-битные к 16-битным, требуется масштабирование:
Код

clr_x16 = WORD( ::MulDiv( clr_x8, 0xffff, 0xff ) );



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Dem_max
Дата 18.1.2012, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Ты же сам код функции привел, в чем проблема то ?


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
suxxor
Дата 18.1.2012, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 14.10.2010

Репутация: нет
Всего: нет



Dem_max, там .NET <censure>

Короче написал, если что исправьте:
Код

TRIVERTEX vert[2] = {0};
GRADIENT_RECT gRect = {0};
vert [0].x      = rc.left;
vert [0].y      = rc.top;
vert [0].Red    = WORD(MulDiv(65, 0xffff, 0xff));
vert [0].Green  = WORD(MulDiv(120, 0xffff, 0xff));
vert [0].Blue   = WORD(MulDiv(165, 0xffff, 0xff));
vert [0].Alpha  = WORD(MulDiv(255, 0xffff, 0xff));
vert [1].x      = rc.right;
vert [1].y      = rc.bottom; 
vert [1].Red    = WORD(MulDiv(0, 0xffff, 0xff));
vert [1].Green  = WORD(MulDiv(0, 0xffff, 0xff));
vert [1].Blue   = WORD(MulDiv(0, 0xffff, 0xff));
vert [1].Alpha  = WORD(MulDiv(255, 0xffff, 0xff));
gRect.UpperLeft  = 0;
gRect.LowerRight = 1;

GradientFill(hDC, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_H);


Это сообщение отредактировал(а) GremlinProg - 19.1.2012, 06:34
PM   Вверх
Dem_max
Дата 19.1.2012, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



Вот твоя функция на С++ для рисования того что тебе нада. Взял с первого поста.

Код

void CCtrlTraffic::OnPaint(HDC dc)
{

    int iMax = GetMaxSpeed();
    RECT rect;
    
   GetClientRect(&rect);

    Graphics graphics(dc);

    //Draw background
    LinearGradientBrush lineargradientbrush(
        Point(rect.left, rect.top), 
        Point(rect.right, rect.bottom),
        Color(255, 65, 120, 165),
        Color(255, 0, 0, 0));

    Pen PenDownload(Color(150, 65, 95, 120));
    Pen PenUpload(Color(255, 135, 135, 135)); //230, 155, 55));
    Pen PenWhite(Color(150, 255, 255, 255)); 


    SolidBrush BrushDownload(Color(150, 65, 95, 120));
    SolidBrush BrushUpload(Color(150, 135, 135, 135)); // 185, 125, 55));
    SolidBrush BrushWhite(Color(150, 255, 255, 255));
    
    Gdiplus::Font fFont(L"Segoe UI", 10);

    PointF pointfDown(0.0f, rect.Height()/2 - 10);
    PointF pointfUp(rect.Width()/2 , rect.Height()/2 - 10);
    //DrawBack ground
    graphics.FillRectangle(&lineargradientbrush, rect.left, rect.top, rect.right, rect.bottom);

    graphics.DrawLine(&PenWhite, rect.left, rect.Height()/2 - 10, (int)rect.right, (int)rect.Height()/2 - 10 );
    graphics.DrawLine(&PenWhite, rect.left, rect.Height()/2 + 10, (int)rect.right, (int)rect.Height()/2 + 10 );
    graphics.DrawLine(&PenWhite, rect.Width()/2, rect.Height()/2 - 10, (int)rect.Width()/2, (int)rect.Height()/2 + 10 );

    TCHAR  sDonwload[200], sUpload[200];
    wsprintf(sDonwload, _T("Up: %i kb/s"),  (int)m_fUploadSpeed);  
    wsprintf(sUpload, _T("Up: %i kb/s"),  (int)m_fUploadSpeed); 

    graphics.DrawString(sDonwload, sDonwload.GetLength(), &fFont, pointfDown, &BrushWhite);
    graphics.DrawString(sUpload, sUpload.GetLength(), &fFont, pointfUp, &BrushWhite);

    int iSize = m_vDownloads.size();
    int iNumberOfBars = rect.Width() / BAR_SIZE;

    std::vector<int>::iterator iItrDownload;
    std::vector<int>::iterator iItrUpload;

    iItrDownload = m_vDownloads.begin();
    iItrUpload = m_vUploads.begin(); 

    while(iItrUpload!= m_vUploads.end() && iItrDownload!= m_vDownloads.end())
    {

        int iHightUpload = (*iItrUpload)*(rect.Height()/2 - 10) / iMax;
        int iHightDownload = (*iItrDownload)*(rect.Height()/2 - 10) / iMax;
        if (iHightDownload > iHightUpload)
        {
            graphics.FillRectangle(&BrushDownload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2-11) - iHightDownload, BAR_SIZE, iHightDownload);        
            graphics.DrawRectangle(&PenDownload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2-11) - iHightDownload + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightDownload - BAR_FRAME_SIZE*2);

            graphics.FillRectangle(&BrushUpload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2+11) , BAR_SIZE, iHightUpload);
            graphics.DrawRectangle(&PenUpload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2+11) + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightUpload - BAR_FRAME_SIZE*2);            
        }
        else
        {
            graphics.FillRectangle(&BrushUpload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2+11), BAR_SIZE, iHightUpload);
            graphics.DrawRectangle(&PenUpload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2+11) + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightUpload - BAR_FRAME_SIZE*2);            

            graphics.FillRectangle(&BrushDownload, rect.right - BAR_SIZE *(iSize) , (rect.Height()/2-11) - iHightDownload, BAR_SIZE, iHightDownload);        
            graphics.DrawRectangle(&PenDownload, rect.right - BAR_SIZE*(iSize) + BAR_FRAME_SIZE, (rect.Height()/2-11) - iHightDownload + BAR_FRAME_SIZE * 2 , BAR_SIZE - BAR_FRAME_SIZE*2, iHightDownload - BAR_FRAME_SIZE*2);
        }

        iItrDownload++;
        iItrUpload++;
        iSize--;
    }
}



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1279 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.