【问题标题】:Load icon from .DLL in wxWidgets从 wxWidgets 中的 .DLL 加载图标
【发布时间】:2020-01-31 18:17:30
【问题描述】:

我试图通过从系统 DLL 加载来在 Windows 中加载 wxIcon(因为 mime 系统告诉我这种文件类型的图标在 DLL 中),例如。

wxIcon icon;
icon.LoadFile("C:\\WINDOWS\\system32\\zipfldr.dll", wxICON_DEFAULT_TYPE);

这失败了,但我想知道代码库中是否有任何方法可以加载它,而不是求助于本机 Win32 函数。

另外,如果有原生的 Win32 函数,有人知道它们是什么吗?

编辑:我尝试了以下但没有成功:

::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
  // location is something like C:\WINDOWS\system32\imageres.dll
  wxIcon icon;
  if (!icon.LoadFile(location.GetFileName(), wxBITMAP_TYPE_ICON /*I have tried wxICON_DEFAULT_TYPE too*/))
  {
    // Failed!
  }
}

编辑 2:作为对 VZ 的回应,我很遗憾地尝试了以下方法,但没有成功:

::wxInitAllImageHandlers();
wxMimeTypesManager manager;
wxFileType* type = manager.GetFileTypeFromExtension("sys");
wxIconLocation location;
if (type->GetIcon(&location))
{
  // location is something like C:\WINDOWS\system32\imageres.dll,
  //with an appropriate index as retrieved by location.GetIndex(), which is -67.
  wxIcon icon(location);
  if (!icon.IsOk())
  {
    BREAK;
    // Failed!
  }
}

编辑 3: 感谢大家的帮助 - 如果我使用 wxBITMAP_TYPE_ICO 而不是 wxBITMAP_TYPE_ICON(注意 N),并且我将测试代码放在我的应用程序的构造函数中而不是 ::OnInit 中,那么效果很好。它在OnInit 中有效,但在构造函数中无效,所以这是一个教训! 感谢大家的帮助和快速响应,一如既往的感谢。

【问题讨论】:

  • 您发布的第二组代码对我有用。虽然根据 wxMimeTypesManager 的文档,“应用程序不应该构造自己的管理器:它应该使用对象指针 wxTheMimeTypesManager”,所以第二行可能应该被删除,第三行应该是 wxFileType* type = ::wxTheMimeTypesManager->GetFileTypeFromExtension("sys"); 但我得到了一个有效的 wxIcon有或没有这种变化的对象。
  • @NewPagodi 谢谢,是的,我已经修改了我的代码。我的第二个示例仅在 ::OnInit 中调用时才有效,但我将测试代码放在构造函数中。显然,在构造和OnInit 调用之间发生了一些事情。我还愚蠢地使用wxBITMAP_TYPE_ICON(不起作用)而不是wxBITMAP_TYPE_ICO(起作用)。谢谢!

标签: c++ windows wxwidgets


【解决方案1】:

如果您指定类型wxBITMAP_TYPE_ICO,它应该可以工作。

【讨论】:

  • wxIcon::LoadFile 对我来说失败了。它找不到 wxBITMAP_TYPE_ICON 的处理程序。该函数中尝试使用 wxBitmap/wxImage 加载的回退也失败了。我用 ::wxInitAllImageHandlers() 加载所有图像处理程序,但没有任何乐趣。欢迎任何其他提示,再次感谢。
  • 我愚蠢地使用wxBITMAP_TYPE_ICON 而不是wxBITMAP_TYPE_ICO。谢谢!
【解决方案2】:

LoadFile() 的第一个参数在使用wxBITMAP_TYPE_ICO 时必须指定图标资源ID(这确实是您从文件加载图标时需要使用的,而不是当前模块的资源),即您也是最后缺少;N 部分,其中NwxFileTypeInfo::GetIconIndex() 返回的值。

但是为了避免显式处理这个问题,你应该只使用wxFileType::GetIcon() 并从它填充的wxIconLocation 构造wxIcon

例如,这个:

diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 0d91f7fc75..3623aacc56 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -123,6 +123,12 @@ bool MyApp::OnInit()
     if ( !wxApp::OnInit() )
         return false;

+    wxIcon icon(wxIconLocation(R"(c:\Windows\system32\imageres.dll)", -67));
+    if ( icon.IsOk() )
+    {
+        wxLogMessage("Loaded icon of size %d*%d", icon.GetWidth(), icon.GetHeight());
+    }
+
     // create the main application window
     MyFrame *frame = new MyFrame("Minimal wxWidgets App");

显示有关加载大小为 32 x 32 的图标的预期消息。

【讨论】:

  • 谢谢 - 在传递 wxIconLocation 时调用 wxIcon 的构造函数中的 LoadFile 也会失败(我认为没有处理程序)。我没有修改在 Windows 上构建的默认 wxWidgets 设置;适当的图像处理程序是否需要任何特定选项?
  • 不确定您出了什么问题。 wxIconwxBitmap 使用的处理程序是not wxImage 处理程序,不需要初始化,它们总是内置并转发到本机::ExtractIcon() 函数。它绝对适合我,请参阅更新的示例。
  • 好的!这行得通!请注意,它在 MyApp::OnInit 和 not 构造函数中有效,因此之间肯定发生了其他事情。此外,wxBITMAP_TYPE_ICO 有效,但 wxBITMAP_TYPE_ICON(注意 N)无效。谢谢!
  • 在构造wxApp 对象时,库还没有初始化,你不能在其中做任何重要的事情,这就是OnInit() 存在的原因(另见OnExit())。
  • 谢谢 - 我通常不会在构造函数中做任何事情,但只是为了这个测试代码。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
相关资源
最近更新 更多