gpt4 book ai didi

c++ - 使用 dll 运行时按钮上未显示位图

转载 作者:行者123 更新时间:2023-11-27 23:13:49 25 4
gpt4 key购买 nike

HBITMAP g_startcapBitmap = NULL, g_stopcapBitmap= NULL;
int nScreenWidth, ntWinx;


enum {ID_BUTTON_START=1,ID_BUTTON_STOP}; //constants for buttons
/*
* Message loop handler for the notification window.
*/
LRESULT CALLBACK myWndProcedure(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

std::string json;
switch(Msg)
{
case WM_CREATE:
buttonStart = CreateWindowEx(WS_EX_TOPMOST,L"Button",L"START CAPTURE",BS_PUSHBUTTON | BS_BITMAP | WS_CHILD | WS_VISIBLE ,10,1,180,30,hWnd,(HMENU)ID_BUTTON_START,NULL,0);
g_startcapBitmap = (HBITMAP)::LoadImage(GetModuleHandle(NULL),
//L"StartCaptureWhite.bmp",
MAKEINTRESOURCE(IDB_BITMAP1),
IMAGE_BITMAP,
180,
30,
LR_DEFAULTCOLOR);
if(g_startcapBitmap == NULL)
LOG_INFO("loading startbitmap failed...!");
if( ::SendMessage(buttonStart, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_startcapBitmap) == 0)
LOG_INFO("sendimage for btnstart failed...!");


break;


case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);

EndPaint(hWnd, &ps);
break;



case WM_COMMAND: //Command from Child windows and menus are under this message
switch(wParam) //the ID is wParam
{
case ID_BUTTON_START: //check for our button ID btnStart
{

json.clear();
ScreenEvent screenEvent("CONTROL","START");
json = screenEvent.getJSONtextAsString();
ScreenIndexHandler* screenIndexHandler = ScreenIndexHandler::getInstance();
if(screenIndexHandler == NULL )
{
LOG_INFO("Bad Screenhandler object");
exit(0);
}
screenIndexHandler->addToEventQueue(json);

::SetWindowPos(hWnd,NULL,ntWinx,0,200,5,SWP_DRAWFRAME);

buttonStop = CreateWindowEx(WS_EX_TOPMOST, L"Button",L"STOP CAPTURE",BS_PUSHBUTTON |BS_BITMAP | WS_CHILD | WS_VISIBLE, 0,0,0,0,hWnd,(HMENU)ID_BUTTON_STOP,NULL,0);
g_stopcapBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_BITMAP2),
//L"..//..//images//StopCaptureWhite.bmp",
IMAGE_BITMAP,
180,
30,
LR_DEFAULTCOLOR);

::SendMessage(buttonStop, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_stopcapBitmap);
::ShowWindow(buttonStart,SW_HIDE);
::UpdateWindow(hWnd);

NotificationWindow::isStartCap = true;
LOG_INFO("Added to EventQueue!");
break;
}

这是通知窗口的代码,当我的插件的某些方法被调用时会显示。

以上代码实际上是插件dll 使用的库(.lib) 文件的一部分。情况是当我将资源文件与独立 exe 的测试程序链接时,开始和停止按钮上的图像得到显示。

但是,当我创建 dll(它是另一个使用我的 .lib 的 .sln 的一部分)时,它的创建没有问题。 .dll 文件包含我使用 .rc 文件嵌入的 2 个图像(使用一些 dll 提取工具验证)。

现在,当我通过浏览器调用 dll 并调用其负责显示通知窗口(带有开始按钮)的函数时,窗口会显示,但 NO IMAGE on开始按钮。

日志显示 LoadImage() 函数失败,因此 SendMessage() 也失败。

如何用dll解决这个问题?

有没有其他方法可以给按钮打包图片/

请帮忙。

谢谢!

最佳答案

关键大概就在这段代码中:

LoadImage(GetModuleHandle(NULL), ...)

GetModuleHandle(NULL)始终返回应用程序主 EXE 的句柄,但您的图像位于 DLL 的资源部分。

如果您希望它从 DLL 运行,您必须将任何资源加载函数传递给 DllMain() 函数接收的 HINSTANCE。或者,您可以使用 GetModuleHandle("name.dll"),但在代码中硬连接 DLL 的名称并不是一个好主意。

在 EXE 和 DLL 中获得相同代码的任何简单方法是定义一个全局变量(不要导出它!):

HINSTANCE g_thisModule = NULL;

然后在 DllMain() 函数中,分配给它:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
g_thisModule = hinstDll;
}

如果不是 DLL,而是 EXE,您可以从 WinMain() 的参数中获取 g_thisModule。如果它是一个控制台程序,只需在 main() 中添加这一行:g_thisModule = GetModuleHandle(NULL);

然后使用这个变量加载任何本地资源:

LoadImage(g_thisModule, ...)

关于c++ - 使用 dll 运行时按钮上未显示位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18020248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com