2014-10-07 124 views
2

有没有一种方法可以用来从Windows CE6应用程序获取屏幕截图?我有一个现有的应用程序,我想从我的应用程序截图。我需要从应用程序本身激活屏幕截图请求,并将屏幕截图保存到预定义的位置。我一直在网上寻找答案,并没有真正发现任何东西。任何帮助将不胜感激。使用Win CE6的屏幕截图

我已经设法启动并运行了一些东西,但它并没有给出整个位图。相反,它只给出位图的下半部分。任何建议,哪里出错了?

截图代码

HWND DesktopHwnd = ::GetDesktopWindow(); 
    RECT DesktopParams; 
    HDC DevC = ::GetDC(DesktopHwnd); 
    ::GetWindowRect(DesktopHwnd,&DesktopParams); 
    DWORD Width = DesktopParams.right - DesktopParams.left; 
    DWORD Height = DesktopParams.bottom - DesktopParams.top; 

    // get the device context of the screen 
    HDC hScreenDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);  
    // and a device context to put it in 
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC); 

    int x = GetDeviceCaps(hScreenDC, HORZRES); 
    int y = GetDeviceCaps(hScreenDC, VERTRES); 

    // maybe worth checking these are positive values 
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y); 

    // get a new bitmap 
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap); 

    BitBlt(hMemoryDC, 0, 0, Width, Height, hScreenDC, 0, 0, SRCCOPY); 
    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap); 

    // now your image is held in hBitmap. You can save it or do whatever with it 
    HWND hwnd = DesktopHwnd; 
    PBITMAPINFO pbi; 
    HBITMAP hBMP = hBitmap; 
    HDC hDC = DevC; 
    HANDLE hf;     // file handle 
    BITMAPFILEHEADER hdr;  // bitmap file-header 
    PBITMAPINFOHEADER pbih;  // bitmap info-header 
    DWORD dwTotal;    // total count of bytes 
    DWORD cb;     // incremental count of bytes 
    BYTE *hp;     // byte pointer 
    DWORD dwTmp; 
    int ret = 0; 

    pbi = CreateBitmapInfoStruct(NULL, hBMP); 
    if(pbi == NULL) 
    { 
    } 
    pbih = (PBITMAPINFOHEADER) pbi; 

    RGBQUAD *rgbq; 
    rgbq = pbi->bmiColors; 
    PALETTEENTRY pe[256]; 
    GetSystemPaletteEntries(hDC, 0, pbih->biClrUsed, pe); 
    for(DWORD i = 0; i < pbih->biClrUsed; i++) 
    { 
    rgbq[i].rgbRed = pe[i].peRed; 
    rgbq[i].rgbBlue = pe[i].peBlue; 
    rgbq[i].rgbGreen = pe[i].peGreen; 
    rgbq[i].rgbReserved = 0; 
    } 

    // CE5.0 + CE6.0 
    HBITMAP h = CreateDIBSection(hScreenDC, pbi, DIB_RGB_COLORS, (void **)&hp, NULL, 0); 
    if(h == NULL) 
    { 
    goto close_bmp; 
    } 
    SelectObject(hMemoryDC, h); 
    BitBlt(hMemoryDC, 0, 0, Width, Height, hScreenDC, 0, 0, SRCCOPY); 

    // Create the .BMP file. 
    hf = CreateFile(_T("\\FlashDisk\\image1.bmp"),GENERIC_READ | GENERIC_WRITE,(DWORD) 0, NULL, 
        CREATE_ALWAYS, 
       FILE_ATTRIBUTE_NORMAL, 
       (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
    { 
    goto close_bmp; 
    } 
    hdr.bfType = 0x4D42;  // 0x42 = "B" 0x4d = "M" 
    // Compute the size of the entire file. 
    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); 
    hdr.bfReserved1 = 0; 
    hdr.bfReserved2 = 0; 

    // Compute the offset to the array of color indices. 
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
       pbih->biSize + pbih->biClrUsed 
       * sizeof (RGBQUAD); 

    // Copy the BITMAPFILEHEADER into the .BMP file. 
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
    (LPDWORD) &dwTmp, NULL)) 
    { 
    goto close_bmp; 
    } 

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
       + pbih->biClrUsed * sizeof (RGBQUAD), 
       (LPDWORD) &dwTmp, (NULL))) 
    { 
    } 

    // Copy the array of color indices into the .BMP file. 
    dwTotal = cb = pbih->biSizeImage; 

    //hp = lpBits;  
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
    { 
    goto close_bmp; 
    } 

    close_bmp: 
    // Close the .BMP file. 
    if(hf != INVALID_HANDLE_VALUE) 
    { 
    if (!CloseHandle(hf)) 
    { 
     int xyz = 2; 
     xyz = 3; 
    } 
    else 
    { 
     ret = 1; 
    } 
    } 

    if(h != NULL) 
    DeleteObject(h); 
    if(pbi != NULL) 
    { 
    free(pbi); 
    } 

    // clean up 
    if(hMemoryDC != NULL) 
     DeleteDC(hMemoryDC); 
    DeleteDC(hScreenDC); 

干杯。

+0

您是否真的在网上看过?我做了一个谷歌搜索“windows ce6截图”,并出现了很多结果。 – 2014-10-07 11:16:05

+0

不是编程问题? – Jolta 2014-10-07 11:16:59

+0

这是一个编程问题。我需要从应用程序本身激活屏幕截图请求,并将屏幕截图保存到预定义位置。 – Neophile 2014-10-07 11:27:29

回答

1

我已经设法最终得到一个截图工作。这可能有助于其他人以后在Win CE6应用程序中截取屏幕截图。希望这有助于他人。

void MyScreenshotFunction::Screenshot() 
     { 
      HWND DesktopHwnd = ::GetDesktopWindow(); 
      RECT DesktopParams; 
      HDC DevC = ::GetDC(DesktopHwnd); 
      ::GetWindowRect(DesktopHwnd,&DesktopParams); 
      DWORD Width = DesktopParams.right - DesktopParams.left; 
      DWORD Height = DesktopParams.bottom - DesktopParams.top; 

      DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBTRIPLE)+1*(Width*Height*4)); 
      char *BmpFileData = (char*)GlobalAlloc(0x0040,FileSize); 

      PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData; 
      PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)]; 

      BFileHeader->bfType = 0x4D42; // BM 
      BFileHeader->bfSize = sizeof(BITMAPFILEHEADER); 
      BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 

      BITMAPINFO bmi; 
      ZeroMemory(&bmi, sizeof(BITMAPINFO)); 
      bmi.bmiHeader.biSize   = sizeof(BITMAPINFOHEADER); 
      bmi.bmiHeader.biWidth   = Width; 
      bmi.bmiHeader.biHeight   = Height; 
      bmi.bmiHeader.biPlanes   = 1; 
      bmi.bmiHeader.biBitCount  = 24; 
      bmi.bmiHeader.biCompression  = BI_RGB; 
      bmi.bmiHeader.biSizeImage  = bmi.bmiHeader.biWidth * abs(bmi.bmiHeader.biHeight) * 3; 

      unsigned char *BitsRGB=0; 
      HDC CaptureDC = CreateCompatibleDC(0); 
      HBITMAP CaptureBitmap = CreateDIBSection(DevC, &bmi, DIB_RGB_COLORS, (void**)&BitsRGB, NULL, 0); 
      SelectObject(CaptureDC,CaptureBitmap); 
      BitBlt(CaptureDC, 0, 0, Width, Height, DevC, 0, 0, SRCCOPY); 

      BITMAPFILEHEADER hdr;  // bitmap file-header 
      hdr.bfType = 0x4d42;  // 0x42 = "B" 0x4d = "M" 
      // Compute the size of the entire file. 
      hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + bmi.bmiHeader.biSize + bmi.bmiHeader.biClrUsed * sizeof(RGBQUAD) + bmi.bmiHeader.biSizeImage); 
      // Compute the offset to the array of color indices. 
      hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + bmi.bmiHeader.biSize + bmi.bmiHeader.biClrUsed * sizeof (RGBQUAD); 
      hdr.bfReserved1 = 0; 
      hdr.bfReserved2 = 0; 

      DWORD Junk; 
      HANDLE FH = CreateFile(_T("\\Destination.bmp"),GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,0,0); 

      // Copy the BITMAPFILEHEADER into the .BMP file. 
      WriteFile(FH, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),(LPDWORD) &Junk, NULL); 

      // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
      WriteFile(FH, (LPVOID) &(bmi.bmiHeader), sizeof(BITMAPINFOHEADER) + bmi.bmiHeader.biClrUsed * sizeof (RGBQUAD), 
      (LPDWORD) &Junk, (NULL)); 

      // Copy the array of color indices into the .BMP file. 
      WriteFile(FH, (LPSTR) BitsRGB, (int) bmi.bmiHeader.biSizeImage, (LPDWORD) &Junk,NULL); 
      CloseHandle(FH); 
      ReleaseDC(DesktopHwnd, DevC); 
      GlobalFree(BmpFileData); 
     } 
1

您可以在设备上启动cerdisp.exe(例如\ windows \ cerdisp.exe),并通过cerhost(\ WINCE600 \ PUBLIC \ COMMON \ OAK \ BIN \ I386 \ cerhost.exe)从桌面PC进行连接。 然后使用PC截图工具捕捉cerhost图像。

问候。

+0

不需要PC来截图。我希望CE应用程序以编程方式拍摄自己的截图。 – Neophile 2014-10-08 09:00:05

+0

好的 - 误解了你的问题(或者你编辑了它?)。 – timmf 2014-10-09 09:36:24

+0

我在你的回答后添加了我的代码。 – Neophile 2014-10-09 09:53:28