-3

I'm trying to make a program that reads a pixel color at a certain point. I think I've managed to set up a clipping and bitmap region to my game, but I just can't tell why it isn't working.

using namespace std;

int main() {
    while (true) {
        LPCWSTR window_title = L"World of Warcraft";
        HWND hWND = FindWindow(NULL, window_title);
        RECT rWindow;
        RECT rClient;

        HRGN hRgnWindow;
        HRGN hRgnClient;
        HRGN hNCRgn;

        //C: Get the window and client rectangles for the window.
        GetWindowRect(hWND, &rWindow);
        GetClientRect(hWND, &rClient);

        //C: Translate the Client rectangle into screen coordinates.
        POINT p = { 0,0 };
        MapWindowPoints(hWND, NULL, &p, 1);
        OffsetRect(&rClient, p.x, p.y);

        //C: Create regions from these two rectangles.
        hRgnWindow = ::CreateRectRgnIndirect(&rWindow);
        hRgnClient = ::CreateRectRgnIndirect(&rClient);
        hNCRgn = ::CreateRectRgn(0, 0, 0, 0);

        //C: Subtract the client region from the window region.
        CombineRgn(hNCRgn, hRgnWindow, hRgnClient, RGN_DIFF);

        while (hWND == NULL) {
            hWND = FindWindowA(NULL, "World of Warcraft");
            cout << "start game!" << endl;
            Sleep(1000);
        }
        Sleep(10);
        if (GetAsyncKeyState(VK_SHIFT)) { // MousePosition
            //HDC hDC = GetDC(hWND); 
            POINT p;
            GetCursorPos(&p);
            ScreenToClient(hWND, &p); // actually only needs window title not HDC but will need for color
            //ReleaseDC(hWND, hDC);
            cout << "(" << p.x << ","<< p.y << ")" << endl;
            Sleep(1000);
        }
        Sleep(10);
        if (GetAsyncKeyState(VK_LBUTTON)) { // pixelColor
            HDC hDC, hCDC;
            HBITMAP hbwin;
            HRGN RrGN = CreateRectRgn(30, 5, 1277, 690);
            int height, width;
            hDC = GetDC(hWND);
            hCDC = CreateCompatibleDC(hDC);
            SetStretchBltMode(hCDC, COLORONCOLOR);

            RECT winsize;
            GetClientRect(hWND, &winsize);
            SetWindowRgn(hWND, RrGN, TRUE);
            SelectClipRgn(hDC, RrGN);
            GetClipRgn(hDC, RrGN);

            POINT p;
            GetCursorPos(&p);
            ScreenToClient(hWND, &p);

            hbwin = CreateCompatibleBitmap(hDC, p.x, p.y);
            SelectObject(hCDC, hbwin);

            COLORREF color = GetPixel(hCDC, p.x, p.y);

            cout << " | Color: " << color << endl;
                /*cout<<  //"(" << p.x << "," << p.y << ")" << " R: " << (int)GetRValue(color) 
                << " | G: " << (int)GetGValue(color) << " | B: "
                << (int)GetBValue(color) << endl;
            BOOL EndPaint(hWND, CONST PAINTSTRUCT * lp);*/
            Sleep(10);
            cout << " | Color: " << color << endl;
            DeleteObject(hbwin);
            DeleteDC(hCDC);
            ReleaseDC(hWND, hDC);
            DeleteObject(RrGN);
            Sleep(1000);
        }
        /*if (GetAsyncKeyState(VK_CONTROL)) {
            HDC hDC = GetDC(hWND);
            COLORREF color;                     //could have the choice of which zone or 
            COLORREF characteristic_ color = ; //color of fishing bobber? --> How to find in different zones
            Sleep(1000);
        }*/
        if (GetAsyncKeyState(VK_MENU)) { // Exit Game
            return 0;
        }
        DeleteObject(hRgnWindow);
        DeleteObject(hRgnClient);
        DeleteObject(hNCRgn);
    }
    return 0;
}

IInspectable has commented that CreateCompatibleBitmap() makes an empty bitmap, but then how would I make it take the pixels from the window? I've tried doing it, but I can't seem to figure it out! Thank you for any help!

v8wr
  • 1
  • 1
  • `CreateCompatibleBitmap` creates an empty bitmap. – IInspectable Apr 04 '20 at 18:45
  • I really can't work out what you're trying to do. You can read the colour of a screen pixel by getting a DC for the whole screen (`GetDC(NULL)`) and then calling `SetPixel` on the DC with the screen coordinates. Does that help? – Jonathan Potter Apr 04 '20 at 22:47
  • @JonathanPotter you mean `GetPixel()`, not `SetPixel()`, right? – Remy Lebeau Apr 05 '20 at 00:24
  • Oops, yes. Thanks. – Jonathan Potter Apr 05 '20 at 00:24
  • @JonathanPotter Thank you for your answering! I'm not trying to set pixel colors. I'm trying to read a pixel color from my game and having it cout the color in a RBG form. I'm trying to first get the mouse position(which works fine, but doesn't make the upper left corner of my game window 0,0 so maybe it lies with that, and then take the pixel RBG color and output the number to my console. – v8wr Apr 05 '20 at 00:38
  • @IInspectable Thank you! I didn't know that created an empty bitmap! – v8wr Apr 05 '20 at 00:39

1 Answers1

0

The full return value is 4294967295‬ which in hex "0xffffffff"(CLR_INVALID). As comments, call CreateCompatibleBitmap only create an empty bitmap, and you'll need to copy content from hDC to hCDC.

    hbwin = CreateCompatibleBitmap(hDC, rClient.right- rClient.left, rClient.bottom - rClient.top);
    SelectObject(hCDC, hbwin);

    BitBlt(hCDC, 0, 0, rClient.right - rClient.left, rClient.bottom - rClient.top, hDC, 0, 0, SRCCOPY);
    COLORREF color = GetPixel(hCDC, p.x, p.y);

    cout << " | Color: " << color << endl;
    cout << " | Color: " << color << endl;

In addition, using GetDIBits may be quicker than using GetPixel You could refer to the sample on msdn:

Capturing an Image

and this question:

GetDIBits and loop through pixels using X, Y

Drake Wu
  • 6,927
  • 1
  • 7
  • 30