InunoTaishou

Storing functions in structs

2 posts in this topic

I know you can store functions in variables but I'm interested in storing functions in structs.

Global $tWindow = DllStructCreate("hwnd hwnd;ptr delete")
$tWindow.hwnd = GUICreate("")
; works
Global $pDelete = GUIDelete
; doesn't work
$tWindow.delete = GUIDelete

ConsoleWrite("Delete using $tWindow.delete: " & $tWindow.delete() & @LF)
ConsoleWrite("Delete using $pDelete: " & $pDelete() & @LF)

Maybe I'm using the wrong data type for my delete member, I've tried int, dword, ptr, handle, hwnd.

Share this post


Link to post
Share on other sites



You can't store funtions in structs.

 

Saludos

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

    • c.haslam
      By c.haslam
      In the code that follows, it appears that DllStructCreate() is not allocating memory in
      $tag = 'byte val['&$iLength&']' . . Static Local $tvalue = DllStructCreate($tag) Running the code below, the problem does not show, but it does show in a much longer script: there _GDIPlus_ImageSaveToFile only writes about 30K bytes when it should write about 1MB, which it does when the code is
      $tag = 'char val['&$iLength&']' . . Static Local $tvalue = DllStructCreate($tag) It should write about 1 MB.
      I suggest caution in running the code below. On my PC, it caused a second instance of SciTE to appear at the top left of the Desktop, showing only the title bar, with a width of only approximately 200 pixels! Then rebooting the PC showed this at login. Further, double-clicking on the SciTE shortcut on the Desktop showed SciTE in the same way! (After running Regedit, and searching for SciTE, the shortcut behaves normally.)
      I would appreciate help in determining whether or not there is a bug in DLLStructCreate, preferably a way which does not clobber Windows. Of course, It is possible that there is a bug in my code.
      I have made $tvalue Static in the hope that this might make the code run properly. Doing this did not help.
      My code is based on code written by Authenticity and ChrisL.
      #include <GDIPlus.au3> #include <Array.au3> Opt('MustDeclareVars',1) ; Property Item structure Global Const $tagGDIPPROPERTYITEM = _ "uint id;" & _ ; ID of this property "ulong length;" & _ ; Length of the property value, in bytes "word type;" & _ ; Type of the value, as one of TAG_TYPE_XXX constants "ptr pvalue;" ; pointer to property value ; Image property types constants ; Ref: https://www.media.mit.edu/pia/Research/deepview/exif.html Global Const $GDIP_PROPERTYTAGTYPEUBYTE = 1 Global Const $GDIP_PROPERTYTAGTYPEASCII = 2 Global Const $GDIP_PROPERTYTAGTYPEUSHORT = 3 Global Const $GDIP_PROPERTYTAGTYPEULONG = 4 Global Const $GDIP_PROPERTYTAGTYPEURATIONAL = 5 Global Const $GDIP_PROPERTYTAGTYPESBYTE = 6 Global Const $GDIP_PROPERTYTAGTYPEUNDEFINED = 7 Global Const $GDIP_PROPERTYTAGTYPESSHORT = 8 Global Const $GDIP_PROPERTYTAGTYPESLONG = 9 Global Const $GDIP_PROPERTYTAGTYPESRATIONAL = 10 Global Const $GDIP_PROPERTYTAGTYPESFLOAT = 11 Global Const $GDIP_PROPERTYTAGTYPEDFLOAT = 12 main() Func main() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile('H:\temp\AP test data\DSC00824 - Copy.jpg') Local $ar = _GDIPlus_ImageGetAllPropertyItemsEx($hImage) Local $propsAr[UBound($ar,1)-1][5],$vec,$j=-1 For $i = 1 To $ar[0][0] If $ar[$i][3]<>0 Then ; pValue -- for Sony! $j += 1 $propsAr[$j][0] = $ar[$i][0] ; id $propsAr[$j][1] = $ar[$i][1] ; length $propsAr[$j][2] =$ar[$i][2]; type $vec = _GDIPlus_ImageGetPropertyItemValue($ar[$i][1],$ar[$i][2],$ar[$i][3]) $propsAr[$j][3] = $vec[0] ; val1 Switch $ar[$i][2] Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL $propsAr[$j][4] = $vec[1] Case Else $propsAr[$j][4] = '' EndSwitch EndIf Next ReDim $propsAr[$j+1][5] For $i = 0 To UBound($propsAr,1)-1 Switch $propsAr[$i][2] ; type Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL _GDIPlus_ImageSetPropertyItemEx($hImage,$propsAr[$i][0],$propsAr[$i][1], _ $propsAr[$i][2],$propsAr[$i][3],$propsAr[$i][4]) Case Else _GDIPlus_ImageSetPropertyItemEx($hImage,$propsAr[$i][0],$propsAr[$i][1], _ $propsAr[$i][2],$propsAr[$i][3]) EndSwitch Next _GDIPlus_ImageSaveToFile($hImage,'H:\b\1.jpg') _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndFunc Func _GDIPlus_ImageGetAllPropertyItemsEx($hImage) Local $iI, $iCount, $tBuffer, $pBuffer, $iBuffer, $tPropertyItem, $aSize, $aPropertyItems[1][1], $aResult $aSize = _GDIPlus_ImageGetPropertySize($hImage) If @error Then Return SetError(@error, @extended, -1) $iBuffer = $aSize[0] $tBuffer = DllStructCreate("byte[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) $iCount = $aSize[1] $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetAllPropertyItems", "hwnd", $hImage, "uint", $iBuffer, "uint", $iCount, "ptr", $pBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) ReDim $aPropertyItems[$iCount + 1][4] $aPropertyItems[0][0] = $iCount For $iI = 1 To $iCount $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer) $aPropertyItems[$iI][0] = DllStructGetData($tPropertyItem, "id") $aPropertyItems[$iI][1] = DllStructGetData($tPropertyItem, "length") $aPropertyItems[$iI][2] = DllStructGetData($tPropertyItem, "type") $aPropertyItems[$iI][3] = DllStructGetData($tPropertyItem, "pvalue") $pBuffer += DllStructGetSize($tPropertyItem) Next Return $aPropertyItems EndFunc Func _GDIPlus_ImageGetPropertyItemValue($iLength, $iType, $pValue) Static Local $tvalue Switch $iType Case 1,6 ; $GDIP_PROPERTYTAGTYPEUBYTE,$GDIP_PROPERTYTAGTYPESBYTE $tvalue = DllStructCreate('byte val',$pValue) Case 2 ; $GDIP_PROPERTYTAGTYPEASCII $tvalue = DllStructCreate('char val['&$iLength&']',$pValue) Case 3 ; $GDIP_PROPERTYTAGTYPEUSHORT $tvalue = DllStructCreate('ushort val',$pValue) Case 4 ; $GDIP_PROPERTYTAGTYPEULONG $tvalue = DllStructCreate('ulong val',$pValue) Case 5 ; $GDIP_PROPERTYTAGTYPEURATIONAL $tvalue = DllStructCreate('ulong val1;ulong val2',$pValue) Case 7 ; $GDIP_PROPERTYTAGTYPEUNDEFINED ; undefined, per specification, but may be a long but is sometimes a string $tvalue = DllStructCreate('byte val['&$ilength&']',$pValue) ; see _GDIPlus_ImageSetPropertyItemEx ;~ $tvalue = DllStructCreate('char val['&$ilength&']',$pValue) Case 8 ; $GDIP_PROPERTYTAGTYPESSHORT $tvalue = DllStructCreate('short val',$pValue) Case 9 ; $GDIP_PROPERTYTAGTYPEULONG $tvalue = DllStructCreate('ulong val',$pValue) Case 10 ; $GDIP_PROPERTYTAGTYPESRATIONAL $tvalue = DllStructCreate('ulong val1;ulong val2',$pValue) Case 11 ; $GDIP_PROPERTYTAGTYPESFLOAT $tvalue = DllStructCreate('float val',$pValue) Case 12 ; $GDIP_PROPERTYTAGTYPEDFLOAT $tvalue = DllStructCreate('double val',$pValue) EndSwitch If @error Then Return SetError(@error,0,-1) Switch $iType Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL Local $aRet[2] $aRet[0] = DllStructGetData($tvalue,'val1') $aRet[1] = DllStructGetData($tvalue,'val2') Case Else Local $aRet[1] $aRet[0] = DllStructGetData($tvalue,'val') EndSwitch Return $aRet EndFunc Func _GDIPlus_ImageGetPropertySize($hImage) Local $aSize[2], $aResult $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint*", 0, "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $aSize[0] = $aResult[2] $aSize[1] = $aResult[3] Return $aSize EndFunc ;==>_GDIPlus_ImageGetPropertySize Func _GDIPlus_ImageSetPropertyItemEx($hImage,$id,$iLength,$iType,$value1,$value2=-1) Local $tProp = DllStructCreate($tagGDIPPROPERTYITEM) DllStructSetData($tProp,'id',$id) DllStructSetData($tProp,'type',$itype) DllStructSetData($tProp,'length',$ilength) Local $tag Switch $iType Case $GDIP_PROPERTYTAGTYPEUBYTE,$GDIP_PROPERTYTAGTYPESBYTE $tag = 'byte val' Case $GDIP_PROPERTYTAGTYPEASCII $tag = 'char val['&$iLength&']' Case $GDIP_PROPERTYTAGTYPEUSHORT $tag = 'ushort val' Case $GDIP_PROPERTYTAGTYPEULONG $tag = 'ulong val' Case $GDIP_PROPERTYTAGTYPEURATIONAL $tag = 'ulong val1;ulong val2' Case $GDIP_PROPERTYTAGTYPEUNDEFINED ; undefined, per specification, but may be a long but is sometimes a string $tag = 'byte val['&$iLength&']' ; causes saving to jpeg to write junk ;~ $tag = 'char val['&$iLength&']' Case $GDIP_PROPERTYTAGTYPESSHORT $tag = 'short val' Case $GDIP_PROPERTYTAGTYPEULONG $tag = 'ulong val' Case $GDIP_PROPERTYTAGTYPESRATIONAL $tag = 'long val1;long val2' Case $GDIP_PROPERTYTAGTYPESFLOAT $tag = 'float val' Case $GDIP_PROPERTYTAGTYPEDFLOAT $tag = 'double val' EndSwitch Static Local $tvalue = DllStructCreate($tag) Switch $iType Case $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL DllStructSetData($tvalue,'val1',$value1) DllStructSetData($tvalue,'val2',$value2) Case Else DllStructSetData($tvalue,1,$value1) EndSwitch DllStructSetData($tProp,'pvalue',DllStructGetPtr($tvalue)) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetPropertyItem", "hwnd", $hImage, "ptr", _ DllStructGetPtr($tProp)) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], -1) Return $aResult[0] = 0 EndFunc I have seen $iLength be as much as 37 KB for $GDIP_PROPERTYTAGTYPEUNDEFINED.
      Is there is a bug, how can this be demonstrated to the developers in a few lines of code (without clobbering Windows)?
       
    • InunoTaishou
      By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms535372(v=vs.85).aspx
      Struct needed:
      PropertyItem class:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.