Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.10.2024, 21:00   #1
LUN2
Пользователь
 
Регистрация: 14.08.2021
Сообщений: 23
По умолчанию Почему OLE-объект читается через IStorage с нулевой длиной (как будто данных нет) ?

У меня написан обработчик перетаскивания OLE drag-and-drop на мое окно.
Источник перетаскивания - MS Word (выделенный в редакторе) или письмо из списка писем в почтовом ящие MS Outlook.
Я перебираю форматы OLE-объектов, которые получил в HRESULT __stdcall MyDropTarget_CLASS::Drop (это наследник IDropTarget), и если вижу, что объект доступен через
IStorage, пытаюсь прочитать его - код процедуры чтения приведен далее.

Меня удивляет то, что первый вызов Stream->Read возвращает S_OK (чтение успешно), НО ActuallyRead =0.

Вопрос: почему это может случаться ?
Ведь я что-то перетащил, почему читаются данные нулевого размера, как будто их просто нет...


Код:
bool GetData_IStream(IDataObject* pDataObj, const FORMATETC* in_FormatEtc) {
    // Запрашиваем возможность получения данных в формате _CurFormat_
    // инициализируем структуру, в которой запросим инф-цию,
    // необходимо указать - format, medium, and target device

    // ---------------- QueryGetData ----------------

    FORMATETC ReadFormat;
    ZeroMemory(&ReadFormat, sizeof(ReadFormat));

    ReadFormat.cfFormat = in_FormatEtc->cfFormat;                     // CLIPFORMAT
    ReadFormat.tymed = TYMED_ISTREAM;           // DWORD
    ReadFormat.ptd = NULL;                      //  [unique] DVTARGETDEVICE*
    ReadFormat.dwAspect = DVASPECT_CONTENT;     // DWORD
    ReadFormat.lindex = -1;                     // LONG

    HRESULT res = pDataObj->QueryGetData(&ReadFormat);
    bool ok_query = (res == S_OK);
    if (ok_query)
        std::cout << "QueryGetData - OK" << std::endl;
    else {
        std::cout << "QueryGetData - ERROR = " << res << std::endl;
        return false;
    }
    

    // ---------------- GetData ----------------

    ZeroMemory(&ReadFormat, sizeof(ReadFormat));

    ReadFormat.cfFormat = in_FormatEtc->cfFormat;                     // CLIPFORMAT
    ReadFormat.tymed = TYMED_ISTREAM;           // DWORD
    ReadFormat.ptd = NULL;                      //  [unique] DVTARGETDEVICE*
    ReadFormat.dwAspect = DVASPECT_CONTENT;     // DWORD
    ReadFormat.lindex = -1;                     // LONG

    STGMEDIUM MediumInfo;   
    res = pDataObj->GetData(&ReadFormat, &MediumInfo);
    bool ok_getdata = (res == S_OK);
    if (ok_getdata)
        std::cout << "GetData - OK" << std::endl;
    else {
        std::cout << "GetData - ERROR = " << res << std::endl;
        return false;
    }

    // MediumInfo должен содержать актуальную ссылку на IStream
    if (MediumInfo.tymed != ReadFormat.tymed) {
        std::cout << "GetData ERROR - invalid _MediumInfo.tymed_ = " << MediumInfo.tymed << std::endl;
        return false;
    }

    IStream* Stream = MediumInfo.pstm;
    if (Stream == NULL) {
        std::cout << "GetData ERROR - Stream == NULL." << std::endl;
        return false;
    }

    bool ReadResult = false;

    // ---------------- подготовим буфер для чтения ----------------
    const int BufferSize = 100000;
    char* BufferPtr = (char* ) malloc(BufferSize);
    if (BufferPtr != nullptr) {

        // ---------------- читаем поток Stream частями ------------------------
        ULONG ActuallyRead = 0;     // прочитано в текущей порции
        ULONG TotalRead = 0;        // всего прочитано
        bool StreamEof = false;
        bool ReadError = false;

        while (!StreamEof && !ReadError) {
            HRESULT res_read = Stream->Read(BufferPtr, (ULONG) BufferSize, &ActuallyRead);

            switch (res_read) {
                case S_OK: 
                case S_FALSE: {
                    // --- что-то прочитано ---

                    StreamEof = (ActuallyRead < BufferSize);
                    TotalRead = TotalRead + ActuallyRead;

                    break;
                }  // S_OK, S_FALSE

                case E_PENDING: {
                    // ---ожидаем данные ---
                    break;
                } // E_PENDING

                default: {
                    // --- все остальное - ошибка чтения ---
                    ReadError = true;
                    std::cout << "Stream reading ERROR = " <<res_read << std::endl;

                } // default
            } // switch


        } // while

        ReadResult = !ReadError;

        if (!ReadError) {
            std::cout << "Stream reading OK. TotalRead = " << TotalRead << std::endl;
        }
    }
    else {
        std::cout << "Malloc ERROR - cannot alloc memory for a stream data." << std::endl;
        ReadResult = false;
    }


    Stream->Release();

    return ReadResult;
}
LUN2 вне форума Ответить с цитированием
Старый 08.10.2024, 08:01   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,363
По умолчанию

В код не вникал, может надо вызвать IStream::Seek и вернуться в начало потока?
waleri вне форума Ответить с цитированием
Старый 08.10.2024, 20:55   #3
LUN2
Пользователь
 
Регистрация: 14.08.2021
Сообщений: 23
По умолчанию

waleri, спасибо!
Да, так оно и было.
Я ожидал, что в начале работы система сама установить нач. позицию, но видимо нет.
короче, Seek(pos=0) помогло...
LUN2 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Объект XHR через Qjuery spoon100500 JavaScript, Ajax 26 27.04.2019 14:29
Delphi базы данных, проблема с "нулевой" строкой в сортировке Taksebe Помощь студентам 4 22.12.2016 23:28
Не могу передать сериализованный объект через сокет - C# ne4kin C# (си шарп) 1 24.08.2015 11:16
Итерация через объект JSON в Javascript maomam Помощь студентам 0 03.11.2012 00:51
Возвращение массива записей через объект CodeNOT PHP 8 14.04.2011 18:30