1

我有功能

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;

并准确地称呼它

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;

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

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;

CAA 的结果再次为 True,即使我完全设置 CAA := False; 我正在开发 Win 7. 和 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;

CAA 是真的。

你有什么主意吗?

在此先感谢博扬

4

1 回答 1

7

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

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

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

SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, Pointer(CAA), 0)

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

if not GetOSVersion >= 60 then

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

if (not GetOSVersion) >= 60 then

由于GetOSVersion返回一个有符号值,因此无论 Windows 版本如何,都会(not GetOSVersion) >= 60计算为。False那是因为not GetOSVersion总是 <= 0

您需要逻辑否定而不是按位否定。所以你应该写

if not (GetOSVersion >= 60) then

或等效地

if GetOSVersion < 60 then

实际上,有一个内置函数可以做到这一点。它被称为CheckWin32Version。像这样称呼它:

if not CheckWin32Version(6, 0) then
  exit;

不过,您的其余功能有点混乱。您ErrorText按值传递,然后分配给它。大概您打算让调用者接收该值。除非您经过,否则不会发生这种情况var

我个人会这样写你的程序:

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

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

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

procedure TForm1.Button3Click(Sender: TObject);
begin
  bgSetDisableOverlappedContent(False);
end;

并且 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;
于 2012-12-29T20:32:41.483 回答