DelphiからSHGetSetSettingsを呼び出す

c delphi msdn translation winapi
DelphiからSHGetSetSettingsを呼び出す

https://stackoverflow.com/questions/3482227/old-delphi-hide-show-desktop-icons-method-not-working-under-windows-7-64-bit [この質問]とhttps:/を読むだけです/stackoverflow.com/questions/3326062/how-do-i-make-the-show-hide-desktop-icons-setting-take-effect [この質問]、それ以来、http:// Delphiのmsdn.microsoft.com/en-us/library/bb762200(VS.85).aspx [SHGetSetSettings] これは「shell32.dll」の関数ですが、「ShlObj.pas」では定義されていないため、独自の定義を記述する必要があります。

まず、http://msdn.microsoft.com/en-us/library/bb759788(VS.85).aspx [SHELLSTATE]構造を翻訳する必要があります。 Cの経験は限られていますが、「:1」は、構造体のメンバーが1ビットである、つまり、8個を1バイトにまとめられることを意味すると思います。 また、「DWORD」=「UINT」= 32ビット符号なし整数であり、「LONG」=「int」は32ビット符号付き整数であると仮定します。 しかし、問題があります。構造全体が228ビット、つまり28.5バイトを占有します。 少なくともDelphiでは、 `sizeof(SomeRecord)`が整数である必要があり、むしろ不可能です。

それでも、最後に4つのダミービットを追加することで解決しようとしました。 232ビット= 29バイト、これはいいですね。

したがって、私は試した

PShellState = ^TShellState;
TShellState = packed record
  Data1: cardinal;
  Data2: cardinal;
  Data3: cardinal;
  Data4: cardinal;
  Data5: cardinal;
  Data6: cardinal;
  Data7: cardinal;
  Data8: byte; // Actually a nibble would be sufficient
end;

そして、私は宣言した(後の便宜のために)

const
  fShowAllObjects = 1;
  fShowExtensions = 2;
  fNoConfirmRecycle = 4;
  fShowSysFiles = 8;
  fShowCompColor = 16;
  fDoubleClickInWebView = 32;
  fDesktopHTML = 64;
  fWin95Classic = 128;
  fDontPrettyPath = 256;
  fShowAttribCol = 512;
  fMapNetDrvButton = 1024;
  fShowInfoTip = 2048;
  fHideIcons = 4096;
  fWebView = 8192;
  fFilter = 16384;
  fShowSuperHidden = 32768;
  fNoNetCrawling = 65536;

今、私は定義する準備ができていると感じました

interface
  procedure SHGetSetSettings(var ShellState: TShellState; Mask: cardinal; DoSet: boolean); stdcall;

implementation
  procedure SHGetSetSettings; external shell32 name 'SHGetSetSettings';

しかし、コードを試す前に、非常に奇妙なことに気付きました。 私が宣言した定数は、ここで既に宣言されていることがわかりました:http://msdn.microsoft.com/en-us/library/bb762591(VS.85).aspx[SSF Constants]。 「SSF_HIDEICONS = 0x00004000 = 16384≠fHideIcons = 4096」に注意してください。 SSF_`定数が実際に SHELLSTATE`と一緒に使用されるマスクである場合、構造内で13番目のビット(およびそのマスクは2 ^ 12でなければなりません)のときに、 `SSF_HIDEICONS`を2 ^ 14として定義しても意味がありません。 したがって、2つのMSDNリファレンスページは互いに矛盾しているようです。

誰かがこれをすべて明確にしてくれませんか?

  3  0


ベストアンサー

ここでのヘルプの読み方は、データを取得するときにSSF_定数がマスクに指定されていることです。 ShellState構造のビットにマップする必要がある理由はありません。

fShowSysFilesが8(0x04)にマップされた場合、ヘルプからSSF_SHOWSYSFILESが0x20であることがわかります。 直接のマッピングはありません。

3


残念ながら、ShlObj.pasのSHELLSTATEのD2010宣言は間違っていますが、ビットの最初のグループ(17)は「Data:DWORD;」と正しく一致しています(実際にOKです)。 それらの18または19がすべて同じである可能性があります。 次に、Data2だけでなく、2つのWin95unusedに対してさらに2つのDWORD / UINTを取得する必要があります。

SSFフラグとSHGetSetSettings宣言が既に行われ、修正されているため、残念です。

MSDNによる正しい宣言は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;

これにより、ソートプロパティを正しく取得できることを確認できます。

var
  lpss: tagSHELLSTATEW;
begin
  ZeroMemory(@lpss, SizeOf(lpss));
  SHGetSetSettings(lpss, SSF_SORTCOLUMNS, False);

2


Delphi 2010のTShellState定義は次のとおりです。

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}

残念ながら、あまり役に立ちません。

1


CのAfaikビットフィールドは整数のサブタイプです。 それをパックする方法がありますが、Cでも、単一ビットフィールドの束の後、次のバイト境界(そしておそらく次の整数境界まで)にパディングがあります。 さらに、Cのsizeofも半分をサポートしていません。

したがって、おそらくsizeof(integer)= 32bytesの1 + 6 + 1倍です。

0


私はパーティーに少し遅れましたが、http://rvelthuis.de/articles/articles-convert.html#bitfields [この記事]はビットフィールドを非常によく説明しており、Delphiにはいくつかのアプローチがあります。

0


タイトルとURLをコピーしました