none
vista下面操作桌面listview的imagelist失败 RRS feed

  • 问题

  •  

    通过以下代码可以获取到桌面listview的imagelist句柄


     m_hSysListView = ::FindWindow(_T("Progman"), _T("Program Manager"));
     if (m_hSysListView)
      m_hSysListView = ::FindWindowEx(m_hSysListView, 0, _T("ShellDll_DefView"), NULL);
     if (m_hSysListView)
      m_hSysListView = ::FindWindowEx(m_hSysListView, 0, _T("SysListView32"), NULL);

    HIMAGELIST hImgList = ListView_GetImageList(m_hSysListView, LVSIL_NORMAL);

     

    我在XP下面有一个桌面程序,Hook到Explorer之后,

    通过 ImageList_AddIcon  ImageList_ReplaceIcon等API函数,

    可以任意操纵桌面图标。

    但是移植到vista下面之后,这些函数都执行失败。

    ImageList_**等函数,目前我只试出 ImageList_GetIconSize能够正常工作,

    其它 ImageList_GetIcon, ImageList_Add, ImageList_Replace等函数执行均失败

    GetLastError返回值是0,所以我无从判断是什么原因导致这些系统API执行失败

     

    不知道有什么办法可以解决这个问题?

    • 已移动 孟宪会Moderator 2009年5月19日 9:41 ([Loc]From:Windows Vista 开发相关讨论)
    • 已移动 MagicDreamModerator 2009年5月19日 9:48 C++开发相关 ([Loc]From:Visual C++)
    2009年1月13日 8:34

答案

  • 你可以自己创建一个桌面。如果·你需要通知Windows图片文件被修改了,用SHChangeNotify
    2009年1月14日 13:14
    版主
  • 很抱歉隔了这么久才来反馈。

    使用CreateDesktop也是不太符合要求,例如switchdesktop的时候会造成窗口的闪烁等

    这些会影响用户的体验。

    目前还没有找到什么好的办法来操作Desktop的Imagelist。

    我打算Hook SysListview的OnPaint消息,在需要操作桌面图标时,直接在桌面上进行绘图覆盖。

    经测试这个方法是可行的,暂时打算使用这个办法来解决图标操作的问题。

     

    不过对于系统imagelist的操作问题我会保持关注,不知道windows7下面是不是和vista一样的,

    迟些也要测试看看。

     

    在此感谢 Sheng Jiang (蒋晟)  提供的思路, 好好学习了一下  ^_^

    2009年1月20日 6:18

全部回复

  • 通过以下代码可以获取到桌面listview的imagelist句柄


     m_hSysListView = ::FindWindow(_T("Progman"), _T("Program Manager"));
     if (m_hSysListView)
      m_hSysListView = ::FindWindowEx(m_hSysListView, 0, _T("ShellDll_DefView"), NULL);
     if (m_hSysListView)
      m_hSysListView = ::FindWindowEx(m_hSysListView, 0, _T("SysListView32"), NULL);

    HIMAGELIST hImgList = ListView_GetImageList(m_hSysListView, LVSIL_NORMAL);

     

    我在XP下面有一个桌面程序,Hook到Explorer之后,

    通过 ImageList_AddIcon  ImageList_ReplaceIcon等API函数,

    可以任意操纵桌面图标。

    但是移植到vista下面之后,这些函数都执行失败。

    ImageList_**等函数,目前我只试出 ImageList_GetIconSize能够正常工作,

    其它 ImageList_GetIcon, ImageList_Add, ImageList_Replace等函数执行均失败

    GetLastError返回值是0,所以我无从判断是什么原因导致这些系统API执行失败

     

    不知道有什么办法可以解决这个问题?

     

    2009年1月13日 8:07
  • 使用软件未公开的实现细节会在软件升级时出现这种问题。重新设计你的应用程序以避免依赖于未公开的实现细节。
    2009年1月13日 17:00
    版主
  • 请问这个问题要如何重新设计呢?

    我的桌面程序在某些情况下需要动态去修改桌面的图标,

    我知道系统的item(例如 我的电脑)图标可以通过修改注册表然后刷新桌面来动态更新,

    但是在vista的桌面,如果放一个图片文件到桌面上,系统会根据图片内容动态生成一个图标。

    我如果要去修改这个图标,就需要通过desktop的imagelist来获取原始的图标然后对这个图标进行操作。

     

    现在的问题是,我对这个imagelist的操作都返回失败(在XP下同样的操作都能成功),系统也没有给出失败的错误信息。

    我现在没有足够的信息来重新设计我的应用程序以实现这个功能,所以来到这里求助。

     

    不知道你这里是否有信息说明为什么对imagelist的操作会失败,

    我挺想知道是否vista下面对桌面的imagelist做了保护不允许用户程序进行修改或者还是有别的什么原因。

    另外不知道你这里是否有什么办法能够让我绕过这个问题实现动态修改桌面图标的功能?

     

    非常感谢!

    2009年1月14日 5:46
  • 你可以自己创建一个桌面。如果·你需要通知Windows图片文件被修改了,用SHChangeNotify
    2009年1月14日 13:14
    版主
  • 自己创建一个桌面,使用CreateDesktop么?

    这两天我会尽快测试并且将结果反馈过来

    非常非常感谢 ^_^

    2009年1月14日 13:30
  • 很抱歉隔了这么久才来反馈。

    使用CreateDesktop也是不太符合要求,例如switchdesktop的时候会造成窗口的闪烁等

    这些会影响用户的体验。

    目前还没有找到什么好的办法来操作Desktop的Imagelist。

    我打算Hook SysListview的OnPaint消息,在需要操作桌面图标时,直接在桌面上进行绘图覆盖。

    经测试这个方法是可行的,暂时打算使用这个办法来解决图标操作的问题。

     

    不过对于系统imagelist的操作问题我会保持关注,不知道windows7下面是不是和vista一样的,

    迟些也要测试看看。

     

    在此感谢 Sheng Jiang (蒋晟)  提供的思路, 好好学习了一下  ^_^

    2009年1月20日 6:18
  • 很奇怪你为什么会有这样的需求
    要是用户有桌面背景图片呢?或者Vista里有的背景视频,你怎么重画?
    2009年1月20日 14:27
    版主
  • 我这里有一个桌面小程序,用户可以把桌面图标当玩具来玩。

    例如在图标上贴上Logo,一脚把图标踢裂开或者踢缺一块等等。

    原来我是考虑在内存处理好图片后替换到系统的imagelist里面,

    这个方法在XP下可行的,但是在vista下面执行失败。

    这几天我测试了可以通过获取桌面背景颜色、背景图片、背景图贴图风格(平铺、拉伸等)在内存中绘一个桌面背景

    然后根据各图标位置对桌面图标进行截图,这样我就得到了每个图标的背景和前景,就可以对图标任意操作了。

    这是目前能想到了比较好的解决方法了,不会影响用户的操作 不会造成屏幕闪烁。

     

    至于背景视频。。。我不知道vista还有这个功能。 不知道使用背景视频是什么效果。

    如果实在不行,那么用户使用背景视频的时候只好禁止程序修改桌面了。

     

    不知道你对此还有什么建议不?

    2009年1月20日 16:38