Jump to content
LightningBit

"\Include\WinAPIGdi.au3" (2480) : ==> Variable must be of type "Object"

Recommended Posts

LightningBit

Hi,

I've a script, using WinAPIGdi, checking info on font files

for some files, I get the error

"C:\DEV\AutoIt3\Include\WinAPIGdi.au3" (2480) : ==> Variable must be of type "Object".:

and then the script stops.

Is there a way I can either "catch" that error, and let my script continue with the next file

or improve something in the WinAPIGdi script?

 

I've searched the forums on error handling, but couldn't immediately find something related tho errors like these which are hardstopping the script

 

P.S. : I'm an AutoIT script newbie.....

 

snippet from WinAPIGdi, line 2480 from the error is this one:

 $sResult = $tResult.szTTFName

 

; #FUNCTION# ====================================================================================================================
; Author ........: funkey
; Modified ......: UEZ, jpm
; ===============================================================================================================================
Func _WinAPI_GetFontMemoryResourceInfo($pMemory, $iFlag = 1)
    Local Const $tagTT_OFFSET_TABLE = "USHORT uMajorVersion;USHORT uMinorVersion;USHORT uNumOfTables;USHORT uSearchRange;USHORT uEntrySelector;USHORT uRangeShift"
    Local Const $tagTT_TABLE_DIRECTORY = "char szTag[4];ULONG uCheckSum;ULONG uOffset;ULONG uLength"
    Local Const $tagTT_NAME_TABLE_HEADER = "USHORT uFSelector;USHORT uNRCount;USHORT uStorageOffset"
    Local Const $tagTT_NAME_RECORD = "USHORT uPlatformID;USHORT uEncodingID;USHORT uLanguageID;USHORT uNameID;USHORT uStringLength;USHORT uStringOffset"

    Local $tTTOffsetTable = DllStructCreate($tagTT_OFFSET_TABLE, $pMemory)
    Local $iNumOfTables = _WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uNumOfTables"))

    ;check is this is a true type font and the version is 1.0
    If Not (_WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uMajorVersion")) = 1 And _WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uMinorVersion")) = 0) Then Return SetError(1, 0, "")

    Local $iTblDirSize = DllStructGetSize(DllStructCreate($tagTT_TABLE_DIRECTORY))
    Local $bFound = False, $iOffset, $tTblDir
    For $i = 0 To $iNumOfTables - 1
        $tTblDir = DllStructCreate($tagTT_TABLE_DIRECTORY, $pMemory + DllStructGetSize($tTTOffsetTable) + $i * $iTblDirSize)
        If StringLeft(DllStructGetData($tTblDir, "szTag"), 4) = "name" Then
            $bFound = True
            $iOffset = _WinAPI_SwapDWord(DllStructGetData($tTblDir, "uOffset"))
            ExitLoop
        EndIf
    Next

    If Not $bFound Then Return SetError(2, 0, "")

    Local $tNTHeader = DllStructCreate($tagTT_NAME_TABLE_HEADER, $pMemory + $iOffset)
    Local $iNTHeaderSize = DllStructGetSize($tNTHeader)
    Local $iNRCount = _WinAPI_SwapWord(DllStructGetData($tNTHeader, "uNRCount"))
    Local $iStorageOffset = _WinAPI_SwapWord(DllStructGetData($tNTHeader, "uStorageOffset"))

    Local $iTTRecordSize = DllStructGetSize(DllStructCreate($tagTT_NAME_RECORD))
    Local $tResult, $sResult, $iStringLength, $iStringOffset, $iEncodingID, $tTTRecord
    For $i = 0 To $iNRCount - 1
        $tTTRecord = DllStructCreate($tagTT_NAME_RECORD, $pMemory + $iOffset + $iNTHeaderSize + $i * $iTTRecordSize)

        If _WinAPI_SwapWord($tTTRecord.uNameID) = $iFlag Then ;1 says that this is font name. 0 for example determines copyright info
            $iStringLength = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uStringLength"))
            $iStringOffset = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uStringOffset"))
            $iEncodingID = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uEncodingID"))

            Local $sWchar = "char"
            If $iEncodingID = 1 Then
                $sWchar = "word"
                $iStringLength = $iStringLength / 2
            EndIf
            $tResult = DllStructCreate($sWchar & " szTTFName[" & $iStringLength & "]", $pMemory + $iOffset + $iStringOffset + $iStorageOffset)

            If $iEncodingID = 1 Then
                $sResult = ""
                For $j = 1 To $iStringLength
                    $sResult &= ChrW(_WinAPI_SwapWord(DllStructGetData($tResult, 1, $j)))
                Next
            Else
                $sResult = $tResult.szTTFName

            EndIf

            If StringLen($sResult) > 0 Then ExitLoop
        EndIf
    Next

    Return $sResult
EndFunc   ;==>_WinAPI_GetFontMemoryResourceInfo


 

the function in my script:

Func FontGetInfoFromFile($sFile, $n, $sElement)

    Local $s = _WinAPI_GetFontResourceInfo($sFile, Default, $n)
    If Not @error And $s Then ConsoleWrite($sElement & " = " & $s & @CRLF)
    If @error Then ConsoleWrite ("ERROR!!!")

EndFunc   ;==>FontGetInfoFromFile

 

and _WinAPI_GetFontResourceInfo uses _WinAPI_GetFontMemoryResourceInfo as you know

 

any help or hints are welcome

 

 

Babylon5.ttf

Bahamas.ttf

Edited by LightningBit
attached 2 example fonts which are giving the problem

Share this post


Link to post
Share on other sites
UEZ

Can you provide the font file that I can reproduce the error please?

 

THX.


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
LightningBit

Hi,

 

I attached 2 example fonts with the problem to my Original post

 

here is my "test" script"

 

#Include <Array.au3>
#Include <File.au3>
#Include <WinAPIEx.au3>
#include <GUIConstantsEx.au3>
#Include <FontConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIGdi.au3>
#include <WinAPIMisc.au3>


Opt('MustDeclareVars', 1)

; Variable Declaration

Global $FileList = _FileListToArray("C:\DEV\TEST\FONTS\", '*.ttf', 1, True)
Global $FontList[UBound($FileList) - 1][2]
Global $sFile = ""
Global $sFont = ""

; Functions

Func FontGetInfoFromFile($sFile, $n, $sElement)
    Local $s = _WinAPI_GetFontResourceInfo($sFile, Default, $n)
    If Not @error And $s Then ConsoleWrite($sElement & " = " & $s & @CRLF)
    If @error Then ConsoleWrite ("ERROR!!!")
EndFunc   ;==>FontGetInfoFromFile

;Main Application

For $i = 1 To $FileList[0]
    $sFile = $FileList[$i]
    $sFont = _WinAPI_GetFontResourceInfo($sFile, 1)
    If Not $sFont Then
        Exit
    Else
        ConsoleWrite("Debug : Found a font!" & $sFile & @LF)
    EndIf
    ConsoleWrite("Debug : Getting the data .... " & @LF)
    FontGetInfoFromFile($sFile, 0, "Copyright")
    FontGetInfoFromFile($sFile, 1, "Font Family name")
    FontGetInfoFromFile($sFile, 2, "Font SubFamily name")
    FontGetInfoFromFile($sFile, 3, "Unique font identifier")
    FontGetInfoFromFile($sFile, 4, "Font full name")
    FontGetInfoFromFile($sFile, 5, "Version string")
    FontGetInfoFromFile($sFile, 6, "Postscript name")
    FontGetInfoFromFile($sFile, 7, "Trademark")
    FontGetInfoFromFile($sFile, 8, "Manufacturer Name")
    FontGetInfoFromFile($sFile, 9, "Designer")
    FontGetInfoFromFile($sFile, 10, "Description")
    FontGetInfoFromFile($sFile, 11, "URL Vendor")
    FontGetInfoFromFile($sFile, 16, "Preferred Family (Windows only)")
    FontGetInfoFromFile($sFile, 17, "Preferred SubFamily (Windows only)")
    FontGetInfoFromFile($sFile, 18, "Compatible Full (Mac OS only)")
    FontGetInfoFromFile($sFile, 19, "Sample text")
    FontGetInfoFromFile($sFile, 20, "PostScript CID findfont name")
    FontGetInfoFromFile($sFile, 256, "Font-specific names")
    ConsoleWrite("Debug : Done getting the data .... " & @LF & @CRLF)
    ConsoleWrite(_WinAPI_GetLastError & @LF)
Next

 

 

Edited by LightningBit

Share this post


Link to post
Share on other sites
UEZ

This is a problem with _WinAPI_GetFontMemoryResourceInfo function that is not handling errors which occurs when $iStringLength is 0.

Should be fixed in next release.

 

Thanks.

 

Workaround:

; #FUNCTION# ====================================================================================================================
; Author ........: funkey
; Modified ......: UEZ
; ===============================================================================================================================
Func _WinAPI_GetFontResourceInfo($sFont, $bForce = False, $iFlag = Default)
    If $iFlag = Default Then
        If $bForce Then
            If Not _WinAPI_AddFontResourceEx($sFont, $FR_NOT_ENUM) Then Return SetError(@error + 20, @extended, '')
        EndIf

        Local $iError = 0
        Local $aRet = DllCall('gdi32.dll', 'bool', 'GetFontResourceInfoW', 'wstr', $sFont, 'dword*', 4096, 'wstr', '', 'dword', 0x01)
        If @error Or Not $aRet[0] Then $iError = @error + 10

        If $bForce Then
            _WinAPI_RemoveFontResourceEx($sFont, $FR_NOT_ENUM)
        EndIf
        If $iError Then Return SetError($iError, 0, '')

        Return $aRet[3]
    Else
        If Not FileExists($sFont) Then
            $sFont = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "Fonts") & "\" & $sFont
            If Not FileExists($sFont) Then Return SetError(31, 0, "")
        EndIf
        Local Const $hFile = _WinAPI_CreateFile($sFont, 2, 2, 2)
        If Not $hFile Then Return SetError(32, _WinAPI_GetLastError(), "")
        Local Const $iFile = FileGetSize($sFont)
        Local Const $tBuffer = DllStructCreate("byte[" & $iFile + 1 & "]")
        Local Const $pFile = DllStructGetPtr($tBuffer)
        Local $iRead
        _WinAPI_ReadFile($hFile, $pFile, $iFile, $iRead)
        _WinAPI_CloseHandle($hFile)
        Local $sTTFName = _WinAPI_GetFontMemoryResourceInfo($pFile, $iFlag)
        If @error Then
            If @error = 1 Then
                $sTTFName = _WinAPI_GetFontResourceInfo($sFont, True)
                Return SetError(@error, @extended, $sTTFName)
            EndIf
            Return SetError(33, @error, "")
        EndIf
        Return $sTTFName
    EndIf
EndFunc   ;==>_WinAPI_GetFontResourceInfo

; #FUNCTION# ====================================================================================================================
; Author ........: funkey
; Modified ......: UEZ, jpm
; ===============================================================================================================================
Func _WinAPI_GetFontMemoryResourceInfo($pMemory, $iFlag = 1)
    Local Const $tagTT_OFFSET_TABLE = "USHORT uMajorVersion;USHORT uMinorVersion;USHORT uNumOfTables;USHORT uSearchRange;USHORT uEntrySelector;USHORT uRangeShift"
    Local Const $tagTT_TABLE_DIRECTORY = "char szTag[4];ULONG uCheckSum;ULONG uOffset;ULONG uLength"
    Local Const $tagTT_NAME_TABLE_HEADER = "USHORT uFSelector;USHORT uNRCount;USHORT uStorageOffset"
    Local Const $tagTT_NAME_RECORD = "USHORT uPlatformID;USHORT uEncodingID;USHORT uLanguageID;USHORT uNameID;USHORT uStringLength;USHORT uStringOffset"

    Local $tTTOffsetTable = DllStructCreate($tagTT_OFFSET_TABLE, $pMemory)
    Local $iNumOfTables = _WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uNumOfTables"))

    ;check is this is a true type font and the version is 1.0
    If Not (_WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uMajorVersion")) = 1 And _
            _WinAPI_SwapWord(DllStructGetData($tTTOffsetTable, "uMinorVersion")) = 0) Then Return SetError(1, 0, "")

    Local $iTblDirSize = DllStructGetSize(DllStructCreate($tagTT_TABLE_DIRECTORY))
    Local $bFound = False, $iOffset, $tTblDir
    For $i = 0 To $iNumOfTables - 1
        $tTblDir = DllStructCreate($tagTT_TABLE_DIRECTORY, $pMemory + DllStructGetSize($tTTOffsetTable) + $i * $iTblDirSize)
        If StringLeft(DllStructGetData($tTblDir, "szTag"), 4) = "name" Then
            $bFound = True
            $iOffset = _WinAPI_SwapDWord(DllStructGetData($tTblDir, "uOffset"))
            ExitLoop
        EndIf
    Next

    If Not $bFound Then Return SetError(2, 0, "")

    Local $tNTHeader = DllStructCreate($tagTT_NAME_TABLE_HEADER, $pMemory + $iOffset)
    Local $iNTHeaderSize = DllStructGetSize($tNTHeader)
    Local $iNRCount = _WinAPI_SwapWord(DllStructGetData($tNTHeader, "uNRCount"))
    Local $iStorageOffset = _WinAPI_SwapWord(DllStructGetData($tNTHeader, "uStorageOffset"))

    Local $iTTRecordSize = DllStructGetSize(DllStructCreate($tagTT_NAME_RECORD))
    Local $tResult, $sResult, $iStringLength = 0, $iStringOffset, $iEncodingID, $tTTRecord, $iError = 0
    For $i = 0 To $iNRCount - 1
        $tTTRecord = DllStructCreate($tagTT_NAME_RECORD, $pMemory + $iOffset + $iNTHeaderSize + $i * $iTTRecordSize)
        If @error Then ContinueLoop

        If _WinAPI_SwapWord($tTTRecord.uNameID) = $iFlag Then ;1 says that this is font name. 0 for example determines copyright info
            $iStringLength = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uStringLength"))
            $iStringOffset = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uStringOffset"))
            $iEncodingID = _WinAPI_SwapWord(DllStructGetData($tTTRecord, "uEncodingID"))

            Local $sWchar = "char"
            If $iEncodingID = 1 Then
                $sWchar = "word"
                $iStringLength /= 2
            EndIf
            If Not $iStringLength Then
                $sResult = ""
                ContinueLoop
            EndIf

            $tResult = DllStructCreate($sWchar & " szTTFName[" & $iStringLength & "]", $pMemory + $iOffset + $iStringOffset + $iStorageOffset)

            If $iEncodingID = 1 Then
                $sResult = ""
                For $j = 1 To $iStringLength
                    $sResult &= ChrW(_WinAPI_SwapWord(DllStructGetData($tResult, 1, $j)))
                Next
            Else
                $sResult = $tResult.szTTFName
            EndIf

            If StringLen($sResult) > 0 Then ExitLoop
        EndIf
    Next
    Return $sResult
EndFunc   ;==>_WinAPI_GetFontMemoryResourceInfo

 

Edited by UEZ
Added workaround

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
LightningBit

Hi,

Thanks for looking into it

the error is gone, but is it possible that it now exits the script completely (without error) when it comes across a font with an issue?

when I ran the script, it just stopped after 24 fonts (here are over 4000 in the folder)

I'll try to get more data the next few days

 

--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
 Testing total number of fonts : 4799
Debug : Found a font!C:\DEV\TEST\FONTS\AbductionIV.ttf
Debug : Getting the data .... 1
Font Family name = Abduction IV
Font SubFamily name = Regular
Debug : Done getting the data .... 

Debug : Found a font!C:\DEV\TEST\FONTS\Abe Regular.ttf
Debug : Getting the data .... 2
Font Family name = Abe
Font SubFamily name = Regular
Debug : Done getting the data .... 

+>23:22:38 AutoIt3.exe ended.rc:0
+>23:22:38 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 2.065

 

Olivier

Share this post


Link to post
Share on other sites
LightningBit

I found the problem

 

I had this piece of code in my script

 

$sFont = _WinAPI_GetFontResourceInfo($sFile, 1)
If Not $sFont Then
  Exit
 Else
  ConsoleWrite("Debug : Found a good font!" & $sFile & @LF)
 EndIf

 

this caused the script to exit with some fonts, although the font itself seemed fine

I took it out and even the fonts on which the script did the exit, can be processed ok, so case closed for now I guess

 

The complete testscript:

#Include <Array.au3>
#Include <File.au3>
#Include <WinAPIEx.au3>
#include <GUIConstantsEx.au3>
#Include <FontConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIGdi.au3>
#include <WinAPIMisc.au3>


Opt('MustDeclareVars', 1)

; Variable Declaration



Global $FileList = _FileListToArray("C:\DEV\TEST\FONTS\", '*.ttf', 1, True)
Global $FontList[UBound($FileList) - 1][2]
Global $sFile = ""
Global $sFont = ""

; Functions



Func FontGetInfoFromFile($sFile, $n, $sElement)
    Local $s = _WinAPI_GetFontResourceInfo($sFile, Default, $n)
    If Not @error And $s Then ConsoleWrite($sElement & " = " & $s & @CRLF)
    If @error Then ConsoleWrite ("ERROR!!!")
EndFunc   ;==>FontGetInfoFromFile



;Main Application

ConsoleWrite(" Testing filelist : " & UBound($FileList) & @LF)

For $i = 1 To $FileList[0]
    $sFile = $FileList[$i]
    $sFont = _WinAPI_GetFontResourceInfo($sFile, 1)
    If Not $sFont Then
        Exit
    Else
        ConsoleWrite("Debug : Found a good font!" & $sFile & @LF)
    EndIf

    ConsoleWrite("Debug : Getting the data .... " & $i & @LF)
    FontGetInfoFromFile($sFile, 0, "Copyright")
    FontGetInfoFromFile($sFile, 1, "Font Family name")
    FontGetInfoFromFile($sFile, 2, "Font SubFamily name")
    FontGetInfoFromFile($sFile, 3, "Unique font identifier")
    FontGetInfoFromFile($sFile, 4, "Font full name")
    FontGetInfoFromFile($sFile, 5, "Version string")
    FontGetInfoFromFile($sFile, 6, "Postscript name")
    FontGetInfoFromFile($sFile, 7, "Trademark")
    FontGetInfoFromFile($sFile, 8, "Manufacturer Name")
    FontGetInfoFromFile($sFile, 9, "Designer")
    FontGetInfoFromFile($sFile, 10, "Description")
    FontGetInfoFromFile($sFile, 11, "URL Vendor")
    FontGetInfoFromFile($sFile, 16, "Preferred Family (Windows only)")
    FontGetInfoFromFile($sFile, 17, "Preferred SubFamily (Windows only)")
    FontGetInfoFromFile($sFile, 18, "Compatible Full (Mac OS only)")
    FontGetInfoFromFile($sFile, 19, "Sample text")
    FontGetInfoFromFile($sFile, 20, "PostScript CID findfont name")
    FontGetInfoFromFile($sFile, 256, "Font-specific names")
    ConsoleWrite("Debug : Done getting the data .... " & @LF & @CRLF)
    ConsoleWrite(_WinAPI_GetLastError & @LF)
Next

 

Edited by LightningBit

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • genius257
      By genius257
      I've made a library, based on AutoItObject UDF with the goal of implementing getter and setter functionality and make it possible to define new object properties in as few steps as possible.
      Thank you to @trancexx for getting me on the right track, and all users in Hooking into the IDispatch interface for the code to get me going.
      If I've forgotten to add credit, please let me know
      Example:
      #include "AutoItObject_Internal.au3" $myCar = IDispatch() $myCar.make = 'Ford' $myCar.model = 'Mustang' $myCar.year = 1969 $myCar.__defineGetter('DisplayCar', DisplayCar) Func DisplayCar($oThis) Return 'A Beautiful ' & $oThis.parent.year & ' ' & $oThis.parent.make & ' ' & $oThis.parent.model EndFunc MsgBox(0, "", $myCar.DisplayCar) More examples: https://github.com/genius257/AutoItObject-Internal/tree/master/Examples
      Version: 2.0.0
      AutoItObject_Internal.au3
      Documentation
      Edit2 (19th March 2017):
      First of all, sorry about the lack of updates on this project. I always start too many projects and end up ignoring old projects, if I run into problems ^^'.
      So I've started moving my AutoIt scripts to GitHub. I will still post the most recent script version here.
    • therks
      By therks
      I'm trying to create a simple clock widget that automatically scales the text to the size of the window. I came up with the following method, but it doesn't work as well as I'd like. It especially has trouble scaling to the width of the window for some reason (in the example, try resizing the window to be narrow and tall).
      Does anyone have a better method?
      #include <Misc.au3> #include <WinAPIConv.au3> #include <GUIConstants.au3> #include <GDIPlus.au3> Opt('MustDeclareVars', 1) Global $_FONT_FAMILY = 'Arial', $_LB_TEXT Main() Func Main() _GDIPlus_Startup() Local $hGUI GUIRegisterMsg($WM_SIZE, WM_SIZE) $hGUI = GUICreate('', 300, 100, Default, Default, $WS_OVERLAPPEDWINDOW, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) $_LB_TEXT = GUICtrlCreateLabel('This is a string', 0, 0, 300, 100, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont($_LB_TEXT, _MeasureString($hGUI, GUICtrlRead($_LB_TEXT), $_FONT_FAMILY), 0, 0, $_FONT_FAMILY, 5) GUISetState() Local $iGM While 1 $iGM = GUIGetMsg() Switch $iGM Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GDIPlus_Shutdown() EndFunc Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) GUICtrlSetFont($_LB_TEXT, _MeasureString($hWnd, GUICtrlRead($_LB_TEXT), $_FONT_FAMILY), 0, 0, $_FONT_FAMILY, 5) EndFunc Func _MeasureString($hWnd, $sString, $sFont = 'Arial') Local $iError, $aSize, $hGraphic, $hFormat, $hFamily, $tLayout, $iFontSize, $hFont, $aInfo If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) EndIf $aSize = WinGetClientSize($hWnd) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd) $hFormat = _GDIPlus_StringFormatCreate() $hFamily = _GDIPlus_FontFamilyCreate($sFont) $tLayout = _GDIPlus_RectFCreate(0, 0, $aSize[0], $aSize[1]) $iFontSize = 0 Do If Not $hFamily Then $iError = 1 $iFontSize = 10 ExitLoop EndIf $iFontSize += 1 $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize, 0) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat) _GDIPlus_FontDispose($hFont) If $aInfo[1] = 0 Then ExitLoop Until DllStructGetData($aInfo[0], 3) >= $aSize[0] Or DllStructGetData($aInfo[0], 4) >= $aSize[1] $iFontSize -= 1 _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) Return SetError($iError, 0, $iFontSize) EndFunc
    • Spartan117
      By Spartan117
      Hi everyone,
      I am wondering if is there any autoit function that make the program ignore errors and move on and resume correct lines?
      Thank you
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I'm working on a little project of mines, and I was trying to use WMI Object.
      The question which I don't find an answer is: 
      Once I do the query with WMI Object, something like "SELECT * FROM Win32_LogonSession", instead of specify the field of the collection returned, ( i.e. $colItems.Caption ), can I loop though each property and each value of the property, writing so one row of code only?
      Hope my question was clear enough.
      Thanks in advance.

      Best Regards.
    • AndyS19
      By AndyS19
      I am trying to print using a small font, but no mater how I try it, the printed font remains unchanged.
      I have created a sample script that sets the font to 8.
      Here are the functions I use to create, then set the font:
      Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Here is the complete script:
      #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 Opt('MustDeclareVars', 1) #include <APIDlgConstants.au3> #include <FontConstants.au3> #include <WinAPI.au3> ; #VARIABLES# ================================================================ Global $i__LastLineNum = -1, $i__NextLineNum = -1, $i__ThisLineNum = -1 Global $i__LeftMargin_X, $i__TopMargin_Y, $i__PageWidth, $i__PageHeight Global $i__CurrentPos_X, $i__CurrentPos_Y Global $i__Printer_Char_H = -1, $i__Printer_Char_W = -1 Global $a__Printer_Font = 0 Global $i__x_start, $i__x_end, $i__y_start, $i__y_end ; ============================================================================ ; #CONSTANTS# ================================================================ Global $PHYSICALWIDTH = 110, $PHYSICALHEIGHT = 111 Global $PHYSICALOFFSETX = 112, $PHYSICALOFFSETY = 113 Const $VLINESPACE = 20 ; Number of pixels between lines Global Const $tagPD = "align 1;DWORD lStructSize;" & "HWND hwndOwner;" & "handle hDevMode;" & "handle hDevNames;" & _ "handle hDC;" & "DWORD Flags;" & _ "WORD nFromPage;" & "WORD nToPage;" & "WORD nMinPage;" & "WORD nMaxPage;" & "WORD nCopies;" & _ "handle hInstance;" & "LPARAM lCustData;" & "ptr lpfnPrintHook;" & "ptr lpfnSetupHook;" & _ "ptr lpPrintTemplateName;" & "ptr lpSetupTemplateName;" & "handle hPrintTemplate;" & "handle hSetupTemplate" Global Const $tagDOCINFO = "int Size;" & "ptr DocName;" & "ptr Output;" & "ptr Datatype;" & "dword Type" ; ============================================================================ _Main() Func _Main() Local $hDC, $str, $str2 = "", $linenum $hDC = _Printer_Open(0, Default, "DOCNAME: ++++") _LogMsg("+++: $hPrintDc = 0x" & Hex($hDC)) If (Not $hDC) Then Exit (1) _Printer_SetFont($hDC) For $y = 1 To 10 $str2 &= "123456789." Next $linenum = 30 ; Start in the middle of the page For $x = 1 To 15 $str = "[" & $x & " " & $str2 _LogMsg("+++: $str ==>" & $str & "<==") _Printer_PrintTextLine($hDC, $str, $linenum) $linenum += 1 Next _Printer_Close($hDC) EndFunc ;==>_Main Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Func _Printer_Open($hGUI = 0, $iFlags = Default, $sDocName = "") Local $hDC, $tPD, $err If $iFlags = Default Then $iFlags = 0 $iFlags = BitOR($iFlags, $PD_RETURNDC) $iFlags = BitOR($iFlags, $PD_USEDEVMODECOPIESANDCOLLATE) EndIf $tPD = DllStructCreate($tagPD) DllStructSetData($tPD, "lStructSize", DllStructGetSize($tPD)) DllStructSetData($tPD, "hwndOwner", $hGUI) ; If $hGUI <> 0 Then DllStructGetData($tPD, "hInstance", _WinAPI_GetModuleHandle("")) EndIf DllStructSetData($tPD, "Flags", $iFlags) DllStructSetData($tPD, "nCopies", 2) Local $bRet = DllCall("Comdlg32.dll", "int", "PrintDlgW", "ptr", DllStructGetPtr($tPD)) $err = @error If $err Then $err = _WinAPI_GetLastError() Local $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: _Printer_Open() returns: (1, " & $err & ", 0) - '" & $errm & "'") $tPD = 0 Return SetError(1, $err, 0) EndIf If $bRet[0] = True Then $hDC = DllStructGetData($tPD, "hDC") Else Return SetError(2, $err, 0) EndIf $tPD = 0 __Printer_SetupCharWH($hDC) _Printer_GetMetrics($hDC) _Printer_Startup($hDC, $sDocName) Return (SetError(0, 0, $hDC)) EndFunc ;==>_Printer_Open Func _Printer_Startup($hDC, $sDocName) Local $oDocNameStruct, $DOCINFO, $printJobID, $errstr __Printer_SetupCharWH($hDC) ; Get the height and width of a printer character $oDocNameStruct = DllStructCreate("char DocName[" & StringLen($sDocName & Chr(0)) & "]") DllStructSetData($oDocNameStruct, "DocName", $sDocName & Chr(0)) ; Size of DOCINFO structure $DOCINFO = DllStructCreate($tagDOCINFO) ; Structure for Print Document info DllStructSetData($DOCINFO, "Size", 20) ; Size of DOCINFO structure DllStructSetData($DOCINFO, "DocName", DllStructGetPtr($oDocNameStruct)) ; Set name of print job (Optional) _Printer_GetMetrics($hDC) $printJobID = _Printer_StartDoc($hDC, $DOCINFO) ; start new print doc If ($printJobID <= 0) Then $errstr = "_Printer_StartDoc() failed" _LogMsg("+++: _Printer_Startup() returns: @error = 1 - " & $errstr) Return (SetError(1, 0, $errstr)) EndIf Return (SetError(0, 0, $printJobID)) ; print job ID EndFunc ;==>_Printer_Startup Func _Printer_Close($hDC) _Printer_EndPage($hDC) ; End the currend page _Printer_EndDoc($hDC) ; End the print job _WinAPI_DeleteDC($hDC) ; Delete the printer device context EndFunc ;==>_Printer_Close Func _Printer_EndPage($hDC) Local $aResult If ($i__ThisLineNum > 1) Then $aResult = DllCall("GDI32.dll", "long", "EndPage", "hwnd", $hDC) EndIf _Printer_SetInitial_XY() $i__ThisLineNum = -1 Return ($aResult[0]) EndFunc ;==>_Printer_EndPage Func _Printer_EndDoc($hDC) Local $aResult $aResult = DllCall("GDI32.dll", "long", "EndDoc", "hwnd", $hDC) Return ($aResult[0]) EndFunc ;==>_Printer_EndDoc Func _Printer_TextOut($hDC, $iXStart, $iYStart, $sString) Local $aResult $aResult = DllCall("GDI32.dll", _ "long", "TextOut", _ "hwnd", $hDC, _ "long", $iXStart, _ "long", $iYStart, _ "str", $sString, _ "long", StringLen($sString)) Return $aResult[0] ; 0 = fail, 1 = OK EndFunc ;==>_Printer_TextOut Func _Printer_PrintTextLine($hDC, $sText, $iLineNumber = -1) Local $ret, $lines, $ndx If ($iLineNumber <= 0) Then $iLineNumber = $i__ThisLineNum EndIf $sText = StringStripWS($sText, 2) ; Clear trailing whitespace ; Break text into an array of lines, based on any of the ; usual line endings (@CR, @LF, etc.) found in the string. $sText = StringRegExpReplace($sText, "[\\][n]", @CR) $sText = StringReplace($sText, @CRLF, @LF) $sText = StringReplace($sText, @CR, @LF) While (StringRight($sText, 1) == @LF) StringTrimRight($sText, 1) ; remove trailing LF's WEnd $lines = StringSplit($sText, @LF, 2) ; Now print each line in the array of lines, advancing the ; printer line position each time For $ndx = 0 To UBound($lines) - 1 $i__CurrentPos_X = $i__x_start ; $i__LeftMargin_X $i__CurrentPos_Y = (($i__Printer_Char_H + $VLINESPACE) * $iLineNumber) + $i__y_start $ret = _Printer_TextOut($hDC, $i__CurrentPos_X, $i__CurrentPos_Y, $lines[$ndx]) $iLineNumber += 1 $i__ThisLineNum += 1 If ($ret == 0) Then ExitLoop If ($iLineNumber > $i__LastLineNum) Then _Printer_EndPage($hDC) $iLineNumber = 1 $i__ThisLineNum = 1 EndIf Next ; Calculate next x/y position $i__CurrentPos_Y = (($i__Printer_Char_H + $VLINESPACE) * $iLineNumber) Return (SetError(0, 0, $iLineNumber)) EndFunc ;==>_Printer_PrintTextLine Func _Printer_StartDoc($hDC, $tDocInfo) Local $aResult $aResult = DllCall("GDI32.dll", "long", "StartDoc", "hwnd", $hDC, "ptr", DllStructGetPtr($tDocInfo)) _Printer_SetInitial_XY() Return ($aResult[0]) ; >0 = OK, <=0 = Fail EndFunc ;==>_Printer_StartDoc Func _Printer_GetMetrics($hDC) $i__LeftMargin_X = _WinAPI_GetDeviceCaps($hDC, $PHYSICALOFFSETX) $i__TopMargin_Y = _WinAPI_GetDeviceCaps($hDC, $PHYSICALOFFSETY) $i__PageWidth = _WinAPI_GetDeviceCaps($hDC, $PHYSICALWIDTH) $i__PageHeight = _WinAPI_GetDeviceCaps($hDC, $PHYSICALHEIGHT) #Tidy_Off _LogMsg("+++:" & @CRLF _ & "$PHYSICALOFFSETX [" & $PHYSICALOFFSETX & "] $i__LeftMargin_X = " & $i__LeftMargin_X & @CRLF _ & "$PHYSICALOFFSETY [" & $PHYSICALOFFSETY & "] $i__TopMargin_Y = " & $i__TopMargin_Y & @CRLF _ & "$PHYSICALWIDTH [" & $PHYSICALWIDTH & "] $i__PageWidth = " & $i__PageWidth & @CRLF _ & "$PHYSICALHEIGHT [" & $PHYSICALHEIGHT & "] $i__PageHeight = " & $i__PageHeight & @CRLF _ ) #Tidy_On $i__x_start = $i__LeftMargin_X - 75 $i__y_start = $i__TopMargin_Y - 75 $i__x_end = $i__PageWidth - 250 $i__y_end = $i__PageHeight - 200 _Printer_SetInitial_XY() $i__LastLineNum = _Printer_GetLastLineNum() EndFunc ;==>_Printer_GetMetrics Func _Printer_SetInitial_XY() $i__CurrentPos_X = $i__LeftMargin_X $i__CurrentPos_Y = $i__TopMargin_Y * 22 EndFunc ;==>_Printer_SetInitial_XY Func _Printer_GetLastLineNum() Local $x1, $y, $linenumber $linenumber = -1 If ($i__Printer_Char_H > 0) Then For $x1 = 1 To 999 $y = (($i__Printer_Char_H + $VLINESPACE) * ($x1 + 1)) If ($y >= $i__y_end) Then $linenumber = $x1 ExitLoop EndIf Next EndIf If ($linenumber == -1) Then MsgBox(0, "Internal Error", "ERROR: Could not calculate the last line number") Exit (1) EndIf $linenumber -= 1 Return ($linenumber) EndFunc ;==>_Printer_GetLastLineNum Func __Printer_SetupCharWH($hDC) Local $vExtents $vExtents = _WinAPI_GetTextExtentPoint32($hDC, "x") $i__Printer_Char_W = DllStructGetData($vExtents, "X") ; Get the width of a character $i__Printer_Char_H = DllStructGetData($vExtents, "Y") ; Get the height of a character EndFunc ;==>__Printer_SetupCharWH Func _LogMsg($msg, $lnum = @ScriptLineNumber) If (StringLeft($msg, 4) = "+++:") Then $msg = StringTrimLeft($msg, 5) $msg = StringStripWS($msg, 3) ConsoleWrite("+++:" & $lnum & "] " & $msg & @CRLF) EndFunc ;==>_LogMsg Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Here is the full script.  Run it to see the problem:
×