Home | Blog | Software | Reviews and Features | Forum | Help | Donate | About us
topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • September 04, 2015, 07:23:55 AM
  • Proudly celebrating 10 years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: Your basic desktop icon save/restore for 32 bit windows  (Read 11408 times)

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Your basic desktop icon save/restore for 32 bit windows
« on: May 05, 2009, 03:45:23 PM »
This shell extension works on every 32 bit version of Windows I've tried, including W7.
(Does not work on Vista64)

No frills, just save and restore from the Desktop Context Menu:

http://www.favessoft.com/iconset.html


tomos

  • Charter Member
  • Joined in 2006
  • ***
  • Posts: 9,524
    • View Profile
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #1 on: May 06, 2009, 04:53:07 AM »
thanks Miles :)
Tom

lanux128

  • Global Moderator
  • Joined in 2005
  • *****
  • Posts: 6,219
    • View Profile
    • Coding Snacks by Lanux128
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #2 on: May 06, 2009, 07:03:52 AM »
this looks nice.. i had been relying on Iconicity's IconSet dll for some time now. Miles, you wouldn't have a command-line version, would you? i mean to save and restore the layout by passing some parameters..

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #3 on: May 06, 2009, 05:32:44 PM »
I was just looking at it to see how tough it would be to get it out of the shell dll.  Only thing is there's a bunch of MS C++-isms in it that I forget even what they are.  The basic operation is the same as Richter's Advanced Windows code.  Just goes through the Listview and gets each icon's position.

Right now I don't have VC ++ set up on anything. I put W7 on and even though VC++ was on drive H: it still put crap on C: in "shared" folders.  So that's all hosed.

If you like I can put up the relevant source code.

I'll dig it out in a bit and post in this thread.


MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #4 on: May 06, 2009, 05:49:07 PM »
There's mumbo jumbo in the code to create a filename by concatenating the userid and screen res and also win9x vs NT based.  You don't need any of that.  The relevant parts are in the SaveIcon, RestoreIcon and GetDesktopListView functions.

Also there's some other stuff about trying to turn AutoArrange off, then back on after icons are restored, but that doesn't work anyway.  Just didn't pull the code out.  The AutoArrange setting has to be disabled or the restore position function won't work.

Also there's an include "autoarray_ptr.h" that's sort of like an auto_ptr with array delete [] in the destructor.  It's just a convenience so that I don't have to manually free memory, esp for char arrays.  It does it when the class instance goes out of scope.  All that's really needed is navigating the desktop listview and gettting and setting info.

And of course there's a whole bunch of ATL crap to be ignored. :)


header file
Code: [Select]
// IconSetter.h : Declaration of the CIconSetter

#ifndef __ICONSETTER_H_
#define __ICONSETTER_H_

#include "resource.h"       // main symbols

#pragma comment(lib, "comctl32.lib")


#include <comdef.h>
#include <shlobj.h>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <fstream>

using namespace std;

#ifdef _UNICODE
#define string wstring
#endif

typedef list<string> STRINGLIST;

/////////////////////////////////////////////////////////////////////////////
// CIconSetter
class ATL_NO_VTABLE CIconSetter :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CIconSetter, &CLSID_IconSetter>,
public IShellExtInit,
public IContextMenu
{
public:
CIconSetter()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_ICONSETTER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CIconSetter)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()

public:
STRINGLIST m_listPaths; // use m_listPaths.front().c_str() to get the first file in the list

// IShellExtInit
public:
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder,LPDATAOBJECT lpdobj,HKEY hkeyProgID);

// IContextMenu
public:
    STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
    STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici);
    STDMETHOD(GetCommandString)(UINT idCmd, UINT uType,UINT* pwReserved,LPSTR pszName,UINT cchMax);

// IIconSetter
public:
protected:
HWND h;
};

#endif //__ICONSETTER_H_



implementation file
Code: [Select]
// IconSetter.cpp : Implementation of CIconSetter
#include "stdafx.h"
#include "IconSet.h"
#include "IconSetter.h"
#include "autoarray_ptr.h"

/////////////////////////////////////////////////////////////////////////////
// CIconSetter

#define ICON_FILE "IconPos"


struct HItemEntryTag {
    int index;
    POINT p;
    bool operator <(const HItemEntryTag& i)
    {
        return p.x < i.p.x;
    }
};

struct VItemEntryTag {
    int index;
    POINT p;
    bool operator <(const VItemEntryTag& i)
    {
        return p.y < i.p.y;
    }
};


static HWND GetDesktopListView()
{
    char ListViewClassName[64];
    string LVClassName;
   
    HWND h = FindWindow("ProgMan", NULL);
    h = GetWindow(h, GW_CHILD);
    h = GetWindow(h, GW_CHILD);
    if(! GetClassName(h, ListViewClassName, 63))
        return 0;
    LVClassName = ListViewClassName;
    return (LVClassName == "SysListView32") ? h : 0;
}


static bool MakeIconPosFileName(string& filename)
{
    int x = GetSystemMetrics(SM_CXSCREEN);
    int y = GetSystemMetrics(SM_CYSCREEN);
    DWORD size = MAX_PATH;
    char path[MAX_PATH] = "";
    char xbuf[8] = "";
    char ybuf[8] = "";
    itoa(x, xbuf, 10);
    itoa(y, ybuf, 10);
    string username, suffix;
    OSVERSIONINFO os = {0};
    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&os);
    if(os.dwPlatformId == VER_PLATFORM_WIN32_NT)
        suffix = "NT.txt";
    else
        suffix = "Win.txt";
    if(GetUserName(path, &size)) {
        for(x = 0;x < strlen(path);x++)
            if(path[x] == ' ') path[x] = '_';
        username = path;
        path[0] = '\0';
    }
   
    if(GetModuleFileName(_Module.GetModuleInstance(), path, MAX_PATH)) {
        filename = string("\\") + username + string(ICON_FILE) + string(xbuf) + string("X") + string(ybuf) + suffix;
        strcpy(strrchr(path, '\\'), filename.c_str());
        filename = path;
        return true;
    }
    return false;   
}

static HRESULT SaveIcons()
{
    HWND h = GetDesktopListView();
    if(! h)
        return E_FAIL;
   
    string IconPosFile;
    char buf[MAX_PATH] = "";
    POINT p;
   
    int x, count = ListView_GetItemCount(h);
   
    if(! MakeIconPosFileName(IconPosFile))
        return E_FAIL;
   
    fstream outfile(IconPosFile.c_str(), ios::out);
    if( !outfile.is_open() ) {
        MessageBox(0, IconPosFile.c_str(), "Error Creating Icon Position File", MB_OK | MB_ICONERROR);
        return E_FAIL;
    }
   
    for(x = 0; x < count; x++) {
        ListView_GetItemText(h, x, 0, buf, MAX_PATH);
        ListView_GetItemPosition(h, x, &p);
        outfile << buf << endl << p.x << " " << p.y  << endl;
    }
   
    return NOERROR;
}

static HRESULT RestoreIcons()
{
    HWND h = GetDesktopListView();
    if(! h)
        return E_FAIL;
   
    char buf[MAX_PATH] = "";
    string IconPosFile;
    int x = 0;
    POINT p;
   
    if(! MakeIconPosFileName(IconPosFile))
        return E_FAIL;
   
    WIN32_FIND_DATA fd = {0};
   
    HANDLE fh = FindFirstFile( IconPosFile.c_str(), &fd);
    if(fh == INVALID_HANDLE_VALUE) {
        MessageBox(0, IconPosFile.c_str(), "Icon Position File Not Found", MB_OK | MB_ICONERROR);
        return E_FAIL;
    }
   
    fstream infile(IconPosFile.c_str(), ios::in);
    if( !infile.is_open() )
        return E_FAIL;
   
    LV_FINDINFO lvfi;
   
    bool RestoreAutoArrange = false;
    DWORD dwStyle = GetWindowLong(h, GWL_STYLE);
    if(dwStyle & LVS_AUTOARRANGE) {
        SetWindowLong(h, GWL_STYLE, dwStyle & ~LVS_AUTOARRANGE);
        RestoreAutoArrange = true;
    }
    for(;;) {
        infile.getline(buf, MAX_PATH);
        if(! buf[0])
            break;
        lvfi.flags = LVFI_STRING;
        lvfi.psz = buf;
        infile >> p.x >> p.y;
        x = ListView_FindItem(h, -1, &lvfi);
        if(x != -1)
            ListView_SetItemPosition(h, x, p.x, p.y);
        infile.getline(buf, MAX_PATH);
    }
    if(RestoreAutoArrange)
        SetWindowLong(h, GWL_STYLE, dwStyle);
   
    return NOERROR;
}

HRESULT CIconSetter::Initialize(LPCITEMIDLIST pidlFolder,LPDATAOBJECT lpdobj, HKEY hkeyProgID)
{

if(pidlFolder == NULL)
return E_FAIL;

// MessageBox(NULL, _T("Got To Here!"), _T("Debug MessageBox"), MB_OK);
if(pidlFolder->mkid.cb != 0)
return E_FAIL;   

return NOERROR;
}

HRESULT CIconSetter::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{

string szItem0 = _T("Save Icon Positions");
string szItem1 = _T("Restore Icon Positions");

UINT idCmd = idCmdFirst;


InsertMenu(hmenu, indexMenu++, MF_STRING | MF_BYPOSITION, idCmd++, szItem0.c_str());
    InsertMenu(hmenu, indexMenu++, MF_STRING | MF_BYPOSITION, idCmd++, szItem1.c_str());

// Must return the greatest menu item identifier plus one.
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmd-idCmdFirst);

}

HRESULT CIconSetter::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
HRESULT hr = E_INVALIDARG;

if (!HIWORD(lpici->lpVerb))   
{       
switch (LOWORD(lpici->lpVerb))       
{
case 0:
hr = SaveIcons();
break;
case 1:
hr = RestoreIcons();
break;
}
}

return hr;
}

HRESULT CIconSetter::GetCommandString(UINT idCmd, UINT uType,UINT* pwReserved,LPSTR pszName,UINT cchMax)
{
USES_CONVERSION;

string szCmdString;

// TODO: Get your help strings from the Resources
switch (idCmd)
{
case 0:
szCmdString=_T("Save Desktop Icon Positions");
break;
case 1:
szCmdString=_T("Restore Desktop Icon Positions");
break;
}

switch (uType)
{
case GCS_HELPTEXTA:
lstrcpyA((LPSTR)pszName,T2A((TCHAR*)szCmdString.c_str()));
case GCS_HELPTEXTW:
lstrcpyW((LPWSTR)pszName,T2W((TCHAR*)szCmdString.c_str()));
break;
}

return NOERROR;
}


lanux128

  • Global Moderator
  • Joined in 2005
  • *****
  • Posts: 6,219
    • View Profile
    • Coding Snacks by Lanux128
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #5 on: May 06, 2009, 08:17:28 PM »
@Miles: thanks for putting up the source but i'm hardly a duck to C++ waters.. i wanted command-line parameters so that i can launch save/restore functions via Farr instead of right-clicking on the desktop. :)

RoadKill

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 7
  • The cheese stands alone.
    • View Profile
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #6 on: May 06, 2009, 10:33:34 PM »
Thanks for this one! :Thmbsup:  Now I can keep my precious desktop icons arranged the way I put them there.
Orange,Glowing,Warm, and Eternal.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #7 on: May 07, 2009, 12:17:54 AM »
@Miles: thanks for putting up the source but i'm hardly a duck to C++ waters.. i wanted command-line parameters so that i can launch save/restore functions via Farr instead of right-clicking on the desktop. :)

I understand but I don't have any C++ compiler set up, so how could I test it?
If you search hard enough you can probably find Richter's original C code.  It was a small dialog box with save/restore buttons.  There must be command line implementations around someplace.  Maybe softpedia or Sourceforge.net


MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #8 on: May 07, 2009, 12:19:27 AM »
Thanks for this one! :Thmbsup:  Now I can keep my precious desktop icons arranged the way I put them there.

You're welcome. I just wish MS would put out a free VC++ IDE so I could to it in 64 bit.  I think I'll have to wait awhile to see that though. :)

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #9 on: May 07, 2009, 12:28:04 AM »
nevermind .. doesn't work for me.

Anyway, you can find it as easily(or with as much difficulty as I) I'm not having much luck with Vista64.
« Last Edit: May 07, 2009, 12:32:18 AM by MilesAhead »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #10 on: May 07, 2009, 12:57:53 AM »
I found the original DIPS code by Richter compiled as 64 bit and even that doesn't work:

http://amip.tools-for.net/files/dips64/

Guess Vista64 does something different with the desktop icons.
I would recommend searching for something that claims Vista64 support.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 6,199
    • View Profile
    • Miles Ahead Software
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #11 on: May 07, 2009, 01:13:04 AM »
hmmm, the other thing that occurs to me is I'm running VistaGlazz and Purple theme. I wouldn't go by my results as some of the shell dlls are probably changed on my system.
If it works for you it's good.  I don't think any of them will work for me now.  Anyway, now I have all my icons in categorized folders for type of application and each of those folders has a custom Icon in RocketDock. No more desktop icon clutter. :)

lanux128

  • Global Moderator
  • Joined in 2005
  • *****
  • Posts: 6,219
    • View Profile
    • Coding Snacks by Lanux128
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #12 on: May 07, 2009, 06:43:17 AM »
@Miles: thanks for putting up the source but i'm hardly a duck to C++ waters.. i wanted command-line parameters so that i can launch save/restore functions via Farr instead of right-clicking on the desktop. :)

I understand but I don't have any C++ compiler set up, so how could I test it?
If you search hard enough you can probably find Richter's original C code.  It was a small dialog box with save/restore buttons.  There must be command line implementations around someplace.  Maybe softpedia or Sourceforge.net

no worries then, i didn't realise that it might be more complicated. thanks anyway.. :)

btw i noticed another program that could do this - DeskSave and it works quite ok with Farr.

ws-desksave-farr.png

Ted M

  • Participant
  • Joined in 2007
  • *
  • default avatar
  • Posts: 6
    • View Profile
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #13 on: May 07, 2009, 06:48:31 AM »
I've been using:

http://midiox.com/

Desktop Save and Restore.

32-bit and 64-bit versions available. Both work fine on my computers.

Ted

TWmailrec

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 122
    • View Profile
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #14 on: May 11, 2009, 11:25:57 AM »
Ive noticed with several Vista-32 systems that icon layout INSIDE folders on the desktop is often reset to alphabetical order (after program install etc).
Since these folders can contain numerous icons it is tedious to restore correct layout.

I now have created a REG save/restore on two keys:

HKEY_USERS\S-1-5-21-913379744-1625067961-1115525842-1000\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell

&

HKEY_USERS\S-1-5-21-913379744-1625067961-1115525842-1000_Classes\Local Settings\Software\Microsoft\Windows\Shell

It doesnt always work on the newest folder, and key:
S-1-5-21-913379744-1625067961-1115525842-1000
is specific for a given Vista system

Surely others would appreciate a proper icon position RESTORE, which extends inside folders.

any veiws?

FSL

  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 5
  • FreeSoftLand
    • View Profile
    • FreeSoftLand Site
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #15 on: May 31, 2009, 08:47:17 AM »
The new release 1.0.5.1 of my IconRestorer now support 64-Bit OS (from XP to Windows 7 RC1).
I've also added a backup preview (desktop thumbnails for each saved layout).
The last (free) release can be downloaded from my site: http://fsl.sytes.net/iconrestorer.html

FSL

TWmailrec

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 122
    • View Profile
    • Donate to Member
Re: Your basic desktop icon save/restore for 32 bit windows
« Reply #16 on: January 09, 2011, 06:56:20 PM »
To FSL

Sorry about delay getting back on this topic
I Tried IconRestorer which works well for Desktop icons.
My problem was that to keep Desktop uncluttered, most program icons grouped in Folders located on the Desktop. These folders contain a large no. of icons, and each Folders' icon arrangement needs to be saved/restored.
My current approach is a bit hit&miss.
Perhaps what Im looking for isnt possible?