Từ 1 tới 2 trên tổng số 2 kết quả

Đề tài: Chụp màn hình máy tính sử dụng Visual C++?

  1. #1
    Ngày gia nhập
    07 2006
    Nơi ở
    Hà nội
    Bài viết
    204

    Mặc định Chụp màn hình máy tính sử dụng Visual C++?

    Em muốn chụp màn hình vào 1 mảng. Nhưng nếu dùng GetPixel lấy từng điểm ảnh thì chậm quá, mất gần 30s. Có cách nào lấy nhanh hơn ko ??
    Life:\> dir

  2. #2
    Ngày gia nhập
    11 2006
    Bài viết
    75

    Visual C++ Code:
    1. //Author: I love C++
    2. //Language: C++
    3. //Enviroment: Dev-C++ 5.0 (MingW32 Compiler)
    4. //Ref: MSDN
    5.  
    6. #define UNICODE
    7. #include <windows.h>
    8.  
    9. /*  Declare Windows procedure  */
    10. void errhandler (LPCTSTR, HWND);
    11. void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC);
    12. PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp);
    13. LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    14.  
    15. /*  Make the class name into a global variable  */
    16. TCHAR szClassName[ ] = TEXT("WindowsApp");
    17.  
    18. int WINAPI WinMain (HINSTANCE hThisInstance,
    19.                     HINSTANCE hPrevInstance,
    20.                     LPSTR lpszArgument,
    21.                     int nFunsterStil)
    22.  
    23. {
    24.     HWND hwnd;               /* This is the handle for our window */
    25.     MSG messages;            /* Here messages to the application are saved */
    26.     WNDCLASSEX wincl;        /* Data structure for the windowclass */
    27.  
    28.     /* The Window structure */
    29.     wincl.hInstance = hThisInstance;
    30.     wincl.lpszClassName = szClassName;
    31.     wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    32.     wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    33.     wincl.cbSize = sizeof (WNDCLASSEX);
    34.  
    35.     /* Use default icon and mouse-pointer */
    36.     wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    37.     wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    38.     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    39.     wincl.lpszMenuName = NULL;                 /* No menu */
    40.     wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    41.     wincl.cbWndExtra = 0;                      /* structure or the window instance */
    42.     /* Use Windows's default color as the background of the window */
    43.     wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    44.  
    45.     /* Register the window class, and if it fails quit the program */
    46.     if (!RegisterClassEx (&wincl))
    47.         return 0;
    48.  
    49.     /* The class is registered, let's create the program*/
    50.     hwnd = CreateWindowEx (
    51.            0,                   /* Extended possibilites for variation */
    52.            szClassName,         /* Classname */
    53.            TEXT("Windows App"),       /* Title Text */
    54.            WS_OVERLAPPEDWINDOW, /* default window */
    55.            CW_USEDEFAULT,       /* Windows decides the position */
    56.            CW_USEDEFAULT,       /* where the window ends up on the screen */
    57.            544,                 /* The programs width */
    58.            375,                 /* and height in pixels */
    59.            HWND_DESKTOP,        /* The window is a child-window to desktop */
    60.            NULL,                /* No menu */
    61.            hThisInstance,       /* Program Instance handler */
    62.            NULL                 /* No Window Creation data */
    63.            );
    64.  
    65.     /* Make the window visible on the screen */
    66.     ShowWindow (hwnd, nFunsterStil);
    67.  
    68.     /* Run the message loop. It will run until GetMessage() returns 0 */
    69.     while (GetMessage (&messages, NULL, 0, 0))
    70.     {
    71.         /* Translate virtual-key messages into character messages */
    72.         TranslateMessage(&messages);
    73.         /* Send message to WindowProcedure */
    74.         DispatchMessage(&messages);
    75.     }
    76.  
    77.     /* The program return-value is 0 - The value that PostQuitMessage() gave */
    78.     return messages.wParam;
    79. }
    80.  
    81.  
    82. /*  This function is called by the Windows function DispatchMessage()  */
    83.  
    84. LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    85. {
    86.    
    87.     switch (message)                  /* handle the messages */
    88.     {
    89.         case WM_LBUTTONDOWN:
    90.              
    91.             HDC hdcScreen;
    92.             HDC hdcMemory;
    93.             HDC hdcMainWindowClient;
    94.             HBITMAP hbmMemory;
    95.             int nScreenWidth;
    96.             int nScreenHeight;
    97.             HWND hwndMainWindow;
    98.                    
    99.             hwndMainWindow = hwnd;
    100.             hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
    101.             nScreenWidth = GetDeviceCaps (hdcScreen, HORZRES);
    102.             nScreenHeight = GetDeviceCaps (hdcScreen, VERTRES);
    103.            
    104.             hdcMemory = CreateCompatibleDC(hdcScreen);
    105.             hbmMemory = CreateCompatibleBitmap (hdcScreen, nScreenWidth, nScreenHeight);
    106.             SelectObject (hdcMemory, hbmMemory);
    107.            
    108.             ShowWindow (hwnd, SW_HIDE);
    109.             Sleep (1000);
    110.             BitBlt (hdcMemory, 0, 0, nScreenWidth, nScreenHeight, hdcScreen, 0, 0, SRCCOPY);
    111.             Sleep (1000);
    112.             ShowWindow (hwnd, SW_SHOW);
    113.            
    114.             hdcMainWindowClient = GetDC (hwndMainWindow);
    115.             BitBlt (hdcMainWindowClient, 0, 0, nScreenWidth, nScreenHeight, hdcMemory, 0, 0, SRCCOPY);
    116.             UpdateWindow (hwnd);
    117.            
    118.             PBITMAPINFO pbi;
    119.             pbi = CreateBitmapInfoStruct (hwndMainWindow, hbmMemory);
    120.             CreateBMPFile (hwndMainWindow, TEXT("C:\\screen.bmp"), pbi, hbmMemory, hdcMemory);
    121.             MessageBox (hwndMainWindow, TEXT("File was created."), TEXT ("Success"), MB_OK);
    122.                        
    123.             ReleaseDC (hwndMainWindow, hdcMainWindowClient);
    124.             DeleteObject ((HGDIOBJ) hbmMemory);
    125.             DeleteDC (hdcMemory);
    126.             DeleteDC (hdcScreen);
    127.            
    128.             break;
    129.              
    130.         case WM_DESTROY:
    131.             PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
    132.             break;
    133.         default:                      /* for messages that we don't deal with */
    134.             return DefWindowProc (hwnd, message, wParam, lParam);
    135.     }
    136.  
    137.     return 0;
    138. }
    139.  
    140. PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
    141. {
    142.     BITMAP bmp;
    143.     PBITMAPINFO pbmi;
    144.     WORD    cClrBits;
    145.  
    146.     // Retrieve the bitmap color format, width, and height.
    147.     if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
    148.         errhandler(TEXT("GetObject"), hwnd);
    149.  
    150.     // Convert the color format to a count of bits.
    151.     cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
    152.     if (cClrBits == 1)
    153.         cClrBits = 1;
    154.     else if (cClrBits <= 4)
    155.         cClrBits = 4;
    156.     else if (cClrBits <= 8)
    157.         cClrBits = 8;
    158.     else if (cClrBits <= 16)
    159.         cClrBits = 16;
    160.     else if (cClrBits <= 24)
    161.         cClrBits = 24;
    162.     else cClrBits = 32;
    163.  
    164.     // Allocate memory for the BITMAPINFO structure. (This structure
    165.     // contains a BITMAPINFOHEADER structure and an array of RGBQUAD
    166.     // data structures.)
    167.  
    168.      if (cClrBits != 24)
    169.          pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
    170.                     sizeof(BITMAPINFOHEADER) +
    171.                     sizeof(RGBQUAD) * (1<< cClrBits));
    172.  
    173.      // There is no RGBQUAD array for the 24-bit-per-pixel format.
    174.  
    175.      else
    176.          pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
    177.                     sizeof(BITMAPINFOHEADER));
    178.  
    179.     // Initialize the fields in the BITMAPINFO structure.
    180.  
    181.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    182.     pbmi->bmiHeader.biWidth = bmp.bmWidth;
    183.     pbmi->bmiHeader.biHeight = bmp.bmHeight;
    184.     pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
    185.     pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
    186.     if (cClrBits < 24)
    187.         pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
    188.  
    189.     // If the bitmap is not compressed, set the BI_RGB flag.
    190.     pbmi->bmiHeader.biCompression = BI_RGB;
    191.  
    192.     // Compute the number of bytes in the array of color
    193.     // indices and store the result in biSizeImage.
    194.     // For Windows NT, the width must be DWORD aligned unless
    195.     // the bitmap is RLE compressed. This example shows this.
    196.     // For Windows 95/98/Me, the width must be WORD aligned unless the
    197.     // bitmap is RLE compressed.
    198.     pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
    199.                                   * pbmi->bmiHeader.biHeight;
    200.     // Set biClrImportant to 0, indicating that all of the
    201.     // device colors are important.
    202.      pbmi->bmiHeader.biClrImportant = 0;
    203.      return pbmi;
    204.  }
    205. void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,
    206.                   HBITMAP hBMP, HDC hDC)
    207.  {
    208.      HANDLE hf;                 // file handle
    209.     BITMAPFILEHEADER hdr;       // bitmap file-header
    210.     PBITMAPINFOHEADER pbih;     // bitmap info-header
    211.     LPBYTE lpBits;              // memory pointer
    212.     DWORD dwTotal;              // total count of bytes
    213.     DWORD cb;                   // incremental count of bytes
    214.     BYTE *hp;                   // byte pointer
    215.     DWORD dwTmp;
    216.  
    217.     pbih = (PBITMAPINFOHEADER) pbi;
    218.     lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
    219.  
    220.     if (!lpBits)
    221.          errhandler(TEXT("GlobalAlloc"), hwnd);
    222.  
    223.     // Retrieve the color table (RGBQUAD array) and the bits
    224.     // (array of palette indices) from the DIB.
    225.     if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
    226.         DIB_RGB_COLORS))
    227.     {
    228.         errhandler(TEXT("GetDIBits"), hwnd);
    229.     }
    230.  
    231.     // Create the .BMP file.
    232.     hf = CreateFile(pszFile,
    233.                    GENERIC_READ | GENERIC_WRITE,
    234.                    (DWORD) 0,
    235.                     NULL,
    236.                    CREATE_ALWAYS,
    237.                    FILE_ATTRIBUTE_NORMAL,
    238.                    (HANDLE) NULL);
    239.     if (hf == INVALID_HANDLE_VALUE)
    240.         errhandler(TEXT("CreateFile"), hwnd);
    241.     hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M"
    242.     // Compute the size of the entire file.
    243.     hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
    244.                  pbih->biSize + pbih->biClrUsed
    245.                  * sizeof(RGBQUAD) + pbih->biSizeImage);
    246.     hdr.bfReserved1 = 0;
    247.     hdr.bfReserved2 = 0;
    248.  
    249.     // Compute the offset to the array of color indices.
    250.     hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
    251.                     pbih->biSize + pbih->biClrUsed
    252.                     * sizeof (RGBQUAD);
    253.  
    254.     // Copy the BITMAPFILEHEADER into the .BMP file.
    255.     if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp,  NULL))
    256.     {
    257.        errhandler(TEXT("WriteFile"), hwnd);
    258.     }
    259.  
    260.     // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
    261.     if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
    262.                   + pbih->biClrUsed * sizeof (RGBQUAD),
    263.                   (LPDWORD) &dwTmp, ( NULL)))
    264.         errhandler(TEXT("WriteFile"), hwnd);
    265.  
    266.     // Copy the array of color indices into the .BMP file.
    267.     dwTotal = cb = pbih->biSizeImage;
    268.     hp = lpBits;
    269.     if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
    270.            errhandler(TEXT("WriteFile"), hwnd);
    271.  
    272.     // Close the .BMP file.
    273.      if (!CloseHandle(hf))
    274.            errhandler(TEXT("CloseHandle"), hwnd);
    275.  
    276.     // Free memory.
    277.     GlobalFree((HGLOBAL)lpBits);
    278. }
    279.  
    280. void errhandler (LPCTSTR sz, HWND hwnd)
    281. {
    282.     MessageBox (hwnd, sz, TEXT("Error"), MB_ICONERROR);
    283.     PostQuitMessage(0);
    284. }

    Chìa khóa nằm ở 2 hàm BitBlt và GetDIBits (bác xem cụ thể trong code).
    Chú ý: Bác nhớ để Sleep để "hãm" việc thực thi các hàm, nếu không có thể vẫn còn một phần cửa sổ của ứng dụng "sót" lại (do thời gian thực thi của các hàm quá ngắn - nhất là đối với các máy cấu hình mạnh).

    Have fun!
    P.S: Để có ảnh chụp của màn hình, bác chỉ cần nhấp chuột trái lên window là được (xem ở thằng WM_LBUTTONDOWN).
    Đã được chỉnh sửa lần cuối bởi ilovecplusplus : 22-01-2007 lúc 02:44 AM.
    Our dreams are young and we both know they take us where we want to go...

Các đề tài tương tự

  1. Source code visual 2008 không chay được trên visual 2005
    Gửi bởi hungmq trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 9
    Bài viết cuối: 11-07-2013, 11:28 AM
  2. Chuyển Project Visual C# 2010 sang Visual C#2008 bằng cách nào?
    Gửi bởi daicamrtran trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 24-08-2012, 07:16 PM
  3. Visual assist Build 1814 support Visual studio 2010
    Gửi bởi haian trong diễn đàn Công cụ, ebooks VC++
    Trả lời: 0
    Bài viết cuối: 12-04-2010, 06:00 PM
  4. Sự khác nhau về Prop -> Tab giữa Visual C# 2005 và Visual C# 2008 như thế nào?
    Gửi bởi boyhandsone trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 8
    Bài viết cuối: 13-04-2009, 12:42 AM
  5. Chương trình chuyển đổi | Convert project từ Visual Basic 6 sang Visual C++ 6
    Gửi bởi dungcoi trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 13-10-2007, 11:54 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn