Здравствуйте Hollander, Вы писали:
H>Привет !
H>Откопал случайно в заголовочном файле функцию. В MSDN у меня недокументировано ничего — апрельский этого года. А заголовочный файл от 4.24.98 !!!
H>Эта функция может, по идее, сохранять все то, что загружает OleLoadPicture — BMP, GIF, JPEG, ICO, WMF, и EMF
H>BOOL SaveBitmap(HBITMAP hBitmap,HPALETTE hPal,LPCTSTR szPath)
H>{
H> PICTDESC pDesc;
H>
H> pDesc.cbSizeofstruct = sizeof(PICTDESC);
H> pDesc.bmp.hbitmap = hBitmap;
H> pDesc.bmp.hpal = hPal;
H> pDesc.picType = PICTYPE_BITMAP;
H> return SavePictureIndirect(pDesc,szPath);
H>}
H>BOOL SavePictureIndirect(PICTDESC pDesc,LPCTSTR szPath)
H>{
H> IPicture* pPicture = NULL;
H> BOOL bResult = TRUE;
H> OleCreatePictureIndirect(&pDesc,&IID_IPicture,FALSE,(void**)&pPicture);
H> if(pPicture == NULL)
H> bResult = FALSE;
H> else
H> bResult = SavePicture(pPicture,szPath);
// Возможно, это дело вкуса, но я не понимаю, зачем еще раз проверять
// pPicture на NULL, когда мы только что это сделали. Впрочем, оптимизатор
// должен разобраться и сделать как надо.
H> if(pPicture != NULL)
H> pPicture->lpVtbl->Release(pPicture);
H> return bResult;
H>}
H>BOOL SavePicture(IPicture* pPicture,LPCTSTR szPath)
H>{
H> HRESULT hr;
// Вот здесь начинается что-то странное. На вход дается строка LPCTSTR,
// ее длина определяется с помощью strlen, что не будет компилироваться
// в Unicode. Кроме того, вызов MultiByteToWideChar нужен только в
// Unicode-компиляции, а вместо SysAllocStringByteLen стоит использоват
// SysAllocStringLen.
//
// Проверку на успешность выделения памяти тоже не мешает добавить.
H> int size = strlen(szPath);
H> BSTR bstrPath = SysAllocStringByteLen(szPath,size*2);
// Последний параметр для MultiByteToWideChar указан неправильно. Это
// количество символов, так что умножать на два не надо.
H> MultiByteToWideChar(CP_ACP,0,szPath,size, bstrPath, size*2);
// В итоге получается#ifdef _UNICODE
BSTR bstrPath = SysAllocString(szPath);
if (bstrPath == NULL)
return FALSE;
#else
int len = ltrlenA(szPath);
BSTR bstrPath = SysAllocStringLen(NULL, len);
if (bstrPath == NULL)
return FALSE;
MultiByteToWideChar(CP_ACP, 0, szPath, -1, bstrPath, len + 1);
#endif
H> hr = OleSavePictureFile((LPDISPATCH)pPicture,bstrPath);
H> SysFreeString(bstrPath);
H> return SUCCEEDED(hr);
H>}
Здравствуйте Alex Fedotov, Вы писали:
AF>И опять есть к чему придраться.
А кроме этого тичего не можешь сказать ? Оцени решение — стоит ли пользоваться и насколько универсально оно.
Этот код я набрал только для того, чтобы проверить. Наспех — потому и коряво. А проверки лишние — это другойй код совсем был — кое-что забыл убрать.
Здравствуйте Hollander, Вы писали:
H>А кроме этого тичего не можешь сказать ? Оцени решение — стоит ли пользоваться и насколько универсально оно.
Вот так значит вопрос стоит. Я не знаю, я начал бы пользоваться, посмотрел бы, как эта функция ведет себя в разных ситуациях. Например, как она сохраняет DIB sections. Надеюсь, она не пытается привести их к формату экрана?
H>Этот код я набрал только для того, чтобы проверить. Наспех — потому и коряво. А проверки лишние — это другойй код совсем был — кое-что забыл убрать.
AF>Вот так значит вопрос стоит. Я не знаю, я начал бы пользоваться, посмотрел бы, как эта функция ведет себя в разных ситуациях. Например, как она сохраняет DIB sections. Надеюсь, она не пытается привести их к формату экрана?
Здравствуйте Hollander, Вы писали:
AF>>Вот так значит вопрос стоит. Я не знаю, я начал бы пользоваться, посмотрел бы, как эта функция ведет себя в разных ситуациях. Например, как она сохраняет DIB sections. Надеюсь, она не пытается привести их к формату экрана?
H>А как это проверить можно ?
Сделать DIB-секцию, формат которой (глубина цвета) не совпадает с форматом экрана, и сохранить с помощью этой функции. А потом посмотреть, сколько цветов получилось в файле.
Здравствуйте Alex Fedotov, Вы писали:
H>>А как это проверить можно ?
AF>Сделать DIB-секцию, формат которой (глубина цвета) не совпадает с форматом экрана, и сохранить с помощью этой функции. А потом посмотреть, сколько цветов получилось в файле.
Эта функция работает с IPicture* . Dib создастся чз OleCreatePictureIndirect — здесь могут быть проблемы.
Здравствуйте Hollander, Вы писали:
AF>>Сделать DIB-секцию, формат которой (глубина цвета) не совпадает с форматом экрана, и сохранить с помощью этой функции. А потом посмотреть, сколько цветов получилось в файле.
H>Эта функция работает с IPicture* . Dib создастся чз OleCreatePictureIndirect — здесь могут быть проблемы.
Здравствуйте Alex Fedotov, Вы писали:
AF>>>Сделать DIB-секцию, формат которой (глубина цвета) не совпадает с форматом экрана, и сохранить с помощью этой функции. А потом посмотреть, сколько цветов получилось в файле.
H>>Эта функция работает с IPicture* . Dib создастся чз OleCreatePictureIndirect — здесь могут быть проблемы.
AF>Вот как раз эти проблемы и хотелось бы изучить.
Проверил — сграбил экран в клипборд — потом в файл — стало TrueColor (хотя экран 16 бит)
Потом вырезал из Паинта монохромное — все кул — сохранил как монохром
Здравствуйте, Hollander, Вы писали:
H>Привет !
H>Откопал случайно в заголовочном файле функцию. В MSDN у меня недокументировано ничего — апрельский этого года. А заголовочный файл от 4.24.98 !!!
H>Эта функция может, по идее, сохранять все то, что загружает OleLoadPicture — BMP, GIF, JPEG, ICO, WMF, и EMF
Да, функция достаточна интересная, мне как раз нужно что-то подобное. Мне необходимо открыть gif или jpg и сохранить в wmf.
Как можно это сделать с помощью OleLoadPicture и OleSavePictureFile?
Трудно ничего не делать, но мы не боимся трудностей.
Здравствуйте, MaxS, Вы писали:
MS>Да, функция достаточна интересная, мне как раз нужно что-то подобное. Мне необходимо открыть gif или jpg и сохранить в wmf.
MS>Как можно это сделать с помощью OleLoadPicture и OleSavePictureFile?
А никак. OleSavePictureFile сохраняет только в BMP. А чтобы сконвертить GIF или JPG в WMF можно например пойти на CodeProject и взять там CxImage class.
Господа, чего вы так носитесь с этой ::OleSavePictureFile()?
У объекта IPicture есть интерфейс IPersistStream (причем IPersist'а нету!)
В MSDN об этом четко и ясно написано:
[msdn]
The picture object also supports IPersistStream so it can save and load itself from an instance of IStream. An object that uses a picture object internally would normally save and load the picture as part of the object's own persistence handling. The function OleLoadPicture simplifies the creation of a picture object based on stream contents.
[/msdn]
Здравствуйте, algol, Вы писали: A>OleSavePictureFile сохраняет только в BMP.
А знаете почему? Потому что ::OleSavePictureFile()
просто вызывает IPicture::SaveAsFile() на потоке,
созданном с файла. И тут возможны только BMP и WMF
Вот если бы она использовала для этого интерфейс IPersistStream,
то формат зависел бы от свойства IPicture::KeepOriginalFormat().
Если оно выставлено в true, то картитка будет созранена
в том формате, в каком она была до загрузки.
Другое дело, что если при объект IPicture создавался с BMP,
то его можно сохранить только в BMP. Пожать в GIF не получится.
Несколько замечаний к приведённому коду:
1. Не знаю, как в других компиляторах, а в VC 2003 атрибута lpVtbl нет.
2. Такой функции как ltrlenA я не нашёл.
В итоге, код, котовый к вставке в программу (проверено на VC 2003, он же 7.1):
Здравствуйте, Vinni-puh, Вы писали:
VP>Несколько замечаний к приведённому коду: VP>1. Не знаю, как в других компиляторах, а в VC 2003 атрибута lpVtbl нет.
Это для языка С, а не С++. Сделай расширение файла С и все пучком.
VP>2. Такой функции как ltrlenA я не нашёл.