Измените параметр RGB API GradientFill, чтобы избежать изменения кода

ВВЕДЕНИЕ И СООТВЕТСТВУЮЩАЯ ИНФОРМАЦИЯ:

я использую GradientFill API для рисования 2 градиентных треугольника.

Вот вспомогательная функция, которую я написал:

void GradientTriangle( HDC MemDC,
LONG x1, LONG y1,
LONG x2, LONG y2,
LONG x3, LONG y3,
COLORREF top, COLORREF bottom )
{
TRIVERTEX vertex[3];

vertex[0].x     = x1;
vertex[0].y     = y1;
vertex[0].Red   = GetRValue(bottom) << 8;
vertex[0].Green = GetGValue(bottom) << 8;
vertex[0].Blue  = GetBValue(bottom) << 8;
vertex[0].Alpha = 0x0000;

vertex[1].x     = x3;
vertex[1].y     = y3;
vertex[1].Red   = GetRValue(bottom) << 8;
vertex[1].Green = GetGValue(bottom) << 8;
vertex[1].Blue  = GetBValue(bottom) << 8;
vertex[1].Alpha = 0x0000;

vertex[2].x     = x2;
vertex[2].y     = y2;
vertex[2].Red   = GetRValue(top) << 8;
vertex[2].Green = GetGValue(top) << 8;
vertex[2].Blue  = GetBValue(top) << 8;
vertex[2].Alpha = 0x0000;

// Create a GRADIENT_TRIANGLE structure that
// references the TRIVERTEX vertices.

GRADIENT_TRIANGLE gTriangle;

gTriangle.Vertex1 = 0;
gTriangle.Vertex2 = 1;
gTriangle.Vertex3 = 2;

// Draw a shaded triangle.

GradientFill( MemDC, vertex, 3, &gTriangle, 1, GRADIENT_FILL_TRIANGLE);
}

ПРОБЛЕМА:

Я столкнулся с проблемой Windows XP где я получаю графический артефакт при перемещении окна к далеко слева, поэтому часть его исчезает из поля зрения.

Чтобы воспроизвести проблему, вот инструкция по SSCCE :

  1. Сделайте проект Win32 по умолчанию в Visual studio.

  2. Добавьте вышеупомянутую вспомогательную функцию.

  3. Добавьте следующее WM_ERASEBKGND обработчик:

    case WM_ERASEBKGND:
    {
    RECT r;
    GetClientRect (hwnd, &р );

        // bottom triangle --> need help with this one!!
    GradientTriangle( (HDC)wParam,
    r.left, r.top,
    r.left, r.bottom - r.top,
    r.right, r.bottom - r.top,
    RGB( 0x0, 0x0, 0xFF ), RGB( 0xFF, 0xFF, 0x0 ) );
    
    // top triangle --> this one is fine !
    GradientTriangle( (HDC)wParam,
    r.right, r.bottom - r.top,
    r.right, r.top,
    r.left, r.top,
    RGB( 0xFF, 0x0, 0x0 ), RGB( 0x0, 0xFF, 0x0 ) );
    }
    return 1L;
    

При запуске программы вы должны получить это:

введите описание изображения здесь

После того, как вы переместили окно далеко влево (так что его часть выходит за пределы экрана, становясь невидимым), а затем переместите его обратно, вы должны получить следующее:

введите описание изображения здесь

МОИ УСИЛИЯ ДЛЯ РЕШЕНИЯ ЭТОГО:

Следуя инструкциям от ответа на мой предыдущий похожий вопрос Я смог решить проблему с артефактом, переключив порядок координат, передаваемых вспомогательной функции.

Тем не менее, цвет нижнего треугольника изменился, и мне нужна помощь, чтобы изменить RGB параметры, чтобы получить это правильно.

Вот мой обходной путь:

// I have modified parametters for bottom triangle
GradientTriangle( (HDC)wParam,
r.left, r.top,
r.right, r.bottom - r.top,  //  switched places
r.left, r.bottom - r.top,   //  of these two coordinates
RGB( 0x0, 0x0, 0xFF ), RGB( 0xFF, 0xFF, 0x0 ) );  // but color has changed

Как я уже сказал, артефакты исчезли, но результирующий цвет изменился:

введите описание изображения здесь

ВОПРОС:

Как я могу изменить RGB параметры, переданные моей вспомогательной функции, чтобы я мог получить правильный цвет градиента?

Спасибо.

С наилучшими пожеланиями.

2

Решение

Делать четыре глобальных переменные типа COLORREF состав.

Вы можете назвать их как хотите, но в вашем случае подходящее имена могут быть «top1», «bottom1», «top2» и «bottom2».

В первом звонке на ваш GradientTriangle функция, установите Топ а также низ последние два параметра к значениям top1 а также bottom1 глобальные переменные соответственно и во втором вызове GradientTriangle функция, установите Топ а также низ последние два параметра к значениям top2 а также bottom2 глобальные переменные соответственно вместо постоянная значения, которые вы сделали:

RGB (0x0, 0x0, 0xFF), RGB (0xFF, 0xFF, 0x0), RGB (0xFF, 0x0, 0x0) и RGB (0x0, 0xFF, 0x0).

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

// Global Variables:
COLORREF top1 = RGB( 0x0, 0x0, 0xFF )
COLORREF bottom1 = RGB( 0xFF, 0xFF, 0x0 )
COLORREF top2 = RGB( 0xFF, 0x0, 0x0 )
COLORREF bottom2 = RGB( 0x0, 0xFF, 0x0 )

// bottom triangle --> need help with this one!!
GradientTriangle( (HDC)wParam,
r.left, r.top,
r.left, r.bottom - r.top,
r.right, r.bottom - r.top,
top1, bottom1 ); //not RGB( 0x0, 0x0, 0xFF ), RGB( 0xFF, 0xFF, 0x0 ), unlike in the code you posted

// top triangle --> this one is fine !
GradientTriangle( (HDC)wParam,
r.right, r.bottom - r.top,
r.right, r.top,
r.left, r.top,
top2, bottom2 ); //not RGB( 0xFF, 0x0, 0x0 ), RGB( 0x0, 0xFF, 0x0 ), unlike in the code you posted
}
return 1L;

Как я могу изменить параметры RGB, переданные моей вспомогательной функции, чтобы я мог
получить правильный цвет градиента?

Вы не изменяете параметры RGB, но изменяете четыре глобальные переменные вместо, то есть top1, bottom1, top2 и bottom2.

После модификации звоните или InvalidateRect или же RedrawWindow или же UpdateWindow функция, если вы не видите изменений в вашем окно клиента.

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

Я думаю, что все это должно ответить на ваш вопрос.

Я надеюсь, что это поможет вам.

Удачи с моей идеей!

1

Другие решения

В вашем ПРОБЛЕМА: раздел, я понимаю, что вы хотите удалить графический артефакт, но в вашем ВОПРОС: раздел, вы хотите изменить параметры RGB, передаваемые вашей вспомогательной функции, чтобы вы могли получить правильный цвет градиента.

В заключение вы просите два разных вещи, но на самом деле вы хотите достичь только один из них.

Я помог тебе только с тем, кого ты на самом деле не хотел.

Вы ищете ответ, который не решение вашей проблемы!

Я также понял из вашего комментарий что вы хотите решение на ваш проблема, не ответ на ваш вопрос, В отличие от Ваш заголовок:

Измените параметр RGB API GradientFill, чтобы избежать изменения кода

, потому что я уже ответил на ваш вопрос, но ваш ответ должен сказать мне:

К сожалению, результат точно такой же

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

Сначала я должен был попытаться решить вашу проблему, а не ответить на ваш вопрос, или хотя бы попробовать и то и другое.

Я думаю, что решение вашей проблемы — переместить вызов InvalidateRect в WM_MOVE обработчик, не в WM_SIZE обработчик, потому что

при перемещении окна в крайнее левое положение, поэтому часть его выходит из
взгляд

Пока вы это делаете, WM_MOVE обрабатывает, или другими словами, код, который вы помещаете в этот обработчик, выполняется, не WM_SIZE, потому что вы перемещение окно, не изменение его размера или изменение его размера.

Вы также можете попробовать: WM_MOVING, WM_WINDOWPOSCHANGED или же WM_WINDOWPOSCHANGING

или же делать или таймер или же поток, который будет автоматически вызывать InvalidateRect.
Используйте либо SetTimer или же CreateThread функция для инициализации таймера или потока и запуска одного из них. Использовать Sleep функция, чтобы задержать поток.

Вызов или KillTimer или же SuspendThread остановить или закончить с таймером или с потоком.

0

По вопросам рекламы [email protected]