я использую 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 :
Сделайте проект Win32 по умолчанию в Visual studio.
Добавьте вышеупомянутую вспомогательную функцию.
Добавьте следующее 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
параметры, переданные моей вспомогательной функции, чтобы я мог получить правильный цвет градиента?
Спасибо.
С наилучшими пожеланиями.
Делать четыре глобальных переменные типа 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
функция, если вы не видите изменений в вашем окно клиента.
В конце концов вы заметите, что цвета ваших градиентных треугольников будут меняться в вашем клиентском окне.
Я думаю, что все это должно ответить на ваш вопрос.
Я надеюсь, что это поможет вам.
Удачи с моей идеей!
В вашем ПРОБЛЕМА: раздел, я понимаю, что вы хотите удалить графический артефакт, но в вашем ВОПРОС: раздел, вы хотите изменить параметры 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
остановить или закончить с таймером или с потоком.