paul
paul

Reputation: 745

How to capture the screen with the "Tool Tips"?

I am using GDI to capture the screen, and I have noticed that the "Tool Tips" are not included in the screenshot. This is my basic code:

HDC hdcDesk = GetDC(0);

HDC hdcMem = CreateCompatibleDC(hdcDesk);
HBITMAP hbmMem = CreateCompatibleBitmap(hdcDesk, 1920, 1080);
SelectObject(hdcMem, hbmMem);

StretchBlt(hdcMem, 0, 0, 1920, 1080, hdcDesk, 0, 0, 1920, 1080, SRCCOPY);

// Now save the bitmap...

Can this be fixed, or should I use another approach to capture the screen (other than GDI)?


Edit:

This is a screenshot that I took that does not display the Tool Tip.

enter image description here

Upvotes: 28

Views: 2588

Answers (2)

Barmak Shemirani
Barmak Shemirani

Reputation: 31629

Update: added CAPTUREBLT as suggested by Alex K., Adrian McCarthy et al.

I can't reproduce the same problem. If you succeed in taking screen shot of desktop then everything should be there! Try this code instead. Note the 3 second wait is supposed to give time to manually activate a tool tip.

SetProcessDPIAware();
HDC hdc = GetDC(HWND_DESKTOP);
RECT rc; GetWindowRect(GetDesktopWindow(), &rc);
int width = rc.right - rc.left;
int height = rc.bottom - rc.top;

HBITMAP hbitmap = CreateCompatibleBitmap(hdc, width, height);
HDC memdc = CreateCompatibleDC(hdc);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, 0, 0, CAPTUREBLT | SRCCOPY);

WORD bpp = 24; //save 24-bit bitmap
DWORD size = ((width * bpp + 31) / 32) * 4 * height;
BITMAPFILEHEADER filehdr = { 'MB', 54 + size, 0, 0, 54 };
BITMAPINFOHEADER infohdr = { 40, width, height, 1, bpp };
BYTE* pix = malloc(size); 
GetDIBits(hdc, hbitmap, 0, height, pix, (BITMAPINFO*)&infohdr, DIB_RGB_COLORS);

FILE* fout = fopen("c:\\test\\_bmp.bmp", "wb"); 
if (fout) //save to file
{
    fwrite(&filehdr, sizeof(filehdr), 1, fout);
    fwrite(&infohdr, sizeof(infohdr), 1, fout);
    fwrite(pix, 1, size, fout);
    fclose(fout);
}

//cleanup
free(pix);
SelectObject(memdc, oldbmp);
DeleteObject(memdc);
DeleteObject(hbitmap);
ReleaseDC(HWND_DESKTOP, hdc);

Upvotes: 10

FastAl
FastAl

Reputation: 6279

I had the exact problem a few years ago with a windows XP system. The code in the answer to my question solved the problem:

Capture screenshot Including Semitransparent windows in .NET

For you, you should be able to just change your stretchblt line to bitblt and add captureblt:

HDC hdcDesk = GetDC(0);

HDC hdcMem = CreateCompatibleDC(hdcDesk);
HBITMAP hbmMem = CreateCompatibleBitmap(hdcDesk, 1920, 1080);
SelectObject(hdcMem, hbmMem);

BitBlt(hdcMem, 0, 0, 1920, 1080, hdcDesk, 0, 0, SRCCOPY | CAPTUREBLT);

// Now save the bitmap...

Tooltips, like transparent windows, are skipped by spec of bitblt. Plus, you're not resizing, so use bitblt. If that doesn't work, there might be something else wrong with what you are doing as the other commenters hint, so you can convert the answer to my question from C# to C, that did work for me on XP. (of course I don't have XP any more to test but that was definitely the issue).

Upvotes: 6

Related Questions