Calling SHGetSetSettings from Delphi

杀马特。学长 韩版系。学妹 提交于 2019-11-29 15:21:00

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.

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);

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!