GradientFill API无法正常运行 [英] GradientFill API doesn't perform as it should

查看:78
本文介绍了GradientFill API无法正常运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

介绍及相关信息:



我想创建一个渐变背景的静态控件。



我想按照以下方式进行:



在主窗口的背景创建渐变,然后在该背景上放置透明静态控件。



为此,我创建了 RECT 变量 WM_PAINT 将渐变定位在静态控制位置的处理程序。



此外,我尝试使用双缓冲以避免闪烁(我还处理了 WM_ERASEBKGND ,删除了标志 CS_VREDRAW CS_HREDRAW 来自窗口类)。



我还处理了 WM_SIZE 消息以使窗口无效,并正确地重新定位静态控件。



在我的 WM_CTLCOLORSTATIC 处理程序中,我已经返回 NULL_BRUSH



我已经通过Visual Studio中的应用程序向导制作了一个演示应用程序来说明这一点。



I在 Windows XP 上工作,使用纯Win32 API C ++



贝娄我将提交演示项目的链接:



http://www.filedropper.com/gradientstaticcontrol [ ^ ]



问题:



当我在 WM_PAINT 处理程序中使用 GradientFill API时,我得到一个更大的屏幕上的矩形应该是它应该是。



贝娄图片说明了这个结果:



http://pbrd.co/1cMWhip [ ^ ]



如果我试试o用一些实心刷子填充相同的矩形,一切正常。



贝娄图片说明了这个结果:



http://pbrd.co/1bjz7cT [ ^ ]



我努力解决问题:



我在设置矩形坐标的地方放置了断点,并且看到设置矩形坐标没有问题。



GradientFill 返回 TRUE ,所以应该没有问题。



问题:



如何解决这个问题?



提前谢谢。



问候。

INTRODUCTION AND RELEVANT INFORMATION:

I want to create a static control with gradient background.

I want to do it the following way:

Create the gradient at the main window’s background, and then place transparent static control on top of that background.

To do that, I have created RECT variable in WM_PAINT handler that positions the gradient at the position where static control should be.

Also, I try to use double buffering to avoid flickering ( I have also handled WM_ERASEBKGND, removed flags CS_VREDRAW and CS_HREDRAW from window class ).

I have also handled WM_SIZE message to invalidate the window, and to reposition static control properly.

In my WM_CTLCOLORSTATIC handler, I have returned NULL_BRUSH.

I have made a demo application to illustrate this, via application wizard in Visual Studio.

I work on Windows XP, using pure Win32 API and C++.

Bellow I will submit the link to the demo project:

http://www.filedropper.com/gradientstaticcontrol[^]

PROBLEM:

When I use GradientFill API in WM_PAINT handler, I get a bigger rectangle on the screen than it should be.

Bellow picture illustrates this result:

http://pbrd.co/1cMWhip[^]

If I try to fill the same rectangle with some solid brush, everything works fine.

Bellow picture illustrates this result:

http://pbrd.co/1bjz7cT[^]

MY EFFORTS TO SOLVE PROBLEM:

I have placed breakpoints at the places where rectangle’s coordinates are set and have seen that there is no problem with setting the rectangles coordinates.

GradientFill returns TRUE, so there should be no problems.

QUESTION:

How to fix this?

Thank you in advance.

Regards.

推荐答案

您只需进行两项更改。在每种情况下,都是因为您忘记了在绘制到控件的HDC时,RECT始终将顶部和左侧成员设置为0.



但是当将此矩形绘制到对话框的背景上时,顶部和左侧成员不再为0.



您需要进行的更改是:



1。

WAS:

There's just two changes you need to make. In each case, it's because you've forgotten that when drawing to the HDC of a control, the RECT always has the top and left members set to 0.

However, when drawing this rect onto the background of the dialog, the top and left members are no longer 0.

The changes you need to make are:

1.
WAS:
vertexS[1].y     = ( rect.bottom - rect.top ) / 2; 





IS:



IS:

vertexS[1].y     = rect.top + ( rect.bottom - rect.top ) / 2; 







2。

WAS:




2.
WAS:

vertex1S[0].y     = ( rect.bottom - rect.top ) / 2;





IS:



IS:

vertex1S[0].y     = rect.top + ( rect.bottom - rect.top ) / 2;









我强烈建议您使用我过去提到的功能,为了清楚起见,在这里重复。







I strongly recommend that you use the functions I've mentioned in the past, repeated here for clarity.

void GradientFillRect(HDC hdc, RECT fillMe, COLORREF colStart, COLORREF colEnd, bool isVertical)
{
    TRIVERTEX vertex[2];
    GRADIENT_RECT gRect;
    gRect.UpperLeft = 0;
    gRect.LowerRight = 1;
    vertex[0].x = fillMe.left;
    vertex[0].y = fillMe.top;
    vertex[0].Red = GetRValue(colStart) << 8;
    vertex[0].Green = GetGValue(colStart) << 8;
    vertex[0].Blue = GetBValue(colStart) << 8;
    vertex[0].Alpha = 255;

    vertex[1].x = fillMe.right;
    vertex[1].y = fillMe.bottom;
    vertex[1].Red = GetRValue(colEnd) << 8;
    vertex[1].Green = GetGValue(colEnd) << 8;
    vertex[1].Blue = GetBValue(colEnd) << 8;
    vertex[1].Alpha = 255;

    if (isVertical)
        GradientFill(hdc, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_V );
    else
        GradientFill(hdc, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H );
}










void drawBigBtn(HDC dst, RECT btnRect, wchar_t *wndText, HFONT btnFont)
{
    RECT topRect, botRect;
    topRect = botRect = btnRect;
    topRect.bottom = botRect.top = ((btnRect.bottom - btnRect.top)/2) + btnRect.top;
    GradientFillRect(dst, topRect, RGB(0x95,0xb3,0xd7), RGB(0x4f,0x8b,0xb0), true);
    GradientFillRect(dst, botRect, RGB(0x4f,0x8b,0xb0), RGB(0x95,0xb3,0xd7), true);

    HBRUSH blueBrush, oldBrush;
    blueBrush = CreateSolidBrush(RGB(79,129,189));
    oldBrush = (HBRUSH) SelectObject(dst, blueBrush);
    FrameRect(dst, &btnRect, blueBrush);
    SelectObject(dst, oldBrush);
    DeleteObject(blueBrush);


    RECT textRect = btnRect;
    textRect.top = textRect.bottom - 40;
    SetBkMode(dst, TRANSPARENT);

   int textLen = wcslen(wndText);
   HFONT oldFont;
   if (btnFont != NULL)
   {
        oldFont = (HFONT)SelectObject( dst, btnFont );
        DrawTextEx( dst, wndText, textLen, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
        SelectObject(dst, oldFont);
   }
   else
        DrawTextEx( dst, wndText, textLen, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
}


这篇关于GradientFill API无法正常运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆