I have some code that expands the size of the system scrollbars for an application running on a touchscreen PC. This code was written in Delphi 7 and has been running satisfactorily for several years, but I have found that there seems to be a problem when running it on Windows 7.
The code looks like this:
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;
The curious thing is that the scrollbar sizes are actually set, so it seems that SystemParametersInfo is doing what it is supposed to do, but then appears to get confused after that point.
Since there is a check in the function to see if the scrollbars are already expanded, the application runs fine the second time and thereafter (unless the scrollbars are reset by reverting the theme back to the original).
I was wondering if it could be something to do with the last parameter (fWinIni) and have tried all the various values for that including zero, but to no avail.
Perhaps Windows 7 does something different to earlier flavours of the OS after the settings have been changed? Having said that, I haven't tried it on Vista, so maybe the same thing happens there. It could be related to the addition of iPaddedBorderWidth for Windows Vista, Windows Server 2008 and subsequent versions - see NONCLIENTMETRICS Structure
There is a similar question on MSDN Problem Changing size of scrollbars using SystemParametersInfo(SPI_SETNONCLIENTMETRICS) regarding the same situation from a .NET perspective but no answer to it so far.
I have used DebugDiag to perform a hang analysis on the application concerned, and it shows the following stack trace:
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
So it looks as if the hang is occurring in uxtheme!Ordinal45+25d - presumably in a system call of some kind.
Perhaps the problem is caused by another window. You are calling SystemParametersInfo
with the SPIF_SENDCHANGE
-parameter. This causes a WM_SETTINGSCHANGE
message to be broadcasted with SendMessage
. When there is a window that does not respond to this message, the call to SystemParametersInfo
will hang. Please read this entry of The Old New Thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With