Добрый день. Есть некий код, который сохраняет изображение в поток IStream и производит различные манипуляции над ним. Поток создается как: Код (Text): IStream *stream = 0; CreateStreamOnHGlobal(NULL, TRUE, &stream); ... screenshot->Save(stream, &jpeg); // манипуляции stream->Releae(); Этот код обернут в функцию и вызывается в цикле. Проблема вот в чем: ф-я отрабатывает нормально несколько итераций цикла(может быть 10, может за 100) и ни с того ни с чего Save возвращает 2(что говорит о том, что некий из параметров не валидный). Поскольку параметров всего два, а jpeg - это обычный CLSID то остается только стрим. Но я вызываю Release. В чем может быть проблема? Спасибо.
bug1z screenshot — это ведь Gdiplus::Bitmap ? Save каким-то образом перегружен или как Вам удалось скомпилировать такой код без ошибок? Метод-то три параметра принимает, а не два.
Да, screenshot - это Код (Text): Gdiplus::Bitmap *screenshot; Компилятор это скушал. Самое странное - это то, что оно работает-работает нормально, а затем какой то параметр почему то становится не валидным. сей час добавлю третий параметр и проверю.
bug1z Ну дык что значит "какой-то"? Третий, естессно, раз он при вызове отсутствует, а вместо него мусор из стека подставляется. Только я до сих пор не пойму, как у Вас вызов Save с двумя параметрами компилируется.
bug1z Ну... Предлагаю проверить на моём старом коде, будет ли возникать та же проблема: Код (Text): DWORD SaveScreenSnapshot(DWORD Quality, char *&SSnapshotPtr, DWORD &SSnapshotSize) { HDC DisplayDC, dcDesktBMP; HBITMAP hDesktBMP; Gdiplus::GdiplusStartupInput gdipSI; Gdiplus::EncoderParameters encoderParams; DWORD gdipToken; LARGE_INTEGER SeekPos = {0}; CLSID clsidEncoder = JPEGEncoderGUID; STATSTG JPGInfo; IStream *ScreenSnapshotStream; VirtualFree(SSnapshotPtr,0,MEM_RELEASE); DisplayDC = GetWindowDC(0); hDesktBMP = CreateCompatibleBitmap(DisplayDC,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); dcDesktBMP = CreateCompatibleDC(DisplayDC); SelectObject(dcDesktBMP,hDesktBMP); BitBlt(dcDesktBMP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),DisplayDC,0,0,SRCCOPY); gdipSI.GdiplusVersion = 1; Gdiplus::GdiplusStartup(&gdipToken,&gdipSI,NULL); Gdiplus::Bitmap *frDesktopBitmap = new Gdiplus::Bitmap(hDesktBMP,NULL); CreateStreamOnHGlobal(NULL,true,&ScreenSnapshotStream); encoderParams.Count = 1; encoderParams.Parameter[0].Guid = Gdiplus::EncoderQuality; encoderParams.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Value = &Quality; frDesktopBitmap->Save(ScreenSnapshotStream,&clsidEncoder,&encoderParams); ScreenSnapshotStream->Stat(&JPGInfo,STATFLAG_DEFAULT); SSnapshotPtr = (char *)VirtualAlloc(NULL,JPGInfo.cbSize.LowPart,MEM_COMMIT,PAGE_READWRITE); ScreenSnapshotStream->Seek(SeekPos,STREAM_SEEK_SET,NULL); ScreenSnapshotStream->Read(SSnapshotPtr,JPGInfo.cbSize.LowPart,NULL); SSnapshotSize = JPGInfo.cbSize.LowPart; ScreenSnapshotStream->Release(); delete(frDesktopBitmap); Gdiplus::GdiplusShutdown(gdipToken); DeleteDC(dcDesktBMP); DeleteObject(hDesktBMP); ReleaseDC(0,DisplayDC); return 0; } P.S. Ах да. const GUID JPEGEncoderGUID = {0x557CF401,0x1A04,0x11D3, {0x9A,0x73,0x00,0x00,0xF8,0x1E,0xF3,0x2E}};
В вашем коде Save тоже возвращает 2. Правда, я его немного переделал под свой проект: Код (Text): DWORD Screenshot::SaveScreenSnapshot(std::vector<char> &vec, DWORD Quality/*, char *&SSnapshotPtr*/, DWORD &SSnapshotSize) { HDC DisplayDC, dcDesktBMP; HBITMAP hDesktBMP; Gdiplus::GdiplusStartupInput gdipSI; Gdiplus::EncoderParameters encoderParams; DWORD gdipToken; LARGE_INTEGER SeekPos = {0}; const GUID JPEGEncoderGUID = {0x557CF401,0x1A04,0x11D3, {0x9A,0x73,0x00,0x00,0xF8,0x1E,0xF3,0x2E}}; CLSID clsidEncoder = JPEGEncoderGUID; STATSTG JPGInfo; IStream *ScreenSnapshotStream; // VirtualFree(SSnapshotPtr,0,MEM_RELEASE); DisplayDC = GetWindowDC(0); hDesktBMP = CreateCompatibleBitmap(DisplayDC,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); dcDesktBMP = CreateCompatibleDC(DisplayDC); SelectObject(dcDesktBMP,hDesktBMP); BitBlt(dcDesktBMP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),DisplayDC,0,0,SRCCOPY); gdipSI.GdiplusVersion = 1; Gdiplus::GdiplusStartup(&gdipToken,&gdipSI,NULL); Gdiplus::Bitmap *frDesktopBitmap = new Gdiplus::Bitmap(hDesktBMP,NULL); CreateStreamOnHGlobal(NULL,true,&ScreenSnapshotStream); encoderParams.Count = 1; encoderParams.Parameter[0].Guid = Gdiplus::EncoderQuality; encoderParams.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Value = &Quality; std::cout << "::::" << frDesktopBitmap->Save(ScreenSnapshotStream,&clsidEncoder,&encoderParams); ScreenSnapshotStream->Stat(&JPGInfo,STATFLAG_DEFAULT); // SSnapshotPtr = (char *)VirtualAlloc(NULL,JPGInfo.cbSize.LowPart,MEM_COMMIT,PAGE_READWRITE); ScreenSnapshotStream->Seek(SeekPos,STREAM_SEEK_SET,NULL); vec.resize(JPGInfo.cbSize.LowPart); ScreenSnapshotStream->Read(&vec[0],JPGInfo.cbSize.LowPart,NULL); SSnapshotSize = JPGInfo.cbSize.LowPart; ScreenSnapshotStream->Release(); delete(frDesktopBitmap); Gdiplus::GdiplusShutdown(gdipToken); DeleteDC(dcDesktBMP); DeleteObject(hDesktBMP); ReleaseDC(0,DisplayDC); return 0; } Но вроде ничего существенного не изменил.