Opened 10 months ago

Last modified 2 months ago

#3968 assigned Bug

global struct gets corrupted after GUISetState() — at Version 6

Reported by: argumentum Owned by:
Milestone: Component: AutoIt
Version: 3.3.16.1 Severity: None
Keywords: Struct Cc:

Description (last modified by mLipok)

#include <WinAPISys.au3> ; for $tagLOGFONT ;
Global $___gt__HiDpi_WinFont, $sFont
_SystemParametersInfo_GetSystemFont()
$hGUI = GUICreate('Test', 400, 400)

GUISetState(@SW_SHOW, $hGUI) ; try the code with this and without it

ConsoleWrite("Font : Attributes: " & $___gt__HiDpi_WinFont.Attributes & @CRLF)
ConsoleWrite("Font :     Weight: " & DllStructGetData($___gt__HiDpi_WinFont, 'Weight') & @CRLF)
ConsoleWrite("Font :    Quality: " & DllStructGetData($___gt__HiDpi_WinFont, 'Quality') & @CRLF)
ConsoleWrite("Font :   FaceName: " & DllStructGetData($___gt__HiDpi_WinFont, 'FaceName') & @CRLF)
ConsoleWrite("Font :   FaceName: " & $sFont & @CRLF) ; this never changes

Func _SystemParametersInfo_GetSystemFont()
        Local $dMenuFont = Binary(RegRead('HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics', 'MenuFont'))
        ConsoleWrite($dMenuFont & @CRLF)
        Local $tLOGFONT = DllStructCreate('byte[' & BinaryLen($dMenuFont) & ']')
        DllStructSetData($tLOGFONT, 1, $dMenuFont)
        $___gt__HiDpi_WinFont = DllStructCreate($tagLOGFONT, DllStructGetPtr($tLOGFONT))
        $sFont = DllStructGetData($___gt__HiDpi_WinFont, 'FaceName')
EndFunc

While troubleshooting we discovered a bug.
The thread is at https://www.autoitscript.com/forum/topic/210637-systemparametersinfo-getsystemfont-i-made-an-ugly-bug/?do=findComment&comment=1522165

Change History (6)

comment:1 Changed 10 months ago by argumentum

so, the bug was in the coder.
This works as advertised:

#include <WinAPISys.au3>
#include <WinAPIsysinfoConstants.au3>

Global $___gt__HiDpi_WinFont = _SystemParametersInfo_GetSystemFont()

$hGUI = GUICreate('Test', 400, 400)
GUISetState(@SW_SHOW, $hGUI)

ConsoleWrite("Font : Attributes: " & $___gt__HiDpi_WinFont.Attributes & @CRLF)
ConsoleWrite("Font :     Weight: " & $___gt__HiDpi_WinFont.Weight & @CRLF)
ConsoleWrite("Font :    Quality: " & $___gt__HiDpi_WinFont.Quality & @CRLF)
ConsoleWrite("Font :   FaceName: " & $___gt__HiDpi_WinFont.FaceName & @CRLF)


Func _SystemParametersInfo_GetSystemFont()
    Local $tLOGFONT = DllStructCreate(StringReplace($tagLOGFONT, 'OutPrecision', 'Attributes'))
    Local $iSize = DllStructGetSize($tLOGFONT)
    Local $tNONCLIENTMETRICS = DllStructCreate("STRUCT;uint cbsize;int iBorderWidth;int iScrollWidth;int iScrollHeight;int iCaptionWidth;" & _
    "int iCaptionHeight;byte lfCaptionFont[" & $iSize & "];int iSmCaptionWidth;int iSmCaptionHeight;byte lfSmCaptionFont[" & $iSize & "];int iMenuWidth;" & _
    "int iMenuHeight;byte lfMenuFont[" & $iSize & "];byte lfStatusFont[" & $iSize & "];byte lfMessageFont[" & $iSize & "];int iPaddedBorderWidth;ENDSTRUCT")
    $tNONCLIENTMETRICS.cbsize = DllStructGetSize($tNONCLIENTMETRICS)
    If Not _WinAPI_SystemParametersInfo($SPI_GETNONCLIENTMETRICS, $tNONCLIENTMETRICS.cbsize, $tNONCLIENTMETRICS) Then Return SetError(@error, @extended, 0)
    Local $tTemp = DllStructCreate($tagLOGFONT, DllStructGetPtr($tNONCLIENTMETRICS, "lfCaptionFont"))
    With $tLOGFONT
        .Weight = $tTemp.Weight
        .FaceName = $tTemp.FaceName
        .Quality = $tTemp.Quality
        .Attributes = BitOR(($tTemp.Italic ? 2 : 0),($tTemp.Underline ? 4 : 0),($tTemp.Strikeout ? 8 : 0))
    EndWith
    Return $tLOGFONT
EndFunc

Do pardon my lack of experience if you would.

Last edited 9 months ago by mLipok (previous) (diff)

comment:2 Changed 10 months ago by Jos

  • Resolution set to No Bug
  • Status changed from new to closed

comment:3 Changed 10 months ago by Jpm

In case it help the error was coming from the fact thatthe global variable was assign to a local variable
the correction is

#include <WinAPISys.au3> ; For $tagLOGFONT ;
Global $g_sFont
Global $___gt__HiDpi_WinFont= _SystemParametersInfo_GetSystemFont()

Local $hGUI = GUICreate('Test', 400, 400)

GUISetState(@SW_SHOW, $hGUI) ; try the code with this and without it

ConsoleWrite("Font : Attributes: " & $___gt__HiDpi_WinFont.Attributes & @CRLF)
ConsoleWrite("Font :     Weight: " & DllStructGetData($___gt__HiDpi_WinFont, 'Weight') & @CRLF)
ConsoleWrite("Font :    Quality: " & DllStructGetData($___gt__HiDpi_WinFont, 'Quality') & @CRLF)
ConsoleWrite("Font :   FaceName: " & DllStructGetData($___gt__HiDpi_WinFont, 'FaceName') & @CRLF)
ConsoleWrite("Font :   FaceName: " & $g_sFont & @CRLF) ; this never changes

Func _SystemParametersInfo_GetSystemFont()
        Local $dMenuFont = Binary(RegRead('HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics', 'MenuFont'))
        ConsoleWrite($dMenuFont & @CRLF)
        Local $tLOGFONT = DllStructCreate('byte[' & BinaryLen($dMenuFont) & ']')
        DllStructSetData($tLOGFONT, 1, $dMenuFont)
        Local $tTemp = DllStructCreate($tagLOGFONT, DllStructGetPtr($tLOGFONT))
        $g_sFont = DllStructGetData($___gt__HiDpi_WinFont, 'FaceName')
        Return $tTemp
EndFunc   ;==>_SystemParametersInfo_GetSystemFont

Cheers

Last edited 9 months ago by mLipok (previous) (diff)

comment:4 Changed 10 months ago by argumentum

hmm, I've run the correction you posted here but it does not correct the original code that is observable while running over and over again while testing.

comment:5 Changed 9 months ago by Jpm

  • Resolution No Bug deleted
  • Status changed from closed to reopened

Hi
I understand that the return is erratic even If I fix the

$g_sFont = DllStructGetData($_gtHiDpi_WinFont, 'FaceName')
to
$g_sFont = DllStructGetData($tTemp, 'FaceName')
I don't understand the influence of the position of
Global $_gtHiDpi_WinFont= _SystemParametersInfo_GetSystemFont()
which is ok after the
GUISetState(@SW_SHOW, $hGUI) ; try the code with this and without it
here is the code which is erratic

#include <WinAPISys.au3> ; For $tagLOGFONT ;
Global $g_sFont
Local $___gt__HiDpi_WinFont= _SystemParametersInfo_GetSystemFont()

Local $hGUI = GUICreate('Test', 400, 400)

GUISetState(@SW_SHOW, $hGUI) ; try the code with this and without it

ConsoleWrite("Font : Attributes: " & $___gt__HiDpi_WinFont.Attributes & @CRLF)
ConsoleWrite("Font :     Weight: " & DllStructGetData($___gt__HiDpi_WinFont, 'Weight') & @CRLF)
ConsoleWrite("Font :    Quality: " & DllStructGetData($___gt__HiDpi_WinFont, 'Quality') & @CRLF)
ConsoleWrite("Font :   FaceName: " & DllStructGetData($___gt__HiDpi_WinFont, 'FaceName') & @CRLF)
ConsoleWrite("Font :   FaceName: " & $g_sFont & @CRLF) ; this never changes

Func _SystemParametersInfo_GetSystemFont()
        Local $dMenuFont = Binary(RegRead('HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics', 'MenuFont'))
        ConsoleWrite(BinaryLen($dMenuFont) & @CRLF)
        ConsoleWrite($dMenuFont & @CRLF)
        Local $tLOGFONT = DllStructCreate('byte[' & BinaryLen($dMenuFont) & ']')
        DllStructSetData($tLOGFONT, 1, $dMenuFont)
        Local $tTemp = DllStructCreate($tagLOGFONT, DllStructGetPtr($tLOGFONT))
        $g_sFont = DllStructGetData($tTemp, 'FaceName')
        Return $tTemp
EndFunc   ;==>_SystemParametersInfo_GetSystemFont

Last edited 9 months ago by mLipok (previous) (diff)

comment:6 Changed 9 months ago by mLipok

  • Description modified (diff)
Note: See TracTickets for help on using tickets.