how to improve a program, GetMessage problem

Hi,
I wrote a program that searches specific windows for a button with GetPixel and if the button exists it presses it.

My code is something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <windows.h>
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;

int click(HWND hwnd, int x, int y);

char titlu[200]="";
double Cx=0.5588235294117647,
		Cy=0.6549019607843137;


COLORREF c = RGB(142,200,255);


int pixel_test(HWND hwnd, int x, int y)
{
		HDC hDC = GetDC(hwnd);
         COLORREF cr =GetPixel(hDC, x, y); 
		if(cr != CLR_INVALID) 
        {
			return(abs(GetRValue(cr)-GetRValue(c))<=5 &&
					abs(GetGValue(cr)-GetGValue(c))<=5 &&
					abs(GetBValue(cr)-GetBValue(c))<=5);
			
		}
		return 0;	
}


HWND mese[9];
int i=0;

BOOL CALLBACK MyEnumProc( HWND hwnd, LPARAM lParam )
{
		if(GetWindowText(hwnd,titlu,200) && strstr(titlu, "My specific window"))
		{	
			mese[i]=hwnd;
			i++;		
		}
	return 1;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{

	DWORD dwThreadId = GetCurrentThreadId(); // Get the current thread id
	HDESK hDesktop = GetThreadDesktop(dwThreadId); // Assign the desktop thread id to hDesktop

	while(1)
	{
	i=0;
	
	EnumDesktopWindows( hDesktop, MyEnumProc, 0 );
	
	for(int t=0; t<15; t++)
	{
		for (int j=0; j < i ; j++)
		{
			if (IsWindow(mese[j]))
			{				
				RECT client;
				GetClientRect(mese[j],&client);
				int width=client.right-client.left;
				int height=client.bottom-client.top;
				int xscalat=(int)(width * Cx);
				int yscalat=(int)(height * Cy);
				if (pixel_test(mese[j],xscalat,yscalat) )
					click(mese[j], xscalat, yscalat);
			}

		}
		Sleep(4000);

	}

	}
	
	



	return 0;


}


int click(HWND hwnd, int x, int y)
{
	
	PostMessage(hwnd,WM_LBUTTONDOWN,0, MAKELONG(x,y));
	PostMessage(hwnd,WM_LBUTTONUP,0, MAKELONG(x,y));
	return 1;
}


The problem is it slows down my computer ... don't know what exactly i could change to improve it ... It gets all the handles from my desired windows every 15*4s (1 minute) and it searches for the button every 4 seconds.

I guess something with GetMessage() function that would intercept the WM_CREATE and WM_QUIT sent by the main window (the ones i search for the button are some kind of childs). I wrote something with GetMessage but it doesnt really work:

1
2
3
4
5
6
7
8
9
10
11
HWND parent = FindWindow(NULL,"Main Window Name");
MSG msg;

while (GetMessage(&msg, parent, 0, 0))
{
if (msg.message == WM_CREATE )
MessageBox(NULL,"new window","Message:",MB_OK);

TranslateMessage(&msg);
DispatchMessage(&msg);
}


Please give me some suggestions on how i could improve the program or at least point me to some good tutorials.

PS: i'm really new to win32 programming ...

Thank you.
Last edited on
The nested loops...

1
2
3
4
5
6
7
8
    i=0;
    
    EnumDesktopWindows( hDesktop, MyEnumProc, 0 );
    
    for(int t=0; t<15; t++)
    {
        for (int j=0; j < i ; j++)
        {


Don't seem to do anything? You never set a value to i so j < i is always false. You're just repeating the sleep comand over and over again.
i is changed in the callback function named MyEnumProc that is called by EnumDesktopWindows
That's pretty cool.

pixel_test is the only thing that could take some time, but you're only doing that a maximum of 9 times per iteration (I hope), as the array's only 9 elements long. Even then, the only possibly expensive calls are GetDC and GetPixel.

There's not much you can do about those. You could consider running the program a lower priority.

A few comments:
1. You call GetDC, but never release the hDC with ReleaseDC.
2. The HWND array is fixed to 9 elements long. You can use a vector to cope with variable size. You can fix this by declaring a vector of HWND in the loop and pass it to MyEnumProc.
1
2
3
4
5
6
7
8
9
10
    std::vector<HWND> mese;
    mese.reserve(9);
    while (true)
    {
        mese.clear();
        EnumDesktopWindows(hDesktop, MyEnumProc, reinterpret_cast<LPARAM>(&mese));

        for (int t=0; t<15; ++t)
        {
            for (size_t j=0; j < mese.size(); ++j)


and changing the callback to:
1
2
3
4
5
6
7
8
9
BOOL CALLBACK MyEnumProc(HWND hwnd, LPARAM lParam)
{
    std::vector<HWND>* mese = reinterpret_cast<std::vector<HWND>*>(lParam);
    char titlu[200];
    if (GetWindowText(hwnd,titlu,200) && strstr(titlu, "My specific window"))
    {
        mese->push_back(hWnd);
    }
}

You'll need to add #include <vector> at the top somewhere.
You can then remove global variables mese, titlu and i.
Last edited on
"You could consider running the program a lower priority." how can i do this within my application ? (not from task manager)
About the vector idea, it seems pretty good, but i don't really understand how to use these vectors.

Meanwhile, i've been searching the web and i found out about system-wide hooks.
I played around with Spy++ over the window that i have to post the click to an i filtered the messages and i came up with this:
00031084 P message: 0x0118 [Unknown] wParam:0000FFF8 lParam:97B03836
after this message has appeared for 4 times in a row, i have to click on the button.
is there any way i can use this ?
Try SendInput rather than Posting messages.
http://msdn.microsoft.com/en-us/library/ms646310%28VS.85%29.aspx
thanks, but the clicks work pretty fine and it's no problem with the CPU because of them
maybe you could help me with the hooks ? (examples or what kind of hook i should use)
i think with hooks the cpu usage will go down drastically
thanks again.


EDIT: PS: i used the ReleaseDC and the CPU usage seems to have lowered :), from a little test i did
Last edited on
I don't know where hooks are applicable to what you're doing.
http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx
Topic archived. No new replies allowed.