我一直都在这一个,而我只是陷入困境。我一直在构建一个项目,我想将一个文本文件作为资源嵌入到可执行文件中。我理解这个“应该”如何工作的所有基础知识,但由于某种原因,它不是。所以,让我从目前的情况开始,也许可以解决这个问题。
这里有两个函数,第一个,EnumResNameProc试图调试我自己的问题,第二个,LoadFileInResource是我试图运行的函数。 这有点乱,因为当我开始遇到问题时,我正在构建它。
确切的问题是,FindResourceExA返回NULL,并且我遗失了确切的原因。我知道这是一个错误,返回代码是1813,“资源未找到”。
我在这个项目中有其他资源,我有一个版本节点,一个mainifest节点,(其中,我没有直接阅读)我有一个图标节点(我正在申请我的窗口系统菜单图标)和一个位图(我将其作为纹理加载。)。这些都有定义的类型,例如,Bitmap的类型是12.现在,我正在尝试加载一个文本文件,其中“用户定义”类型为10.我知道数据是INSIDE可执行文件,因为如果我在文本编辑器中打开它...(是的,我试过了)它存在,因此,它被包含在内。
第一个功能是尝试遍历所有文件资源以尝试定位数据。它找到了类型2,3,14,16和24.但不是10.我已经排除了这些其他类型作为上述资源。 (位图= 2),(icon = 3),(RT_ICON(3)+ RT_ICON_GROUP(11)= 14)(版本= 16),(清单= 24)。用户定义应该是类型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的结果,没有骰子。
对于LPCSTR,这是资源ID,我已经尝试了你看到的,MAKEINTRESOURCE(IDR_textfile1),我也试过硬编码ID号,在这种情况下,102。没有骰子。 对于类型,我已经厌倦了其他变化,根据微软的正确值应为10.这就是为什么我创建EnumResNameProc,试图查看其他ID存在,从0到500,我回来的是上面列出的那些,关于机会的事情被定义为有趣。没有骰子。
我已尝试过FindResourceExA FindResourceA(有和没有'Ex') 没有骰子。
我知道它就在那里,我已经学到了更多,然后我关心这个功能,但是它找不到它,而且我不知道还有什么可以尝试。
至于开发环境,我使用的是MinGW + Eclipse + CDT,并使用GCC工具中的winres来构建资源对象文件。我已经在winres中查找错误,看看它是否在二进制类型上做了一些有趣的事情。 (即使我正在加载文本文件,这也是未定义的内容。)哦,我还尝试将文件重新保存为ANSI,UTF-8和UNICODE,以防文本的二进制格式重要。
我不知所措,我不知道还能尝试什么。我知道数据存在,我只是不知道为什么它不会访问它。 Windows API调用既不能查看数据,也不能以screwey方式编码,因此无法访问它。
我还能尝试什么?
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);
}
答案 0 :(得分:6)
IDR_textfile1 textfile ".\\Data\\World.txt"
您将资源类型声明为“textfile”。这很好,但这是一个字符串,而不是一个数字。因此,使用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));
答案 1 :(得分:4)
对FindResourceExA
的调用是错误的,资源类型在第二个参数中传递,而id在第三个参数中传递。