Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
#1

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

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

Снова обращаюсь к уважаемому обществу. На этот раз проблема такая (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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.12.2013, 17:59
Я подобрал для вас темы с готовыми решениями и ответами на вопрос VC++2010 не могу открыть ресурсы (C++):

vs 2010 выдает ошибку fatal error C1083: Не удается открыть файл включение: iostream.h: No such file or directory - C++
всем привет! помогите пожалуйста исправить ошибку! вот код! #include &quot;StdAfx.h&quot; #include &lt;iostream.h&gt; using namespace std; ...

vs 2010 выдает ошибку fatal error C1083: Не удается открыть файл включение: ntddcdrm: No such file or directory - C++
Не понимаю в чем ошибка,помогите,пожалуйста. #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;windows.h&gt; #include &lt;winioctl.h&gt; ...

Не могу создать проект в VS 2010 - C++
Здравствуйте форумчане! В общем скачал на днях visual studio 2010 proffesional, в итоге при ее запуске я не могу создать проект, как это...

Не могу открыть хост - C++
Хочу написать программку которая будет редактировать файл host... но при написание кода (стандартное открытие файла) комп не может открыть,...

Не могу открыть проект С++ - C++
Есть готовые исходники задачи, все лежит в папке, могу открыть каждый файл по отдельности и просмотреть код через visual studio 2013...

Не могу нормально открыть файл - C++
Скачал Microsoft Visual C ++ 2010, создал пустой проект, добавил файл с вот таким кодом. #include &lt;stdio.h&gt; int main() { ...

28
alsav22
5435 / 4830 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.12.2013, 18:21 #2
Цитата Сообщение от kotgav Посмотреть сообщение
Включил текстовый файл .txt в ресурсы
Сам файл где находится?
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
08.12.2013, 18:19  [ТС] #3
Цитата Сообщение от alsav22 Посмотреть сообщение
Сам файл где находится?
В проекте в папке res.
В файле resource.h автоматически записалось при подключении ресурса такое определение:
#define IDR_TEXT1 101

а в файле ресурсов Sht_Traning_Example.rc автоматически сформирован блок этого типа ресурса:
/////////////////////////////////////////////////////////////////////////////
//
// TEXT
//

IDR_TEXT1 TEXT "C:\\Users\\DMITRY\\Documents\\Visual Studio 2010\\Projects\\My_ProjectsFSX\\Sht_Training_Example\\res\\ShtProba.txt"

Тип пользовательского ресурса я определил как TEXT

Добавлено через 16 часов 23 минуты
Чудеса творятся!
Дополнил начало программы загрузкой библиотеки с нулевым значением, так сказать для порядка - указал все функции для работы с ресурсами. Читаю значение этой функции. Оно должно быть равно NULL, а оно какое угодно, только не NULL!
Т.е. программа в принципе не видит моего ресурса! Что делать?

Фрагмент, которым я дополнил программу:
C++
1
2
3
4
5
6
7
    HMODULE hMod=GetModuleHandle(NULL);
    
    std::cout << "Значение hMod: " << hMod << std::endl;
 
    if(!hMod) {            // Если хэндл модуля не равен нулю, т.е. модуль не ассоциирован с текущим процессом
        std::cout << "Модуль не ассоциирован с текущим процессом" << std::endl;
    }
Добавлено через 7 часов 14 минут
Проблема остается, ресурсы недоступны.
Дополнительная информация: попробовал почти все из доступных типов ресурсов, в том числе и пользовательский WAVE, пытался музыку увидеть в ресурсах. Ничего не меняется, сразу после функции FindResource программа сообщает об отсутствии ресурса и завершается.
В то же время, если я открываю текстовый файл не как ресурс, а просто как внешний файл, то его содержимое читается нормально.
Что же делать с открытием ресурса? Кто-нибудь может подсказать?
0
alsav22
5435 / 4830 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.12.2013, 18:27 #4
Цитата Сообщение от kotgav Посмотреть сообщение
Кто-нибудь может подсказать?
Всё это далеко от С++. Может в специально ветке по VC++ спросить? http://www.cyberforum.ru/visual-cpp/
0
lpvoid
322 / 305 / 17
Регистрация: 06.03.2013
Сообщений: 869
08.12.2013, 18:30 #5
http://stackoverflow.com/questions/2...ws-application
?
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
08.12.2013, 18:44  [ТС] #6
Большое спасибо за отклики!
Пример по ссылке посмотрел, на первый взгляд у меня так все и сделано. MSDN и другие источники о работе с ресурсами уже наизусть выучил, не меньше сотни экспериментов провел.
Буду экспериментировать дальше, может и наткнусь где на какую скрытую загогулину, которая откроет доступ к ресурсам.
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 10:19  [ТС] #7
Проблема доступа к ресурсам пока не решилась. Но кое-что изменилось, проблема действительно в сочетании С++ 2010 и VS 2010.
Сделал такие изменения в коде:
C++
1
2
3
4
5
6
7
8
9
10
11
    HMODULE hModS = GetModuleHandle(NULL);
    std::cout << "hModS:   " << hModS << std::endl;
 
    HRSRC hShtDataTXT = NULL;            // Определяем и инициализируем переменную ресурса
    
    LPCTSTR SIpName = MAKEINTRESOURCE(IDB_BITMAP2);
    LPCTSTR SIpType = MAKEINTRESOURCE(RT_BITMAP);
 
    hShtDataTXT = FindResource(hModS, SIpName, SIpType);     // Ищем файл ресурса. Получаем указатель на ресурс
     
    std::cout << "hShtDataTXT:   " << hShtDataTXT << std::endl;
Т.е. в явном виде применил макросы MAKEINTRESOURCE для имен ресурса и его типа. Так вот при загрузке битмапа появилось ненулевое значение дескриптора hShtDataTXT. Т.е. этот ресурс отыскивается.
Все другие ресурсы, всех других типов, указанных в MSDN и моих (пользовательских типа TEXT, TXT и т.д.) функция FindResource() завершает с результатом NULL, т.е. ресурс не находит.
Так же не дает результата изменение свойств данного ресурса с типа по умолчанию на тип ресурс. Это приводит к ошибке компиляции.
На подсказку не надеюсь уже, это просто для информации тем, кто столкнулся с подобной проблемой.
0
Убежденный
Ушел с форума
Эксперт С++
15929 / 7239 / 1140
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
10.12.2013, 12:30 #8
Цитата Сообщение от kotgav Посмотреть сообщение
Все другие ресурсы, всех других типов, указанных в MSDN и моих (пользовательских типа TEXT, TXT и т.д.) функция FindResource() завершает с результатом NULL, т.е. ресурс не находит.
Потому что "IDR_TEXT1" и MAKEINTRESOURCE(IDR_TEXT1) - разные вещи.
Обратите внимание, что в файле ресурсов у Вас объявлено так:
Код
#define IDR_TEXT1 101
а в коде загружается так:
C++
1
LPCTSTR IpName = "IDR_TEXT1";
Так что никаких чудес здесь нет, просто нужно быть чуть дотошнее в таких мелочах.

C++
1
2
3
4
5
HMODULE hMod=GetModuleHandle(NULL);
std::cout << "Значение hMod: " << hMod << std::endl;
if(!hMod) { // Если хэндл модуля не равен нулю, т.е. модуль не ассоциирован с текущим процессом
 std::cout << "Модуль не ассоциирован с текущим процессом" << std::endl;
 }
Этот код дважды ошибочен.
Во-первых, комментарий "Если хэндл модуля не равен нулю, т.е. модуль не ассоциирован с
текущим процессом" неверен - GetModuleHandle возвращает хэндл модуля, для NULL она
вернет хэндл exe, т.е. значение 0x400000, например. Во-вторых, комментарий не
соответствует проверке, т.к. условие "if(!hMod)" выполняется когда hMod == NULL, а в
комментарии сказано обратное.

проблема действительно в сочетании С++ 2010 и VS 2010.
Во всем всегда виноваты в первую очередь компилятор, Винда и Билл Гейтс лично.
1
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 13:38  [ТС] #9
Цитата Сообщение от Убежденный Посмотреть сообщение
Потому что "IDR_TEXT1" и MAKEINTRESOURCE(IDR_TEXT1) - разные вещи.
Обратите внимание, что в файле ресурсов у Вас объявлено так:
Код
#define IDR_TEXT1 101
а в коде загружается так:
C++
1
LPCTSTR IpName = "IDR_TEXT1";
Так что никаких чудес здесь нет, просто нужно быть чуть дотошнее в таких мелочах.
Большое спасибо за пояснение. Хотя с ним я окончательно запутался и ничего не понял.
Вот в этом фрагменте - среда VS2010 автоматически определила подключаемый текстовый файл в resourse.h. Имя этому ресурсу дано автоматически в соответствии с новым типом ресурса, который я определил как TEXT, и имя это - IDR_TEXT1. А цифровой идентификатор этого нового ресурса равен 101.
Из описаний MSDN следует, что в функцию FindResource(hMod, IpName, IpType) я должен поместить имя ресурса и его тип параметрами типа LPCTSTR.
Вот это я и сделал строчкой LPCTSTR IpName = "IDR_TEXT1";
Т.к. ресурс не отыскивается, то понимаю, что здесь что-то не так, хотя строковые данные типа LPCTSTR записываются именно так.
Применяю второй способ объявления параметров для FindResource - с помощью макросов MAKEINTRESOURCE(IDR_TEXT1). Причем пробую как строчные параметры IDR_TEXT1 и TEXT (применял и RT_RCDATA), так и цифровые - тот самый 101, а тип - 10.
Результат тот же, ресурс функция не находит.


Цитата Сообщение от Убежденный Посмотреть сообщение
Этот код дважды ошибочен.
Во-первых, комментарий "Если хэндл модуля не равен нулю, т.е. модуль не ассоциирован с
текущим процессом" неверен - GetModuleHandle возвращает хэндл модуля, для NULL она
вернет хэндл exe, т.е. значение 0x400000, например. Во-вторых, комментарий не
соответствует проверке, т.к. условие "if(!hMod)" выполняется когда hMod == NULL, а в
комментарии сказано обратное.
Это разъяснение тоже не понял, но принимаю его как аксиому. Это условие буду осваивать после отыскания своего текстового ресурса.

Еще раз спасибо за отклик!

P.S. Цитата из MSDN, описание функции FindResource:
lpName [in]
Type: LPCTSTR
The name of the resource. Alternately, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is the integer identifier of the resource.
Здесь четко написано, что это имя ресурса типа LPCTSTR.
Альтернативой ей может применяться MAKEINTRESOURCE(ID).
Других прочтений нет. Поэтому я и написал имя ресурса в кавычках.
0
Убежденный
Ушел с форума
Эксперт С++
15929 / 7239 / 1140
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
10.12.2013, 14:26 #10
Можно начать с более простого кода.
Например, среда Visual C++ по умолчанию вставляет в проект ресурс "манифест",
его тип - 24 (RT_MANIFEST), а имя - 1. Загрузить и отобразить этот ресурс
можно так:
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
#include <string>
#include <Windows.h>
 
 
 
#define PRINT_ERROR_AND_EXIT(FuncName)                                      \
{                                                                           \
    printf("%s failed (last error = %lu).\r\n", FuncName, GetLastError());  \
    return EXIT_FAILURE;                                                    \
}
 
 
 
int main()
{
    wchar_t const *pResName = MAKEINTRESOURCEW(1);
    wchar_t const *pResType = MAKEINTRESOURCEW(24); // RT_MANIFEST
 
    HRSRC const hResInfo = FindResourceW(NULL, pResName, pResType);
    if (NULL == hResInfo) PRINT_ERROR_AND_EXIT("FindResourceW");
 
    DWORD const ResSize = SizeofResource(NULL, hResInfo);
    if (0 == ResSize) PRINT_ERROR_AND_EXIT("SizeofResource");
 
    HGLOBAL const hRes = LoadResource(NULL, hResInfo);
    if (NULL == hRes) PRINT_ERROR_AND_EXIT("LoadResource");
 
    VOID const *pResData = LockResource(hRes);
    if (NULL == pResData) PRINT_ERROR_AND_EXIT("LockResource");
 
    std::string Str;
    Str.append(static_cast<char const *>(pResData), static_cast<DWORD>(ResSize));
    printf(Str.c_str());
    return EXIT_SUCCESS;
}


Вывод:
XML
1
2
3
4
5
6
7
8
9
10
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 18:16  [ТС] #11
Только что открыл и прочел содержимое текстового файла - ресурса!
Убежденный, большое спасибо за подсказку!
К вечеру опишу подробнее, как и что у меня получилось, может быть это случайно вышло :-)

Добавлено через 2 часа 16 минут
Описываю, как открылся текстовый файл-ресурс.
Подключил текстовый файл, как тип ресурса исходных данных RT_RCDATA, его значение 10.
Номер моего текстового файла автоматически определился в resource.h равным 115.
Использовал макросы MAKEINTRESOURCE(115) с численным значением имени и типа ресурса.
Получился такой код.
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
void ShtReadDATAFromFileRes()
{
    std::setlocale(LC_ALL, "Russian_Russia.1251");        // Устанавливаем русский шрифт для окна консоли
 
    //Получаем хэндл модуля (исполняемого файла, *.exe или *.dll), в котором лежит ресурс.
    HMODULE hModS = GetModuleHandle(NULL);
    std::cout << "hModS:   " << hModS << std::endl;
 
    HRSRC hShtDataTXT = NULL;            // Определяем и инициализируем переменную ресурса
    
    LPCTSTR SIpName = MAKEINTRESOURCE(115);
    LPCTSTR SIpType = MAKEINTRESOURCE(10);
 
    hShtDataTXT = FindResource(NULL, SIpName, SIpType);     // Ищем файл ресурса
     
    std::cout << "hShtDataTXT:   " << hShtDataTXT << std::endl;
 
    if(hShtDataTXT!=NULL)
    {
        std::cout <<  "Ресурс найден!" << "\n" << std::endl;
        HGLOBAL  hShtProbaRes = NULL;    // Определяем и инициализируем переменную для работы с функциями
        hShtProbaRes = LoadResource(NULL, hShtDataTXT);   // Загружаем ресурс в память
 
        if(hShtProbaRes!=NULL)
        {
            LPVOID res = LockResource(hShtProbaRes);    // Фиксируем наш файл в памяти, для чего передаем указатель HGLOBAL.
            DWORD dwSize = SizeofResource(0, hShtDataTXT);   // Определяем размер нашего текстового файла
            char *TXTFile = (char* )res;               // Приводим к типу char* и работаем с указателем как со строкой, хранящей все содержимое файла
// Читаем значение res и содержание файла
            std::cout << "res:  " << res << "\n" << std::endl;
            std::cout << "TXTFile:  " << "\n" << TXTFile << std::endl;
        }
        else
        std::cout <<  "Файл не открыт!" << "\n" << std::endl;
           return;                // Если файл не открыт, возвращается 0 по умолчанию
    }
    else
        std::cout <<  "Ресурс не найден!" << "\n" << std::endl;
        return;            // Если ресурс не найден, возвращается 0 по умолчанию
}
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 18:20  [ТС] #12
Запустил программу. Содержание всего файла вывелось в консольное окно.
0
Миниатюры
VC++2010 не могу открыть ресурсы  
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 18:24  [ТС] #13
Остались вопросы.
1. Почему после содержания файла выводится содержание манифеста? Я его не запрашиваю.
2. Как использовать информацию прочитанного текстового файла, в частности, как выводить и присваивать другим переменным символы и строки для дальнейшего использования в программе? Обычные процедуры работы с файлом, типа get, не помогают.
Если найду ответ, напишу.
Не найду, тоже напишу.
Еще раз спасибо всем за помощь!
0
Убежденный
Ушел с форума
Эксперт С++
15929 / 7239 / 1140
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
10.12.2013, 20:31 #14
Цитата Сообщение от kotgav Посмотреть сообщение
C++
1
char *TXTFile = (char* )res; // Приводим к типу char* и работаем с указателем как со строкой, хранящей все содержимое файла
Это ошибка. По умолчанию ресурсы не обязаны заканчиваться нулевым символом.
0
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
10.12.2013, 21:36  [ТС] #15
Цитата Сообщение от Убежденный Посмотреть сообщение
Это ошибка. По умолчанию ресурсы не обязаны заканчиваться нулевым символом.
То есть текст, который идет в консольном окне после содержания файла - это сообщение об ошибке? И дает ее эта строка?
Я эту строку:
char *TXTFile = (char* )res;
подсмотрел где-то в пояснениях и в примерах. Показалась вполне понятной - берем результат загрузки ресурса и определяем его в памяти. Указатель типа char на ячейку используем для вывода содержимого файла.
Поизучаю еще, подумаю.
0
10.12.2013, 21:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.12.2013, 21:36
Привет! Вот еще темы с ответами:

Не могу открыть файл fstream - C++
Добрый день. Не могу открыть файл с помощью fstream файл, файл лежит в корне проекта. Пользуюсь QT creator с gcc. #include &lt;iostream&gt; ...

Не могу открыть файл OFSTREAM - C++
Доброго времен суток! Помогите разобраться: пытаюсь открыть файл с параметром ios::out, а он не открывается :( Почему это может...

Не могу открыть старые проекты - C++
Вобщем все началось с переустановки ОС, на С ++ я работаю недели 2-3. Мои проекты сохранялись в документах на диске С, перед переустановкой...

Не могу открыть программу на других компьютерах - C++
Здравствуйте! Написал програмку которая общается с SQLite и делает разные запросы к ней. У меня всё работает прекрасно! Но на других...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru