Click here to Skip to main content
15,888,351 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
hello all

I want to save the printer hdc to a image file,and the hdc I get from hook the api EndPage().
the code as follow:

bool SaveToBmp(HDC hdc, RECT rc, SIZE ImgDstSize, LPCWSTR lpFilePath)
{
    bool bResult = false;
    BITMAPINFO bmpInfo = { 0 };
    BYTE *pData = NULL;
    SIZE ImgSrcSize = { rc.right - rc.left, rc.bottom - rc.top };
    HBITMAP hBmp = NULL;
    HGDIOBJ hOldObj = NULL;
    HDC hdcMem = NULL;
    //Initilaize the bitmap information   
    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = ImgDstSize.cx;
    bmpInfo.bmiHeader.biHeight = ImgDstSize.cy;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 24;
    // 
    HANDLE hFile = INVALID_HANDLE_VALUE;
    BITMAPFILEHEADER bmFileHeader = { 0 };
    BITMAPINFOHEADER bmInfoHeader = { 0 };
    hdcMem = ::CreateCompatibleDC(NULL);
    if (hdcMem == NULL) {
        goto _EXIT_FUNC;
    }
    // Get the data from the memory DC 
    hBmp = CreateDIBSection(hdcMem, &bmpInfo, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&pData), NULL, 0);
    if (hBmp == NULL) {
        goto _EXIT_FUNC;
    }
    // Draw to the memory DC
    hOldObj = SelectObject(hdcMem, hBmp);
    ::StretchBlt(hdcMem, 0, 0, ImgDstSize.cx, ImgDstSize.cx, hdc, rc.left, rc.top, ImgSrcSize.cx, ImgSrcSize.cy, SRCCOPY);
    DWORD dwbmpSize = ImgDstSize.cx * ImgDstSize.cy * 3;
    

    bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfoHeader.biWidth = ImgDstSize.cx;
    bmInfoHeader.biHeight = ImgDstSize.cy;
    bmInfoHeader.biPlanes = 1;
    bmInfoHeader.biBitCount = 24;
    //Bimap file header in order to write bmp file
    bmFileHeader.bfType = 0x4d42;  //bmp 
    bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
    hFile = CreateFile(lpFilePath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFile == INVALID_HANDLE_VALUE) {
        goto _EXIT_FUNC;
    }
    DWORD dwWrite = 0;
    WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
    WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
    WriteFile(hFile,pData, dwbmpSize,&dwWrite,NULL);
    SelectObject(hdcMem, hOldObj);
    bResult = true;
_EXIT_FUNC:
    if (hBmp != NULL) {
        ::DeleteObject(hBmp);
    }
    if (hdcMem != NULL) {
        ::DeleteObject(hdcMem);
    }
    if (hFile != INVALID_HANDLE_VALUE) {
        CloseHandle(hFile); 
    }
    return bResult;
}


If I put in the hdc From the screen hdc ,the program can Get the Image,but if I put in the hdc from hook the EndPage(); the program save a error image.why

Please give me the best solution for this.

thank you!
Posted
v2
Comments
Sergey Alexandrovich Kryukov 13-Jun-11 13:28pm    
Solution for what?!
--SA
Member 8773664 2-Apr-12 9:11am    
what should be the value of rect and ImgDestSize in the arguments??

There is not point of saving HDC; you wan't be able to use it. This is a handle which is created during run-time and can be different each time. Without creating a HDC you cannot use a value of it. This would be the same as using a pointer of some random value without memory allocation of getting address of some really existing object.

The whole idea does not makes any sense. What's your ultimate goal?

—SA
 
Share this answer
 
v2
The problem probably isn't in the code you posted.

It's probably in how/when you are calling it.

I would suspect that the printer hdc may not point to what you think it's pointing to at the time you call your routine.

You don't say what the error is that you are getting. (That would be helpful in understanding the problem.)

And you don't show how you are calling this code. It's not clear what you are doing when you say "hdc from hook the EndPage()".

The Win32 function int EndPage(HDC hdc) takes an hdc as an input, it doesn't supply an hdc. Are you sure you have the right hdc?

Also, MSDN says that the EndPage function is "typically used to direct the device driver to advance to a new page". That doesn't imply anything about the state of the device context at that point. It's already been printed at that point, so it could very well be empty.
 
Share this answer
 
Comments
luama 13-Jun-11 21:35pm    
thank you for you answerthe error is The Image File I Got was a Black Picture.

I Bind a dll By that code,And inject the dll into Notepad.exe,and the dll will hook the EndPage(), as:
bool EndPageHook(HDC hdc)
{
// calculate some parameters

SaveToBmp(hdc, rc, ImgDstSize, lpFilePath);

// ReSet Unhook the Func Addr
bool bResult = EndPage(hdc);

// Set Hook the Func Addr

return bResult;
}

The hdc should not be an error hdc.
TRK3 14-Jun-11 10:03am    
Hmmm.... I'm not sure why you want to capture an image of something notepad would print. Why do you think you need to do that? There is probably an easier way to do whatever you are trying to do.

Also, there is no guarantee at all that the printer device context has any bitmap data associated with it at all. In fact it's a pretty good bet it doesn't. See: http://msdn.microsoft.com/en-us/library/dd162859(v=VS.85).aspx

When you print to a printer dc, whatever you do gets translated to commands to the printer -- it doesn't write to a bit map.

If you really want to do this, you'll have to hook something much earlier in the print sequence (like the CreateDC call) and provide a memDC instead of a printer dc.
Have you solved the problem ?
or use the driver instead .
 
Share this answer
 
Hi,

Did you solve this problem?

Regards,
Yuksel.
 
Share this answer
 
Comments
CHill60 5-Dec-13 7:29am    
Please don't post comments as solutions - if you do this on an unanswered question you make it drop out of the list waiting for answers and fewer people will view it. Use the "Have a Question or Comment?" link next to the appropriate post.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900