c++ - FindResource() 无法找到数据,即使数据在 exe 中

标签 c++ winapi resources

我一直都在研究这个,但我只是被困住了。我一直在构建一个项目,我想将一个文本文件作为资源嵌入到可执行文件中。我理解这个“应该”如何工作的所有基础知识,但出于某种原因,事实并非如此。因此,让我从目前的情况着手,也许可以确定问题所在。

这里有两个函数,第一个,EnumResNameProc 是我自己调试问题的尝试,第二个,LoadFileInResource 是我试图开始工作的函数。 它有点乱,因为当我开始遇到问题时,我正在构建它。

确切的问题是,FindResourceExA 返回 NULL,我不知道确切的原因。我知道这是一个错误,返回代码是 1813,“找不到资源”。

我在这个项目中还有其他资源,我有一个版本节点,一个 mainifest 节点,(其中,我没有直接读取)我有一个图标节点(我正在应用于我的窗口系统菜单图标)和一个位图(我正在加载为纹理。)。这些都有定义的类型,例如,位图的类型是 12。现在,我正在尝试加载一个文本文件,其“用户定义”类型为 10。我知道数据在可执行文件中,因为如果我在文本编辑器中打开它...(是的,我试过了)它存在,所以它被包含在内。

第一个函数是尝试遍历所有文件资源以定位数据。它找到了类型 2、3、14、16 和 24,但没有找到 10。我已经排除了这些其他类型是上述资源。 (位图=2),(图标=3),(RT_ICON(3)+RT_ICON_GROUP(11)=14)(版本=16),( list =24)。 User defined 应该是type 10,但是没找到。

我的 Resources.rc 文件包括以下内容:

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_textfile1      textfile       ".\\Data\\World.txt"

这定义了要加载的文件,(同样,我知道这有效,我可以在可执行文件中看到代码的文本。)

我的 resources.h 文件定义如下:

#define IDR_textfile1                           102

因此,它正在被定义、包含、构建,并且所有其他资源都在工作,然而,FindResourceExA 对此返回 NULL。所有包含文件都已排列,(如果不是,我会收到警告和错误。)

所以,问题是,我是否正确调用了 FindResourceExA?它被定义为:

WINBASEAPI HRSRC WINAPI FindResourceExA(HINSTANCE,LPCSTR,LPCSTR,WORD);

好吧,我已经尝试了 HINSTANCE,null,hInstance 在 WinMain 中传递为我的 Windows,甚至 GetModuleHandleA 的结果,没有骰子。

对于作为资源 ID 的 LPCSTR,我已经尝试过您所看到的 MAKEINTRESOURCE(IDR_textfile1),并且我也尝试过对 ID 号进行硬编码,在本例中为 102。没有骰子。 对于该类型,我已经厌倦了其他变体,根据 Microsoft 的正确值应该是 10。这就是我创建 EnumResNameProc 的原因,试图查看存在的其他 ID,从 0 到 500,而我得到的只是上面列出的那些,在偶然的情况下,某些事情被定义为有趣。没有骰子。

我已经尝试了 FindResourceExA FindResourceA(有和没有“Ex”) 没有骰子。

我知道它在那里,我了解的比我关心的更多,但它找不到它,我不知道还能尝试什么。

开发环境,我是用MinGW+Eclipse+CDT,用GCC工具中的winres构建资源目标文件。我已经在 winres 中寻找错误,看看它是否在二进制类型上做了一些有趣的事情。 (这就是未定义的内容,即使我正在加载文本文件。)哦,我还尝试将文件重新保存为 ANSI、UTF-8 和 UNICODE,以防文本的二进制格式很重要。

我很茫然,我不知道还能尝试什么。我知道数据在那里,我只是不知道为什么它不会访问它。 Windows API 调用要么看不到数据,要么数据以一种奇怪的方式编码,因此它无法访问它。

我还能尝试什么?

BOOL CALLBACK EnumResNameProc (
  HMODULE hModule,
  LPCTSTR lpszType,
  LPTSTR lpszName,
  LONG_PTR lParam)
{
    std::cerr << "WTF INFO BEGIN here! \n";
    // std::string info = lpszName;
    int a = lParam;
    std::cerr  << "We found something: " << a << std::endl;
    MessageBoxA ( NULL, lpszName, (LPCSTR) "Found: ", MB_OK);
    std::cerr << "WTF INFO END here! \n";
    return true;
} 

void LoadFileInResource( HINSTANCE hInstance,
                         int name,
                         int type,
                         DWORD size,
                         const char* data)
{
    //  HMODULE handle = GetModuleHandleA(NULL);

    for (int a = 0;a<500;a++) {
    EnumResourceNamesA(hInstance, MAKEINTRESOURCE(a),
                      (ENUMRESNAMEPROCA) & EnumResNameProc, (LONG_PTR) a);
   }

   HRSRC rc = FindResourceExA(hInstance,
                               MAKEINTRESOURCE(IDR_textfile1),
                               MAKEINTRESOURCE(10),
                               MAKELANGID(LANG_NEUTRAL,
                               SUBLANG_NEUTRAL));
   if (rc == NULL) {
       DWORD fup = GetLastError();
       MessageBoxA ( NULL, (LPCSTR) "Crap not loaded.", (LPCSTR) "Error", MB_OK);
       std::cerr << "Crap not loaded, ERR: " << fup << std::endl;
   }

   // MessageBoxA ( NULL, (LPCSTR) " Test ", (LPCSTR) "Found: ", MB_OK);
   HGLOBAL rcData = LoadResource(hInstance, rc);
   // data = static_cast<const char*>(LockResource(rcData));
   data = (const char*) LockResource(rcData);
   size = SizeofResource(hInstance, rc);
   std::cout << "Res size = " << (long) size << std::endl;
   std::cout << "data =" << data << :: std::endl;
   //    wsprintf(szMsg,"Values loaded : %d, %d, %d\nSize = %d",
   //    pmem->Value1,pmem->Value2,pmem->Value3);
   //   MessageBox(hWnd, szMsg,lpszAppName,MB_OK);
}

最佳答案

IDR_textfile1      textfile       ".\\Data\\World.txt"

您将资源类型声明为“文本文件”。这很好,但那是一个字符串,而不是一个数字。因此,对资源类型使用 MAKEINTRESOURCE() 不会帮助您找到它,这就是 EnumResourceNames 找不到它的原因。修复:

IDR_textfile1      RC_DATA       ".\\Data\\World.txt"

HRSRC rc = FindResourceEx(hInstance,
                           MAKEINTRESOURCE(RC_DATA),
                           MAKEINTRESOURCE(IDR_textfile1),
                           MAKELANGID(LANG_NEUTRAL,
                           SUBLANG_NEUTRAL));

或者如果您想使用原来的方法:

HRSRC rc = FindResourceEx(hInstance,
                           L"textfile",
                           MAKEINTRESOURCE(IDR_textfile1),
                           MAKELANGID(LANG_NEUTRAL,
                           SUBLANG_NEUTRAL));

关于c++ - FindResource() 无法找到数据,即使数据在 exe 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9646752/

相关文章:

scala - 如何从sbt/apache flink项目中的资源文件夹中打开文件

visual-studio - 如何 merge 资源文件?

c++ - Qt Widgets 和派生类

c++ - 关键点大小和倍频程之间的 OpenCV 连接

c - 提高屏幕捕获性能

winapi - EnumProcessModules 返回 0 错误 299

解决方案子文件夹中的 C# 资源文件导致 MissingManifestResourceException

c++ - catch 站点异常的常见用法是什么?

C++:简单方程式的问题?

c++ - IAT Hook - 无法 Hook ExitProcess