2013-04-28 3 views
1

Я поставил процедуру для захвата скриншотов в памятьDC в таймере Winapi. Я могу успешно разбить указанное изображение в окно, но как бы я это делал многократно, скажем каждые 1-2 секунды?Правильный способ многократного нажатия на окно DC?

Код currenct, который у меня есть, может разбить его на 1-2 секунды за раз, но он не будет близок к окну правильно (изображение неуместно).

Как мне это сделать?

#include <windows.h> 
#include <iostream> 

#include <windowsx.h> 

    #define TIMERID 3232 
/* Declare Windows procedure */ 
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 

RECT rectangle{ 
    50, 
    50, 
    690, 
    409 
}; 

/* Make the class name into a global variable */ 
    char szClassName[ ] = "CodeBlocksWindowsApp"; 


HDC handle_WindowDC; 
    HDC handle_MemoryDC; 
    HDC handle_ScreenDC; 
    //BITMAP bitmap; 
    HBITMAP handle_Bitmap; 
    int x, y; 
    HWND hand; 

int WINAPI WinMain (HINSTANCE hThisInstance, 
       HINSTANCE hPrevInstance, 
       LPSTR lpszArgument, 
       int nCmdShow) 
{ 
HWND hwnd;    /* This is the handle for our window */ 
MSG messages;   /* Here messages to the application are saved */ 
WNDCLASSEX wincl;  /* Data structure for the windowclass */ 

/* The Window structure */ 
wincl.hInstance = hThisInstance; 
wincl.lpszClassName = szClassName; 
wincl.lpfnWndProc = WindowProcedure;  /* This function is called by windows */ 
wincl.style = CS_DBLCLKS;     /* Catch double-clicks */ 
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;     /* No menu */ 
wincl.cbClsExtra = 0;      /* No extra bytes after the window class */ 
wincl.cbWndExtra = 0;      /* structure or the window instance */ 
/* Use Windows's default colour as the background of the window */ 
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; 

/* Register the window class, and if it fails quit the program */ 
if (!RegisterClassEx (&wincl)) 
    return 0; 

/* The class is registered, let's create the program*/ 
hwnd = CreateWindowEx (
     0,     /* Extended possibilites for variation */ 
     szClassName,   /* Classname */ 
     "Code::Blocks Template Windows App",  /* Title Text */ 
     WS_OVERLAPPEDWINDOW, /* default window */ 
     CW_USEDEFAULT,  /* Windows decides the position */ 
     CW_USEDEFAULT,  /* where the window ends up on the screen */ 
     1600,     /* The programs width */ 
     900,     /* and height in pixels */ 
     HWND_DESKTOP,  /* The window is a child-window to desktop */ 
     NULL,    /* No menu */ 
     hThisInstance,  /* Program Instance handler */ 
     NULL     /* No Window Creation data */ 
     ); 

/* Make the window visible on the screen */ 
ShowWindow (hwnd, nCmdShow); 


     SetTimer(hwnd, TIMERID, 1000, (TIMERPROC)NULL); 
/* Run the message loop. It will run until GetMessage() returns 0 */ 
while (GetMessage (&messages, NULL, 0, 0)) 
{ 
    /* Translate virtual-key messages into character messages */ 
    TranslateMessage(&messages); 
    /* Send message to WindowProcedure */ 
    DispatchMessage(&messages); 
} 

/* The program return-value is 0 - The value that PostQuitMessage() gave */ 
return messages.wParam; 
} 


/* This function is called by the Windows function DispatchMessage() */ 

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
switch (message)     /* handle the messages */ 
{ 

    case WM_CREATE:{ 

    } 

     //hand = CreateWindowEx(NULL, "STATIC", "", SS_BITMAP|WS_VISIBLE, 500,300, 640 ,360 , hwnd, HMENU(IDCSTATIC_BITMAP), GetModuleHandle(NULL), NULL);  } 
    break; 
    case WM_TIMER: 
     switch(LOWORD(wParam)){ 

      case TIMERID:{ 

       //MessageBox(NULL,NULL,NULL,NULL); 
        handle_ScreenDC = GetDC(NULL); 
        handle_MemoryDC = CreateCompatibleDC(handle_ScreenDC); 



        x = GetDeviceCaps(handle_ScreenDC, HORZRES); 
        y = GetDeviceCaps(handle_ScreenDC, VERTRES); 

       handle_Bitmap = CreateCompatibleBitmap(handle_ScreenDC, 640, 360); 

       SelectObject(handle_MemoryDC, handle_Bitmap); 
       StretchBlt(handle_MemoryDC, 0, 0, 640, 360, handle_ScreenDC, 0, 0, x, y, SRCCOPY); 
       UpdateWindow(hwnd); 
       BitBlt(handle_WindowDC, 50, 50, x, y, handle_MemoryDC, 0, 0, SRCCOPY); 


      } 
      break; 
    }break; 

    case WM_PAINT:{ 

     PAINTSTRUCT paintstruct; 
     handle_WindowDC = BeginPaint(hwnd, &paintstruct); 
     //BitBlt(handle_WindowDC, 50, 50, x, y, handle_MemoryDC, 0, 0, SRCCOPY); 
     EndPaint(hwnd, &paintstruct); 

    } 
    break; 
    case WM_DESTROY: 
     PostQuitMessage (0);  /* send a WM_QUIT to the message queue */ 
     break; 

    case WM_LBUTTONDOWN:{ 

     std::cout <<"\nx: " << GET_X_LPARAM(lParam) << "\ny: " << GET_Y_LPARAM(lParam); 
     tagPOINT point; 
     point.x = GET_X_LPARAM(lParam); 
     point.y = GET_Y_LPARAM(lParam); 

     if(PtInRect(&rectangle, point)){ 

      int x, y; 
      x = 2.5*(point.x - 50); 
      y = 2.5*(point.y - 50); 


      //I juse use setcursorpos for now, but when connecting to server.exe i will do a send() and send x,y coordinates along with 
      //a click or rightclick, or whatever. 
      SetCursorPos(x, y); 

     } 

    } 
    break; 
    default:      /* for messages that we don't deal with */ 
     return DefWindowProc (hwnd, message, wParam, lParam); 
} 

return 0; 
} 

ответ

1

Вы используете DC от WM_PAINT окрасить в WM_TIMER коды, что DC был бы освобожден во время EndPaint() - MSDN Docs говорит «EndPaint освобождает контекст устройства отображения, которые BeginPaint найденного»

. Также убедитесь, что вы отпускаете свои контроллеры домена с ReleaseDC(handle_ScreenDC) и DeleteObject(handle_MemoryDC).

код для WM_TIMER должен просто аннулирует прямоугольник, сделайте все картина во время WM_PAINT. Посмотреть this article для примера кода.

+0

спасибо. Я понял, что перед тем, как вы ответили, я должен был аннулировать право. Но я следил за советом о том, чтобы делать всю картину в WM_PAINT и называть ее таймером. Я использовал RedrawWindow – Kelvin