SPI_SETDISABLEOVERLAPPEDCONTENT

boj*_*vic 1 windows delphi winapi

我有功能

function bgSetDisableOverlappedContent(CAA: BOOL; var ErrorCode: DWORD; ErrorText: string): Boolean;  
begin
  errorCode := ERROR_SUCCESS;
  ErrorText := '';  
  if not GetOSVersion >= 60 then
    Exit;
  Result := SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, @CAA, 0);
  if not Result then
  begin
    ErrorCode := GetLastError;
    ErrorText := GetErrorText(ErrorCode);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

并准确地称呼它

procedure TForm1.Button3Click(Sender: TObject);
var
  CAA: BOOL;
  OS: TUsableInOS;
  ErrorCode: DWORD;
  ErrorText: string;
begin
  CAA := False;
  if bgSetDisableOverlappedContent(CAA, ErrorCode, ErrorText) then
    ShowMessage('Success');
end;
Run Code Online (Sandbox Code Playgroud)

但是,当我再次检查下一个代码时

function bgGetDisableOverlappedContent(var CAA: BOOL; OS: TUsableInOS; ErrorCode: DWORD; ErrorText: string): Boolean;
begin
  errorCode := ERROR_SUCCESS;
  ErrorText := '';
  os := tosVistaUp;   
  if not GetOSVersion >= 60 then
    Exit;   
  Result := SystemParametersInfo(SPI_GETDISABLEOVERLAPPEDCONTENT, 0, @CAA, 0);   
  if not Result then
  begin
    ErrorCode := GetLastError;
    ErrorText := GetErrorText(ErrorCode);
  end;
end;
function GetOSVersion: Integer;
var
  OSVersionInfo : TOSVersionInfo;
begin
  Result:= 0;
  FillChar(OsVersionInfo, Sizeof(OsVersionInfo), 0);
  OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
  if GetVersionEx(OSVersionInfo) then
  begin
    if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
    begin
      if (OsVersionInfo.dwMajorVersion = 5) and ((OsVersionInfo.dwMinorVersion = 0)) then
         Result:= 50; //2000
      if (OsVersionInfo.dwMajorVersion = 5) and ((OsVersionInfo.dwMinorVersion = 1)) then
         Result:= 51; //XP
      if (OsVersionInfo.dwMajorVersion = 5) and ((OsVersionInfo.dwMinorVersion = 2)) then
         Result:= 52; //2003, 2003 R2
      if (OsVersionInfo.dwMajorVersion = 6) and ((OsVersionInfo.dwMinorVersion = 0)) then
         Result:= 60; //Vista, Windows Server 2008
      if (OsVersionInfo.dwMajorVersion = 6) and ((OsVersionInfo.dwMinorVersion = 1)) then
         Result:= 61; //Server 2008 R2, 7
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

CAA的结果再次为True,即使我确切地设置了CAA:= False; 我正在研究Win 7.和Result of Result:= SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT,0,@ CAA,0); 为True,但SPI_GETDISABLEOVERLAPPEDCONTENT为CAA返回True,即使在完全设置为False之前的步骤中也是如此.

procedure TForm1.Button3Click(Sender: TObject);
var
  CAA: BOOL;
  OS: TUsableInOS;
  ErrorCode: DWORD;
  ErrorText: string;
  Res: Bool;
begin
  CAA := False;
{  if bgSetDisableOverlappedContent(CAA, ErrorCode, ErrorText) then
    ShowMessage('Success'); }
  Res := SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT,
                                 0,
                                 @CAA,
                                 0);

  Res := SystemParametersInfo(SPI_GETDISABLEOVERLAPPEDCONTENT,
                                 0,
                                 @CAA,
                                 0);
  if Caa then
    ShowMessage('True')
  else
    ShowMessage('False');
end;
Run Code Online (Sandbox Code Playgroud)

CAA是真的.

你有什么主意吗?

在此先感谢Bojan

Dav*_*nan 7

主要的问题是,当SPI_SETDISABLEOVERLAPPEDCONTENT你传递时,你想要传递一个BOOL变量,但是你传递一个指向a的指针BOOL.该文件说:

pvParam参数是BOOL变量.将pvParam设置为TRUE以禁用重叠内容,或将FALSE设置为启用重叠内容.

这意味着您设置属性的代码需要如下所示:

SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, Pointer(CAA), 0)
Run Code Online (Sandbox Code Playgroud)

GetOSVersion是一场灾难.抱歉听起来很刺耳!它返回0Windows 8及更高版本.并且您的代码存在运算符优先级问题.你写:

if not GetOSVersion >= 60 then
Run Code Online (Sandbox Code Playgroud)

和运算符优先级意味着被解释为

if (not GetOSVersion) >= 60 then
Run Code Online (Sandbox Code Playgroud)

由于GetOSVersion返回有符号值,因此无论Windows版本如何,都会(not GetOSVersion) >= 60进行评估False.那是因为not GetOSVersion总是<= 0.

你想要逻辑否定而不是按位否定.所以你应该写

if not (GetOSVersion >= 60) then
Run Code Online (Sandbox Code Playgroud)

或者等价的

if GetOSVersion < 60 then
Run Code Online (Sandbox Code Playgroud)

实际上,有一个内置的功能来做到这一点.它被称为CheckWin32Version.像这样称呼它:

if not CheckWin32Version(6, 0) then
  exit;
Run Code Online (Sandbox Code Playgroud)

你的其余功能虽然有点混乱.您传递ErrorText值,然后分配给它.据推测,您打算让调用者接收该值.除非你路过,否则不会发生这种情况var.

就个人而言,我会像这样编写你的程序:

procedure bgSetDisableOverlappedContent(CAA: BOOL);
begin
  if CheckWin32Version(6, 0) then
    if not SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, Pointer(CAA), 0) then
      RaiseLastOSError;
end;
Run Code Online (Sandbox Code Playgroud)

我认为将错误转换为异常更好,SystemParametersInfo因为这是一种特殊情况.我无视你实际上产生了一次失败SystemParametersInfo.在这种情况下,没有必要为不会发生的事情构建错误代码返回机制.检查错误并转换为运行时异常.这使得调用代码变得更加简单.

您的按钮单击处理程序可以更简单:

procedure TForm1.Button3Click(Sender: TObject);
begin
  bgSetDisableOverlappedContent(False);
end;
Run Code Online (Sandbox Code Playgroud)

并且getter函数也比必要复杂得多.我有这样的:

function bgGetDisableOverlappedContent: Boolean;
var
  CAA: BOOL;
begin
  if not CheckWin32Version(6, 0) then
  begin
    Result := False;//or True, I don't know, you decide
    exit;
  end;
  if not SystemParametersInfo(SPI_GETDISABLEOVERLAPPEDCONTENT, 0, @CAA, 0) then
    RaiseLastOSError;
  Result := CAA;
end;
Run Code Online (Sandbox Code Playgroud)