gpt4 book ai didi

delphi - 为什么 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, ...) 在 Windows 7 中挂起,而以前却没有?

转载 作者:行者123 更新时间:2023-12-03 15:21:17 35 4
gpt4 key购买 nike

我有一些代码可以扩展触摸屏 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 正在做它应该做的事情,但在那之后似乎变得困惑。

由于该函数会检查滚动条是否已展开,因此应用程序第二次及此后都可以正常运行(除非通过将主题恢复为原始状态来重置滚动条)。

我想知道这是否与最后一个参数(fWinIni)有关,并尝试了所有不同的值,包括零,但无济于事。

在更改设置后,Windows 7 可能会做一些与早期操作系统不同的事情吗?话虽如此,我还没有在 Vista 上尝试过,所以也许同样的事情也会发生。这可能与 Windows Vista、Windows Server 2008 及后续版本添加的 iPaddedBorderWidth 有关 - 请参阅 NONCLIENTMETRICS Structure

MSDN上有类似的问题Problem Changing size of scrollbars using SystemParametersInfo(SPI_SETNONCLIENTMETRICS)从 .NET 的角度来看同样的情况,但到目前为止还没有答案。

<小时/>

更多信息

我使用 DebugDiag 对相关应用程序执行挂起分析,它显示了以下堆栈跟踪:

Function
ntdll!KiFastSystemCallRet
uxtheme!Ordinal45+25d
uxtheme!BeginBufferedAnimation+25b
user32!SystemParametersInfoA+40
programName+13024f
programName+117c8d
programName+6ae72
programName+727dc
programName+132645
kernel32!BaseThreadInitThunk+12
ntdll!RtlInitializeExceptionChain+ef
ntdll!RtlInitializeExceptionChain+c2

所以看起来好像挂起发生在 uxtheme!Ordinal45+25d 中 - 可能是在某种系统调用中。

最佳答案

也许问题是由另一个窗口引起的。您正在使用 SPIF_SENDCHANGE 参数调用 SystemParametersInfo。这会导致使用 SendMessage 广播 WM_SETTINGSCHANGE 消息。当有一个窗口不响应此消息时,对 SystemParametersInfo 的调用将挂起。请阅读this entry的旧新事物。

关于delphi - 为什么 SystemParametersInfo(SPI_SETNONCLIENTMETRICS, ...) 在 Windows 7 中挂起,而以前却没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11123369/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com