Qua*_*002 3 c++ resources winapi
我一直都在这一个,而我只是陷入困境.我一直在构建一个项目,我想将一个文本文件作为资源嵌入到可执行文件中.我理解这个"应该"如何工作的所有基础知识,但由于某种原因,它不是.所以,让我从目前为止开始,也许可以解决问题.
这里有两个函数,第一个,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"
Run Code Online (Sandbox Code Playgroud)
这定义了要加载的文件(再次,我知道这有效,我可以在可执行文件中看到代码的文本.)
我的resources.h文件定义了以下内容:
#define IDR_textfile1 102
Run Code Online (Sandbox Code Playgroud)
因此,它被定义,包含,构建,并且所有其他资源都可以工作,但FindResourceExA在此处返回NULL.所有包含文件都排成一行,(如果不是,我会收到警告和错误.)
所以,问题是,我正确地调用了FindResourceExA吗?它被定义为:
WINBASEAPI HRSRC WINAPI FindResourceExA(HINSTANCE,LPCSTR,LPCSTR,WORD);
Run Code Online (Sandbox Code Playgroud)
好吧,我已经尝试过HINSTANCE,null,hInstance在WinMain中传递给我的Windows,甚至是GetModuleHandleA的结果,没有骰子.
对于LPCSTR,这是资源ID,我已经尝试了你看到的,MAKEINTRESOURCE(IDR_textfile1),我也试过硬编码ID号,在这种情况下,102.没有骰子.对于类型,我已经厌倦了其他变化,根据微软的正确值应为10.这就是为什么我创建EnumResNameProc,试图查看其他ID存在,从0到500,我回来的是上面列出的那些,关于机会的事情被定义为有趣.没有骰子.
我已经尝试了FindResourceExA FindResourceA(有和没有'Ex')No Dice.
我知道它就在那里,我已经学到了更多,然后我关心这个功能,但是它找不到它,而且我不知道还有什么可以尝试.
至于开发环境,我使用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);
}
Run Code Online (Sandbox Code Playgroud)
IDR_textfile1 textfile ".\\Data\\World.txt"
Run Code Online (Sandbox Code Playgroud)
您将资源类型声明为"textfile".这很好,但这是一个字符串,而不是一个数字.因此,使用MAKEINTRESOURCE()作为资源类型不会帮助您找到它,这就是EnumResourceNames找不到它的原因.固定:
IDR_textfile1 RC_DATA ".\\Data\\World.txt"
Run Code Online (Sandbox Code Playgroud)
和
HRSRC rc = FindResourceEx(hInstance,
MAKEINTRESOURCE(RC_DATA),
MAKEINTRESOURCE(IDR_textfile1),
MAKELANGID(LANG_NEUTRAL,
SUBLANG_NEUTRAL));
Run Code Online (Sandbox Code Playgroud)
或者如果您想使用原始方法:
HRSRC rc = FindResourceEx(hInstance,
L"textfile",
MAKEINTRESOURCE(IDR_textfile1),
MAKELANGID(LANG_NEUTRAL,
SUBLANG_NEUTRAL));
Run Code Online (Sandbox Code Playgroud)
调用FindResourceExA
错误,资源类型在第二个参数中传递,id在第三个参数中传递。