Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сохранение окна программы в wmf-файл, создать скриншот окна программы 
V
    Опции темы
DukeCpp
Дата 27.2.2006, 05:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



Здравствуйте, уважаемые;

Можно ли стандартными средствами Visual C++ 2003 сохранить содержимое окна программы в wmf (предпочтительнее в gif) - файл (или на худой конец всё окно, как по Alt+PrintScreen) в несколько строк кода?

Если данный вопрос уже поднимался -- дайте, пожалуйста, линк;

Заранее благодарен
PM   Вверх
Coocky
Дата 27.2.2006, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 25
Всего: 62



Цитата(DukeCpp @ 27.2.2006, 05:02 Найти цитируемый пост)
Можно ли стандартными средствами Visual C++ 2003 сохранить содержимое окна программы в wmf (предпочтительнее в gif) - файл (или на худой конец всё окно, как по Alt+PrintScreen) в несколько строк кода?

Элементарно..
Есть класс CFile для работы с файлами smile CFile::Read() CFile::Write()
А вот ЧТО ты будешь сохранять(какие даные)-это твои проблемы.
Для этого нужно знать ФОРМАТ данного расширения..



--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
DukeCpp
Дата 27.2.2006, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



ну-с, всё элементарно, когда знаешь;

вот, например, я могу скопировать форму приложения в буфер обмена очень просто:

Код

                 keybd_event(VK_SNAPSHOT, 1, 0 ,0);
                 keybd_event(VK_SNAPSHOT, 1, KEYEVENTF_KEYUP,0);


а далее есть

Код

void GetClipboardData(
   COleDataSource* pDataSource,
   BOOL bIncludeLink = FALSE,
   LPPOINT lpOffset = NULL,
   LPSIZE lpSize = NULL 
);


и вот этот pDataSource нужно нужно юзать в CFile::Write()?

мб это и хорошо, но при наведении на эту функцию студия показывает хинт: HANDLE GetClipboardData( UINT uFormat /* clipboard format */);

а при нажатии F1 на этой функции он выдаёт такой хелп:

Код


void GetClipboardData(
   COleDataSource* pDataSource,
   BOOL bIncludeLink = FALSE,
   LPPOINT lpOffset = NULL,
   LPSIZE lpSize = NULL 
);


И что здесь к чему? Помогите разобраться, что писать в Write, т.к. код

Код

     UINT uFormat;
      h = GetClipboardData(uFormate);

      HANDLE hFile = CreateFile(_T("C:\\MyFile.DAT"),
         GENERIC_WRITE, FILE_SHARE_READ,
         NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

      CFile myFile(hFile);


      myFile.Write(h, 4000);

      myFile.Close();



генерит ожидаемую ошибку Runtime при попытки закрытия файла. Каким мне задать этот uFormate. В хелпе не разобрался:

Parameters
uFormat
Specifies a clipboard format. For a description of the clipboard formats. Это прекрасно, но _как_ его описать?


И ещё простите за возможно слишком простой вопрос:

как мне узнать, например, в каком файле находится описание COleDataSource. Что нужно подключить, чтобы его юзать. При нажатии F1 удобной строки с файлом, в котором описан тип, как в билдере, нет. (Метод "правой кнопкой на имени, GoToDeclaration, имхо преизварщенский)

Это сообщение отредактировал(а) DukeCpp - 27.2.2006, 17:37
PM   Вверх
DukeCpp
Дата 27.2.2006, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



При данном коде
Код

                 keybd_event(VK_SNAPSHOT, 1, 0 ,0);
                 keybd_event(VK_SNAPSHOT, 1, KEYEVENTF_KEYUP,0);
                 HANDLE h = GetClipboardData(CF_BITMAP);                
                HANDLE hFile = CreateFile(_T("C:\\MyFile.BMP"),
                                        GENERIC_WRITE, FILE_SHARE_READ,
                                        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

            CFile myFile(hFile);
      
               myFile.Write(h, 40000);
//picture size is 200*200 pixels;
              myFile.Close();




возникает Dubug Assertion Failed при попытке закрытия файла. Я не знаю, почему;
подскажите, где хоть копать..

Это сообщение отредактировал(а) DukeCpp - 27.2.2006, 19:33
PM   Вверх
Earnest
Дата 27.2.2006, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



1) Clipboard сначала неплохо бы открыть (OpenClipboard). Потом, соответственно, закрыть.
2) То, что возвращает GetClipboardData, зависит от формата. В случае CF_BITMAP возвращается HBITMAP. Неплохо бы проверить, что это не 0. И кто вообще сказал, что PrintScreen записывает CF_BITMAP. Т.е. возможно, конечно, но проверить надо.
3) HBITMAP - это не указатель на память! И с чего ты взял, что картинка размером 200*200 пикселов занимает 40000 байтов?

Цитата(DukeCpp @ 27.2.2006, 18:56 Найти цитируемый пост)
подскажите, где хоть копать..

Сначала копать MSDN на предмет работы с Clipboard. Кстати, возможно, использование COleDataObject (MFC'шный объект для работы с Clipboard) окажется более удобным, чем голый API.
Потом копать MSDN на предмет - как из HBITMAP вытащить нужную тебе информацию. Тут может помочь класс CImage - он умеет конструироваться из HBITMAP, а также записываться в файл.


--------------------
...
PM   Вверх
DukeCpp
Дата 27.2.2006, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



Цитата

2) То, что возвращает GetClipboardData, зависит от формата. В случае CF_BITMAP возвращается HBITMAP. Неплохо бы проверить, что это не 0.


с удовольствием, только вот студия (Watch List) говорит, что в данном коде:

Код

                 if (OpenClipboard(NULL))
                 {
                    SetClipboardData(CF_BITMAP, NULL);
                    HBITMAP h = (HBITMAP)GetClipboardData(CF_BITMAP);
                                                                                if (h) {...}




в строке проверки
h <undefined value> HBITMAP__*

как это расценивать?

а если без явного преобразования типа, так вообще не компиляет.


И как проверить, что записывает PrintScreen?

Цитата

3) HBITMAP - это не указатель на память!


А как его тогда расценивать, учитывая макросы, которым этот тип определяется?

да, с размером ошибся, спасибо:
200*200*глубина_цвета (кстати, как color_depth узнатЬ?)


попробовал ещё другой способ, который описан в хелпе к Clipboard, то он для графики не идёт:
Код


System::Windows::Forms::IDataObject *iData = Clipboard::GetDataObject();
if(iData->GetDataPresent(DataFormats::Bitmap))
{
     CImage im = CImage();
     im.Attach(h);
}




однако тело условной конструкции он проускает.

Цитата

Потом копать MSDN на предмет - как из HBITMAP вытащить нужную тебе информацию. Тут может помочь класс CImage - он умеет конструироваться из HBITMAP, а также записываться в файл.


с этим проблем возникнуть не должно -- осталось теперь вытащить объект из буфера.

Это сообщение отредактировал(а) DukeCpp - 27.2.2006, 22:43
PM   Вверх
Earnest
Дата 28.2.2006, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(DukeCpp @ 27.2.2006, 22:30 Найти цитируемый пост)
студия (Watch List) говорит

Студия может говорить что угодно, это ее личные тараканы. Ты должен понимать, что студия - это одна программа, а компилятор - совсем другая...

Цитата(DukeCpp @ 27.2.2006, 22:30 Найти цитируемый пост)
а если без явного преобразования типа, так вообще не компиляет.

Правильно, возвращается нечто неопределенное (HANDLE), что требуется явно преобразовать к нужному типу. Для WinAPI это нормально.

Цитата(DukeCpp @ 27.2.2006, 22:30 Найти цитируемый пост)
да, с размером ошибся, спасибо:
200*200*глубина_цвета (кстати, как color_depth узнатЬ?)

Пожалйста, только это тоже неправильно. Во-первых, есть заголовок, во-вторых - данные могут быть сжаты. Да и ничем тебе размер не поможет - еще раз повторяю - HBITMAP - не указатель. В форуме по WinAPI совсем недавно обсуждалась тема - что находится по адресу HBITMAP.

Как узнать, в каком формате записывает PrintScreen - ну, во первых, проверить - а вдруг все-таки в CF_BITMAP (тогда GetClipboardData должна возвратать не 0). Еще есть функции EnumClipboardFormats, а также IsClipboardFormatAvailable.



--------------------
...
PM   Вверх
DukeCpp
Дата 6.3.2006, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



Имея битмап, правомерно ведь такое действие
Код


    CImage im;
    (HBITMAP)pBitmap->m_hObject;
    im.Attach(pOldBitmap->GetBitmap);
    im.Save("c:\image2");    // если im.Save("c:\image2", ImageFormatBMP); то вообще ругается на неизвестную ImageFormatBMP

    im.Destroy();


Но студия даже не создаёт файла на диске.

мало того,

Код

    im.Load("c:\2.bmp");
    im.Save("c:\1.bmp");




тоже не работает -- не создаётся файл; как это объяснить?

Это сообщение отредактировал(а) DukeCpp - 6.3.2006, 01:21
PM   Вверх
DukeCpp
Дата 6.3.2006, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 27.2.2006
Где: St.Petersburg

Репутация: 1
Всего: 1



Всем спасибо за соучастие; вопрос разрешил и объявляю его закрытым.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0521 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.