开发者

Change background color of another program from C++ program

开发者 https://www.devze.com 2023-01-12 13:19 出处:网络
I\'m trying to change the background color of a program I did NOT write. Looking at it with Spy++ I can see that the main class is \"ThunderRT6FormDC\". One of its children has the class \"ThunderRT6

I'm trying to change the background color of a program I did NOT write.

Looking at it with Spy++ I can see that the main class is "ThunderRT6FormDC". One of its children has the class "ThunderRT6Frame". Inside ThunderRT6Frame there are a bunch of ThunderRT6CommandButtons.

I want to change the background color behind the buttons. I tried doing this by changing the color of the ThunderRT6Frame window, but I can't get it to work. Any ideas?

This is what I tried first:

HWND hwndCnt = FindWindow("ThunderRT6FormDC", NULL);
HWND hwndCntFrame = FindWindowEx(hwndCnt, NULL, "ThunderRT6Frame", NULL);

SetClassLong(hwndCnt, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(220,220,255)));
InvalidateRect(hwndCnt, 0, TRUE);
SetClassLong(hwndCntFrame, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(220,220,255)));
InvalidateRect(hwndCntFrame, 0, TRUE);

No visible changes came out of that, so I moved on to injecting a dll and subclass WM_PAINT:

PAINTSTRUCT ps;
HDC hdcPaint = BeginPaint(Hwnd, &ps);
SetBkColor(hdcPaint, RGB(255,0,0));

HPEN pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));

HPEN hOldPen = (HPEN)SelectObject(hdcPaint, pen);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hdcPaint, brush);

RoundRect(hdcPaint, 1, 1, 100, 100, 10, 10);

SelectObject(hdcPaint, hOldPen);
SelectObject(hdcPaint, hOldBrush);

DeleteObject(pen);
DeleteObject(brush);

EndPaint(Hwnd, &ps);

return 0;

I have WM_PAINT subclassed for both ThunderRT6FormDC and ThunderRT6Frame but no red rectangle is drawn that I can see.

What am I doing wrong? What else do I need to try?

PS. The window class names in the program I'm trying to change indicates that it is a VB6 program, if that's any help.

EDIT:

I tried adding the following to both window procedures

case WM_ERASEBKGND:
{
    HDC hdcPaint = (HDC)wParam;
    SetBkColor(hdcPaint, RGB(255,0,0));

    HPEN pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
    HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));

    HPEN hOldPen = (HPEN)SelectObject(hdcPaint, pen);
    HBRUSH hOldBrush = (HBRUSH)SelectObject(hdcPaint, brush);

    RoundRect(hdcPaint, 1, 1, 100, 100, 10, 10);

    SelectObject(hdcPaint, hOldPen);
    SelectObject(hdcPaint, hOldBrush);

    DeleteObject(pen);
    DeleteObject(brush);

    retur开发者_运维知识库n TRUE;
}

But I get no visible results

EDIT 2:

Putting MessageBoxes in the different WM_* cases I can see the rectangles being painted and even after I have closed all the message boxes the rectangles are left on the screen. But if I don't have any message boxes at all I can't see the rectangles.

So I'm guessing something is redrawing the windows after I have painted on them. What is doing this redrawing, and where?

EDIT 3:

Cleaning up my code and keeping just WM_PAINT for the ThunderRT6Form window made it work. This is what WM_PAINT looks like now:

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdcPaint = BeginPaint(Hwnd, &ps);
    HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));

    RECT r;
    GetClientRect(Hwnd, &r);
    FillRect(hdcPaint, &r, brush);

    DeleteObject(brush);
    EndPaint(Hwnd, &ps);

    return 0;
}

EDIT 4:

I never did find out exactly why the rectangles wouldn't show up in my first tries. But it was some error in my code somewhere.

This is what I did: First I added message boxes to make sure all code was getting called. That made the rectangles appear. Then I fiddled around a bit with where I had the message boxes (only for the Form, only for the Frame, only for WM_PAINT etc). And I always got the rectangle. Then I removed all the message boxes, and sure enough, the rectangles went away too. So I added some message boxes back in and started cleaning up my code. Some of this "clean up" fixed my error, because after that I could remove all message boxes and still be able to paint on the background.


You might see some success if you handle the WM_ERASEBKGND message similarly to the way you handle WM_PAINT.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号