I'm sorry if a similar post exists but I couldn't find it.
I have been learning to use the windows.h library for 2 days. I have problems with the GetPixel function returns 0 on google chrome but returns the good values on applications installed on my computer.
Here is my code:
#include <windows.h>
#include <iostream>
#include <tchar.h>
void handleGame(HWND& _window) {
LPCWSTR windowClass = L"Chrome_WidgetWin_1";
LPCWSTR windowName = L"Stack Overflow - Where Developers Learn, Share, & Build Careers - Google Chrome";
_window = FindWindow(windowClass, windowName);
while (_window == NULL) {
std::cout << "failed" << std::endl;
_window = FindWindow(windowClass, windowName);
Sleep(1000);
}
}
int main() {
HWND window = NULL;
while (true)
{
handleGame(window);
if (GetAsyncKeyState(VK_NUMPAD1)) {
HDC hdc = GetDC(window);
COLORREF color;
COLORREF characteristic_color = 5460819;
RECT rect = {};
GetClientRect(window, &rect);
for (int i = rect.left; i < rect.right; i++) {
for (int j = rect.top; j < rect.bottom; j++) {
color = GetPixel(hdc, i, j);
std::cout << color << std::endl;
if (color == characteristic_color) {
std::cout << "FOUND!" << std::endl;
SetCursorPos(i, j);
ReleaseDC(window, hdc);
break;
}
}
}
ReleaseDC(window, hdc);
std::cout << "not found..!" << std::endl;
break;
}
}
std::cout << "end" << std::endl;
return 0;
}
I tried to follow some tutorials and I search several hours for this problem but I can't find a good answer. I have seen the BITMAP structure but I don't know how to use it and I don't think it will solve my problem.
For example my code works well on "paint" but there is a bug on google chrome.
I tried to use the mouse to get the pixel but it returns 0 too. I tried to use the function GetDC(NULL) and it works well, but I need to get just the window of the web browser, not all my screen.
The goal of the program is to find a specific COLORREF but it returns always 0 on google chrome.
I apologize for my ignorance and hope someone can help me!
Thank you!
Related
I found this article and tried to follow it to find the position of the caret in any Windows application:
How to get caret position in ANY application from C#?
However, I have a problem with following it.
This is the C# code I was following:
var guid = typeof(IAccessible).GUID;
object accessibleObject = null;
var retVal = WinApiProvider.AccessibleObjectFromWindow(hwnd, WinApiProvider.OBJID_CARET, ref guid, ref accessibleObject);
var accessible = accessibleObject as IAccessible;
accessible.accLocation(out int left, out int top, out int width, out int height, WinApiProvider.CHILDID_SELF);
But I have no idea how to put CHILDID_SELF in the fifth parameter of the IAccessible::accLocation() function:
Rect rect;
VARIANT varCaret;
varCaret.vt = VT_I4;
varCaret.lVal = CHILDID_SELF;
std::cout << object->accLocation(&rect.x, &rect.y, &rect.w, &rect.h, varCaret);
After some research, I found out that I should put CHILDID_SELF in this way. But it's not working as expected.
I assume this should be able to get the position of the caret in Microsoft Edge or Chrome, but it just returns S_FALSE.
The guy from the link also didn't get the caret position from Chrome or other windows, but made it work after adding CHILDID_SELF. So, I guess the problem I have is related to the way that I'm using CHILDID_SELF.
I'm also using 21H1 build 19043.1889, but still I'm using 21H1 so it shouldn't be the problem, in my opinion.
I also tried to just plug it in, but of course C++ didn't let me do that:
object->accLocation(&rect.x, &rect.y, &rect.w, &rect.h, CHILDID_SELF);
object->accLocation(&rect.x, &rect.y, &rect.w, &rect.h, (VARIANT)CHILDID_SELF);
What would be the solution of this problem? Am I doing something wrong?
FULL CODE
#include <iostream>
#include <Windows.h>
#include <oleacc.h>
#pragma comment(lib, "Oleacc.lib")
typedef struct {
long x;
long y;
long w;
long h;
} Rect;
int main(int argc, char* argv[]) {
HWND hwnd;
DWORD pid;
DWORD tid;
while (true) {
system("cls");
GUITHREADINFO info;
info.cbSize = sizeof(GUITHREADINFO);
hwnd = GetForegroundWindow();
tid = GetWindowThreadProcessId(hwnd, &pid);
GetGUIThreadInfo(tid, &info);
IAccessible* object = nullptr;
if (SUCCEEDED(AccessibleObjectFromWindow(info.hwndFocus, OBJID_CARET, IID_IAccessible, (void**)&object))) {
Rect rect;
VARIANT varCaret;
varCaret.vt = VT_I4;
varCaret.lVal = CHILDID_SELF;
object->accLocation(&rect.x, &rect.y, &rect.w, &rect.h, varCaret);
std::cout << rect.x << std::endl;
object->Release();
}
Sleep(10);
}
return 0;
}
Used Microsoft Visual Studio 2019, x86, Debug to build
Your first code snippet is the correct way to pass CHILDID_SELF in a VARIANT parameter, per the documentation:
How Child IDs Are Used in Parameters
When initializing a VARIANT parameter, be sure to specify VT_I4 in the vt member in addition to specifying the child ID value (or CHILDID_SELF) in the lVal member.
So, the problem must be something else. For instance, one thing I notice is that you are not initializing the COM library before calling AccessibleObjectFromWindow(). Try calling CoInitialize/Ex() first and see if it makes a difference.
Also, you are not checking the return value of accLocation() for failure before using the RECT coordinates.
Try this:
#include <iostream>
#include <Windows.h>
#include <oleacc.h>
#pragma comment(lib, "Oleacc.lib")
typedef struct {
long x;
long y;
long w;
long h;
} Rect;
int main(int argc, char* argv[]) {
HWND hwnd;
DWORD pid;
DWORD tid;
CoInitialize(nullptr); // <-- add this
while (true) {
system("cls");
GUITHREADINFO info;
info.cbSize = sizeof(GUITHREADINFO);
hwnd = GetForegroundWindow();
tid = GetWindowThreadProcessId(hwnd, &pid);
GetGUIThreadInfo(tid, &info);
IAccessible* object = nullptr;
if (SUCCEEDED(AccessibleObjectFromWindow(info.hwndFocus, OBJID_CARET, IID_IAccessible, (void**)&object))) {
Rect rect;
VARIANT varCaret;
varCaret.vt = VT_I4;
varCaret.lVal = CHILDID_SELF;
if (SUCCEEDED(object->accLocation(&rect.x, &rect.y, &rect.w, &rect.h, varCaret))) {
std::cout << rect.x << std::endl;
}
object->Release();
}
Sleep(10);
}
CoUninitialize(); // <-- add this
return 0;
}
I wonder how to solve this problem. I want to check every X seconds if the screen contains an image (for example a red dot) and if so return True. I am very familiar with Python, and there are some easy solutions there. But I haven't found a similar solution yet.
What I basically want to do is:
Take a screenshot
Locate image X on the screenshot
Return bool
Looked into OpenCV and would be possible to solve it that way, but might be a bit overextending. I was thinking about getPixel to loop over all the pixels in the screen. But it's extremely slow.
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
HWND runelite = GetForegroundWindow();
HMONITOR monitor = MonitorFromWindow(runelite, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
int monitor_width = info.rcMonitor.right - info.rcMonitor.left;
int monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;
int r, g, b;
HDC screenshot = GetDC(NULL);
for (int i = 0; i < monitor_height; i++) {
for (int j = 0; j < monitor_width; j++) {
DWORD color = GetPixel(screenshot, j, i);
cout << "Scanning -> X: " << j << " Y: " << i << endl;
r = GetRValue(color);
g = GetGValue(color);
b = GetBValue(color);
if (r == 0 && g == 0 && b == 0) {
cout << "Button found by color!" << endl;
goto end;
}
}
}
end:
ReleaseDC(NULL, screenshot);
return 0;
}
you could greatly increase the speed if you copy your HDCs content to another bitmap and get a pointer to the image data and loop over this.
create a memory bitmap
HDC memDC = CreateCompatibleDC ( hDC );
HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
SelectObject ( memDC, memBM );
then bitblt the screen data to that bitmap via BitBlt and get the bitmap data with GetDIBits.
please also note, that GetDC(NULL) does not make a screenshot, but gets you access to windows live main HDC. drawing to it directly draws on the desktop.
Thatswhy every GetPixel on it does take quite long.
I got a problem with changing console size. This is my code:
BOOL setConsole(int x, int y)
{
hStdin = GetStdHandle(STD_INPUT_HANDLE);
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE ||
hStdout == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, TEXT("GetStdHandle"),
TEXT("Console Error"), MB_OK);
return false;
}
SMALL_RECT windowSize = {0, 0, x-1, y-1};
// Change the console window size:
SetConsoleWindowInfo(hStdout, TRUE, &windowSize);
COORD c = { x, y};
//Change the internal buffer size:
SetConsoleScreenBufferSize(hStdout, c);
SetConsoleDisplayMode(hStdout,CONSOLE_FULLSCREEN_MODE, &c);
return true;
}
It works perfectly fine, when I try to enlarge the console. When one parameter is smaller than previous one nothing happens. What is wrong?
#edit: after some tests I noticed, that resizing(reducing) is possible if I change one parameter at once. Example(assume console is 100x100)
setConsole(90,90); //dosen't work.
setConsole(90,100);
setConsole(90,90); // works perfectly
WHY?!
SetConsoleScreenBufferSize changes the size of the internal buffer of the console.
Changing it has no effect on the console windows extent.
Call SetConsoleWindowInfo if you need an effect on the visible part of the console (buffer).
The window buffer cannot be smaller than the internal buffer , and decreasing it will also decrease the internal buffer,
but not the other way around.
If you call SetConsoleScreenBufferSize with illegal value in COORDS (e.g. too little height/width) then you get an
error, usually 87 'invalid argument'.
Try this code:
#include <iostream>
#include <windows.h>
using namespace std;
void SetWindow(int Width, int Height)
{
_COORD coord;
coord.X = Width;
coord.Y = Height;
_SMALL_RECT Rect;
Rect.Top = 0;
Rect.Left = 0;
Rect.Bottom = Height - 1;
Rect.Right = Width - 1;
HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE); // Get Handle
SetConsoleScreenBufferSize(Handle, coord); // Set Buffer Size
SetConsoleWindowInfo(Handle, TRUE, &Rect); // Set Window Size
}
int main(void)
{
SetWindow(80,40);
int dx=1,i=5,l=0;
while(l<5)
{
i=i+dx;
if( (i<1) || (i>10)){ dx=-dx; l++;}
SetWindow(10*i,5*i);
Sleep(100);
}
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}
Late to the party ...
As far as can be devised from MSDN and a few tests, the screen buffer can't be set smaller than the window's extent or the window's extent made bigger than the screen buffer.
One hack is to shrink the window to a minimal before changing the buffer size :
static void
set_console_size(HANDLE screen_buffer, SHORT width, SHORT height)
{
assert(screen_buffer != NULL);
assert(width > 0);
assert(height > 0);
COORD const size = { width, height };
BOOL success;
SMALL_RECT const minimal_window = { 0, 0, 1, 1 };
success = SetConsoleWindowInfo(screen_buffer, TRUE, &minimal_window);
CHECK(success);
success = SetConsoleScreenBufferSize(screen_buffer, size);
CHECK(success);
SMALL_RECT const window = { 0, 0, size.X - 1, size.Y - 1 };
success = SetConsoleWindowInfo(screen_buffer, TRUE, &window);
CHECK(success);
}
try this code:
system("mode 650");
I modified the code provided by 'Software_Designer' on Oct 15' 12 and created a command line utility to set the console size and scroll buffers.
I compiled it using DEV C++ (http://www.bloodshed.net/devcpp.html).
An executable is included in https://sourceforge.net/projects/wa2l-wintools/. I hope this helps.
/*
* consolesize.cpp - set console size and buffer dimensions
*
* [00] 02.07.2016 CWa Initial Version
*
* inspired by: http://stackoverflow.com/questions/12900713/reducing-console-size
*
*/
#include <iostream>
#include <windows.h>
using namespace std;
// SetWindow(Width,Height,WidthBuffer,HeightBuffer) -- set console size and buffer dimensions
//
void SetWindow(int Width, int Height, int WidthBuffer, int HeightBuffer) {
_COORD coord;
coord.X = WidthBuffer;
coord.Y = HeightBuffer;
_SMALL_RECT Rect;
Rect.Top = 0;
Rect.Left = 0;
Rect.Bottom = Height - 1;
Rect.Right = Width - 1;
HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE); // Get Handle
SetConsoleScreenBufferSize(Handle, coord); // Set Buffer Size
SetConsoleWindowInfo(Handle, TRUE, &Rect); // Set Window Size
} // SetWindow
// main(Width,Height,WidthBuffer,HeightBuffer) -- main
//
int main(int argc, char *argv[]) {
int width = 80;
int height = 25;
int wbuffer = width + 200;
int hbuffer = height + 1000;
if ( argc == 5 ){
width = atoi(argv[1]);
height = atoi(argv[2]);
wbuffer = atoi(argv[3]);
hbuffer = atoi(argv[4]);
} else if ( argc > 1 ) {
cout << "Usage: " << argv[0] << " [ width height bufferwidth bufferheight ]" << endl << endl;
cout << " Where" << endl;
cout << " width console width" << endl;
cout << " height console height" << endl;
cout << " bufferwidth scroll buffer width" << endl;
cout << " bufferheight scroll buffer height" << endl;
return 4;
}
SetWindow(width,height,wbuffer,hbuffer);
return 0;
}
/* So, tiny recap --
SetConsoleScreenBufferSize(): fails if buffer width and height
are less than the width and height of the current screen window
rectangle.
SetConsoleWindowInfo(): fails if the specified window rectangle
is larger than the boundaries of the screen buffer.
Setting the correct one 1st (buffer or window rectangle) would
solve much in a screen resize, but that's hard to know because
calls to GetConsoleScreenBufferInfo() fail easily, and so you cannot
reliably discover the current screen rectangle and/or buffer size,
and hence you cannot know if you'll be setting the screen rectangle
larger or smaller than the current size, and in turn you can't
always know which function to call 1st.
WORKAROUND:
Sloppy solution but super-reliable...
- Set the buffer 1st to something uncommonly large -- like 1000x1000.
- Then set the window rectangle to the actual desired size.
- Finally, set the window buffer to the actual desired size
(matching the screen rectangle) */
int set_screen_size(int requested_wdth, int requested_hgt)
{
SMALL_RECT srWindowRect; /* hold the new console size */
COORD coordBuffer;
BOOL bsuccess = FALSE, wsuccess = FALSE;
srWindowRect.Left = 0;
srWindowRect.Right = requested_wdth-1;
srWindowRect.Top = 0;
srWindowRect.Bottom = requested_hgt-1;
/*set buffer oversize -- like 1000x1000 (500x500 and less
could do too)*/
coordBuffer.X = coordBuffer.Y = 1000;
bsuccess = SetConsoleScreenBufferSize(hConOut, coordBuffer);
wsuccess = SetConsoleWindowInfo(hConOut, TRUE, &srWindowRect);
coordBuffer.X = requested_wdth;
coordBuffer.Y = requested_hgt;
bsuccess = SetConsoleScreenBufferSize(hConOut, coordBuffer);
/* ... */
}
I "copied" a simple code snippet from a site and adjusted it to a game I was trying to hack. An old game with no multiplayer, basically just to practice all this memory editing stuff. Every time my program successfully returns a window handle, but then fails to return the process handle. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
long address = 0x47C0F04;
int newvalue = 200;
DWORD newvaluesize = sizeof(newvalue);
HWND hWnd = FindWindow(0, L"No One Lives Forever");
HANDLE pHandle;
DWORD pid;
if(hWnd != 0) {
cout << "Found windowx.\n";
GetWindowThreadProcessId(hWnd, &pid);
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
else {
cout << "Can't find window\n";
}
if(pHandle !=0) {
WriteProcessMemory(pHandle, (LPVOID)address, (LPVOID)newvalue, newvaluesize, 0);
cout << "Written to memory successfully\n";
}
else {
cout << "Couldn't get handle.\n";
}
CloseHandle(pHandle);
return 0;
}
The game is from 2000 if I recall correctly (really awesome game by the way) so I'm assuming it doesn't have any advanced anti-hack shield, since I can also pretty much edit the value of that address in cheat engine and it works with no hassle.
EDIT: I'll just explain what exactly happens. It always prints "Found window" but then it directly prints "Couldn't get handle". I don't get any compiler errors (I'm compiling in Microsoft Visual C++ 2010 Express)
You must run your program as administrator to get a handle with PROCESS_ALL_ACCESS permissions, this will fix your problem.
As GuidedHacking mentioned you need to run program as Admin ,Use this code to check whether your process is running as Admin rights.
BOOL IsElevatedProcess()
{
BOOL is_elevated = FALSE;
HANDLE token = NULL;
if (GT_IsPrivateMethod(gt_private_method, FUNC_NAME, LINE_NO))
{
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
TOKEN_ELEVATION elevation;
DWORD token_sz = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &token_sz))
{
is_elevated = elevation.TokenIsElevated;
}
}
if (token)
{
CloseHandle(token);
}
}
return is_elevated;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Colorize stdout output to Windows cmd.exe from console C++ app
I am using codeblocks on Windows XP and I need a way to output colored text, and maybe change the color of the background as well in a console application.
I tried the conio.h functions but they don't seem to be compatible with code blocks.
It looks like you'll want to use some Windows API features to accomplish this.
If you were using Cygwin for windows, it'd be a bit easier.
Here's an example courtesy of daniweb:
// color your text in Windows console mode
// colors are 0=black 1=blue 2=green and so on to 15=white
// colorattribute = foreground + background * 16
// to get red text on yellow use 4 + 14*16 = 228
// light red on yellow would be 12 + 14*16 = 236
// a Dev-C++ tested console application by vegaseat 07nov2004
#include <iostream>
#include <windows.h> // WinApi header
using namespace std; // std::cout, std::cin
int main()
{
HANDLE hConsole;
int k;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// you can loop k higher to see more color choices
for(k = 1; k < 255; k++)
{
// pick the colorattribute k you want
SetConsoleTextAttribute(hConsole, k);
cout << k << " I want to be nice today!" << endl;
}
cin.get(); // wait
return 0;
}
This piece of code might help:
WinConsole.h
#pragma once
typedef void* HANDLE;
class WinConsole
{
public:
WinConsole(void);
~WinConsole(void);
void SetColour(WORD colour);
WORD GetDefaultColour() const;
void Reset();
private:
HANDLE fConsoleHandle;
CONSOLE_SCREEN_BUFFER_INFO fDefaultScreenBufferInfo;
};
WinConsole.cpp
#include "WinConsole.h"
#define WIN32_LEAN_AND_MEAN
#define <Windows.h>
WinConsole::WinConsole(void)
{
fConsoleHandle = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE != fConsoleHandle)
{
::GetConsoleScreenBufferInfo(fConsoleHandle, &fDefaultScreenBufferInfo);
}
}
WinConsole::~WinConsole(void)
{
}
void WinConsole::SetColour( WORD colour )
{
if (INVALID_HANDLE_VALUE != fConsoleHandle)
{
::CONSOLE_SCREEN_BUFFER_INFO info = { sizeof(CONSOLE_SCREEN_BUFFER_INFO), 0 };
if(::GetConsoleScreenBufferInfo(fConsoleHandle, &info))
{
::SetConsoleTextAttribute(fConsoleHandle, (info.wAttributes & 0xff00)|colour);
}
}
}
void WinConsole::Reset()
{
if (INVALID_HANDLE_VALUE != fConsoleHandle)
{
::SetConsoleTextAttribute(fConsoleHandle, fDefaultScreenBufferInfo.wAttributes);
}
}
WORD WinConsole::GetDefaultColour() const
{
if (INVALID_HANDLE_VALUE != fConsoleHandle)
{
return (WORD)(fDefaultScreenBufferInfo.wAttributes & 0x00ff);
}
return e_FGRed | e_FGGreen | e_FGBlue;
}
Usage:
WinConsole console;
console.SetColour(FOREGROUND_RED|BACKGROUND_BLUE); // Superman style ;)