Page 1 of 2

Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 1:46 pm
by Hi-Toro
Hi all,

I want to use the SHGetSetSettings Win32 function (see http://msdn.microsoft.com/en-us/library ... 85%29.aspx ), which allows for various interactions with the Windows desktop.

It needs a SHELLSTATE structure, which in almost 15 years of PureBasic Win32 coding is the weirdest, most f***ed-up thing I've ever seen!

It uses bitfields -- fields that are each 1 bit in size. It starts with 17 bits (yes, seventeen), followed by some 32-bit integers, followed by another bunch of bits. From my reading (see URLs in source), it seems these bitfields need to be padded out to 32 bits in C-style languages like PB, but no matter what I try, this crashes when trying to call SHGetSetSettings, with an invalid memory access/write error:

Code: Select all

#SSF_HIDEICONS = $00004000

Structure SHELLSTATE

; Some references...

; http://msdn.microsoft.com/en-us/library/bb759788%28VS.85%29.aspx
; http://www.windows-tech.info/1/31087e8b743a89c2.php
; http://fossies.org/dox/wine-1.7.18/structSHELLSTATE.html
; http://social.msdn.microsoft.com/Forums/vstudio/en-US/c309f758-aa76-423c-9a58-d6d2b6694fe2/reading-from-shellstate-structure-modifying-explorer-settings-and-startmenu?forum=csharpgeneral

; 	; 17 bits! WTF?!
; 	
; 	fShowAllObjects.bit0
; 	fShowExtensions.bit1
; 	fNoConfirmRecycle.bit2
; 	fShowSysFiles.bit3
; 	fShowCompColor.bit4
; 	fDoubleClickInWebView.bit5
; 	fDesktopHTML.bit6
; 	fWin95Classic.bit7
; 	fDontPrettyPath.bit8
; 	fShowAttribCol.bit9
; 	fMapNetDrvBtn.bit10
; 	fShowInfoTip.bit11
; 	fHideIcons.bit12
; 	fWebView.bit13
; 	fFilter.bit14
; 	fShowSuperHidden.bit15
; 	fNoNetCrawling.bit16
	
	; Some references suggest this should be padded out to 32 bits...
	
	bits.l
	
	; ^^^ 17 bits + 15 padding = 32 bits...
	
	; 6 x 32-bit integer?
	
	dwWin95Unused.l
	uWin95Unused.l
	lParamSort.l
	iSortDirection.l
	version.l
	uNotUsed.l
	
	; ^^^ Fair enough... I guess...
	
	; 7 bits...
	
; 	fSepProcess.bit0
; 	fStartPanelOn.bit1
; 	fShowStartPage.bit2
; 	fAutoCheckSelect.bit3
; 	fIconsOnly.bit4
; 	fShowTypeOverlay.bit5
; 	fShowStatusBar.bit6
	
;	fSpareFlags.bit0-8 ; 9 bits... holy sh
	
	; Another one that should be padded to 32 bits... ?
	
	bits2.l
	
	; ^^^ 7 bits + 9 padding = 16 bits...
	
EndStructure

Debug SizeOf (SHELLSTATE)
lib = OpenLibrary (#PB_Any, "shell32.dll")

If lib
	
	; SHGetSetSettings: http://msdn.microsoft.com/en-us/library/bb762200%28VS.85%29.aspx
	
	*SHGetSetSettings = GetFunction (lib, "SHGetSetSettings")
	If *SHGetSetSettings
		*lpss.SHELLSTATE
		If CallFunctionFast (lib, *SHGetSetSettings, *lpss, #SSF_HIDEICONS, #False) ; False means READ the shell settings!
			Debug "OK"
		Else
			Debug GetLastError_ ()
		EndIf
	Else
		Debug "Nope"
	EndIf
	CloseLibrary (lib)
EndIf


;SHGetSetGettings ()
Has anyone ever used this function, or can anyone figure out HOW to use it with this bizarre structure?!

Thanks in advance for any help!

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 2:25 pm
by PB
What do you want to do with it? There may be other ways to
do what you want, without trying to work out this abomination.

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 2:49 pm
by Hi-Toro
I originally wanted to show/hide the desktop icons, and there is code on the forums to do this, but I felt it was a little clunky (using a hidden window), and found out that this is the 'correct' way to show/hide icons.

However, it has quite a lot of other options that I'd like to experiment with.

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 3:15 pm
by Thunder93
You should show your interest over on http://www.purebasic.fr/english/viewtop ... =3&t=56923 :lol:

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 3:17 pm
by PB
BTW, when I said "abomination", I meant the structure; not your code sample. ;)

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 3:21 pm
by Thunder93
LOL!

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 3:23 pm
by Hi-Toro
Ha ha!

Actually, the bitfield support is probably not my main problem here -- it should be easy enough to set/get the bits I need.

What I don't really understand is why it's crashing -- even if I allocate 10 MB of memory and point SHGetSetSettings to this block of memory, I get a write error, so even if I have the structure wrong, for some reason it seems to be writing outside of my block of memory...

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 3:32 pm
by Thunder93
CallFunctionFast.. shouldn't that be like

Code: Select all

CallFunctionFast (*SHGetSetSettings, *lpss, #SSF_HIDEICONS, #False)
?

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 5:00 pm
by Hi-Toro
I've tried that, too -- it still gives the same error.

Code: Select all

*lpss.SHELLSTATE
If CallFunctionFast (lib, *SHGetSetSettings, *lpss, #SSF_HIDEICONS, #False)

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 5:17 pm
by Thunder93
Yea but that's wrong.*FunctionPointer - This pointer may be found using the GetFunction()..... Hence *SHGetSetSettings = GetFunction(lib, "SHGetSetSettings")

CallFunctionFast(*FunctionPointer [,Parameter1 [, Parameter2...]])
Hi-Toro wrote:I've tried that, too -- it still gives the same error.

Code: Select all

*lpss.SHELLSTATE
If CallFunctionFast (lib, *SHGetSetSettings, *lpss, #SSF_HIDEICONS, #False)

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 5:21 pm
by Thunder93
The experiences are different, I'm observing.

With the change, and if you Null out #SSF_HIDEICONS and try test. It should give OK results. Having #SSF_HIDEICONS set, it causes structure to be written and gives problem.

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 5:35 pm
by Zebuddi123
Check the address error, debugger write error -> is pointing to the (lib address) and not the (*lpss address) which is 0 ---- with Call FunctionFast

this works without write mem err but the structures empty. this is not my thing so just some observations

Zebuddi. :)

Code: Select all

#SSF_HIDEICONS = $00004000
CallDebugger
Structure SHELLSTATE

; Some references...

; http://msdn.microsoft.com/en-us/library/bb759788%28VS.85%29.aspx
; http://www.windows-tech.info/1/31087e8b743a89c2.php
; http://fossies.org/dox/wine-1.7.18/structSHELLSTATE.html
; http://social.msdn.microsoft.com/Forums/vstudio/en-US/c309f758-aa76-423c-9a58-d6d2b6694fe2/reading-from-shellstate-structure-modifying-explorer-settings-and-startmenu?forum=csharpgeneral

;    ; 17 bits! WTF?!
;    
;    fShowAllObjects.bit0
;    fShowExtensions.bit1
;    fNoConfirmRecycle.bit2
;    fShowSysFiles.bit3
;    fShowCompColor.bit4
;    fDoubleClickInWebView.bit5
;    fDesktopHTML.bit6
;    fWin95Classic.bit7
;    fDontPrettyPath.bit8
;    fShowAttribCol.bit9
;    fMapNetDrvBtn.bit10
;    fShowInfoTip.bit11
;    fHideIcons.bit12
;    fWebView.bit13
;    fFilter.bit14
;    fShowSuperHidden.bit15
;    fNoNetCrawling.bit16
   
   ; Some references suggest this should be padded out to 32 bits...
   
   bits.l
   
   ; ^^^ 17 bits + 15 padding = 32 bits...
   
   ; 6 x 32-bit integer?
   
   dwWin95Unused.l
   uWin95Unused.l
   lParamSort.l
   iSortDirection.l
   version.l
   uNotUsed.l
   
   ; ^^^ Fair enough... I guess...
   
   ; 7 bits...
   
;    fSepProcess.bit0
;    fStartPanelOn.bit1
;    fShowStartPage.bit2
;    fAutoCheckSelect.bit3
;    fIconsOnly.bit4
;    fShowTypeOverlay.bit5
;    fShowStatusBar.bit6
   
;   fSpareFlags.bit0-8 ; 9 bits... holy sh
   
   ; Another one that should be padded to 32 bits... ?
   
   bits2.l
   
   ; ^^^ 7 bits + 9 padding = 16 bits...
   
EndStructure

Define lpss.SHELLSTATE

Debug SizeOf (SHELLSTATE)                               ;  = 32 bytes
lib = OpenLibrary (#PB_Any, "shell32.dll")

If lib
  
   ; SHGetSetSettings: http://msdn.microsoft.com/en-us/library/bb762200%28VS.85%29.aspx
   
;    *SHGetSetSettings = GetFunction (lib, "SHGetSetSettings")
;    If *SHGetSetSettings
      *lpss=lpss
      If CallFunction(lib, "SHGetSetSettings", *lpss, #SSF_HIDEICONS, #False) ; False means READ the shell settings!
         Debug "OK"
      Else
         Debug GetLastError_ ()
      EndIf
;    Else
;       Debug "Nope"
;    EndIf
   CloseLibrary (lib)
EndIf


;SHGetSetGettings ()

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 5:36 pm
by Hi-Toro
AAAAHHH!!! Well done, guys! Can't believe it came down to that!

Thanks for all your help, hopefully I can manage from here!

Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 7:05 pm
by RASHAD
Show Hide
- Desktop Icons
- TaskBar
- Start Button

Tested with Windows 7 & 8

Code: Select all

hWnd = FindWindow_("Progman", 0)
hWnd = FindWindowEx_(hWnd, 0, "SHELLDLL_DefView", 0)
If hWnd
     dtWnd = FindWindowEx_(hWnd, 0, "SysListView32", 0)
EndIf

TaskBar = FindWindow_("Shell_TrayWnd",0)
Start = FindWindow_(0,"Start")
  If IsWindowVisible_(TaskBar)
    ShowWindow_(dtWnd,#SW_HIDE)
    ShowWindow_(TaskBar,#SW_HIDE)
    ShowWindow_(Start,#SW_HIDE)
    Delay(2000)
    ShowWindow_(dtWnd,#SW_SHOW)
    ShowWindow_(TaskBar,#SW_SHOW)
    ShowWindow_(Start,#SW_SHOW)
  EndIf


Re: Can't use Win32 SHELLSTATE structure!

Posted: Sat May 10, 2014 8:03 pm
by Hi-Toro
Ah... turns out SHGetSetSettings is effectively deprecated:

http://msdn.microsoft.com/en-us/library ... 85%29.aspx
End of client support | Windows XP with SP2
My code does now toggle the "Show Desktop Icons" menu, but doesn't actually affect the icons!

I'll go with RASHAD's code (thanks, RASHAD!) and just forget about the cool list of options SHGetSetSettings seemed to promise!