c++ - 从 c++ CLR/CLI 项目的资源文件加载图像
问题描述
我的项目是一个c++ CLR/CLI,我的资源文件中有一些PNG图像,我想在System::Windows::Forms::Button
单击按钮时更改a的BackgroundImage,我的代码如下:
#include <Windows.h>
#include "resource.h"
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
HBITMAP hBitMap = (HBITMAP) LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PNG2), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
Bitmap^ bitMap = Bitmap::FromHbitmap((IntPtr) hBitMap);
DeleteObject(hBitMap);
button1->BackgroundImage = (System::Drawing::Image^) bitMap;
}
这是我的资源.h:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Disneyy.rc
//
#define IDB_PNG1 101
#define IDB_PNG2 102
#define IDB_PNG3 103
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
编译时出现此错误:
1>MyForm.obj : error LNK2028: unresolved token (0A000036) "extern "C" void * __stdcall LoadImageW(struct HINSTANCE__ *,wchar_t const *,unsigned int,int,int,unsigned int)" (?LoadImageW@@$$J224YGPAXPAUHINSTANCE__@@PB_WIHHI@Z) referenced in function "private: void __clrcall Disneyy::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@MyForm@Disneyy@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>MyForm.obj : error LNK2028: unresolved token (0A00003F) "extern "C" int __stdcall DeleteObject(void *)" (?DeleteObject@@$$J14YGHPAX@Z) referenced in function "private: void __clrcall Disneyy::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@MyForm@Disneyy@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>MyForm.obj : error LNK2019: unresolved external symbol "extern "C" void * __stdcall LoadImageW(struct HINSTANCE__ *,wchar_t const *,unsigned int,int,int,unsigned int)" (?LoadImageW@@$$J224YGPAXPAUHINSTANCE__@@PB_WIHHI@Z) referenced in function "private: void __clrcall Disneyy::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@MyForm@Disneyy@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>MyForm.obj : error LNK2019: unresolved external symbol "extern "C" int __stdcall DeleteObject(void *)" (?DeleteObject@@$$J14YGHPAX@Z) referenced in function "private: void __clrcall Disneyy::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click@MyForm@Disneyy@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
编辑: 好的,我通过将 User32.lib 添加到 Additional Dependencies 来修复它,并将入口点指定为 main。但是,这条线有问题:
HBITMAP hBitMap = (HBITMAP) LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PNG2), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
现在我收到此错误:
First-chance exception at 0x77130c3f in Disneyy.exe: 0xC0000005: Access violation reading location 0x00000066.
A first chance exception of type 'System.AccessViolationException' occurred in Disneyy.exe
An unhandled exception of type 'System.AccessViolationException' occurred in Disneyy.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
编辑:
我再次通过更改IMAGE_BITMAP
为来修复它BI_PNG
,但现在出现了一个新错误:Bitmap^ bitMap = Bitmap::FromHbitmap((IntPtr) hBitMap);
A first chance exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
Additional information: A generic error occurred in GDI+.
解决方案
最后经过数小时的研究,我找到了一个很好的适应解决方案!
该解决方案结合了 Giuseppe Pischedda 的回答:https ://www.codeproject.com/Articles/17996/Load-JPEG-images-from-DLL-with-LoadResource-in-Man
由我改编为PNG图像:
public: System::Drawing::Image^ getImageFromRes(long resource_ID) {
// Function getImageFromRes
// A function for loading PNG images from resources in C++ CLR/CLI
// Copyright (C) Giuseppe Pischedda 2007 for most code
// and a little part of this code by Bordon and adapted by me for PNG images in C++ CLR/CLI.
//Load the resource module:
HMODULE hInst = NULL;
// Find the resource using the resource ID from file "resource.h"
HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(resource_ID), L"PNG");
if (!hResource) return nullptr;
// Load the resource and save the total size.
DWORD Size = SizeofResource(hInst, hResource);
HGLOBAL MemoryHandle = LoadResource(hInst, hResource);
if (MemoryHandle == NULL) return nullptr;
//Create a cli::array of byte with size = total size + 2
cli::array<BYTE>^ MemPtr = gcnew array<BYTE>(Size + 2);
//Cast from LPVOID to char *
char *lkr = (char *) (LockResource(MemoryHandle));
//Copy from unmanaged memory to managed array
System::Runtime::InteropServices::Marshal::Copy((IntPtr) lkr, MemPtr, 0, Size);
// Create a new MemoryStream with size = MemPtr
System::IO::MemoryStream^ stream = gcnew System::IO::MemoryStream(MemPtr);
//Write in the MemoryStream
stream->Write(MemPtr, 0, Size);
//Set the position for read the stream
stream->Position = 0;
//Free allocated resources
FreeLibrary(hInst);
//Create an Image abstract class pointer
System::Drawing::Image^ ptrPNG;
//Assign the stream to abstract class pointer
ptrPNG = System::Drawing::Image::FromStream(stream);
return ptrPNG;
}
用法:
System::Drawing::Image^ image = getImageFromRes(IDB_PNG2);
if (image != nullptr) button1->BackgroundImage = image;
推荐阅读
- python - shelljs.exec(`sudo pkill -P ${process.pid}` 在 ubuntu 中不起作用
- python - Matplotlib - 用三角形框注释图
- python - 如何将 3D Obj 文件转换为图矩阵的邻接矩阵
- go - go get failed with "AsynkronIT / protoactor-go" undefined: balancer.PickOptions and undefined: resolver.BuildOption
- python-3.x - 将字符串 1-24 转换为日期时间格式
- javascript - 使用 HTML5 和 Javascript 录制/上传带有进度条的固定长度视频
- python - 贝叶斯神经网络 PYMC3 代码执行中的问题..error: ('Variable type field must be a TensorType.',)
- permissions - ~Library 文件夹的扩展属性
- amazon-web-services - AWS ECS 任务定义更新
- javascript - JavaScript 中的 Collatz 猜想