• Log in or sign up for an account here: https://www.sythe.org/login

FindColor Help

  • Thread starter Thread starter False Skorpion
  • Start date Start date
F

False Skorpion

Guest
Hey guys, I'm new to programming and I'm trying to make my first FindColor program. I'm using Dev-C++ Bloodshed and for some reaosn can not compile! I keep getting the error 'Findcolor' undeclared (first use of this function).

What is the correct syntax for findcolor? If someone could post code of a simple program to find one color and click on it that would really help! Thanks in advance
 
Le Monkey
PHP Shit Show 2k26
Potamus
Prove it!
Sythe Awards 2011 Winner
Tier 1 Prizebox
Tortoise Penis
Trole
UWotM8?
Wait, do you not have an Archer rank?
There's no equivalent of FindColor in the C++ STL or even the Windows headers. The only thing you can do is write your own FindColor function.

Have a look at:
GetPixel
 
Thanks for your quick response SMR. I think I might have said what I'm trying to do incorrectly.

Right now I want to input a color in my script then I want my program to scan my screen until it finds the color then I want my program to click on it.

I'm just starting to try and write my own random prevention programs and I'm also trying to write a program to do tut island. The link you gave me shows me how to write a program that gives me the RGB color value of a pixel.

Also does your auto alcher have anti randoms? I'm guessing not but it never hurts to ask!
 
Le Monkey
PHP Shit Show 2k26
Potamus
Prove it!
Sythe Awards 2011 Winner
Tier 1 Prizebox
Tortoise Penis
Trole
UWotM8?
Wait, do you not have an Archer rank?
You guessed right @ the last question.
 
So? Any help with my color locator? I don't want to just use x & y coordinates to click I want my mouse to click based on the color of a pixel
 
Code:
#include <windows.h>
bool FindColor(long color, int XS, int YS, int XF, int YF)
{
	HDC dc1;
	int x,y;
	bool found = false;
	dc1 = GetDC(NULL);
	for(y = YS; y < YF; y++){
		for(x = XS; x < XF; x++){
			if(GetPixel(dc1,x,y)==color){
				SetCursorPos(x,y);
				found = true;
			}
		}
	}
	return found;
}

Credits to SMR; He posted this at Fagex a long time ago and probably forgot. As he said it's not perfect so you will have to look it over and if you're not willing to do that then you can't really call yourself a programmer... just a source leecher.
 
Le Monkey
PHP Shit Show 2k26
Potamus
Prove it!
Sythe Awards 2011 Winner
Tier 1 Prizebox
Tortoise Penis
Trole
UWotM8?
Wait, do you not have an Archer rank?
Ah, yeah. One thing I should have changed is color should be COLORREF, not long. Otherwise you might get a signed/unsigned mismatch warning.
 
@ function in Nullware's post... the found variable is not needed. And you'll want to return true after you find the color (and return false at the end) anyways, otherwise it'll keep searching through colors even after it has already found one.
 
I actually coded something like this few days ago. Problem of GetPixel is that it's very, very slow when searching for colors from bigger area. I recommend you to use GetDIBits instead. It's a bit harder to use though :\

Here's the source code of my program, which searchs arbitrary color from the whole screen (lots of crappy win32 GUI code in it, the first ScanForColor() is the only important function):

Code:
#include <windows.h>
#include <stdio.h>

/*  Määritellään funccarit  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
WNDPROC OldWndProc;
LRESULT CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);
void LogMessage(char*);
int ScanForColor(COLORREF);

/*  Globaalipopaalit ja jännät määrittelyt */
char szClassName[ ] = "ColorthingyApp";
#define WIN_WIDTH 300
#define WIN_HEIGHT 300
HINSTANCE hInstance;
COLORREF crCurColor = 0x00FF00;
static HWND eColorDisplay, eRed, eGreen, eBlue, eLogBox, lbResultBox;

// juu se tärkein tässä
int ScanForColor(COLORREF crColor)
{
    HDC hdcMem, hdcScreen;
    HBITMAP hbmScreen;
    BITMAPINFO bmiScreen;
    DWORD* lpScreenBits;
    DWORD dwTargetColor, dwHits = 0, dwStartTicks;
    UINT wScreenX, wScreenY;
    char szBuf[512];
    
    sprintf(szBuf, "ScanForColor(RGB(%u, %u, %u)) called.",
        GetRValue(crColor), GetGValue(crColor), GetBValue(crColor));
    LogMessage(szBuf);
    // Muutellaan vähän annetun värin tavujen järjestystä, koska värit
    // muistissa ovat "väärin päin"
    dwTargetColor = (GetRValue(crColor) << 16) + (GetGValue(crColor) << 8) + GetBValue(crColor);
    
    // Device Contextit muistiin
    hdcScreen = GetDC(NULL); // NULL nii nappaa koko skreenin
    hdcMem = CreateCompatibleDC(hdcScreen);
    wScreenX = GetDeviceCaps(hdcScreen, HORZRES);
    wScreenY = GetDeviceCaps(hdcScreen, VERTRES);
    sprintf(szBuf, "Scanning pixels 0, 0 -> %u, %u (%u pixels total)",
        wScreenX, wScreenY, (UINT)(wScreenX * wScreenY));
    LogMessage(szBuf);
    
    // Alustetaan bitmapin headeri
    bmiScreen.bmiHeader.biSize = sizeof(bmiScreen.bmiHeader);
    bmiScreen.bmiHeader.biWidth = wScreenX;
    bmiScreen.bmiHeader.biHeight = wScreenY;
    bmiScreen.bmiHeader.biPlanes = 1;
    bmiScreen.bmiHeader.biBitCount = 32;
    bmiScreen.bmiHeader.biCompression = 0;
    bmiScreen.bmiHeader.biSizeImage = 0;
    bmiScreen.bmiHeader.biXPelsPerMeter = 0;
    bmiScreen.bmiHeader.biYPelsPerMeter = 0;
    bmiScreen.bmiHeader.biSizeImage = wScreenX * wScreenY * 4; // * 4 ku yks pikseli 4 tavuu
    bmiScreen.bmiHeader.biClrUsed = 0;
    bmiScreen.bmiHeader.biClrImportant = 0;
    
    // Bittikartta muistiin näytöstä
    hbmScreen = CreateCompatibleBitmap(hdcScreen, wScreenX, wScreenY);
    lpScreenBits = (DWORD*)malloc(bmiScreen.bmiHeader.biSizeImage*4);
    
    SelectObject(hdcMem, hbmScreen);
    BitBlt(hdcMem, 0, 0, wScreenX, wScreenY, hdcScreen, 0, 0, SRCCOPY);
    
    dwStartTicks = GetTickCount();
    SelectObject(hdcMem, hbmScreen);
    if(GetDIBits(hdcMem, hbmScreen, 0, bmiScreen.bmiHeader.biHeight,
        lpScreenBits, &bmiScreen, DIB_RGB_COLORS) == bmiScreen.bmiHeader.biHeight) // Palauttaa muistista luettujen rivien määrän
    {
        LogMessage("Loaded screenshot to memory successfully, now scanning...");
        for(DWORD dwOffset = 0; dwOffset < wScreenX * wScreenY * 4; dwOffset++)
        {
            if(lpScreenBits[dwOffset] == dwTargetColor)
            {
                sprintf(szBuf, "RGB(%u, %u, %u) at %u,%u",
                    GetRValue(crColor), GetGValue(crColor), GetBValue(crColor),
                    (UINT)(dwOffset % wScreenX), (UINT)abs(wScreenY-(dwOffset / wScreenX))-1); // Y väärinpäin muistisaxd
                SendMessage(lbResultBox, LB_ADDSTRING, 0, (LPARAM)szBuf);
                dwHits++;
            }
        }
        sprintf(szBuf, "Scan finished, %u hits and took %u ms!", (UINT)dwHits, (UINT)(GetTickCount()-dwStartTicks));
        LogMessage(szBuf);
    } else LogMessage("Failed to take a screenshot!");
    
    // Vapautellaas ku ei enään tarvita
    free(lpScreenBits);
    DeleteObject(hdcScreen);
    DeleteObject(hdcMem);
    return 0;
}

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hWnd;
    MSG messages;
    WNDCLASSEX wincl;
    hInstance = hThisInstance;

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH)0x10; // Öö kivempi taustaväri juu

    if (!RegisterClassEx (&wincl))
        return 0;

    /* Ikkunan luonti */
    hWnd = CreateWindowEx(
           0,
           szClassName,
           "Color thingy",
           WS_OVERLAPPEDWINDOW, 
           /* Asetellaan ikkuna nätisti keskelle näyttöä */
           (GetSystemMetrics(SM_CXSCREEN)-WIN_WIDTH)/2,
           (GetSystemMetrics(SM_CYSCREEN)-WIN_HEIGHT)/2,
           WIN_WIDTH,
           WIN_HEIGHT,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    ShowWindow (hWnd, nFunsterStil);

    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    return messages.wParam;
}

enum Childs {
    bScanID,
    bColorSelectID,
    eColorDisplayID,
    eRedID,
    eGreenID,
    eBlueID,
    eLogBoxID,
    lbResultBoxID,
    bClearLogID,
    bClearResultsID
};
/*  Viestien käsittely  */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HWND bScan, bColorSelect, bClearLog, bClearResults;
    static HFONT hfntDefault;
    RECT rcPos;
    char szBuf[255];
    switch (uMsg)
    {
        case WM_CREATE:
            GetClientRect(hwnd, &rcPos);
            hfntDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
            bScan = CreateWindowEx(0, "BUTTON", "Scan screen", WS_CHILD|WS_VISIBLE,
                5, 5, 82, 24, hwnd, (HMENU)bScanID, hInstance, NULL);
                SendMessage(bScan, WM_SETFONT, (WPARAM)hfntDefault, 0);
            bColorSelect = CreateWindowEx(0, "BUTTON", "Select new color", WS_CHILD|WS_VISIBLE,
                rcPos.right-92, 5, 99, 24, hwnd, (HMENU)bColorSelectID, hInstance, NULL);
                SendMessage(bColorSelect, WM_SETFONT, (WPARAM)hfntDefault, 0);
            eColorDisplay = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE,
                99, 7, rcPos.right-103, 21, hwnd, (HMENU)eColorDisplayID, hInstance, NULL);
                OldWndProc = (WNDPROC)SetWindowLong(eColorDisplay, GWL_WNDPROC, (LONG_PTR)EditWndProc); // Subclassataa
                
            eRed = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0", WS_CHILD|WS_VISIBLE|ES_NUMBER,
                92+5+rcPos.right-200, 5, 30, 24, hwnd, (HMENU)eRedID, hInstance, NULL);
                SendMessage(eRed, WM_SETFONT, (WPARAM)hfntDefault, 0);
                SetWindowLong(eRed, GWL_WNDPROC, (LONG_PTR)EditWndProc);
            eGreen = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "255", WS_CHILD|WS_VISIBLE|ES_NUMBER,
                92+10+30+rcPos.right-200, 5, 30, 24, hwnd, (HMENU)eRedID, hInstance, NULL);
                SendMessage(eGreen, WM_SETFONT, (WPARAM)hfntDefault, 0);
                SetWindowLong(eGreen, GWL_WNDPROC, (LONG_PTR)EditWndProc);
            eBlue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0", WS_CHILD|WS_VISIBLE|ES_NUMBER,
                92+15+60+rcPos.right-200, 5, 30, 24, hwnd, (HMENU)eRedID, hInstance, NULL);
                SendMessage(eBlue, WM_SETFONT, (WPARAM)hfntDefault, 0);
                SetWindowLong(eBlue, GWL_WNDPROC, (LONG_PTR)EditWndProc);
            
            lbResultBox = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", WS_CHILD|WS_VISIBLE|WS_VSCROLL,
                5, 34, rcPos.right-112, rcPos.bottom-104, hwnd, (HMENU)lbResultBoxID, hInstance, NULL);
                SendMessage(lbResultBox, WM_SETFONT, (WPARAM)hfntDefault, 0);
            eLogBox = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE|ES_READONLY|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL,
                5, rcPos.bottom-70, rcPos.right-10, 65, hwnd, (HMENU)eColorDisplayID, hInstance, NULL);
                SendMessage(eLogBox, WM_SETFONT, (WPARAM)hfntDefault, 0);
                
            bClearLog = CreateWindowEx(0, "BUTTON", "Clear log", WS_CHILD|WS_VISIBLE,                
                rcPos.right-103, rcPos.bottom-99, 99, 24, hwnd, (HMENU)bClearLogID, hInstance, NULL);
                SendMessage(bClearLog, WM_SETFONT, (WPARAM)hfntDefault, 0);
            bClearResults = CreateWindowEx(0, "BUTTON", "Clear hits", WS_CHILD|WS_VISIBLE,                
                rcPos.right-103, rcPos.bottom-128, 99, 24, hwnd, (HMENU)bClearResultsID, hInstance, NULL);
                SendMessage(bClearResults, WM_SETFONT, (WPARAM)hfntDefault, 0);
                
            LogMessage("Application started.");
            //break; Hihii, pyöräytetää WM_SIZINki WM_CREATEn jälkeen suoraan
        case WM_SIZE: // Ikkunan kokoa muutellaan, laitetaan napit paikoilleen jne
            GetClientRect(hwnd, &rcPos);

            SetWindowPos(bColorSelect, NULL, rcPos.right-103, 34, 99, 24, 0);
            SetWindowPos(eColorDisplay, NULL, 92, 7, rcPos.right-200, 20, 0);
            
            SetWindowPos(eRed, NULL, 92+5+rcPos.right-200, 5, 30, 24, 0);
            SetWindowPos(eGreen, NULL, 92+10+30+rcPos.right-200, 5, 30, 24, 0);
            SetWindowPos(eBlue, NULL, 92+15+60+rcPos.right-200, 5, 30, 24, 0);
            
            SetWindowPos(lbResultBox, NULL, 5, 34, rcPos.right-112, rcPos.bottom-104, 0);
            SetWindowPos(eLogBox, NULL, 5, rcPos.bottom-70, rcPos.right-10, 65, 0);
            
            SetWindowPos(bClearLog, NULL, rcPos.right-103, rcPos.bottom-99, 99, 24, 0);
            SetWindowPos(bClearResults, NULL, rcPos.right-103, rcPos.bottom-128, 99, 24, 0);
            RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
            break;
        case WM_CTLCOLOREDIT:
            if((HWND)lParam == eColorDisplay)
                (GetRValue(crCurColor) != 255) ?
                    SetBkColor((HDC)wParam, crCurColor + 1) // Säädetää vähä toi paska skannates hittaa tot displaytä
                    : SetBkColor((HDC)wParam, crCurColor -1);
            break;
        case WM_COMMAND:
            switch(wParam)
            {
                case bColorSelectID:
                case eColorDisplayID:
                    CHOOSECOLOR lpCc;
                    lpCc.lStructSize = sizeof(CHOOSECOLOR);
                    lpCc.hwndOwner = hwnd;
                    lpCc.rgbResult = crCurColor;
                    lpCc.lpCustColors = &crCurColor;
                    lpCc.Flags = CC_RGBINIT|CC_FULLOPEN|CC_SOLIDCOLOR;
                    lpCc.lCustData = 0;
                    lpCc.lpfnHook = 0;
                    lpCc.lpTemplateName = 0;
                    if(ChooseColor(&lpCc))
                    {
                        crCurColor = lpCc.rgbResult;
                        sprintf(szBuf, "%u", GetRValue(lpCc.rgbResult));
                        SetWindowText(eRed, szBuf);
                        sprintf(szBuf, "%u", GetGValue(lpCc.rgbResult));
                        SetWindowText(eGreen, szBuf);
                        sprintf(szBuf, "%u", GetBValue(lpCc.rgbResult));
                        SetWindowText(eBlue, szBuf);
                        RedrawWindow(eColorDisplay, 0, 0, RDW_INVALIDATE);
                    }
                    break;
                case bClearLogID:
                    SendMessage(eLogBox, WM_SETTEXT, 0, 0);
                    LogMessage("Log cleared.");
                    break;
                case bClearResultsID:
                    SendMessage(lbResultBox, LB_RESETCONTENT, 0, 0);
                    LogMessage("Hits cleared.");
                    break;
                case bScanID:
                    ScanForColor(crCurColor);
                    break;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

LRESULT EditWndProc(HWND hEdit, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    char szBuf[256];
    char bNewColor;
    if(hEdit == eColorDisplay)
    {
        if(uMsg == WM_SETFOCUS || uMsg == WM_CHAR || uMsg == WM_PASTE) // Ei anneta focusii siihe värijuttuu
            return 0;
    } else // if(hEdit == eRed || hEdit == eGreen || hEdit == eBlue)
    {
        if(uMsg == WM_KEYUP)
        {
            GetWindowText(hEdit, szBuf, 256);
            if(atoi(szBuf) > 255)
            {
                SetWindowText(hEdit, "255");
                bNewColor = 255;
            } else bNewColor = atoi(szBuf);

            if(hEdit == eRed)
                crCurColor = RGB(bNewColor, GetGValue(crCurColor), GetBValue(crCurColor));
            else if(hEdit == eGreen)
                crCurColor = RGB(GetRValue(crCurColor), bNewColor, GetBValue(crCurColor));
            else
                crCurColor = RGB(GetRValue(crCurColor), GetGValue(crCurColor), bNewColor);

            RedrawWindow(eColorDisplay, 0, 0, RDW_INVALIDATE);
        }
    }
    return CallWindowProc(OldWndProc, hEdit, uMsg, wParam, lParam);
}

void LogMessage(char* szMsg)
{
    SYSTEMTIME stTime;
    GetLocalTime(&stTime);
    char* szBuf = new char[lstrlen(szMsg) + 256];
    
    sprintf(szBuf, "\r\n[%02u:%02u:%02u] %s", stTime.wHour, stTime.wMinute, stTime.wSecond, szMsg);
    SendMessage(eLogBox, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
    SendMessage(eLogBox, EM_REPLACESEL, false, (LPARAM)szBuf);
    
    delete [] szBuf;
}

Compiles w/o problems with MinGW (dev-cpp uses mingw). Comments are in finnish, sorry :\ Output from the program:

Code:
[23:59:06] Application started.
[23:59:07] ScanForColor(RGB(0, 255, 0)) called.
[23:59:07] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:07] Loaded screenshot to memory successfully, now scanning...
[23:59:07] Scan finished, 36 hits and took 31 ms!
[23:59:11] ScanForColor(RGB(255, 255, 0)) called.
[23:59:11] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:12] Loaded screenshot to memory successfully, now scanning...
[23:59:12] Scan finished, 122 hits and took 46 ms!
[23:59:22] ScanForColor(RGB(0, 0, 255)) called.
[23:59:22] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:22] Loaded screenshot to memory successfully, now scanning...
[23:59:22] Scan finished, 164 hits and took 93 ms!
[23:59:26] ScanForColor(RGB(0, 255, 0)) called.
[23:59:26] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:26] Loaded screenshot to memory successfully, now scanning...
[23:59:26] Scan finished, 36 hits and took 63 ms!
[23:59:30] ScanForColor(RGB(0, 255, 0)) called.
[23:59:30] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:30] Loaded screenshot to memory successfully, now scanning...
[23:59:30] Scan finished, 36 hits and took 63 ms!
[23:59:31] ScanForColor(RGB(0, 255, 0)) called.
[23:59:31] Scanning pixels 0, 0 -> 1440, 900 (1296000 pixels total)
[23:59:31] Loaded screenshot to memory successfully, now scanning...
[23:59:31] Scan finished, 36 hits and took 31 ms!

So it's possible to scan all the pixels from 0, 0 -> 1440, 900 area under 100ms easily. Those times doesn't include allocation for memory and all initialization shit, but they can be done only once in program startup instead of every time when calling the function. But, this searchs all the colors and in your own program you may only want to return the first hit. You'll have to modify it if you want to use, that means you can't use it effectively if you don't understand the concept :P

For comparison, I modified the program to use GetPixel... I noticed that scanning my whole 1440x900 resolution would take just too long, so I used GetPixel to scan only the first 1440 x 10 pixels from my screen for color 0x00FF00.

Code:
[00:35:21] Application started.
[00:35:28] ScanForColorGetPixel(RGB(0, 255, 0)) called.
[00:35:28] Scanning pixels 0, 0 -> 1440, 10 (14400 pixels total)
[00:40:35] Scan finished, 0 hits and took 306963 ms!

It sounds incredible but it's true :P. GetPixel is slow as hell. In case I'm doing something wrong (I don't think so), here's the function I used for searching and measuring the speed:

Code:
int ScanForColorGetPixel(COLORREF crColor)
{
    DWORD dwHits = 0, dwStartTicks;
    UINT wScreenX, wScreenY;
    char szBuf[512];
    HDC hdcTarg;
    
    sprintf(szBuf, "ScanForColorGetPixel(RGB(%u, %u, %u)) called.",
        GetRValue(crColor), GetGValue(crColor), GetBValue(crColor));
    LogMessage(szBuf);
    
    hdcTarg = GetDC(NULL);
    wScreenX = GetDeviceCaps(hdcTarg, HORZRES);
    wScreenY = 10;
    
    sprintf(szBuf, "Scanning pixels 0, 0 -> %u, %u (%u pixels total)",
        wScreenX, wScreenY, (UINT)(wScreenX * wScreenY));
    LogMessage(szBuf);
    
    dwStartTicks = GetTickCount();
    for(WORD y = 0; y < wScreenY; y++)
    {
        for(WORD x = 0; x < wScreenX; x++)
        {
            if(GetPixel(hdcTarg, x, y) == crColor)
            dwHits++;
        }
    }

    sprintf(szBuf, "Scan finished, %u hits and took %u ms!", (UINT)dwHits, (UINT)(GetTickCount()-dwStartTicks));
    LogMessage(szBuf);
    return 0;
}
 
Runescape Gamblingrunescape gambling
Back
Top