przyśpieszenie działania funkcji

0

Napisałem sobie ostatnio dll wstrzykiwany do danego programu tworzący nowy wątek i robiący w funkcji wątku swoje, otóż mój problem polega na tym że wszystko za wolno chodzi jest tam funkcja GetPixel która czasami nie nadąża za szybkością zmieniania się piksela, i SendInput który naciska przycisk "mouse3", nie wiem co ale coś za wolno chodzi czy jest to wykrywanie piksela czy naciśnięcie pokrętła myszki. Czy jest jakiś sposób aby to wszystko przyśpieszyć? Kiedy usunę Sleep() program któremu wstrzyknąłem dll muli się.

 
#include <windows.h>
#include <gdiplus.h>

const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);

const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);

DWORD WINAPI ThreadFunction(PVOID pvParam)
{
	// pixel detect and shooting
	register HDC hdc = GetDC(0);
	register COLORREF lcolor;
	register INPUT ip;
	DWORD shotbot = 0;
	ip.type = INPUT_MOUSE;
	ip.mi.dx = 0;
	ip.mi.dy = 0;
	ip.mi.dwExtraInfo = 0;
	ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
	while(1)
	{
		if(shotbot == 1)
		{
			Sleep(1);
			lcolor = GetPixel(hdc,SCREEN_X,SCREEN_Y);
			if(lcolor == RGB(255, 0, 0))
			{
				Sleep(50);
				ip.mi.dx = 0;
				ip.mi.dy = 0;
				ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
				SendInput(1, &ip, sizeof(INPUT));
				Sleep(50);
				ip.mi.dx = 0;
				ip.mi.dy = 0;
				ip.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
				SendInput(1, &ip, sizeof(INPUT));
			}
		}
		Sleep(50);
		if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
		{
			if(shotbot == 1)
			{
				Sleep(50);
				shotbot = 0;
				PlaySound((LPCSTR)SND_ALIAS_SYSTEMASTERISK, NULL, SND_ALIAS_ID);
			}
			else
			{
				Sleep(50);
				shotbot = 1;
				PlaySound((LPCSTR)SND_ALIAS_SYSTEMEXCLAMATION, NULL, SND_ALIAS_ID);
			}
		}
	}
	return 0;
}

BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) 
{
	if(fdwReason==DLL_PROCESS_ATTACH) 
    {
                                                                   
		//MessageBox(0,"oppkan.dll loaded.","Attention",0);  
		CreateThread(0, 0, ThreadFunction, 0, 0, NULL);

    }
	return TRUE;
}
0

Zamiast spać 50 ms napisz funkcję która przez 50 ms bada czy pojawiał się pixel.

bool SleepChceck(HDC hdc)
  {
   time_t stop=GetTickCount()+50;
   bool result=false;
   while(GetTickCount()<stop)
      {
       if(jest czerwony) result=true;
      }
   return result;
  }
0

tak?

bool PixelCheck(HDC hdc)
{
	time_t stop=GetTickCount()+50;
	bool result=false;
	register COLORREF lcolor;
	while(GetTickCount()<stop)
	{
		lcolor = GetPixel(hdc,SCREEN_X,SCREEN_Y);
		if(lcolor == RGB(255, 0, 0)) result=true;
	}
	return result;
}

DWORD WINAPI ThreadFunction(PVOID pvParam)
{
	// pixel detect and shooting
	register HDC hdc = GetDC(0);
	register INPUT ip;
	bool isPixelRed = PixelCheck(hdc);
	DWORD shotbot = 0;
	ip.type = INPUT_MOUSE;
	ip.mi.dx = 0;
	ip.mi.dy = 0;
	ip.mi.dwExtraInfo = 0;
	ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
	while(isPixelRed)
/////dalszy kod
0

Teraz to nie działa(nie wykrywa piksela) albo coś źle napisałem.

 
#include <windows.h>
#include <gdiplus.h>

const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);

const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);

bool PixelCheck(HDC hdc)
{
	time_t stop=GetTickCount()+50;
	bool result=false;
	register COLORREF lcolor;
	while(GetTickCount()<stop)
	{
		lcolor = GetPixel(hdc,SCREEN_X,SCREEN_Y);
		if(lcolor == RGB(255, 0, 0)) result=true;
	}
	return result;
}

DWORD WINAPI ThreadFunction(PVOID pvParam)
{
	// pixel detect and shooting
	register HDC hdc = GetDC(0);
	register INPUT ip;
	bool isPixelRed = PixelCheck(hdc);
	DWORD shotbot = 0;
	ip.type = INPUT_MOUSE;
	ip.mi.dx = 0;
	ip.mi.dy = 0;
	ip.mi.dwExtraInfo = 0;
	ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
	while(isPixelRed == TRUE)
	{
		
	}
	while(1)
	{
		if(isPixelRed && shotbot == 1)
		{
			Sleep(50);
			ip.mi.dx = 0;
			ip.mi.dy = 0;
			ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
			SendInput(1, &ip, sizeof(INPUT));
			Sleep(50);
			ip.mi.dx = 0;
			ip.mi.dy = 0;
			ip.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
			SendInput(1, &ip, sizeof(INPUT));
		}
		Sleep(50);
		if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
		{
			if(shotbot == 1)
			{
				Sleep(50);
				shotbot = 0;
				PlaySound((LPCSTR)SND_ALIAS_SYSTEMASTERISK, NULL, SND_ALIAS_ID);
			}
			else
			{
				Sleep(50);
				shotbot = 1;
				PlaySound((LPCSTR)SND_ALIAS_SYSTEMEXCLAMATION, NULL, SND_ALIAS_ID);
			}
		}
	}
	return 0;
}

BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) 
{
	if(fdwReason==DLL_PROCESS_ATTACH) 
    {
                                                                   
		//MessageBox(0,"oppkan.dll loaded.","Attention",0);  
		CreateThread(0, 0, ThreadFunction, 0, 0, NULL);

    }
	return TRUE;
}
0
  1. Po kiego czy ten register?
bool PixelCheck(HDC hdc)
  {
   static const COLORREF red=RGB(255, 0, 0);
   time_t stop=GetTickCount()+50;
   bool result=false;
   while(GetTickCount()<stop) if(red==GetPixel(hdc,SCREEN_X,SCREEN_Y)) result=true;
   return result;
  }
  1. while(isPixelRed) - Nie, jak tylko stanie się nie czerwony skończy się twój wątek. Zamiast:
                        Sleep(1);
                        lcolor = GetPixel(hdc,SCREEN_X,SCREEN_Y);
                        if(lcolor == RGB(255, 0, 0))
                        {
                                Sleep(50);

Dajesz:

   if(PixelCheck(hdc))
       {
  1. Przeanalizuj te fragmenty:
const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
bool shotbot=false;

                if(shotbot)
                {
                 ...
                }
 
                if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
                  {
                   shotbot=!shotbot;
                   PlaySound((LPCSTR)Sound[shotbot], NULL, SND_ALIAS_ID);
                  }
0

testowałem bez tego sleepa przed PixelCheck i muliło, poza czytelniejszym kodem nic się nie zmieniło, dalej za wolno naciska przycisk lub sprawdza piksel.

 
#include <windows.h>
#include <gdiplus.h>

const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);

const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);

bool PixelCheck(HDC hdc)
{
	static const COLORREF red=RGB(255, 0, 0);
	static COLORREF lcolor;
	time_t stop=GetTickCount()+50;
	bool result=false;
	while(GetTickCount()<stop)
	{
		lcolor = GetPixel(hdc,SCREEN_X,SCREEN_Y);
		if(lcolor == red) result=true;
	}
	return result;
}

DWORD WINAPI ThreadFunction(PVOID pvParam)
{
        // pixel detect and shooting
        HDC hdc = GetDC(0);
        INPUT ip;
		const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
        bool shotbot = false;
        ip.type = INPUT_MOUSE;
        ip.mi.dx = 0;
        ip.mi.dy = 0;
        ip.mi.dwExtraInfo = 0;
        ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
        while(1)
        {
                if(shotbot)
                {
						// sleep bo muli
						Sleep(10);
                        if(PixelCheck(hdc))
                        {
                                Sleep(50);
                                ip.mi.dx = 0;
                                ip.mi.dy = 0;
                                ip.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
                                SendInput(1, &ip, sizeof(INPUT));
                                Sleep(50);
                                ip.mi.dx = 0;
                                ip.mi.dy = 0;
                                ip.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
                                SendInput(1, &ip, sizeof(INPUT));
                        }
                }
                Sleep(50);
                if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
                {
					shotbot=!shotbot;
					PlaySound((LPCSTR)Sound[shotbot], NULL, SND_ALIAS_ID);
                }
        }
        return 0;
}
 
BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) 
{
        if(fdwReason==DLL_PROCESS_ATTACH) 
    {
 
                //MessageBox(0,"oppkan.dll loaded.","Attention",0);  
                CreateThread(0, 0, ThreadFunction, 0, 0, NULL);
 
    }
        return TRUE;
}
 
0

Oczywiście bo nie zrobiłeś tego co powiedziałem.

#include <windows.h>
#include <gdiplus.h>
 
const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);
 
const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);
const COLORREF red=RGB(255, 0, 0);
const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
const int State[]={MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP};
 
bool PixelCheck(HDC hdc)
  {
   time_t stop=GetTickCount()+50;
   bool result=false;
   while(GetTickCount()<stop) if(GetPixel(hdc,SCREEN_X,SCREEN_Y) == red) result=true;
   return result;
  }
 
DWORD WINAPI ThreadFunction(PVOID pvParam)
  {
   HDC hdc=GetDC(0);
   bool shotbot=false,isdown=false;
   INPUT ip;
   ip.type=INPUT_MOUSE;
   ip.mi.dx=0;
   ip.mi.dy=0;
   ip.mi.dwExtraInfo=0;
   while(true)
     {
      if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
        {
         shotbot=!shotbot;
         PlaySound((LPCSTR)Sound[shotbot],NULL,SND_ALIAS_ID);
        }         
      if((shotbot&&PixelCheck(hdc))||isdown)
        {
         ip.mi.dwFlags=State[isdown];
         SendInput(1,&ip,sizeof(INPUT));
         isdown=!isdown;
        }
     }
   ReleaseDC(hdc);
   return 0;
  }
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) 
  {
   if(fdwReason==DLL_PROCESS_ATTACH)  SetThreadPriority(CreateThread(0,0,ThreadFunction,0,0,NULL),THREAD_PRIORITY_BELOW_NORMAL);
   return TRUE;
  }
0

z THREAD_PRIORITY_BELOW_NORMAL nie działa, natomiast działa z THREAD_PRIORITY_NORMAL i teraz bez spania tnie strasznie gr ę.

0
while(GetTickCount()<stop) { if(GetPixel(hdc,SCREEN_X,SCREEN_Y) == red) result=true; Sleep(1); }
0

dałem sleepa jeszcze, po włączeniu (alt + s) gra dalej tnie, co prawda szybciej strzela ale tnie.
Nie jest możliwe zrobienie zdarzenia/callbacka coś jak OnPixelChange? Trzeba dawać te wszystkie pętle? Bez sleepów to raczej nie będzie szybko chodzić. Efekt nie jest jeszcze za dobry.

 
Sleep(1);
		if((shotbot&&PixelCheck(hdc))||isdown)
0

może użyć wskaźników i funkcji inline?

0

Nie ma gdzie. Jedynie co możesz zrobić to zwiększyć oba sleep'y do 2 czy nawet 5.
Sprawdź jakimś WinSpy jak wygląda docelowa aplikacja. Jeżeli ma normalne windowsówe okno to rysowania to możesz za pomocą:
SetWindowLong - http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx
podmienić mu GWL_HINSTANCE.
Oczywiście zapamiętując poprzednią wartość przez
GetWindowLong - http://msdn.microsoft.com/en-us/library/windows/desktop/ms633584%28v=vs.85%29.aspx
bo prawie zawsze trzeba ją wywołać.

I reagować na WM_PAINT oraz na WM_KEYDOWN oraz na WM_TIMER.
Strzelanie zrealizować przez SetTimer
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx

We wszystkich przypadkach oprócz WM_TIMER z twoim ID wywołujesz starą wersję HInstance.

0

można też użyć YieldProcessor, SwitchToThread tylko że trzeba by było mieć procesor odpowiedni :x, szkoda zachodu. Czytałem też, że jest inny szybszy sposób pozyskania koloru piksela z HBITMAPy, popróbuje :p.

0

Sprawdzałem Spy++ i jest to normalne windowsowe okno tylko na full screen.
Co mi da ustawienie zmienienie atrybutu GWL_HINSTANCE tego okna?

0

Podpinasz się pod okno i wszystkie komunikaty idą do twojego kodu. Już tłumaczyłem to w tamtym wątku, czy nie możesz otworzyć go i poczytać?

0

nie rozumiem, gdzie mam dać SetWindowLong i GetWindowLong i w czym mi to pomoże jak to pobiera tylko uchwyt do procesu aplikacji i ustawia nowy.

0

jak ma to zwiększyć szybkość, i

GWL_HINSTANCE
Sets a new application instance handle.

skąd mam wiedzieć jaką liczbę tu wpisać

0

temat jest dość często wałkowany, dziwne, że Trzynasty Smok tego nie zauważył. GetPixel jest niemożebnie powolne. użyj scanline (np. http://www.richelbilderbeek.nl/CppGetPixel.htm).
poza tym sleep ma rozdzielczość około 18ms (tak przynajmniej było w systemach NT i starszych) i zastanawianie się nad wyborem sleep(1) czy sleep(5) jest bezcelowe, bo jedno i drugie trwa tyle samo. jednak użycie sleep z jakąś małą wartością jest dobrym pomysłem, po spowoduje znacznie zmniejszenie obciążenia procesora.

0

to ja już się pogubiłem w końcu użycie bitmap jest lepsze nawet dla jednego piksela czy nie... jeden pisze tak drugi tak.

0
noswear napisał(a):

to ja już się pogubiłem w końcu użycie bitmap jest lepsze nawet dla jednego piksela czy nie... jeden pisze tak drugi tak.

to weź i sprawdź. :D

0

dokonałem tego wczoraj, efekt jest już prawie taki jaki oczekiwałem, stworzyłem funkcję GetColor która jest 10x szybsza od funkcji GetPixel, może komuś się przyda, aczkolwiek przydało by się to jeszcze przyśpieszyć myślę że GetAsyncKeyState w pętli while spowalnia działanie, dałoby się dać ten GetAsyncKeyState w osobnym wątku żeby można było włączyć?

 
#include <windows.h>
#include <gdiplus.h>
 
const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);
 
const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);
const COLORREF red=RGB(255, 0, 0);
const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
const int State[]={MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP};

COLORREF GetColor(POINT pt) {
    HDC hDc = GetDC(0);
    HDC hDcmem = CreateCompatibleDC(0);
    HBITMAP hBmp = CreateCompatibleBitmap(hDc, 1, 1);
    SelectObject(hDcmem, hBmp);
    BitBlt(hDcmem, 0, 0, 1, 1, hDc, pt.x, pt.y, SRCCOPY);
    LPBITMAPINFO lpbmi = new BITMAPINFO;
    lpbmi->bmiHeader.biBitCount = 24;
    lpbmi->bmiHeader.biCompression = BI_RGB;
    lpbmi->bmiHeader.biPlanes = 1;
    lpbmi->bmiHeader.biHeight = 1;
    lpbmi->bmiHeader.biWidth = 1;
    lpbmi->bmiHeader.biSize = sizeof(BITMAPINFO);
    BYTE lpvBits[4];
    GetDIBits(hDcmem, hBmp, 0, 1, lpvBits, lpbmi, DIB_RGB_COLORS);
    COLORREF currColor = RGB(lpvBits[2], lpvBits[1], lpvBits[0]);
    delete lpbmi;
    DeleteObject(hBmp);
    DeleteDC(hDcmem);
    ReleaseDC(0, hDc);
    return currColor;
}
 
DWORD WINAPI ThreadFunction(PVOID pvParam)
{
	bool shotbot=false,isdown=false;
	INPUT ip;
	ip.type=INPUT_MOUSE;
	ip.mi.dx = 0;
	ip.mi.dy = 0;
	ip.mi.dwExtraInfo = 0;
	POINT coord;
	coord.x = SCREEN_X;
	coord.y = SCREEN_Y;
	while(true)
	{
		int R = GetRValue(GetColor(coord)); 
		int G = GetGValue(GetColor(coord)); 
		int B = GetBValue(GetColor(coord)); 
		
		Sleep(18);
		if((shotbot && R == 255 && G == 0 && B == 0 ) || isdown)
        {
			ip.mi.dwFlags = State[isdown];
			SendInput(1, &ip, sizeof(INPUT));
			isdown = !isdown;
		}
		
		Sleep(18);
		if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
		{
			shotbot=!shotbot;
			PlaySound((LPCSTR)Sound[shotbot],NULL,SND_ALIAS_ID);
		}
	}
	return 0;
}
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) 
{
	if(fdwReason==DLL_PROCESS_ATTACH) SetThreadPriority(CreateThread(0,0,ThreadFunction,0,0,NULL),THREAD_PRIORITY_NORMAL);
	return TRUE;
}
0
noswear napisał(a):

... stworzyłem funkcję GetColor która jest 10x szybsza od funkcji GetPixel ...
Waść chrzani!

#include <pthread.h>
#include <windows.h>
#include <iostream>
#include <iomanip>
using namespace std;

struct ThreadData
  {
   void *(*execute)(void *ptr);
   pthread_t handle;
   unsigned counter;
   COLORREF color;
  };

void *run1(void *ptr)
  {
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
   ThreadData &td=*((ThreadData*)ptr);
   HDC hDc=GetDC(0);
   while(true)
     {
      td.color=GetPixel(hDc,2,2);
      ++td.counter;
     }      
   ReleaseDC(0,hDc);
   return ptr;
  }

void *run2(void *ptr)
  {
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
   ThreadData &td=*((ThreadData*)ptr);
   while(true)
     {
      HDC hDc=GetDC(0);
      HDC hDcmem = CreateCompatibleDC(0);
      HBITMAP hBmp = CreateCompatibleBitmap(hDc, 1, 1);
      SelectObject(hDcmem, hBmp);
      BITMAPINFO bmi;
      bmi.bmiHeader.biBitCount = 24;
      bmi.bmiHeader.biCompression = BI_RGB;
      bmi.bmiHeader.biPlanes = 1;
      bmi.bmiHeader.biHeight = 1;
      bmi.bmiHeader.biWidth = 1;
      bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
      BYTE lpvBits[4];
      BitBlt(hDcmem, 0, 0, 1, 1, hDc, 2, 2, SRCCOPY);
      GetDIBits(hDcmem, hBmp, 0, 1, lpvBits, &bmi, DIB_RGB_COLORS);
      td.color=RGB(lpvBits[2], lpvBits[1], lpvBits[0]);
      DeleteObject(hBmp);
      DeleteDC(hDcmem);
      ReleaseDC(0,hDc);
      ++td.counter;
     }      
   return ptr;
  }

void *run3(void *ptr)
  {
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
   ThreadData &td=*((ThreadData*)ptr);
   HDC hDc=GetDC(0);
   HDC hDcmem = CreateCompatibleDC(0);
   HBITMAP hBmp = CreateCompatibleBitmap(hDc, 1, 1);
   SelectObject(hDcmem, hBmp);
   BITMAPINFO bmi;
   bmi.bmiHeader.biBitCount = 24;
   bmi.bmiHeader.biCompression = BI_RGB;
   bmi.bmiHeader.biPlanes = 1;
   bmi.bmiHeader.biHeight = 1;
   bmi.bmiHeader.biWidth = 1;
   bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
   BYTE lpvBits[4];
   while(true)
     {
      BitBlt(hDcmem, 0, 0, 1, 1, hDc, 2, 2, SRCCOPY);
      GetDIBits(hDcmem, hBmp, 0, 1, lpvBits, &bmi, DIB_RGB_COLORS);
      td.color=RGB(lpvBits[2], lpvBits[1], lpvBits[0]);
      ++td.counter;
     }      
   DeleteObject(hBmp);
   DeleteDC(hDcmem);
   ReleaseDC(0,hDc);
   return ptr;
  }

ThreadData Tb[]=
  {
   {run1},
   {run2},
   {run3},
  };
const unsigned TbSize=sizeof(Tb)/sizeof(*Tb);

int main()
  {
   for(unsigned i=0;i<TbSize;++i)
     {
      if(pthread_create(&Tb[i].handle,0,Tb[i].execute,Tb+i))
        {
         cout<<"thread "<<(i+1)<<" error"<<endl;
        }
     }
   for(unsigned t=0;t<60;++t)
     {
      for(unsigned i=0;i<TbSize;++i)
        {
         cout<<'T'<<(i+1)<<'='<<setw(6)<<Tb[i].counter<<" ("<<hex<<setw(8)<<setfill('0')<<Tb[i].color<<dec<<")\t";
        }
      cout<<endl;
      Sleep(1000);
     }     
   for(unsigned i=0;i<TbSize;++i)
     {
      pthread_cancel(Tb[i].handle);
      pthread_join(Tb[i].handle,0);
     }
   cout<<"Done:";
   cin.sync();
   cin.get();
   return 0;
  }

Trzy wątki:

  • w jednym pobiera się kolor zwykłym GetPixel,
  • w drugim twój "10x razy szybszy sposób" tylko że bez zbędnego new/delete, czyli jeszcze trochę szybszy
  • w trzecim moja zoptymalizowana wersja twojego sposoby, czyli jeszcze nieco szybszy.
    W trzech kolumnach (co sekunda) pokazywana jest ilość wykonań każdego z tych trzech wątków.
    W nawiasach szesnastkowy kod ostatnio odczytanego koloru.
    Kolor jest odczytywany ze współrzędnych (2,2)
    Wyniki mówią same za siebie, nie da się odczytać z ekranu w szybszy sposób (dopóki chodzi o jeden piksel) koniec kropka.
    Gdyby chodziło o przynajmniej dwa pikseli to sposób 2 i 3 byli by lepsze.
0

nie mam biblioteki pthread, nawet nie ma jej w bibliotekach od visual studio 2008

0

a nie dobra juz znalazlem http://sourceware.org/pthreads-win32/

0

jeszcze jedno pytanie w twojej funkcji void *run3(void *ptr) jest to wskaźnik do ...? I zwraca wskaźnik... jak więc mam sprawdzić kolor?

0

twoja funkcja nie działa ;x
ciągle wyświetla 52, 48, 64

 
#include <pthread.h>
#include <windows.h>
#include <iostream>
#include <iomanip>
using namespace std;

#define SCREENX	(1024/2)
#define SCREENY (768/2)
 
struct ThreadData
  {
   void *(*execute)(void *ptr);
   pthread_t handle;
   unsigned counter;
   COLORREF color;
  };
 
void *run3(void *ptr)
  {
   pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
   ThreadData &td=*((ThreadData*)ptr);
   HDC hDc=GetDC(0);
   HDC hDcmem = CreateCompatibleDC(0);
   HBITMAP hBmp = CreateCompatibleBitmap(hDc, 1, 1);
   SelectObject(hDcmem, hBmp);
   BITMAPINFO bmi;
   bmi.bmiHeader.biBitCount = 24;
   bmi.bmiHeader.biCompression = BI_RGB;
   bmi.bmiHeader.biPlanes = 1;
   bmi.bmiHeader.biHeight = 1;
   bmi.bmiHeader.biWidth = 1;
   bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
   BYTE lpvBits[4];
   //while(true)
   //  {
      BitBlt(hDcmem, 0, 0, 1, 1, hDc, SCREENX, SCREENY, SRCCOPY);
      GetDIBits(hDcmem, hBmp, 0, 1, lpvBits, &bmi, DIB_RGB_COLORS);
      td.color=RGB(lpvBits[2], lpvBits[1], lpvBits[0]);
      ++td.counter;
   //  }      
   DeleteObject(hBmp);
   DeleteDC(hDcmem);
   ReleaseDC(0,hDc);
   return ptr;
  }
 
 
int main()
  {
	//POINT coord;
	//coord.x = (1024/2);
	//coord.y = (768/2);
	int R, G, B;

    ThreadData run3;
   while(1)
   {
		R = GetRValue(run3.color);
		G = GetGValue(run3.color);
		B = GetBValue(run3.color);
		cout << R << ", " << G  << ", " << B << endl;
   }
   return 0;
  }
0

Po zepsuciu przez ciebie, owszem nie działa, wróć do oryginalnej wersji.

0

jak ja usunąłem tylko, dlaczego nie dziala

ThreadData run3;
R = GetRValue(run3.color);
G = GetGValue(run3.color);
B = GetBValue(run3.color);

 
ThreadData Tb[]=
  {
   {run1},
   {run2},
   {run3},
  };
const unsigned TbSize=sizeof(Tb)/sizeof(*Tb);
 
int main()
  {
   for(unsigned i=0;i<TbSize;++i)
     {
      if(pthread_create(&Tb[i].handle,0,Tb[i].execute,Tb+i))
        {
         cout<<"thread "<<(i+1)<<" error"<<endl;
        }
     }
   for(unsigned t=0;t<60;++t)
     {
      for(unsigned i=0;i<TbSize;++i)
        {
         cout<<'T'<<(i+1)<<'='<<setw(6)<<Tb[i].counter<<" ("<<hex<<setw(8)<<setfill('0')<<Tb[i].color<<dec<<")\t";
        }
      cout<<endl;
      Sleep(1000);
     }     
   for(unsigned i=0;i<TbSize;++i)
     {
      pthread_cancel(Tb[i].handle);
      pthread_join(Tb[i].handle,0);
     }
   cout<<"Done:";
   cin.sync();
   cin.get();
   return 0;
  }
0

Nie działa ponieważ po zepsuciu funkcja run3 nigdzie i nigdy nie zostaje uruchomiona.

1 użytkowników online, w tym zalogowanych: 0, gości: 1