Save & Restore Desktop Icons Position[Windows]
Re: Save & Restore Desktop Icons Position[Windows]
Rashad, I just discovered today that your code in the first post is failing for me again. After some testing, I realized "ReadData(fn,@count,SizeOf(Integer))" in RestoreDesktopIconsPositions() was returning 0 sometimes. So if I ignored that and put "count=4" after that line (4 is the number of icons on my desktop), it worked and successfully restored all icons again. So it appears ReadData is not getting the correct saved icon count from the saved icon file. Do you know how to fix that? I looked but am not sure.
Re: Save & Restore Desktop Icons Position[Windows]
Hi Rashad,
excellent code (as always), works on Win 11 pro.
I modified and saved the screen resolution in the file as well to get the same layout and position on another computer with a lower resolution.
But I have a question, why a loop from 1 to 3 in the RestoreDesktopIconsPositions() procedure?
If i do the loop once, it's Ok.
excellent code (as always), works on Win 11 pro.
I modified and saved the screen resolution in the file as well to get the same layout and position on another computer with a lower resolution.
But I have a question, why a loop from 1 to 3 in the RestoreDesktopIconsPositions() procedure?
Code: Select all
For no = 1 To 3
A+
Denis
Denis
Re: Save & Restore Desktop Icons Position[Windows]
Hi Denis
This is an old thread
Just searched my archive and next is my last attempt
You will need Restore.png and Delete.png
Support PB x86 and x64
Added Balloon Tool-tip
This is an old thread
Just searched my archive and next is my last attempt
You will need Restore.png and Delete.png
Support PB x86 and x64
Added Balloon Tool-tip
Code: Select all
Prototype GetNativeSystemInfo(*lpSystemInfo.SYSTEM_INFO)
#PROCESSOR_ARCHITECTURE_AMD64 = 9
#PROCESSOR_ARCHITECTURE_IA64 = 6
#PROCESSOR_ARCHITECTURE_INTEL = 0
#PROCESSOR_ARCHITECTURE_UNKNOWN = $ffff
#SHCNE_ASSOCCHANGED = $8000000
#SHCNF_IDLIST = $1000
Structure LV_ITEM1 Align 2
mask.l
iItem.l
iSubItem.l
state.l
stateMask.l
Padding.l
*pszText
Padding1.l
cchTextMax.l
iImage.l
lParam.l
Padding2.l
EndStructure
Structure DeskInfo
sz.i
name.s
pt.point
EndStructure
Global Dim GlobalDeskinfo.DeskInfo(0)
Global Explorer, GlobalLVItem , GlobalBuffer ,hDesktopListView ,String$,count
String$ = Space(#MAX_PATH)
hProgman = FindWindow_("ProgMan", 0)
hDesktopWnd = GetDesktopWindow_()
If hProgman
hShellViewWin = FindWindowEx_(hProgman, 0, "SHELLDLL_DefView", 0);
If hShellViewWin
hDesktopListView = FindWindowEx_(hShellViewWin, 0, "SysListView32", 0);
Else
Repeat
hWorkerW = FindWindowEx_( hDesktopWnd, hWorkerW, "WorkerW", #Null );
hShellViewWin = FindWindowEx_(hWorkerW, 0, "SHELLDLL_DefView", 0) ;
Until hShellViewWin <> #Null And hWorkerW <> #Null
hDesktopListView = FindWindowEx_(hShellViewWin, 0, "SysListView32", 0);
EndIf
EndIf
Procedure refresh()
ClearGadgetItems(0)
If ExamineDirectory(0, GetHomeDirectory(), "*.dmr")
n = 1
While NextDirectoryEntry(0)
AddGadgetItem(0,-1,Str(n)+Chr(10)+ DirectoryEntryName(0))
n+1
Wend
FinishDirectory(0)
EndIf
EndProcedure
Import ""
GetNativeSystemInfo(*info)
EndImport
Procedure Is64bitOS()
Protected Info.SYSTEM_INFO
GetNativeSystemInfo(Info)
If info\wProcessorArchitecture
ProcedureReturn #True
EndIf
EndProcedure
Procedure DesktopProcessOpen()
Protected ExplorerID
Protected Flags = #PROCESS_VM_OPERATION | #PROCESS_VM_READ | #PROCESS_VM_WRITE | #PROCESS_QUERY_INFORMATION
GetWindowThreadProcessId_(hDesktopListView,@ExplorerID)
Explorer = OpenProcess_(Flags,#Null,ExplorerID)
GlobalLVItem = VirtualAllocEx_(Explorer,#Null,SizeOf(LV_ITEM),#MEM_COMMIT,#PAGE_READWRITE )
GlobalBuffer = VirtualAllocEx_(Explorer,#Null,#MAX_PATH,#MEM_COMMIT,#PAGE_READWRITE)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
If Is64bitOS()
ItemB.LV_ITEM1
With ItemB
\mask = #LVIF_TEXT
\iSubItem = 0
\pszText = GlobalBuffer
\cchTextMax = #MAX_PATH
EndWith : WriteProcessMemory_(Explorer,GlobalLVItem,ItemB,SizeOf(ItemB),#Null)
Else
ItemA.LV_ITEM
With ItemA
\mask = #LVIF_TEXT
\iSubItem = 0
\pszText = GlobalBuffer
\cchTextMax = #MAX_PATH
EndWith : WriteProcessMemory_(Explorer,GlobalLVItem,ItemA,SizeOf(ItemA),#Null)
EndIf
CompilerElse
ItemA.LV_ITEM
With ItemA
\mask = #LVIF_TEXT
\iSubItem = 0
\pszText = GlobalBuffer
\cchTextMax = #MAX_PATH
EndWith : WriteProcessMemory_(Explorer,GlobalLVItem,ItemA,SizeOf(ItemA),#Null)
CompilerEndIf
EndProcedure
Procedure DesktopProcessClose ( )
VirtualFreeEx_(Explorer,GlobalLVItem,#Null,#MEM_RELEASE)
VirtualFreeEx_(Explorer,GlobalBuffer,#Null,#MEM_RELEASE)
CloseHandle_(Explorer)
EndProcedure
Procedure.s DesktopGetIconString(Index)
SendMessage_(hDesktopListView,#LVM_GETITEMTEXT,Index,GlobalLVItem)
ReadProcessMemory_(Explorer,GlobalBuffer,@String$,#MAX_PATH,#Null)
ProcedureReturn String$
EndProcedure
Procedure DesktopGetIconPosition(index,*pt.point)
If SendMessage_(hDesktopListView,#LVM_GETITEMPOSITION,index,GlobalLVItem )
ReadProcessMemory_(Explorer,GlobalLVItem,*pt,SizeOf(Point),#Null)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure SaveDesktopIconsPositions()
Protected fn,index,pt.point,name.s
file$ = FormatDate("%yy-%mm-%dd-%hh-%ii-%ss", Date())+".dmr"
fn = OpenFile(#PB_Any,GetHomeDirectory()+file$)
If fn
DesktopProcessOpen()
Count = SendMessage_(hDesktopListView,#LVM_GETITEMCOUNT,#Null,#Null)
ReDim GlobalDeskinfo.DeskInfo(count)
WriteData(fn,@count,SizeOf(Integer))
For index = 0 To Count-1
GlobalDeskinfo(index)\name = DesktopGetIconString(index)
GlobalDeskinfo(index)\sz = StringByteLength(GlobalDeskinfo(index)\name)
If DesktopGetIconPosition(index,pt)
GlobalDeskinfo(index)\pt\x = pt\x
GlobalDeskinfo(index)\pt\y = pt\y
EndIf
WriteData(fn,@GlobalDeskinfo(index)\sz,SizeOf(Integer))
WriteData(fn,@GlobalDeskinfo(index)\name,GlobalDeskinfo(index)\sz)
WriteData(fn,@GlobalDeskinfo(index)\pt,SizeOf(point))
Next
CloseFile(fn)
EndIf
DesktopProcessClose()
EndProcedure
Procedure RestoreDesktopIconsPositions()
Protected count,*buf,name.s,len,pt.point,fn,index
ShowWindow_(hDesktopListView,#SW_HIDE)
;For no = 1 To 3
*buf = AllocateMemory(#MAX_PATH)
count = ArraySize(GlobalDeskinfo())
DesktopProcessOpen()
file$ = GetGadgetItemText(0,GetGadgetState(0),1)
fn = ReadFile(#PB_Any,GetHomeDirectory()+file$)
If fn
ReadData(fn,@count,SizeOf(Integer))
If count > 0
For index = 0 To count-1
FillMemory(*buf, #MAX_PATH)
ReadData(fn,@len,SizeOf(Integer))
ReadData(fn,*buf,len)
name = PeekS(*buf,len)
ReadData(fn,@PT,SizeOf(point))
For item = 0 To count - 1
If DesktopGetIconString(item) = name
SendMessage_(hDesktopListView,#LVM_SETITEMPOSITION,item,pt\y<<16|pt\x)
Break
EndIf
Next
Next
EndIf
CloseFile(fn)
EndIf
DesktopProcessClose()
FreeMemory(*buf)
;Next
;SHChangeNotify_(#SHCNE_ASSOCCHANGED, #SHCNF_IDLIST, 0, 0)
ShowWindow_(hDesktopListView,#SW_SHOW)
EndProcedure
Procedure IsMouseOver(hWnd)
GetWindowRect_(hWnd,r.RECT)
GetCursorPos_(p.POINT)
Result = PtInRect_(r,p\y << 32 + p\x)
ProcedureReturn Result
EndProcedure
Define Event
UsePNGImageDecoder()
LoadFont(0,"Consolas",14)
Dim gtext$(5)
OpenWindow(0,0,0,500,300,"Desktop Icons Positions",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
SetWindowColor(0,$0)
If CreateToolBar(0, WindowID(0))
ToolBarID = ToolBarID(0)
TBIL = SendMessage_(ToolBarID, #TB_GETIMAGELIST , 0, 0)
ImageList_SetIconSize_(TBIL,24,24)
SetWindowLongPtr_(ToolBarID(0),#GWL_STYLE, GetWindowLongPtr_(ToolBarID(0),#GWL_STYLE)|#CCS_NODIVIDER)
SendMessage_(ToolBarID,#TB_SETBUTTONSIZE,0,24 | 24 << 16)
SendMessage_(ToolBarID,#TB_AUTOSIZE,0,0)
ToolBarImageButton(0, 0)
ToolBarImageButton(1, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Save.png"))
gtext$(1) = " Save "
ToolBarImageButton(2, 0)
ToolBarImageButton(3, LoadImage(0, "Restore.png"))
gtext$(3) = " Restore "
ToolBarImageButton(4, 0)
ToolBarImageButton(5, LoadImage(0, "Delete.png"))
gtext$(5) = " Delete "
EndIf
DisableToolBarButton(0,0,1)
DisableToolBarButton(0,2,1)
DisableToolBarButton(0,4,1)
FrameGadget(1, 10, 35, 480,250, " Desktop Icons Positions ")
ListIconGadget(0,20,62,460,210,"No.",42,#PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE)|#LVS_NOCOLUMNHEADER)
SetGadgetFont(0,FontID(0))
AddGadgetColumn(0,1,"Desktop State",414)
SetGadgetColor(0,#PB_Gadget_BackColor,$050505)
SetGadgetColor(0,#PB_Gadget_FrontColor,$FFFFFF)
SetGadgetColor(0,#PB_Gadget_LineColor,$858585)
refresh()
ttip = CreateWindowEx_(0, "Tooltips_Class32", "", #TTS_BALLOON, 0, 0, 0, 0, 0, 0, 0, 0)
SetWindowTheme_(ttip, @null.w, @null.w)
SendMessage_(ttip,#TTM_SETTIPTEXTCOLOR,#Red,0)
SendMessage_(ttip,#TTM_SETTIPBKCOLOR,$CBFEFD,0)
SendMessage_(ttip,#WM_SETFONT,FontID(0),0)
; SendMessage_(ttip,#TTM_SETMAXTIPWIDTH,0,180)
; SendMessage_(ttip, #TTM_SETDELAYTIME, #TTDT_AUTOMATIC,500)
ti.TOOLINFO
ti\cbSize = SizeOf(ti)
ti\uFlags = #TTF_IDISHWND | #TTF_SUBCLASS
Repeat
Event = WaitWindowEvent()
Select Event
Case #WM_MOUSEMOVE
If IsMouseOver(ToolBarID)
iindex = SendMessage_(ToolBarID,#TB_GETHOTITEM,0,0)
If iindex >= 0 And iindex <> oldiindex
ti\uId= ToolBarID
Text$ = gtext$(iindex)
ti\lpszText = @Text$
SendMessage_(ttip, #TTM_SETDELAYTIME, #TTDT_AUTOPOP,1000)
SendMessage_(ttip, #TTM_ADDTOOL, 0, ti)
; Else
; ti\uId= ToolBarID
; Text$ = ""
; ti\lpszText = @Text$
; SendMessage_(ttip, #TTM_SETDELAYTIME, #TTDT_AUTOPOP,1000)
; SendMessage_(ttip, #TTM_ADDTOOL, 0, ti)
EndIf
EndIf
oldiindex = iindex
Case #PB_Event_Menu
Select EventMenu()
Case 1
SaveDesktopIconsPositions()
refresh()
MessageRequester("Info","Desktop Icons Position Saved",#MB_ICONINFORMATION|#MB_OK)
Case 3
RestoreDesktopIconsPositions()
MessageRequester("Info","Desktop Icons Position Restored",#MB_ICONINFORMATION|#MB_OK)
Case 5
DeleteFile(GetHomeDirectory()+GetGadgetItemText(0,GetGadgetState(0),1))
refresh()
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
Egypt my love
Re: Save & Restore Desktop Icons Position[Windows]
Thanks Rashad, works fine.
I go less often on the forum so sometimes I discover old posts but still excellent. Lots of good coders here with lots of interesting stuff.
I go less often on the forum so sometimes I discover old posts but still excellent. Lots of good coders here with lots of interesting stuff.
A+
Denis
Denis