2012-05-09 7 views
8

私はWindowsアプリの自動ライカーを作ろうとしています。それはうまくいくが、それは非常に遅い! 私は現在、呼び出されるたびに配列をリロードするメソッド "getPixel"を使用しています。ここでピクセルの色を最も速く取得できますか?

は私の現在のコードです:

hdc = GetDC(HWND_DESKTOP); 
bx = GetSystemMetrics(SM_CXSCREEN); 
by = GetSystemMetrics(SM_CYSCREEN); 
start_bx = (bx/2) - (MAX_WIDTH/2); 
start_by = (by/2) - (MAX_HEIGHT/2); 
end_bx = (bx/2) + (MAX_WIDTH/2); 
end_by = (by/2) + (MAX_HEIGHT/2); 

for(y=start_by; y<end_by; y+=10) 
{ 
    for(x=start_bx; x<end_bx; x+=10) 
    { 
     pixel = GetPixel(*hdc, x, y); 
     if(pixel==RGB(255, 0, 0)) 
     { 
      SetCursorPos(x,y); 
      mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
      Sleep(50); 
      mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 
      Sleep(25); 
     } 
    } 
} 

だから、基本的には、それだけで画面の画素の範囲をスキャンし、それが赤のボタンを検出した場合、マウスイベントを開始します。

私はbitbltなど、ピクセルの色を取得する他の方法があることを知っています。しかし、私はいくつかの研究をしましたが、色配列をスキャンするためには、どうやってやるのか分かりません。ボタンをキャッチするために画面を非常に高速にスキャンするものが必要です。

私を助けてもらえますか?

ありがとうございました。

+0

あなたのコードが呼び出されたら?アイドルタイムで?ユーザーがマウスを動かすと?たとえば、FindWindow()を使用して、赤いボタンを検出するさまざまな方法があります。 –

+0

Btw、私のコードは無限ループです。しかし、私はカラーキャッチャーを使いたいのに対し、オフセットキャッチャーを使いたい。コードを開始すると、ループに入り、赤いボタンを確認するだけです。 – Manitoba

+2

このコードが無限ループの場合、問題は 'GetPixel'ではありません。あなたのアプリは他のアプリにCPU時間を持たせないという事実です。 – tenfour

答えて

11

私は明らかに速くgetPixelと1よりも完璧な方法を見つけました:

HDC hdc, hdcTemp; 
RECT rect; 
BYTE* bitPointer; 
int x, y; 
int red, green, blue, alpha; 

while(true) 
{ 
    hdc = GetDC(HWND_DESKTOP); 
    GetWindowRect(hWND_Desktop, &rect); 
      int MAX_WIDTH = rect.right; 
     int MAX_HEIGHT = rect.bottom; 

    hdcTemp = CreateCompatibleDC(hdc); 
    BITMAPINFO bitmap; 
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader); 
    bitmap.bmiHeader.biWidth = MAX_WIDTH; 
    bitmap.bmiHeader.biHeight = MAX_HEIGHT; 
    bitmap.bmiHeader.biPlanes = 1; 
    bitmap.bmiHeader.biBitCount = 32; 
    bitmap.bmiHeader.biCompression = BI_RGB; 
    bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT; 
    bitmap.bmiHeader.biClrUsed = 0; 
    bitmap.bmiHeader.biClrImportant = 0; 
    HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL); 
    SelectObject(hdcTemp, hBitmap2); 
    BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY); 

    for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4) 
    { 
     red = (int)bitPointer[i]; 
     green = (int)bitPointer[i+1]; 
     blue = (int)bitPointer[i+2]; 
     alpha = (int)bitPointer[i+3]; 

     x = i/(4 * MAX_HEIGHT); 
     y = i/(4 * MAX_WIDTH); 

     if (red == 255 && green == 0 && blue == 0) 
     { 
      SetCursorPos(x,y); 
      mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
      Sleep(50); 
      mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 
      Sleep(25); 
     } 
    } 
} 

私は、これは他の誰かを助けることができる願っています。

+0

これはすべてのピクセルをチェックしていますか?私はあなたのxとyの割り当てを理解していません。 – user1397417

+0

'X'と' Y'はレビュー中のピクセルの位置です。このピクセルでアクションを実行しない限り、それらは役に立たない。その色が赤色であれば、このピクセルにマウスを合わせ、左クリックします。 – Manitoba

+1

いい仕事ですが、私は理解できないことがあります。なぜピクセルのアルファコンポーネントに割り当てられたバイトを考慮に入れますか?スクリーンショットであるため、alphaの値は常に255になるでしょうか?ですから、biBitCountパラメータの値を24にする方が良いでしょうか? – Delgan

1

単純な答えは、これがあなたが主張している方法であれば、最適化することはあまりありません。コメントの中で他の人が指摘しているように、おそらくクリックする領域を見つけるために別の方法を使うべきです。たとえば、FindWindowを使って見てみましょう。

メソッドを変更したくない場合は、完全な画面スキャンが完了するたびにスレッドを少しスリープ状態にしてください。

+0

こんにちは、Findwindowについてもっと教えていただけますか?私はそれを次のように使用しています: 'mhwnd = FindWindow(NULL、" Application Window Name "); hdc = GetDC(mhwnd); '次は何ですか? – Manitoba

+1

クリックしたいボタンには、おそらく独自のウィンドウハンドルがあります。 Spy ++などのウィンドウインスペクタプログラムを使用して、クリックしたいもののウィンドウハンドルを見つけてみてください。その特定のアイテムを賢明なコードで見つけることができます。 – korona

関連する問題