#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;
}