Author Topic: [C++] making some screenshots with gdiplus  (Read 705 times)

0 Members and 1 Guest are viewing this topic.

Offline Lenoch

  • EZ's Menstruator
  • VIP
  • Serf
  • *
  • Posts: 49
  • Cookies: 37
    • View Profile
[C++] making some screenshots with gdiplus
« on: December 12, 2015, 04:21:13 pm »
Hello you guys. I'm working a bit on improving my C++ so I decided to mess around with screenshots. it's windows based an uses gdiplus and windows api. It gets your window with the windows api then handles the bitmap that it generates with gdiplus and saves it to a file.

The screenshot header file
Code: [Select]
#include <Windows.h>
#include <gdiplus.h>


#pragma comment(lib, "gdiplus.lib")
#pragma once

class Screenshot
{
public:
    Screenshot();
    ~Screenshot();
    void makeScreenshot(const WCHAR*);
private:
    ULONG_PTR token;
    int GetEncoderClsid(const WCHAR*, CLSID*);
};

The screenshot class

Code: [Select]
#include "Screenshot.h"

ULONG_PTR gdiToken;

Screenshot::Screenshot()
{
    Gdiplus::GdiplusStartupInput StartupInput;
    Gdiplus::GdiplusStartup(&gdiToken, &StartupInput, NULL);
}


Screenshot::~Screenshot()
{
    Gdiplus::GdiplusShutdown(gdiToken);
}

int Screenshot::GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
    UINT num = 0;
    UINT size = 0;

    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
    Gdiplus::GetImageEncodersSize(&num, &size);
   
    if (size == 0)
        return -1;

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));

    if (pImageCodecInfo == NULL)
        return -1;

    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT codec = 0; codec < num; ++codec)
    {
        if (wcscmp(pImageCodecInfo[codec].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[codec].Clsid;
            free(pImageCodecInfo);
            return codec;
        }
    }

    free(pImageCodecInfo);
    return -1;
}

void Screenshot::makeScreenshot(const WCHAR* filename) {
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);

    HWND desktopWindow = GetDesktopWindow();

    HDC desktopDC = GetDC(desktopWindow);
    HDC captureDC = CreateCompatibleDC(desktopDC);

    HBITMAP captureBitmap = CreateCompatibleBitmap(desktopDC, screenWidth, screenHeight);
    SelectObject(captureDC, captureBitmap);
    BitBlt(captureDC, 0, 0, screenWidth, screenHeight, desktopDC, 0, 0, SRCCOPY | CAPTUREBLT);

    Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(captureBitmap, NULL);
    CLSID clsId;

    int retVal = this->GetEncoderClsid(L"image/png", &clsId);
    bitmap->Save(filename, &clsId, NULL);
   
    ReleaseDC(desktopWindow, desktopDC);
    DeleteDC(captureDC);
    DeleteObject(captureBitmap);
}


Quote
<m0dem> I find evilzone is a really HQ community

Offline romancodis

  • /dev/null
  • *
  • Posts: 15
  • Cookies: -9
    • View Profile
Re: [C++] making some screenshots with gdiplus
« Reply #1 on: January 30, 2016, 10:44:37 pm »
Hi buddy,
                  i just compiled your code in gcc compiler by using following command
"g++ filename.cpp  screenshot.h -o filename.exe"
That is give  undefined reference says lot .what i will do to overcome this problem


thanks  ;)


Offline ArkPhaze

  • Peasant
  • *
  • Posts: 136
  • Cookies: 20
  • null terminated
    • View Profile
Re: [C++] making some screenshots with gdiplus
« Reply #2 on: January 31, 2016, 03:26:03 am »
Hello you guys. I'm working a bit on improving my C++ so I decided to mess around with screenshots. it's windows based an uses gdiplus and windows api. It gets your window with the windows api then handles the bitmap that it generates with gdiplus and saves it to a file.

The screenshot header file
Code: [Select]
#include <Windows.h>
#include <gdiplus.h>


#pragma comment(lib, "gdiplus.lib")
#pragma once

class Screenshot
{
public:
    Screenshot();
    ~Screenshot();
    void makeScreenshot(const WCHAR*);
private:
    ULONG_PTR token;
    int GetEncoderClsid(const WCHAR*, CLSID*);
};

The screenshot class

Code: [Select]
#include "Screenshot.h"

ULONG_PTR gdiToken;

Screenshot::Screenshot()
{
    Gdiplus::GdiplusStartupInput StartupInput;
    Gdiplus::GdiplusStartup(&gdiToken, &StartupInput, NULL);
}


Screenshot::~Screenshot()
{
    Gdiplus::GdiplusShutdown(gdiToken);
}

int Screenshot::GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
    UINT num = 0;
    UINT size = 0;

    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
    Gdiplus::GetImageEncodersSize(&num, &size);
   
    if (size == 0)
        return -1;

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));

    if (pImageCodecInfo == NULL)
        return -1;

    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT codec = 0; codec < num; ++codec)
    {
        if (wcscmp(pImageCodecInfo[codec].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[codec].Clsid;
            free(pImageCodecInfo);
            return codec;
        }
    }

    free(pImageCodecInfo);
    return -1;
}

void Screenshot::makeScreenshot(const WCHAR* filename) {
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);

    HWND desktopWindow = GetDesktopWindow();

    HDC desktopDC = GetDC(desktopWindow);
    HDC captureDC = CreateCompatibleDC(desktopDC);

    HBITMAP captureBitmap = CreateCompatibleBitmap(desktopDC, screenWidth, screenHeight);
    SelectObject(captureDC, captureBitmap);
    BitBlt(captureDC, 0, 0, screenWidth, screenHeight, desktopDC, 0, 0, SRCCOPY | CAPTUREBLT);

    Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(captureBitmap, NULL);
    CLSID clsId;

    int retVal = this->GetEncoderClsid(L"image/png", &clsId);
    bitmap->Save(filename, &clsId, NULL);
   
    ReleaseDC(desktopWindow, desktopDC);
    DeleteDC(captureDC);
    DeleteObject(captureBitmap);
}

That is an odd place to put #pragma once. Do you know that you have effectively made it completely redundant? I think you should look up what it is actually meant to do, before moving it to the top of your file. Why are you using malloc() and free() in C++ though? You don't really need to use GDI for this task either.

Hi buddy,
                  i just compiled your code in gcc compiler by using following command
"g++ filename.cpp  screenshot.h -o filename.exe"
That is give  undefined reference says lot .what i will do to overcome this problem


thanks  ;)

You have to compile using Visual Studio for this code as it stands.
« Last Edit: January 31, 2016, 03:29:23 am by ArkPhaze »
sig=: ArkPhaze

[ J/ASM/.NET/C/C++ - Software Engineer ]