2012-03-01 19 views
8

संभव डुप्लिकेट:
how to make screen screenshot with win32 in c++?स्क्रीन का हिस्सा कैप्चर कैसे करें और इसे बीएमपी में कैसे सहेजें?

मैं वर्तमान में है कि एक bmp करने के लिए स्क्रीन के एक हिस्से को बचाया एक आवेदन बनाने के लिए कोशिश कर रहा हूँ। मुझे BitBlt मिला है लेकिन मुझे नहीं पता कि इसके साथ क्या करना है। मैंने कुछ उत्तरों की तलाश करने की कोशिश की है लेकिन मुझे अभी भी सी ++ का उपयोग करके स्पष्टीकरण नहीं मिला है।

तो, मूल रूप से मैं इस समारोह चाहते हैं:

bool capturePartScreen(int x, int y, int w int, h, string dest){ 
    //Capture part of screen according to coordinates, width and height. 
    //Save that captured image as a bmp to dest. 
    //Return true if success, false if failure 
} 

BitBlt:

BOOL BitBlt(
    __in HDC hdcDest, 
    __in int nXDest, 
    __in int nYDest, 
    //The three above are the ones I don't understand! 
    __in int nWidth, 
    __in int nHeight, 
    __in HDC hdcSrc, 
    __in int nXSrc, 
    __in int nYSrc, 
    __in DWORD dwRop 
); 

कि hdc क्या होना चाहिए और मैं bmp कैसे प्राप्त करते हैं?

+1

देखो (http://stackoverflow.com/questions/3291167/how-to-make-screen-screenshot -साथ-Win32-इन-सी)। –

+0

यह [प्रश्न] देखें (http://stackoverflow.com/questions/5292700/efficiently-acquiring-a-screenshot-of-the-windows-desktop), यह आपको सही दिशा में इंगित करना चाहिए –

+0

@ जेसे: धन्यवाद , उस पोस्ट ने मुझे थोड़ा सा मदद की :) – Anton

उत्तर

17

यह कुछ समय लिया, लेकिन मैं अब अंत में एक कामकाज स्क्रिप्ट के साथ समाप्त हो गया है।

आवश्यकताएँ: (?)

#include <iostream> 
#include <ole2.h> 
#include <olectl.h> 

इसके अलावा, आप हो सकता है ole32, oleaut32 जोड़ सकते हैं और अपने लिंकर को UUID किया है।

screenCapturePart:

bool screenCapturePart(int x, int y, int w, int h, LPCSTR fname){ 
    HDC hdcSource = GetDC(NULL); 
    HDC hdcMemory = CreateCompatibleDC(hdcSource); 

    int capX = GetDeviceCaps(hdcSource, HORZRES); 
    int capY = GetDeviceCaps(hdcSource, VERTRES); 

    HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h); 
    HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap); 

    BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY); 
    hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld); 

    DeleteDC(hdcSource); 
    DeleteDC(hdcMemory); 

    HPALETTE hpal = NULL; 
    if(saveBitmap(fname, hBitmap, hpal)) return true; 
    return false; 
} 

saveBitmap: इस [तो सवाल] पर

bool saveBitmap(LPCSTR filename, HBITMAP bmp, HPALETTE pal) 
{ 
    bool result = false; 
    PICTDESC pd; 

    pd.cbSizeofstruct = sizeof(PICTDESC); 
    pd.picType  = PICTYPE_BITMAP; 
    pd.bmp.hbitmap = bmp; 
    pd.bmp.hpal  = pal; 

    LPPICTURE picture; 
    HRESULT res = OleCreatePictureIndirect(&pd, IID_IPicture, false, 
         reinterpret_cast<void**>(&picture)); 

    if (!SUCCEEDED(res)) 
    return false; 

    LPSTREAM stream; 
    res = CreateStreamOnHGlobal(0, true, &stream); 

    if (!SUCCEEDED(res)) 
    { 
    picture->Release(); 
    return false; 
    } 

    LONG bytes_streamed; 
    res = picture->SaveAsFile(stream, true, &bytes_streamed); 

    HANDLE file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, 0, 
       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 

    if (!SUCCEEDED(res) || !file) 
    { 
    stream->Release(); 
    picture->Release(); 
    return false; 
    } 

    HGLOBAL mem = 0; 
    GetHGlobalFromStream(stream, &mem); 
    LPVOID data = GlobalLock(mem); 

    DWORD bytes_written; 

    result = !!WriteFile(file, data, bytes_streamed, &bytes_written, 0); 
    result &= (bytes_written == static_cast<DWORD>(bytes_streamed)); 

    GlobalUnlock(mem); 
    CloseHandle(file); 

    stream->Release(); 
    picture->Release(); 

    return result; 
} 
+0

OleCreatePictureIndirect के बाद E_UNEXPECTED प्राप्त करने वालों के लिए, मैं PICTDESC.picType को PICTYPE_BMP पर सेट करना भूल गया। –

+0

भविष्य के पाठकों के लिए बस एक नोट ... उस पहले कोड ब्लॉक में 'बिट कैप्चरपार्ट' बिट जो बिट बिट (एचडीसी मेमरी, 0, 0, डब्ल्यू, एच, एचडीसी स्रोत, एक्स, एक्स, एसआरसीसीओपीवाई) पढ़ता है; वास्तव में 'बिटबल्ट होना चाहिए (एचडीसी मेमरी, 0, 0, डब्ल्यू, एच, एचडीसीसोर्स, एक्स, वाई, एसआरसीसीओपीवाई); '। –

+0

@ क्रिसबर्लो फिक्स्ड, ध्यान देने और कहने के लिए धन्यवाद! – Anton

3

आप संपूर्ण स्क्रीन के लिए डिवाइस संदर्भ प्राप्त करने के लिए GetDC(NULL) का उपयोग कर सकते हैं, फिर उस स्रोत डिवाइस संदर्भ के रूप में BitBlt के साथ उपयोग करें।

क्या करना है से बाकी के लिए:

Bitmap Creation (Windows)

Bitmap Storage (Windows)

+0

हाँ मुझे पता है, लेकिन मुझे समझ में नहीं आता कि गंतव्य एचडीसी को कैसे परिभाषित किया जाए। मैं एक एचडीसी से बीएमपी में कैसे जा सकता हूं? इसे स्पष्ट करने के लिए खेद है। – Anton