• 0

C++/Windows 7: Can't programmatically "hide" desktop icons


Question

I've been using C++ to send an LVM_DELETEITEM message to the desktop listview window, but it seems to be ignoring the index I give it.

It always seems to delete the same icon (last index), regardless of whichever index I send as the WPARAM.

I've tried using both Listview_DeleteItem() and SendMessage(LVM_DELETEITEM).

It seems Microsoft has subclassed the listview and are handling the LVM_DELETEITEM message differently to previous versions of Windows.

The code has been tested and working fine with WinXP x86, Vista (x86 and x64).

Both Win7 x86 and x64 are showing this strange behaviour.

Does anyone know of another way I can get this to work?

Any suggestions are welcome!

9 answers to this question

Recommended Posts

  • 0

This is a very flaky thing to be doing, and it shouldn't be surprising that it no longer works.

First, LVM_DELETEITEM was never designed to be sent directly by an external source (e.g., it's not like WM_KEYDOWN, which can be sent as the result of user input, and it's not designed to be sent by external apps). LVM_DELETEITEM is really more like an API, to allow the application that uses the list view control to communicate with the list view control, and since the list view control is implemented as a window, the API takes the form of window messages. Just because window messages can be sent by an external application doesn't mean that it should be sent, and this is one example of that. By injecting yourself into the private interactions of Explorer and its list view control, you may very well violate assumptions that Explorer may make about the state of the list view.

This is especially true for Explorer's main list view, since that list view is almost certainly a virtual list view, in which Explorer maintains much of the list view's state. Sending LVM_DELETEITEM from an external app in a situation like this is simply a bad idea, and it's surprising that this hack has even worked at all up to this point.

If you want to hide a file, why not just call SetFileAttributes and flip on the hidden bit?

(PS: Listview_DeleteItem is just a C macro that expands out to SendMessage LVM_DELETEITEM)

  • 0
  code.kliu.org said:
Sending LVM_DELETEITEM from an external app in a situation like this is simply a bad idea, and it's surprising that this hack has even worked at all up to this point.

If you want to hide a file, why not just call SetFileAttributes and flip on the hidden bit?

yes, i know its a bad idea and im not happy that i have to do this at all.

but ever since vista, the desktop has decided to simply ignore the hidden attribute on desktop.ini files

i'm just trying to make something that'll hide the icons without the need to delete the files.

  • 0
  twigboy said:
but ever since vista, the desktop has decided to simply ignore the hidden attribute on desktop.ini files

That's not Explorer's fault. Nor Vista's. It's simply doing what you are telling it to do. It still honors the hidden attribute. And the system attribute. desktop.ini has both +H and +S set. The desktop will only show desktop.ini if you enable "Show hidden files and folders" (which shows files with the +H bit) and uncheck "Hide protected operating system files" (which shows files with the +S bit). If you enable both of those options, then Explorer, by design, should show desktop.ini. If either one of those is not set, then desktop.ini will be hidden.

Incidentally, the reason why desktop.ini has the +S bit set is so that people can turn on "Show hidden files" and not have to see desktop.ini (aside from desktop.ini, very few files actually use the +S bit).

XP didn't have a desktop.ini for the Desktop folder, which is why you didn't see this in XP. But if you created a desktop.ini in XP, set the +H and +S attribs on it, but then enable the options to show +H and +S in Explorer, you'll see desktop.ini on your desktop, just like in Vista.

Now, if you insist on keeping both the "show +H" and "show +S" options enabled in Explorer, and you are bothered by the desktop.ini files, you can just delete them. It's only there so that it can show a special cute icon for the folder and use a localized display name, but if you care about neither of those things, you can just delete desktop.ini.

Edited by code.kliu.org
  • 0
  code.kliu.org said:
Now, if you insist on keeping both the "show +H" and "show +S" options enabled in Explorer, and you are bothered by the desktop.ini files, you can just delete them. It's only there so that it can show a special cute icon for the folder and use a localized display name, but if you care about neither of those things, you can just delete desktop.ini.

well yes, i do like having an icon for my desktop which is why i do not want to opt for the brute "delete the file" method.

  • 0
  code.kliu.org said:
This is especially true for Explorer's main list view, since that list view is almost certainly a virtual list view, in which Explorer maintains much of the list view's state. Sending LVM_DELETEITEM from an external app in a situation like this is simply a bad idea, and it's surprising that this hack has even worked at all up to this point.

If he insists on using the LVM_DELETEITEM method, wouldn't it be possible instead to inject a custom DLL into explorer, and send the LVM_DELETEITEM message through the injected process? If the reason being that explorer now ignores the LVM_DELETEITEM message from external apps it should work right? Not saying that this is a good idea either though. Just an interesting thought.

  • 0
  dlegend said:
... wouldn't it be possible instead to inject a custom DLL into explorer, and send the LVM_DELETEITEM message through the injected process?

yep, thats what i'm currently doing

i've subclassed it to make sure that the right message is being passed through and its correct up until the point where i have to process the LVM_DELETEITEM message

im wondering if theres a way to temporarily replace the custom LVM_DELETEITEM handler for the desktop with the default SysListview wndproc.

suggestions/advice still welcome!

  • 0
  dlegend said:
If he insists on using the LVM_DELETEITEM method, wouldn't it be possible instead to inject a custom DLL into explorer, and send the LVM_DELETEITEM message through the injected process?

That's not the problem. Whether the message comes from the Explorer process or not is irrelevant. The interaction between the list view and Explorer is just that: between the list view and Explorer, especially since the W7 list view is a virtual list view and Explorer is maintaining much of the list view state. It doesn't matter how you inject yourself into this.

If you are typing on your keyboard and your cat decides that it likes to walk on the keyboard, it's going to be disruptive regardless of whether your cat walks on the same keyboard that you are currently typing on or on a second keyboard connected to the same computer.

  twigboy said:
im wondering if theres a way to temporarily replace the custom LVM_DELETEITEM handler for the desktop with the default SysListview wndproc.

You can't--and most importantly, shouldn't--do this with LVM_DELETEITEM. Period. Nor would subclassing or "replacing" LVM_DELETEITEM work since this is a virtual list view where the list view itself does not maintain the state.

  twigboy said:
suggestions/advice still welcome!

If you really insist on showing +S files and having a cute icon for your desktop and hiding desktop.ini, then you have two options:

Option 1: Create a custom shell extension implementing the IExtractIcon interface that sets a cute, pretty icon for the desktop folder (thus bypassing the need for desktop.ini) and then delete desktop.ini.

Option 2: Get the IShellFolderView interface (hint) for the desktop shell view, find the desktop.ini object, and call IShellFolderView::RemoveObject on it.

Seems like a lot of effort to go through for a cute icon. :p

Disclaimer: I haven't actually tried either option. In theory, they should work, but as you can imagine, this isn't something that many people have tried doing before.

Edited by code.kliu.org
  • 0
  code.kliu.org said:
Option 2: Get the IShellFolderView interface (hint) for the desktop shell view, find the desktop.ini object, and call IShellFolderView::RemoveObject on it.

Seems like a lot of effort to go through for a cute icon. :p

thanks for that, i'll try it out and let you guys know how it goes.

i dont really mind the trouble. despite being much more difficult than deleting the files, its a good excuse to learn some new tricks :)

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.