Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
1

VC++2010 не могу открыть ресурсы

07.12.2013, 17:59. Показов 4449. Ответов 28
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Снова обращаюсь к уважаемому обществу. На этот раз проблема такая (VS2010 Professional, консольное приложение).
Включил текстовый файл .txt в ресурсы. Написал такой доступ к нему (ниже). Однако никак такой код не хочет находить мой ресурс, сразу уходит на сообщение "Ресурс не найден". Т.е. функция FindResource возвращает не имя ресурса, а NULL.
Что надо сделать, чтобы ресурс был найден и можно было читать данные из текстового файла?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <clocale>
#include <strsafe.h>
 
// == Пробная Функция открытия текстового файла ресурса и чтения строк и символов из него ======
 
char ShtReadDATAFromFile()
{
    std::setlocale(LC_ALL, "Russian_Russia.1251");   // Устанавливаем русский шрифт для окна консоли
 
    HRSRC hShtDataTXT = NULL;      // Определяем и инициализируем переменную ресурса
    char buf[75] = {0};                  // Определяем и инициализируем нулями сроку длиной 75 символов    
    
    HMODULE hModule = NULL;
    LPCTSTR IpName = "IDR_TEXT1";
    LPCTSTR IpType = "TEXT";
    hShtDataTXT = FindResource(hModule, IpName, IpType);  // Ищем файл ресурса. Получаем указатель на ресурс
 
    if(hShtDataTXT!=NULL)         // Если указатель не равен нулю 
    {
        std::cout <<  "Ресурс найден!" << "\n" << std::endl;
        HGLOBAL  hShtAirportsRes = NULL;   // Определяем и инициализируем переменную для работы с другими функциями
        hShtAirportsRes = LoadResource(0, hShtDataTXT);  // Загружаем и открываем файл ресурса 
        if(hShtAirportsRes!=NULL)
        {
            LPVOID res = LockResource(hShtAirportsRes);         // Фиксируем наш файл в памяти, для чего передаем указатель HGLOBAL.
                                                                // Приводим к типу const char* и работаем с указателем как со строкой, хранящей все содержимое файла
            DWORD dwSize = SizeofResource(0, hShtDataTXT);      // Определяем размер нашего текстового файла
            char *t = (char* )res;
            
            std::ifstream  AirportDATA("ShtProba.txt");    // Объявляем объект AirportDATA типа ifstream и открываем текстовый файл ресурса для вывода данных
            std::cout <<  "Файл открыт!" << "\n" << std::endl;
 
            AirportDATA.getline(buf, 75, 0);                  // Считываем первую строчку
            std::cout <<  "A:  " << AirportDATA.getline(buf, 75, 0)  << std::endl;
            return buf[1];
        }
        else
        std::cout <<  "Файл не открыт!" << "\n" << std::endl;
           return NULL;                // Если файл не открыт, возвращается 0 по умолчанию
    }
    else
        std::cout <<  "Ресурс не найден!" << "\n" << std::endl;
        return NULL;            // Если ресурс не найден, возвращается 0 по умолчанию
}
 
// Главная программа С++
//--------------------------------
int __cdecl _tmain(int argc, _TCHAR* argv[])
{
    ShtReadDATAFromFile();
 
    std::system("Pause");               // Предотвращение закрытия консольного окна
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.12.2013, 17:59
Ответы с готовыми решениями:

аксес 2003 ( ХР ) не могу открыть на 2010 ( 7 )
создал простейшую БД на 2003 (ХР) написано несколько макросов вба на 2010 ( 7 ) при открытии...

Не могу открыть в Microsoft Visual Studio 2010 Express
Здравствуйте не могу отрыть SmsBase_v2.0.sln. Пишет один или несколько проектов в решении не были...

Access 2010 не могу открыть бд (workgroup information file is missing)
не могу открыть бд Access 2010.. вот код Dim cn As ADODB.connection Dim cnStr As String ...

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

28
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:16 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от kotgav Посмотреть сообщение
Открыл свой текстовый ресурс в проекте, в конце дописал \0. И сохранил это изменение.
Почерпнул этот прием из учебника: Прохоренок Н.А. Глава 6 Символы и строки стр.20. (на первом скрине выдержка из учебника).
Указывал и без кавычек, и в кавычках символ \0 выводится как обычный символ.
На скрине, разве '\0' добавляется в текстовом редакторе (как вы сделали)? Когда вы в текстовом редакторе пишите '\0', то это не терминальный ноль (управляющий символ), а просто четыре символа. Терминальный ноль существует в языке, в коде, (в редакторе его нет), и использовать его можно только методами языка. Например, строковые функции чтения из файла добавляют его в конец строки. В файл, терминальный ноль, можно записать в бинарном режиме, т.е., открыть файл для дозаписи в конец файла (ios::app), и, в бинарном режиме, записать туда переменную char, со значением 0:
C++
1
2
3
4
5
fstream f("file.txt", ios::app);
char ch = 0;
f.write((const char*)&ch, 1);
 
f.close();
1
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
11.12.2013, 17:26  [ТС] 22
Вот какой код в результате получился:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void ShtReadDATAFromFileRes()
{
    std::setlocale(LC_ALL, "Russian_Russia.1251");        // Устанавливаем русский шрифт для окна консоли
 
    /*Получаем хэндл модуля (исполняемого файла, *.exe или *.dll), в котором лежит ресурс.
    NULL означает модуль, ассоциированный с текущим процессом, хотя возвращен будет не ноль, а хэндл модуля.
    При работе с текущим модулем можно сразу вызывать FindResource, передавая первым параметром NULL, а под VCL можно использовать глобальную HInstance*/
    HMODULE hModS = GetModuleHandle(NULL);
    std::cout << "hModS:   " << hModS << std::endl;    // Вызываем в консоль для проверки
 
    HRSRC hShtDataTXT = NULL;            // Определяем и инициализируем переменную ресурса
 
    // Определяем указатели имени и типа ресурса
    wchar_t const *pResName = MAKEINTRESOURCEW(115); // Номер в resource.h
    wchar_t const *pResType = MAKEINTRESOURCEW(10);  // RT_RCDATA для текстового файла
    
    // Производим поиск ресурса
    HRSRC const hResInfo = FindResourceW(hModS, pResName, pResType);
    if (NULL == hResInfo)
    {
        std::cout << "Ресурс не найден!" << std::endl;
        return;  // Если ресурс не найден, возвращается 0 по умолчанию, выход из программы
    }
    
    // Определяем размер ресурса
    DWORD const ResSize = SizeofResource(NULL, hResInfo);
    if (0 == ResSize)
    {
        std::cout << "Размер ресурса не определен!" << std::endl;
        return;  // Если размер ресурса не определен, возвращается 0 по умолчанию, выход из программы
    }
 
    // Загружаем ресурс в память
    HGLOBAL const hRes = LoadResource(NULL, hResInfo);
    if (NULL == hRes)
    {
        std::cout << "Ресурс не загружен!" << std::endl;
        return;  // Если ресурс не загружен, возвращается 0 по умолчанию, выход из программы
    }       
 
    // Получаем указатель на ресурс, как на строку. Читаем его
    VOID const *pResData = LockResource(hRes);
    if (NULL == pResData)
    {
        std::cout << "Ресурс не читается!" << std::endl;
        return;  // Если ресурс не читается, возвращается 0 по умолчанию, выход из программы
    }           
            std::string Str;
            std::string TextFromResource;
            TextFromResource.append(static_cast<char const *>(pResData), static_cast<DWORD>(ResSize));
 
            std::cout << "dwSize:  " << ResSize << "\n" << std::endl;
            std::cout << "TXTFile:  " << "\n" << TextFromResource << std::endl;
}
Результат показан на скрине консольного окна, файл читается правильно.
Миниатюры
VC++2010 не могу открыть ресурсы  
0
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
11.12.2013, 17:30  [ТС] 23
Цитата Сообщение от alsav22 Посмотреть сообщение
На скрине, разве '\0' добавляется в текстовом редакторе (как вы сделали)? Когда вы в текстовом редакторе пишите '\0', то это не терминальный ноль (управляющий символ), а просто четыре символа. Терминальный ноль существует в языке, в коде, (в редакторе его нет), и использовать его можно только методами языка. Например, строковые функции чтения из файла добавляют его в конец строки. В файл, терминальный ноль, можно записать в бинарном режиме, т.е., открыть файл для дозаписи в конец файла (ios::app), и, в бинарном режиме, записать туда переменную char, со значением 0:
C++
1
2
3
4
5
fstream f("file.txt", ios::app);
char ch = 0;
f.write((const char*)&ch, 1);
 
f.close();
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:44 24
Цитата Сообщение от kotgav Посмотреть сообщение
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
Да.
1
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
11.12.2013, 17:50  [ТС] 25
Понятно.
Убежденный и alsav22!
Большое Вам спасибо за помощь!
Вопрос с открытием и чтением ресурса решен.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:51 26
Цитата Сообщение от kotgav Посмотреть сообщение
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
Но это, если очень нужно именно через терминальный ноль в конце файла (некое извращение). Если есть другой способ, то лучше его использовать.
0
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
22.12.2013, 12:22  [ТС] 27
Возвращаюсь к проблеме чтения ресурса.
Мне надо, чтобы ресурс хранился в библиотеке. Там же происходит некоторая обработка, связанная с чтением ресурса. На основе примера в сообщении #22 я сделал функцию чтения текстового ресурса, подключил к библиотеке ресурс и скомилировал файл *.dll.
Из исполняющей exe программы я обращаюсь к библиотеке и хочу увидеть значение одного из параметров ресурса.
Библиотека и библиотечная функция чтения ресурса отыскиваются нормально, параметр HMODULE hModS имеет не нулевое значение, параметры функции
HRSRC const hResInfo = FindResourceW(hModS, pResName, pResType);
тоже имеют ненулевые значения, т.е. функция нахождения текстового ресурса FindResourceW должна завершиться с ненулевым значением. А она возвращает 0!
Т.е. ресурс на находит.
В то же время, если я подключаю ресурс также и в исполняющую программу, то ресурс библиотечная функция находит и открывает исправно.
В чем может быть дело?
Мне надо хранить ресурс именно в библиотеке.

Добавлено через 11 минут
Дополнение.
Если точнее описать задачу, то мне надо иметь две библиотеки.
Одна - с текстовыми файлами ресурсов.
Другая - с функциями обработки тестовых файлов ресурсов, из которой вызывается первая библиотека.
А уже исполняющая программа вызывает вторую библиотеку.
Т.е. такая пирамида получается:
исполняющая программа -> библиотека2 -> библиотека1(с ресурсами).
0
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
24.12.2013, 14:58  [ТС] 28
Еще дополнение.
Попробовал открывать текстовый файл (не ресурс) через библиотеку с помощью std::ifstream, open() и прочих функций открытия текстового файла.
Не Открывает!
Может быть С++ в принципе не может работать с файлами-ресурсами и текстами через библиотеку?
Если так, то грустно!
0
3 / 3 / 1
Регистрация: 13.07.2013
Сообщений: 71
19.01.2014, 15:24  [ТС] 29
Для тех, кто столкнется с такой же проблемой.
Напомню, что мне надо было использовать ресурс, находящийся в текстовом файле и включенный в библиотеку DLL №1. В свою очередь, доступ к библиотеке DLL №1 должен быть из библиотеки DLL №2. А уже доступ к библиотеке DLL №2 должен быть из исполняющего файла. Т.е. цепочка доступа к ресурсу такая:
исполняющая программа -> библиотека №2 -> библиотека №1(с ресурсами).
Открытие файла ресурса, который находится в библиотеке №1, через библиотеку № 1, долго не мог произвести и вот наконец добился положительного результата.
Причина оказалась простой - соглашение о вызовах!
Это соглашение о вызове функции для доступа к библиотеке и ресурсам (у меня оно extern "C" __declspec(dllexport) ) было записано только в библиотеке №1. А во второй библиотеке написать забыл. Поэтому доступ к библиотекам был, а доступа к функциям, и соответственно - к ресурсам, не было.
Теперь все работает, ресурс через две библиотеки открывается и читается.
0
19.01.2014, 15:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.01.2014, 15:24
Помогаю со студенческими работами здесь

Прошу открыть проект в VS 2010
Прошу открыть проект в VS 2010 и скинуть мне код в читаемом виде. Если конечно удастся (вдруг...

Возможно ли проект, созданный в C++ 6.0, открыть в C++ 2010?
Подскажите, плиз, возможно ли открыть проект созданный в Microsoft visual C++ 6.0 открыть в...

Как открыть программу VS 2012 в VS 2010
Имеется VS 2010 и программа написанная в более новой версии - VS 2012. Как открыть ее???

Excel 2010 открыть в разных окнах
Перейду с ходу к сути. :help: Есть ПК с Excel 2010. + 2 монитора Необходимо открывать 2 файла в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru