タッチスクリーン PC で実行されているアプリケーションのシステム スクロールバーのサイズを拡大するコードがあります。このコードは Delphi 7 で書かれており、数年間問題なく動作していますが、Windows 7 で実行すると問題があるようです。
コードは次のようになります。
procedure SetLargeScrollBars();
type
// Extended NONCLIENTMETRICS structure not defined in Delphi 7's Windows.pas
tagNONCLIENTMETRICSXA = packed record
cbSize: UINT;
iBorderWidth: Integer;
iScrollWidth: Integer;
iScrollHeight: Integer;
iCaptionWidth: Integer;
iCaptionHeight: Integer;
lfCaptionFont: TLogFontA;
iSmCaptionWidth: Integer;
iSmCaptionHeight: Integer;
lfSmCaptionFont: TLogFontA;
iMenuWidth: Integer;
iMenuHeight: Integer;
lfMenuFont: TLogFontA;
lfStatusFont: TLogFontA;
lfMessageFont: TLogFontA;
// This member not supported for Windows Server 2003 and Windows XP/2000
iPaddedBorderWidth: Integer;
end;
NONCLIENTMETRICSX = tagNONCLIENTMETRICSXA;
var
ncm: NONCLIENTMETRICSX;
osvi: OSVERSIONINFO;
const
LARGE_SCROLL_DIM = 48;
begin
// Zero the NONCLIENTMETRICS type and fill in its size
ZeroMemory(@ncm, Sizeof(ncm));
ncm.cbSize := SizeOf(ncm);
// This is necessary because SystemParametersInfo works differently for
// Windows Server 2008, Windows Vista and after.
ZeroMemory(@osvi, SizeOf(osvi));
osvi.dwOSVersionInfoSize := SizeOf(osvi);
GetVersionEx(osvi);
if (osvi.dwMajorVersion < 6) then
begin
ncm.cbSize := ncm.cbSize - SizeOf(ncm.iPaddedBorderWidth);
end;
// Seems to return true all the time.
SystemParametersInfo(
SPI_GETNONCLIENTMETRICS,
Sizeof(ncm),
@ncm,
0);
if (ncm.iScrollWidth <> LARGE_SCROLL_DIM) then
begin
// Save the scrollbar width and height for restoration when the application closes.
m_ScrollWidth := ncm.iScrollWidth;
m_ScrollHeight := ncm.iScrollHeight;
ncm.iScrollWidth := LARGE_SCROLL_DIM;
ncm.iScrollHeight := LARGE_SCROLL_DIM;
// This call never returns...
SystemParametersInfo(
SPI_SETNONCLIENTMETRICS,
Sizeof(ncm),
@ncm,
SPIF_SENDCHANGE);
end;
end;
興味深いのは、スクロールバーのサイズが実際に設定されていることです。そのため、SystemParametersInfo は本来の処理を行っているように見えますが、その後は混乱しているように見えます。
スクロールバーが既に展開されているかどうかのチェック機能があるため、2 回目以降は問題なく動作します (テーマを元に戻してスクロールバーをリセットしない限り)。
最後のパラメーター (fWinIni) と関係があるのではないかと思っていたので、ゼロを含むさまざまな値をすべて試しましたが、役に立ちませんでした。
おそらく、設定が変更された後、Windows 7 は以前のフレーバーの OS とは何か違うことをするのでしょうか? とは言っても、Vistaでは試していないので、同じことが起こるかもしれません。これは、Windows Vista、Windows Server 2008、およびそれ以降のバージョンの iPaddedBorderWidth の追加に関連している可能性があります - NONCLIENTMETRICS 構造を参照してください
.NET の観点から見た同じ状況に関するMSDN Problem Changing size of scrollbars using SystemParametersInfo(SPI_SETNONCLIENTMETRICS)に同様の質問がありますが、これまでのところ回答はありません。
さらに詳しい情報
関連するアプリケーションでハング分析を実行するために DebugDiag を使用したところ、次のスタック トレースが表示されました。
関数
ntdll!KiFastSystemCallRet
uxtheme!Ordinal45+25d
uxtheme!BeginBufferedAnimation+25b
user32!SystemParametersInfoA+40
プログラム名+13024f
プログラム名+117c8d
プログラム名+6ae72 プログラム
名+727dc プログラム
名+132645
kernel32!BaseThreadInitThunk+12
ntdll!RtlInitializeExceptionChain+tInitializeExceptionChain+ef
ntdll
したがって、ハングが uxtheme!Ordinal45+25d で発生しているように見えます - おそらく何らかのシステム コールで発生しています。