Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c - Calling SHGetSetSettings from Delphi

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 defined in ShlObj.pas, so we need to write our own definition.

First we need to translate the SHELLSTATE structure. Now I have only limited experience in C, but I suppose that ": 1" means that the member of the structure is a single bit, that is, that eight of them can be packed together in a byte. I also suppose that DWORD = UINT = 32-bit unsigned integers and that LONG = int are 32-bit signed integers. But then we have a problem: The entire structure will then occupy 228 bits, or 28.5 bytes, which is ... rather impossible, at least in Delphi, where sizeof(SomeRecord) has to be an integer.

Nevertheless, I tried to solve it by adding four dummy bits at the end. 232 bits = 29 bytes, which is nice.

Hence I tried

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;

and then I declared (for later convenience)

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;

Now I felt ready to define

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

implementation
  procedure SHGetSetSettings; external shell32 name 'SHGetSetSettings';

But before I tried the code, I noticed something very strange. I found that the constants I declared were already declared here: SSF Constants. Notice that SSF_HIDEICONS = 0x00004000 = 16384 ≠ fHideIcons = 4096. If the SSF_ constants really are masks used together with SHELLSTATE, then it makes no sense to define SSF_HIDEICONS as 2^14 when it is the 13th bit (and its mask should be 2^12) in the structure. Hence, it seems, the two MSDN reference pages contradict eachother.

Could someone please bring some clarity into all this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...