I just read this question and this question, and since then I have been trying to call SHGetSetSettings in Delphi. This is a function of shell32.dll
, but is not
My reading of the help here is that the SSF_ constants are specified for the mask when retrieving data. There's no reason they have to map to the bits in the ShellState structure.
If they did fShowSysFiles would map to 8 (0x04), and we know from the help that SSF_SHOWSYSFILES is 0x20. There's no direct mapping.
Here is TShellState definition in Delphi 2010:
type
tagSHELLSTATEW = record
Data: DWORD;
Data2: UINT;
{ fShowAllObjects: BOOL:1;
fShowExtensions: BOOL:1;
fNoConfirmRecycle: BOOL:1;
fShowSysFiles: BOOL:1;
fShowCompColor: BOOL:1;
fDoubleClickInWebView: BOOL:1;
fDesktopHTML: BOOL:1;
fWin95Classic: BOOL:1;
fDontPrettyPath: BOOL:1;
fShowAttribCol: BOOL:1;
fMapNetDrvBtn: BOOL:1;
fShowInfoTip: BOOL:1;
fHideIcons: BOOL:1;
fWebView: BOOL:1;
fFilter: BOOL:1;
fShowSuperHidden: BOOL:1;
fNoNetCrawling: BOOL:1;}
//dwWin95Unused: DWORD;// Win95 only - no longer supported pszHiddenFileExts
//uWin95Unused: UINT; // Win95 only - no longer supported cbHiddenFileExts
// Note: Not a typo! This is a persisted structure so we cannot use LPARAM
lParamSort: Integer;
iSortDirection: Integer;
version: UINT;
// new for win2k. need notUsed var to calc the right size of ie4 struct
// FIELD_OFFSET does not work on bit fields
uNotUsed: UINT;// feel free to rename and use
{ fSepProcess: BOOL:1;
// new for Whistler.
fStartPanelOn: BOOL:1;
fShowStartPage: BOOL:1;
// new for Windows Vista
fAutoCheckSelect: BOOL:1;
fIconsOnly: BOOL:1;
fShowTypeOverlay: BOOL:1;
// If you need a new flag, steal a bit from from fSpareFlags.
// Also, keep SHELLFLAGSTATE and SHGetSettings in sync when adding new flags.
fSpareFlags: UINT:11;
}
end;
{$EXTERNALSYM tagSHELLSTATEW}
SHELLSTATEA = tagSHELLSTATEW;
{$EXTERNALSYM SHELLSTATEA}
SHELLSTATEW = tagSHELLSTATEW;
{$EXTERNALSYM SHELLSTATEW}
SHELLSTATE = SHELLSTATEW;
{$EXTERNALSYM SHELLSTATE}
TShellState = SHELLSTATE;
PShellState = ^TShellState;
const
SHELLSTATEVERSION_IE4 = 9;
{$EXTERNALSYM SHELLSTATEVERSION_IE4}
SHELLSTATEVERSION_WIN2K = 10;
{$EXTERNALSYM SHELLSTATEVERSION_WIN2K}
Not very helpful, unfortunately.
Afaik bitfields in C are a subtype of integer. There are ways to pack it, but also in C, after a bunch of single bit fields, there will be padding to the next byte boundery (and probably even to the next integer boundery). Moreover C's sizeof doesn't support halves either.
So probably it is 1+6+1 times sizeof(integer)= 32bytes.
The D2010 declaration of SHELLSTATE in ShlObj.pas is unfortunately incorrect, but the first group of bits (17) is correctly matched with Data: DWORD;
(Yours is indeed OK).
There could be 18 or 19 of them all the same. Then we should get 2 more DWORD/UINT for the 2 Win95unused, not only Data2.
Too bad because the SSF flags and SHGetSetSettings declarations are already done in there and correct.
The correct declaration according to MSDN should be IMO:
tagSHELLSTATEW = record
Data: DWORD;
{ fShowAllObjects: BOOL:1;
fShowExtensions: BOOL:1;
fNoConfirmRecycle: BOOL:1;
fShowSysFiles: BOOL:1;
fShowCompColor: BOOL:1;
fDoubleClickInWebView: BOOL:1;
fDesktopHTML: BOOL:1;
fWin95Classic: BOOL:1;
fDontPrettyPath: BOOL:1;
fShowAttribCol: BOOL:1;
fMapNetDrvBtn: BOOL:1;
fShowInfoTip: BOOL:1;
fHideIcons: BOOL:1;
fWebView: BOOL:1;
fFilter: BOOL:1;
fShowSuperHidden: BOOL:1;
fNoNetCrawling: BOOL:1;}
dwWin95Unused: DWORD;// Win95 only - no longer supported pszHiddenFileExts
uWin95Unused: UINT; // Win95 only - no longer supported cbHiddenFileExts
// Note: Not a typo! This is a persisted structure so we cannot use LPARAM
lParamSort: Integer;
iSortDirection: Integer;
version: UINT;
// new for win2k. need notUsed var to calc the right size of ie4 struct
// FIELD_OFFSET does not work on bit fields
uNotUsed: UINT;// feel free to rename and use}
Data2: DWORD;
{ fSepProcess: BOOL:1;
// new for Whistler.
fStartPanelOn: BOOL:1;
fShowStartPage: BOOL:1;
// new for Windows Vista
fAutoCheckSelect: BOOL:1;
fIconsOnly: BOOL:1;
fShowTypeOverlay: BOOL:1;
// If you need a new flag, steal a bit from from fSpareFlags.
// Also, keep SHELLFLAGSTATE and SHGetSettings in sync when adding new flags.
fSpareFlag: UINT:13;}
end;
You can verify that this allows to get the sorting properties correctly with:
var
lpss: tagSHELLSTATEW;
begin
ZeroMemory(@lpss, SizeOf(lpss));
SHGetSetSettings(lpss, SSF_SORTCOLUMNS, False);