Change background color of another program from C++ program
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.
精彩评论