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 := False; を正確に設定しても、CAA の結果は再び True になります。私はWin 7に取り組んでいます。そして結果の結果:= SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, @CAA, 0); は True ですが、SPI_GETDISABLEOVERLAPPEDCONTENT は、正確に False に設定される前のステップであっても、CAA に対して True を返します。

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を渡すことを意図しているのに、へのポインターを渡していることです。ドキュメントには次のように記載されています。BOOLBOOL

pvParam パラメータは BOOL 変数です。pvParam を TRUE に設定して重複コンテンツを無効にするか、FALSE に設定して重複コンテンツを有効にします。

つまり、プロパティを設定するコードは次のようにする必要があります。

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

あなたGetOSVersionは災害です。耳障りでごめんなさい!0Windows 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;

また、ゲッター関数も必要以上に複雑です。私は次のようにします:

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 に答える