Valik Posted April 26, 2005 Share Posted April 26, 2005 Thats one of those C++ thingies<{POST_SNAPBACK}>Yes, yes it is. Re-read my post for an example. Link to comment Share on other sites More sharing options...
Ejoc Posted April 26, 2005 Author Share Posted April 26, 2005 (edited) What's the advantage of using the template vs a macro? I setup 2 macros to make it easier to read: #define GetFromCast(s,p,v) v = (__int64)*((s *)(p)) #define SetFromCast(s,p,v) *((s *)(p)) = (s)v SetFromCast(__int32,(iBaseAddr+iOffset),vParams[2].n64Value()); GetFromCast(__int32,(iBaseAddr+iOffset),vResult); Edited April 27, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
Valik Posted April 27, 2005 Share Posted April 27, 2005 The advantages are that its type-safe and that it uses the language features instead of the pre-processor which can sometimes be a dirty hack. Your solution is perfectly acceptable in a C environment, but their are more eloquent solutions in a C++ environment. However, so long as the code works correctly, its probably more a matter of taste than anything else. I prefer the C++ way of doing things including the more verbose casts. In this particular case, I would definitely not use something like your code because it looks a bit weird seeing standard function call notation but instead of passing a variable, a type is passed for the first parameter. With templates, the type is passed as a template parameter which looks more natural, or at least provides a more logical distinction between types and variables. Link to comment Share on other sites More sharing options...
Ejoc Posted April 27, 2005 Author Share Posted April 27, 2005 Thanks to JdeB, I was able to get a beta w/ DllStruct* included, and... it worked!! I want to make more tests, but it looks good Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
Ejoc Posted April 27, 2005 Author Share Posted April 27, 2005 Probably the most important test, I've called it "The Larry Test" works $hwnd = WinGetHandle("") $coor = WinGetPos($hwnd) $rect = DllStructCreate("int;int;int;int") DLLCall("user32.dll","int","GetWindowRect",_ "hwnd",$hwnd,_ "ptr",DllStructPtr($rect)) $l = DllStructGet($rect,1) $t = DllStructGet($rect,2) $r = DllStructGet($rect,3) $b = DllStructGet($rect,4) DllStructFree($rect) MsgBox(0,"The Larry Test :)","WinGetPos(): (" & $coor[0] & "," & $coor[1] &_ ") (" & $coor[2] + $coor[0] & "," & $coor[3] + $coor[1] & ")" & @CRLF&_ "GetWindowRect(): (" & $l & "," & $t & ") (" & $r & "," & $b & ")") Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
Ejoc Posted April 27, 2005 Author Share Posted April 27, 2005 While writing the help files I realized that I dont support floating point numbers atm. Can anyone else suggest basic data types that "have" to be supported, Currently you can use: byte 8bit(1byte) signed char ubyte 8bit(1byte) unsigned char char 8bit(1byte) ASCII char short 16bit(2byte) signed integer ushort 16bit(2byte) unsigned integer int 32bit(4byte) signed integer uint 32bit(4byte) unsinged integer dword 32bit(4byte) signed integer udword 32bit(4byte) unsinged integer ptr 32bit(4byte) integer int64 64(8byte) signed integer uint64 64bit(8byte) unsinged integer Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
SumTingWong Posted April 27, 2005 Share Posted April 27, 2005 While writing the help files I realized that I dont support floating point numbers atm. Can anyone else suggest basic data types that "have" to be supported, Currently you can use:byte 8bit(1byte) signed charubyte 8bit(1byte) unsigned charchar 8bit(1byte) ASCII charshort 16bit(2byte) signed integerushort 16bit(2byte) unsigned integerint 32bit(4byte) signed integeruint 32bit(4byte) unsinged integerdword 32bit(4byte) signed integerudword 32bit(4byte) unsinged integerptr 32bit(4byte) integerint64 64(8byte) signed integeruint64 64bit(8byte) unsinged integer<{POST_SNAPBACK}>List of basic Windows types supported by DllCall is posted here.Would you be able to provide support for the Windows type names as well as the C names? Link to comment Share on other sites More sharing options...
SumTingWong Posted April 29, 2005 Share Posted April 29, 2005 I am trying to use SHFileOperation with the following struct: typedef struct _SHFILEOPSTRUCT { HWND hwnd; UINT wFunc; LPCTSTR pFrom; LPCTSTR pTo; FILEOP_FLAGS fFlags; BOOL fAnyOperationsAborted; LPVOID hNameMappings; LPCTSTR lpszProgressTitle; } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT I have tried: "ptr;uint;char[" & sizeofprfrom & "];char[" & sizeofpto & "];uint;int;ptr;char[" & sizeoftitle & "]" and various other combinations, including using byte instead of char How would you translate the struct above? Thanks Link to comment Share on other sites More sharing options...
Ejoc Posted April 29, 2005 Author Share Posted April 29, 2005 (edited) I am trying to use SHFileOperation with the following struct:typedef struct _SHFILEOPSTRUCT { HWND hwnd; UINT wFunc; LPCTSTR pFrom; LPCTSTR pTo; FILEOP_FLAGS fFlags; BOOL fAnyOperationsAborted; LPVOID hNameMappings; LPCTSTR lpszProgressTitle; } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCTI have tried:"ptr;uint;char[" & sizeofprfrom & "];char[" & sizeofpto & "];uint;int;ptr;char[" & sizeoftitle & "]"and various other combinations, including using byte instead of charHow would you translate the struct above?Thanks<{POST_SNAPBACK}>This will be tricky$pFrom = DllStructCreate("char[256]") $pTo - DllStructCreate("char[256]") $lpszProgressTitle = DllStructCreate("char[256]");could be more or less then 256 $SHFILEOPSTRUCT = DllStructCreate("int;uint;ptr;ptr;int;int;ptr;ptr") DllStructSet($SHFILEOPSTRUCT,1,$HWND) DllStructSet($SHFILEOPSTRUCT,2,0);no idea what it should be DllStructSet($SHFILEOPSTRUCT,3,DllStructPtr($pFrom)) DllStructSet($SHFILEOPSTRUCT,4,DllStructPtr($pTo)) DllStructSet($SHFILEOPSTRUCT,5,0);unsure of value DllStructSet($SHFILEOPSTRUCT,6,0);unsure of value DllStructSet($SHFILEOPSTRUCT,7,0);If you need something other then NULL do like $pTo DllStructSet($SHFILEOPSTRUCT,8,DllStructPtr($lpszProgressTitle))One thing people need to remember is if the Data Type starts with LP (Long Pointer) it is always a "ptr" and you have to create the space for it using another struct and setting its value using DllStructPtr() Edited April 29, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
SumTingWong Posted April 29, 2005 Share Posted April 29, 2005 Thanks....I tried that earlier as well but couldn't get it work. Here's what I have so far. expandcollapse popupGlobal Const $FO_MOVE = 0x0001 Global Const $FO_COPY = 0x0002 Global Const $FO_DELETE = 0x0003 Global Const $FO_RENAME = 0x0004 Global Const $FOF_MULTIDESTFILES = 0x0001 Global Const $FOF_CONFIRMMOUSE = 0x0002 Global Const $FOF_SILENT = 0x0004 Global Const $FOF_RENAMEONCOLLISION = 0x0008 Global Const $FOF_NOCONFIRMATION = 0x0010 Global Const $FOF_WANTMAPPINGHANDLE = 0x0020 Global Const $FOF_ALLOWUNDO = 0x0040 Global Const $FOF_FILESONLY = 0x0080 Global Const $FOF_SIMPLEPROGRESS = 0x0100 Global Const $FOF_NOCONFIRMMKDIR = 0x0200 Global Const $FOF_NOERRORUI = 0x0400 Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x0800 Global Const $FOF_NORECURSION = 0x1000 Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000 Global Const $FOF_WANTNUKEWARNING = 0x4000 Global Const $FOF_NORECURSEREPARSE = 0x8000 Dim $n $n = _CopyWithProgress("C:\Temp\au3src\*.*", "C:\Temp\Test") ConsoleWrite(@error & @LF) ConsoleWrite($n & @LF) Func _CopyWithProgress($sFrom, $sTo, $sTitle = "") #cs typedef struct _SHFILEOPSTRUCT { HWND hwnd; UINT wFunc; LPCTSTR pFrom; LPCTSTR pTo; FILEOP_FLAGS fFlags; BOOL fAnyOperationsAborted; LPVOID hNameMappings; LPCTSTR lpszProgressTitle; } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT #ce Local $SHFILEOPSTRUCT Local $pFrom Local $pTo Local $pTitle Local $aDllRet Local $nError = 0 $SHFILEOPSTRUCT = DllStructCreate("int;uint;ptr;ptr;uint;int;ptr;ptr") If @error Then Return False ; hwnd DllStructSet($SHFILEOPSTRUCT, 1, 0) ; wFunc DllStructSet($SHFILEOPSTRUCT, 2, $FO_COPY) ; pFrom $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sFrom)+1 DllStructSet($pFrom, 1, $sFrom) ; We need a second null at the end DllStructSet($pFrom, 1, 0, StringLen($sFrom)+2) DllStructSet($SHFILEOPSTRUCT, 3, $pFrom) ; pTo $pTo = DllStructCreate("char[" & StringLen($sTo)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sTo)+1 DllStructSet($pTo, 1, $sTo) ; We need a second null at the end DllStructSet($pTo, 1, 0, StringLen($sTo)+2) DllStructSet($SHFILEOPSTRUCT, 4, $pTo) ; fFlags DllStructSet($SHFILEOPSTRUCT, 5, BitOR($FOF_SIMPLEPROGRESS, _ $FOF_NOCONFIRMMKDIR, _ $FOF_NOCONFIRMATION, _ $FOF_NOERRORUI)) ; fAnyOperationsAborted DllStructSet($SHFILEOPSTRUCT, 6, 0) ; hNameMappings DllStructSet($SHFILEOPSTRUCT, 7, 0) $pTitle = DllStructCreate("char[" & StringLen($sTitle)+1 & "]") If $sTitle <> "" Then DllStructSet($pTitle, 1, $sTitle) DllStructSet($SHFILEOPSTRUCT, 3, $pTitle) Else DllStructSet($SHFILEOPSTRUCT, 8, 0) EndIf $aDllRet = DllCall("shell32.dll", "int", "SHFileOperation", "ptr", DllStructPtr($SHFILEOPSTRUCT)) If @error Or $aDllRet[0] <> 0 Then $aDllRet = DllCall("kernel32.dll", "long", "GetLastError") If Not @error Then $nError = $aDllRet[0] EndIf DllStructFree($pFrom) DllStructFree($pTo) DllStructFree($pTitle) DllStructFree($SHFILEOPSTRUCT) If $nError <> 0 Then SetError($nError) Return False EndIf Return True EndFunc pFrom and pTo need to be double-null terminated. This is what I did to add the second null. ; pFrom $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sFrom)+1 DllStructSet($pFrom, 1, $sFrom) ; We need a second null at the end DllStructSet($pFrom, 1, 0, StringLen($sFrom)+2) DllStructSet($SHFILEOPSTRUCT, 3, $pFrom) Link to comment Share on other sites More sharing options...
Ejoc Posted April 29, 2005 Author Share Posted April 29, 2005 (edited) Thanks....I tried that earlier as well but couldn't get it work. Here's what I have so far.expandcollapse popupGlobal Const $FO_MOVE = 0x0001 Global Const $FO_COPY = 0x0002 Global Const $FO_DELETE = 0x0003 Global Const $FO_RENAME = 0x0004 Global Const $FOF_MULTIDESTFILES = 0x0001 Global Const $FOF_CONFIRMMOUSE = 0x0002 Global Const $FOF_SILENT = 0x0004 Global Const $FOF_RENAMEONCOLLISION = 0x0008 Global Const $FOF_NOCONFIRMATION = 0x0010 Global Const $FOF_WANTMAPPINGHANDLE = 0x0020 Global Const $FOF_ALLOWUNDO = 0x0040 Global Const $FOF_FILESONLY = 0x0080 Global Const $FOF_SIMPLEPROGRESS = 0x0100 Global Const $FOF_NOCONFIRMMKDIR = 0x0200 Global Const $FOF_NOERRORUI = 0x0400 Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x0800 Global Const $FOF_NORECURSION = 0x1000 Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000 Global Const $FOF_WANTNUKEWARNING = 0x4000 Global Const $FOF_NORECURSEREPARSE = 0x8000 Dim $n $n = _CopyWithProgress("C:\Temp\au3src\*.*", "C:\Temp\Test") ConsoleWrite(@error & @LF) ConsoleWrite($n & @LF) Func _CopyWithProgress($sFrom, $sTo, $sTitle = "") #cs typedef struct _SHFILEOPSTRUCT { HWND hwnd; UINT wFunc; LPCTSTR pFrom; LPCTSTR pTo; FILEOP_FLAGS fFlags; BOOL fAnyOperationsAborted; LPVOID hNameMappings; LPCTSTR lpszProgressTitle; } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT #ce Local $SHFILEOPSTRUCT Local $pFrom Local $pTo Local $pTitle Local $aDllRet Local $nError = 0 $SHFILEOPSTRUCT = DllStructCreate("int;uint;ptr;ptr;uint;int;ptr;ptr") If @error Then Return False ; hwnd DllStructSet($SHFILEOPSTRUCT, 1, 0) ; wFunc DllStructSet($SHFILEOPSTRUCT, 2, $FO_COPY) ; pFrom $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sFrom)+1 DllStructSet($pFrom, 1, $sFrom) ; We need a second null at the end DllStructSet($pFrom, 1, 0, StringLen($sFrom)+2) DllStructSet($SHFILEOPSTRUCT, 3, $pFrom) ; pTo $pTo = DllStructCreate("char[" & StringLen($sTo)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sTo)+1 DllStructSet($pTo, 1, $sTo) ; We need a second null at the end DllStructSet($pTo, 1, 0, StringLen($sTo)+2) DllStructSet($SHFILEOPSTRUCT, 4, $pTo) ; fFlags DllStructSet($SHFILEOPSTRUCT, 5, BitOR($FOF_SIMPLEPROGRESS, _ $FOF_NOCONFIRMMKDIR, _ $FOF_NOCONFIRMATION, _ $FOF_NOERRORUI)) ; fAnyOperationsAborted DllStructSet($SHFILEOPSTRUCT, 6, 0) ; hNameMappings DllStructSet($SHFILEOPSTRUCT, 7, 0) $pTitle = DllStructCreate("char[" & StringLen($sTitle)+1 & "]") If $sTitle <> "" Then DllStructSet($pTitle, 1, $sTitle) DllStructSet($SHFILEOPSTRUCT, 3, $pTitle) Else DllStructSet($SHFILEOPSTRUCT, 8, 0) EndIf $aDllRet = DllCall("shell32.dll", "int", "SHFileOperation", "ptr", DllStructPtr($SHFILEOPSTRUCT)) If @error Or $aDllRet[0] <> 0 Then $aDllRet = DllCall("kernel32.dll", "long", "GetLastError") If Not @error Then $nError = $aDllRet[0] EndIf DllStructFree($pFrom) DllStructFree($pTo) DllStructFree($pTitle) DllStructFree($SHFILEOPSTRUCT) If $nError <> 0 Then SetError($nError) Return False EndIf Return True EndFuncpFrom and pTo need to be double-null terminated. This is what I did to add the second null.; pFrom $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]") ; Hopefully, the string will now be null-terminated at StringLen($sFrom)+1 DllStructSet($pFrom, 1, $sFrom) ; We need a second null at the end DllStructSet($pFrom, 1, 0, StringLen($sFrom)+2) DllStructSet($SHFILEOPSTRUCT, 3, $pFrom)<{POST_SNAPBACK}>Forgot to use DllStructPtrDllStructSet($SHFILEOPSTRUCT, 3, DllStructPtr($pFrom))DllStructSet($SHFILEOPSTRUCT, 4, DllStructPtr($pTo))DllStructSet($SHFILEOPSTRUCT, 3, DllStructPtr($pTitle)) *This should be 8 not 3Glad you got the Double NULL, I noticed that when looking on MSDN Edited April 29, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
SumTingWong Posted April 30, 2005 Share Posted April 30, 2005 Forgot to use DllStructPtrDllStructSet($SHFILEOPSTRUCT, 3, DllStructPtr($pFrom))DllStructSet($SHFILEOPSTRUCT, 4, DllStructPtr($pTo))DllStructSet($SHFILEOPSTRUCT, 3, DllStructPtr($pTitle)) *This should be 8 not 3Glad you got the Double NULL, I noticed that when looking on MSDN<{POST_SNAPBACK}>Doh!....that's what burning the midnight candle will do to you. Thanks Link to comment Share on other sites More sharing options...
Ejoc Posted April 30, 2005 Author Share Posted April 30, 2005 (edited) Since I see some common problems I thought I'd try to make some UDFs to help people out. This is my first UDF for it, feed this one your string you are using to create a struct and It will give you info about it.structbuilder.au3 Edited April 30, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
SumTingWong Posted April 30, 2005 Share Posted April 30, 2005 (edited) OK, here's an interesting one.I am trying to get QueryServiceConfig to work with 3 different methods in the attached script. The problem is that I can get the addresses of string params but not the actual content.Any ideas?EDIT: sorry wrong link and function nameServiceTest.au3 Edited April 30, 2005 by SumTingWong Link to comment Share on other sites More sharing options...
Smed Posted April 30, 2005 Share Posted April 30, 2005 How should arrays of structures be handled? It seems to me that this is somewhat less than elegant: $baseStructure = "int;dword;byte" $arrayOfStructures = $baseStructure $arraySize = 8 For $i = 1 To $arraySize $arrayOfStructures &= ";" & $baseStructure Next 601DisengageEnd Program Link to comment Share on other sites More sharing options...
Smed Posted May 1, 2005 Share Posted May 1, 2005 Ow Larry, I'm getting stabbing pains in my chest now. I was just concerned about simple arrays and you had to go float the tree concept. Little Steps.. One at a time.. Rome wasn't built in a day. 601DisengageEnd Program Link to comment Share on other sites More sharing options...
Ejoc Posted May 1, 2005 Author Share Posted May 1, 2005 Bleh I was hoping to avoid dealing w/ structs in structs but it doesnt look like I can. I could almost do this "easily" with a UDF but there's 1 problem. Anyways here are some idea's I had on how to handle it: 1: $p = DllStructCreate("ptr;byte[16];ptr"); problem is here, need to know the size of the sub struct $sub = _DllStructSubStruct($p,2,"int;int;int;int");$p=struct,2=element 2 of that struct,"the sub struct" $value1 = DllStructGet($sub,1) DllStructFree($p);dont call it on $sub 2:(I'm leaning towards this method, no change to the DllStruct... Functions) $RECT = "int;int;int;int" $p = DllStructCreate("ptr;" & $RECT & ";ptr");seperate the sub struct so it's more clear $sub = _DllStructSubStruct($p,2,5);this would then change $p to have 3 elements, 1=the first ptr; 2=the substruct but you wouldn't access it from $p anymore; 3=the second ptr ;or $sub = _DllStructSubStruct($p,2,$RECT) $value1 = DllStructGet($sub,1) DllStructFree($p);dont call on $sub 3: Dim $sub $p = DllStructCreate("ptr;param;ptr","int;int;int;int",$sub);param would tell it to take the next param passed to DllStructCreate $value1 = DllStructGet($sub,1) DllStructFree($p) Hmmm... Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
Ejoc Posted May 1, 2005 Author Share Posted May 1, 2005 would it be a pointer array?$a = DLLStructCreate("int;int;int")$b = DLLStructCreate("int;int;int")$c = DLLStructCreate("int;int;int")$d = DLLStructCreate("int;int;int")$e = DLLStructCreate("int;int;int")$f = DLLStructCreate("int;ptr[5]")DLLStructSet($f,2,DLLStructPtr($a),1)DLLStructSet($f,2,DLLStructPtr($,2)DLLStructSet($f,2,DLLStructPtr($c),3)DLLStructSet($f,2,DLLStructPtr($d),4)DLLStructSet($f,2,DLLStructPtr($e),5)I don't know about useful, but hypothetical?Also... Is there a way to get a piece of a struct pointer? DLLStructGetMem?Lar.<{POST_SNAPBACK}>That's how you'd do an array of pointers.Not sure exactly what you mean by piece of a struct pointer. Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
Ejoc Posted May 1, 2005 Author Share Posted May 1, 2005 (edited) So based on my #2 method here is a UDF for sub structs: ;===================================================== ; _DllStructSubStruct(ByRef $p, $iElement, $szStruct) ; $p The return from DllStructCreate() ; $iElement The element where the sub struct is located ; $szStruct The String representing the Sub Struct ; Returns a new struct for use in DllStructGet/DllStructSet ; Sets @Error to -1 if $iElement is outside, -2 sub struct ; would go outside the bounds of the struct ; $p's elements are decreased as the substruct elements are removed ; ; $RECT_STR = "int;int;int;int" ; $POINT_STR = "int;int" ; $p = DllStructCreate("ptr;" & $RECT_STR & ";" & $POINT_STR) ; $rect = _DllStructSubStruct($p,2,$RECT_STR) ; $point = _DllStructSubStruct($p,3,$POINT_STR) ; DllCall("some.dll","int","func","ptr",DllStructPtr($p)) ; $point_x = DllStructGet($point,1) ; $point_y = DllStructGet($point,2) ; $left = DllStructGet($rect,1) ; $top = DllStructGet($rect,2) ; $right = DllStructGet($rect,3) ; $bottom = DllStructGet($rect,4) ; DllStructFree($p) ;=====================================================SubStruct.au3 Edited May 1, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs Link to comment Share on other sites More sharing options...
GaryFrost Posted May 2, 2005 Share Posted May 2, 2005 (edited) Haven't had a chance to try the substruct stuff yet, but thought you might find the next bit of code interesting. expandcollapse popup#include <GuiConstants.au3> GUICreate("Sample", 220, 210, -1, -1) $color = _ChooseColor() If(@error)Then MsgBox(0,"","Error _ChooseColor: " & @error) Else ConsoleWrite($color & @LF) EndIf $a_font = _ChooseFont() If(IsArray($a_font)) Then MsgBox(0,"","Font Name: " & $a_font[2] & @LF & "Size: " & $a_font[3] & @LF & "Weight: " & $a_font[4]) Else MsgBox(0,"","Error _ChooseFont: " & $a_font) EndIf Func _ChooseFont() ;~ typedef struct { ;~ DWORD lStructSize; ;~ HWND hwndOwner; ;~ HDC hDC; ;~ LPLOGFONT lpLogFont; ;~ INT iPointSize; ;~ DWORD Flags; ;~ COLORREF rgbColors; ;~ LPARAM lCustData; ;~ LPCFHOOKPROC lpfnHook; ;~ LPCTSTR lpTemplateName; ;~ HINSTANCE hInstance; ;~ LPTSTR lpszStyle; ;~ WORD nFontType; ;~ INT nSizeMin; ;~ INT nSizeMax; ;~ } CHOOSEFONT, *LPCHOOSEFONT; Global Const $CF_EFFECTS = 0x100 ;~ Causes the dialog box to display the controls that allow the user to specify strikeout, underline, and text color options. ;~ If this flag is set, you can use the rgbColors member to specify the initial text color. ;~ You can use the lfStrikeOut and lfUnderline members of the structure pointed to by lpLogFont to specify the initial settings of the strikeout and underline check boxes. ;~ ChooseFont can use these members to return the user's selections. Global Const $CF_PRINTERFONTS = 0x2 ;~ CF_PRINTERFONTS ;~ Causes the dialog box to list only the fonts supported by the printer associated with the device context (or information context) identified by the hDC member. Global Const $CF_SCREENFONTS = 0x1 ;~ Causes the dialog box to list only the screen fonts supported by the system. Global Const $CF_SHOWHELP = 0x4 ;~ Causes the dialog box to display the Help button. ;~ The hwndOwner member must specify the window to receive the HELPMSGSTRING registered messages that the dialog box sends when the user clicks the Help button. ;~ typedef struct tagLOGFONT { ;~ LONG lfHeight; ;~ LONG lfWidth; ;~ LONG lfEscapement; ;~ LONG lfOrientation; ;~ LONG lfWeight; ;~ BYTE lfItalic; ;~ BYTE lfUnderline; ;~ BYTE lfStrikeOut; ;~ BYTE lfCharSet; ;~ BYTE lfOutPrecision; ;~ BYTE lfClipPrecision; ;~ BYTE lfQuality; ;~ BYTE lfPitchAndFamily; ;~ TCHAR lfFaceName[LF_FACESIZE]; 32 chars max ;~ } LOGFONT, *PLOGFONT; $logfont = "int;int;int;int;int;byte;byte;byte;byte;byte;byte;byte;byte;char[32]" $struct = "dword;int;int;ptr;int;dword;int;int;ptr;ptr;int;ptr;dword;int;int" Local $p = DllStructCreate($struct) if @error Then ;MsgBox(0,"","Error in DllStructCreate " & @error); SetError(-1) Return -1 endif Local $lf = DllStructCreate($logfont) if @error Then ; MsgBox(0,"","Error in DllStructCreate " & @error); DllStructFree($p) SetError(-2) Return -2 endif DllStructSet($p,1,DllStructSize($p)) DllStructSet($p,2,WinGetHandle(WinGetTitle(""))) DllStructSet($p,4,DllStructPtr($lf)) DllStructSet($p,6,BitOR($CF_SCREENFONTS,$CF_PRINTERFONTS,$CF_EFFECTS)) $ret = DllCall("comdlg32.dll","long","ChooseFont","ptr",DllStructPtr($p)) If ($ret[0] == 0) Then ; user selected cancel or struct settings incorrect DllStructFree($p) DllStructFree($lf) SetError(-3) Return -3 EndIf $fontname = DllStructGet($lf,14) $italic = 0 $underline = 0 $strikeout = 0 If(DllStructGet($lf,6)) Then $italic = 2 EndIf If(DllStructGet($lf,7)) Then $underline = 4 EndIf If(DllStructGet($lf,8)) Then $strikeout = 8 EndIf $attributes = BitOR($italic,$underline,$strikeout) $size = DllStructGet($p,5) / 10 $weight = DllStructGet($lf,5) DllStructFree($p) DllStructFree($lf) Return StringSplit($attributes & "," & $fontname & "," & $size & "," & $weight,",") EndFunc Func _ChooseColor() ;~ typedef struct { ;~ DWORD lStructSize; ;~ HWND hwndOwner; ;~ HWND hInstance; ;~ COLORREF rgbResult; ;~ COLORREF *lpCustColors; ;~ DWORD Flags; ;~ LPARAM lCustData; ;~ LPCCHOOKPROC lpfnHook; ;~ LPCTSTR lpTemplateName; ;~ } CHOOSECOLOR, *LPCHOOSECOLOR; Global Const $CC_ANYCOLOR = 0x100 ;~ Causes the dialog box to display all available colors in the set of basic colors. Global Const $CC_FULLOPEN = 0x2 ;~ Causes the dialog box to display the additional controls that allow the user to create custom colors. ;~ If this flag is not set, the user must click the Define Custom Color button to display the custom color controls. Global Const $CC_SHOWHELP = 0x8 ;~ Causes the dialog box to display the Help button. The hwndOwner member must specify the window to receive the HELPMSGSTRING registered messages that the dialog box sends when the user clicks the Help button. $custcolors = "int[16]" $struct = "dword;int;int;int;ptr;dword;int;ptr;ptr" Local $p = DllStructCreate($struct) if @error Then ;MsgBox(0,"","Error in DllStructCreate " & @error); SetError(-1) Return -1 endif Local $cc = DllStructCreate($custcolors) if @error Then ; MsgBox(0,"","Error in DllStructCreate " & @error); DllStructFree($p) SetError(-2) Return -1 endif DllStructSet($p,1,DllStructSize($p)) DllStructSet($p,2,WinGetHandle(WinGetTitle(""))) DllStructSet($p,5,DllStructPtr($cc)) DllStructSet($p,6,BitOR($CC_ANYCOLOR,$CC_FULLOPEN)) $ret = DllCall("comdlg32.dll","long","ChooseColor","ptr",DllStructPtr($p)) If ($ret[0] == 0) Then ; user selected cancel or struct settings incorrect DllStructFree($p) DllStructFree($cc) SetError(-3) Return -1 EndIf Local $color_picked = Hex(String(DllStructGet($p,4)), 6) DllStructFree($p) DllStructFree($cc) ; return Hex RGB Color Return '0x' & StringMid($color_picked, 5, 2) & StringMid($color_picked, 3, 2) & StringMid($color_picked, 1, 2) EndFunc Edit: added _ChooseFont Edited May 2, 2005 by gafrost SciTE for AutoItDirections for Submitting Standard UDFs  Don't argue with an idiot; people watching may not be able to tell the difference.  Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now