tags:

views:

40

answers:

1

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);

    return 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.

+1  A: 

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

Mark Ransom
No luck. Nothing is drawn as far as I can see.
Tobbe
@Tobbe, What you're trying to do is difficult, as it should be. Have you tried putting in some indicator to see if your code is even being called at all?
Mark Ransom
I have now :) And the code *is* being called. See my second edit to the question for more details.
Tobbe
I'm accepting this as the answer since your hint about the indicator lead me in the right direction :)
Tobbe
@Tobbe, now I'm curious - did you ever find the cause of the disappearing rectangles? Your final solution looks nice and simple.
Mark Ransom
No, I'm afraid I never did find the exact cause. I added one more edit to my question with some more details because the text was too long to fit in a comment.
Tobbe