Advertisement
EckOp

Lũy thừa bằng label text

Feb 6th, 2016
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 18.25 KB | None | 0 0
  1. ; Create by Vinh Pham, http://opdo.top
  2. ; #INDEX# ============================================================================================================
  3. ; Title .........: _LuyThua_Create
  4. ; Language ......: Vietnamese
  5. ; Description ...: Tạo biểu thức có chứa lũy thừa
  6. ; Remarks .......:
  7. ; Note ..........: nhập biểu thức lũy thừa theo định dạng ^ số hoặc ^[< ký tự muốn lũy thừa>], ví dụ: 3^6 hoặc 3^[6k]
  8. ; Author(s) .....:  VinhPham - thanks to Melba23 for the UDF StringSize
  9. ; ====================================================================================================================
  10.  
  11. ; Example
  12. #include <ButtonConstants.au3>
  13. #include <EditConstants.au3>
  14. #include <GUIConstantsEx.au3>
  15. #include <StaticConstants.au3>
  16. #include <WindowsConstants.au3>
  17. $Form1 = GUICreate("LuyThua", 344, 149, -1, -1)
  18. $Label1 = GUICtrlCreateLabel("Text:", 56, 8, 28, 17)
  19. $bDelete = GUICtrlCreateButton("Exit", 56, 96, 73, 25)
  20. $Input = GUICtrlCreateInput("3^6-3^2[k]=3^7", 96, 8, 121, 21)
  21. $control = _LuyThua_Create('', 56, 48)
  22. $bOK = GUICtrlCreateButton("OK", 224, 8, 75, 25)
  23. $bHidenShow = GUICtrlCreateButton("Hide Control", 136, 96, 75, 25)
  24. $bText = GUICtrlCreateButton("Get Text", 216, 96, 75, 25)
  25. GUISetState(@SW_SHOW)
  26.  
  27. While 1
  28.     $nMsg = GUIGetMsg()
  29.     Switch $nMsg
  30.  
  31.       Case $bOK
  32.             _LuyThua_SetData($control,GUICtrlRead($Input))
  33.       Case $bText
  34.             MsgBox(0,'Text','Text = '&_LuyThua_GetData($control))
  35.       Case $bHidenShow
  36.             if GUICtrlRead($bHidenShow) == "Hide Control" Then
  37.                _LuyThua_Show($control,False)
  38.                GUICtrlSetData($bHidenShow,'Show Control')
  39.             Else
  40.                _LuyThua_Show($control)
  41.                GUICtrlSetData($bHidenShow,'Hide Control')
  42.             EndIf
  43.       Case $GUI_EVENT_CLOSE,$bDelete
  44.             Exit
  45.  
  46.     EndSwitch
  47.  WEnd
  48.  
  49. Func _LuyThua_Show(ByRef $control,$show = True)
  50.    for $i = 5 To UBound($control)-1
  51.       if $show Then
  52.          GUICtrlSetState($control[$i],$GUI_SHOW)
  53.       Else
  54.          GUICtrlSetState($control[$i],$GUI_HIDE)
  55.       EndIf
  56.    Next
  57. EndFunc
  58.  
  59. Func _LuyThua_SetData(ByRef $control,$text)
  60.    $control[0] = $text
  61.    $left = $control[1]
  62.    $top = $control[2]
  63.    $font = $control[3]
  64.    $size = $control[4]
  65.    For $i = 5 To UBound($control)-1
  66.       GUICtrlDelete($control[$i])
  67.    Next
  68.  
  69.    Local $sNewString = StringSplit($text,'^') ; 3^5 + 5^6
  70.    Local $number = ($sNewString[0]-1)*2+5
  71.    if $sNewString[0] <= 1 Then $number = 6
  72.    Local $array_number = 5
  73.    Local $iSize
  74.    For $i = 1 to $sNewString[0]
  75.       if $i > 1 Then
  76.          Local $sLaySoMu = StringSplit($sNewString[$i],'')
  77.          Local $sGhepChu = '', $sGhepSo = '',$flag = True,$flag2 = False
  78.          For $j = 1 to $sLaySoMu[0]
  79.             if (String(Number($sLaySoMu[$j])) = $sLaySoMu[$j] And $flag) or ($flag And $sLaySoMu[$j] == '[') Then
  80.                if $sLaySoMu[$j] = '[' Then
  81.                   $flag2 = True
  82.                   $flag = False
  83.                Else
  84.                   $sGhepSo = $sGhepSo&$sLaySoMu[$j]
  85.                EndIf
  86.             Elseif $flag2 Then
  87.                if $sLaySoMu[$j] == ']' Then
  88.                   $flag2 = False
  89.                Else
  90.                   $sGhepSo = $sGhepSo&$sLaySoMu[$j]
  91.                EndIf
  92.             Else
  93.                $sGhepChu = $sGhepChu&$sLaySoMu[$j]
  94.                $flag = False
  95.             EndIf
  96.          Next
  97.          ReDim $control[5+$array_number+1]
  98.          $iSize = _StringSize($sGhepSo,int($size/1.2),400,0,$font)
  99.          $control[$array_number] =  GUICtrlCreateLabel($sGhepSo,$left,$top-3,$iSize[2],$iSize[3])
  100.          GUICtrlSetFont(-1,int($size/1.5),400,0,$font)
  101.          if $sGhepChu <> '' Then
  102.             $left += $iSize[2]
  103.             $array_number+=1
  104.             ReDim $control[5+$array_number+1]
  105.             $iSize = _StringSize($sGhepChu,$size,400,0,$font)
  106.             $control[$array_number] =  GUICtrlCreateLabel($sGhepChu,$left,$top,$iSize[2],$iSize[3])
  107.             GUICtrlSetFont(-1,$size,400,0,$font)
  108.          EndIf
  109.       Else
  110.          ReDim $control[5+$array_number+1]
  111.          $iSize = _StringSize($sNewString[$i],$size,400,0,$font)
  112.          if @error Then MsgBox(0,$font,$sNewString[$i])
  113.          $control[$array_number] =  GUICtrlCreateLabel($sNewString[$i],$left,$top,$iSize[2],$iSize[3])
  114.          GUICtrlSetFont(-1,$size,400,0,$font)
  115.       EndIf
  116.       $array_number+=1
  117.       $left += $iSize[2]
  118.    Next
  119. EndFunc
  120.  
  121. Func _LuyThua_Create($text = '',$left = 0,$top = 0,$font = 'Tahoma',$size = 10)
  122.    Local $sNewString = StringSplit($text,'^') ; 3^5 + 5^6
  123.    Local $number = $sNewString[0]
  124.    Local $control[($number-1)*2+5]
  125.    $control[0] = $text
  126.    $control[1] = $left
  127.    $control[2] = $top
  128.    $control[3] = $font
  129.    $control[4] = $size
  130.    _LuyThua_SetData($control,$text)
  131.    Return $control
  132. EndFunc
  133.  
  134. Func _LuyThua_GetData(ByRef $control)
  135.    Return $control[0]
  136. EndFunc
  137.  
  138.  
  139.  
  140. ; #INDEX# ============================================================================================================
  141. ; Title .........: _StringSize
  142. ; AutoIt Version : v3.2.12.1 or higher
  143. ; Language ......: English
  144. ; Description ...: Returns size of rectangle required to display string - maximum width can be chosen
  145. ; Remarks .......:
  146. ; Note ..........:
  147. ; Author(s) .....:  Melba23 - thanks to trancexx for the default DC code
  148. ; ====================================================================================================================
  149.  
  150. ;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
  151.  
  152. ; #CURRENT# ==========================================================================================================
  153. ; _StringSize: Returns size of rectangle required to display string - maximum width can be chosen
  154. ; ====================================================================================================================
  155.  
  156. ; #INTERNAL_USE_ONLY#=================================================================================================
  157. ; _StringSize_Error_Close: Releases DC and deletes font object after error
  158. ; _StringSize_DefaultFontName: Determines Windows default font
  159. ; ====================================================================================================================
  160.  
  161. ; #FUNCTION# =========================================================================================================
  162. ; Name...........: _StringSize
  163. ; Description ...: Returns size of rectangle required to display string - maximum permitted width can be chosen
  164. ; Syntax ........: _StringSize($sText[, $iSize[, $iWeight[, $iAttrib[, $sName[, $iWidth[, $hWnd]]]]]])
  165. ; Parameters ....: $sText   - String to display
  166. ;                  $iSize   - [optional] Font size in points - (default = 8.5)
  167. ;                  $iWeight - [optional] Font weight - (default = 400 = normal)
  168. ;                  $iAttrib - [optional] Font attribute (0-Normal (default), 2-Italic, 4-Underline, 8 Strike)
  169. ;                             + 1 if tabs are to be expanded before sizing
  170. ;                  $sName   - [optional] Font name - (default = Tahoma)
  171. ;                  $iWidth  - [optional] Max width for rectangle - (default = 0 => width of original string)
  172. ;                  $hWnd    - [optional] GUI in which string will be displayed - (default 0 => normally not required)
  173. ; Requirement(s) : v3.2.12.1 or higher
  174. ; Return values .: Success - Returns 4-element array: ($iWidth set // $iWidth not set)
  175. ;                  |$array[0] = String reformatted with additonal @CRLF // Original string
  176. ;                  |$array[1] = Height of single line in selected font // idem
  177. ;                  |$array[2] = Width of rectangle required for reformatted // original string
  178. ;                  |$array[3] = Height of rectangle required for reformatted // original string
  179. ;                  Failure - Returns 0 and sets @error:
  180. ;                  |1 - Incorrect parameter type (@extended = parameter index)
  181. ;                  |2 - DLL call error - extended set as follows:
  182. ;                       |1 - GetDC failure
  183. ;                       |2 - SendMessage failure
  184. ;                       |3 - GetDeviceCaps failure
  185. ;                       |4 - CreateFont failure
  186. ;                       |5 - SelectObject failure
  187. ;                       |6 - GetTextExtentPoint32 failure
  188. ;                  |3 - Font too large for chosen max width - a word will not fit
  189. ; Author ........: Melba23 - thanks to trancexx for the default DC code
  190. ; Modified ......:
  191. ; Remarks .......: The use of the $hWnd parameter is not normally necessary - it is only required if the UDF does not
  192. ;                   return correct dimensions without it.
  193. ; Related .......:
  194. ; Link ..........:
  195. ; Example .......: Yes
  196. ;=====================================================================================================================
  197. Func _StringSize($sText, $iSize = 8.5, $iWeight = 400, $iAttrib = 0, $sName = "", $iMaxWidth = 0, $hWnd = 0)
  198.  
  199.     ; Set parameters passed as Default
  200.     If $iSize = Default Then $iSize = 8.5
  201.     If $iWeight = Default Then $iWeight = 400
  202.     If $iAttrib = Default Then $iAttrib = 0
  203.     If $sName = "" Or $sName = Default Then $sName = _StringSize_DefaultFontName()
  204.  
  205.     ; Check parameters are correct type
  206.     If Not IsString($sText) Then Return SetError(1, 1, 0)
  207.     If Not IsNumber($iSize) Then Return SetError(1, 2, 0)
  208.     If Not IsInt($iWeight) Then Return SetError(1, 3, 0)
  209.     If Not IsInt($iAttrib) Then Return SetError(1, 4, 0)
  210.     If Not IsString($sName) Then Return SetError(1, 5, 0)
  211.     If Not IsNumber($iMaxWidth) Then Return SetError(1, 6, 0)
  212.     If Not IsHwnd($hWnd) And $hWnd <> 0 Then Return SetError(1, 7, 0)
  213.  
  214.     Local $aRet, $hDC, $hFont, $hLabel = 0, $hLabel_Handle
  215.  
  216.     ; Check for tab expansion flag
  217.     Local $iExpTab = BitAnd($iAttrib, 1)
  218.     ; Remove possible tab expansion flag from font attribute value
  219.     $iAttrib = BitAnd($iAttrib, BitNot(1))
  220.  
  221.     ; If GUI handle was passed
  222.     If IsHWnd($hWnd) Then
  223.         ; Create label outside GUI borders
  224.         $hLabel = GUICtrlCreateLabel("", -10, -10, 10, 10)
  225.         $hLabel_Handle = GUICtrlGetHandle(-1)
  226.         GUICtrlSetFont(-1, $iSize, $iWeight, $iAttrib, $sName)
  227.         ; Create DC
  228.         $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hLabel_Handle)
  229.         If @error Or $aRet[0] = 0 Then
  230.             GUICtrlDelete($hLabel)
  231.             Return SetError(2, 1, 0)
  232.         EndIf
  233.         $hDC = $aRet[0]
  234.         $aRet = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hLabel_Handle, "int", 0x0031, "wparam", 0, "lparam", 0) ; $WM_GetFont
  235.         If @error Or $aRet[0] = 0 Then
  236.             GUICtrlDelete($hLabel)
  237.             Return SetError(2, _StringSize_Error_Close(2, $hDC), 0)
  238.         EndIf
  239.         $hFont = $aRet[0]
  240.     Else
  241.         ; Get default DC
  242.         $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hWnd)
  243.         If @error Or $aRet[0] = 0 Then Return SetError(2, 1, 0)
  244.         $hDC = $aRet[0]
  245.         ; Create required font
  246.         $aRet = DllCall("gdi32.dll", "int", "GetDeviceCaps", "handle", $hDC, "int", 90) ; $LOGPIXELSY
  247.         If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(3, $hDC), 0)
  248.         Local $iInfo = $aRet[0]
  249.         $aRet = DllCall("gdi32.dll", "handle", "CreateFontW", "int", -$iInfo * $iSize / 72, "int", 0, "int", 0, "int", 0, _
  250.             "int", $iWeight, "dword", BitAND($iAttrib, 2), "dword", BitAND($iAttrib, 4), "dword", BitAND($iAttrib, 8), "dword", 0, "dword", 0, _
  251.             "dword", 0, "dword", 5, "dword", 0, "wstr", $sName)
  252.         If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(4, $hDC), 0)
  253.         $hFont = $aRet[0]
  254.     EndIf
  255.  
  256.     ; Select font and store previous font
  257.     $aRet = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hFont)
  258.     If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(5, $hDC, $hFont, $hLabel), 0)
  259.     Local $hPrevFont = $aRet[0]
  260.  
  261.     ; Declare variables
  262.     Local $avSize_Info[4], $iLine_Length, $iLine_Height = 0, $iLine_Count = 0, $iLine_Width = 0, $iWrap_Count, $iLast_Word, $sTest_Line
  263.     ; Declare and fill Size structure
  264.     Local $tSize = DllStructCreate("int X;int Y")
  265.     DllStructSetData($tSize, "X", 0)
  266.     DllStructSetData($tSize, "Y", 0)
  267.  
  268.     ; Ensure EoL is @CRLF and break text into lines
  269.     $sText = StringRegExpReplace($sText, "((?<!\x0d)\x0a|\x0d(?!\x0a))", @CRLF)
  270.     Local $asLines = StringSplit($sText, @CRLF, 1)
  271.  
  272.     ; For each line
  273.     For $i = 1 To $asLines[0]
  274.         ; Expand tabs if required
  275.         If $iExpTab Then
  276.             $asLines[$i] = StringReplace($asLines[$i], @TAB, " XXXXXXXX")
  277.         EndIf
  278.         ; Size line
  279.         $iLine_Length = StringLen($asLines[$i])
  280.         DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$i], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
  281.         If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
  282.         If DllStructGetData($tSize, "X") > $iLine_Width Then $iLine_Width = DllStructGetData($tSize, "X")
  283.         If DllStructGetData($tSize, "Y") > $iLine_Height Then $iLine_Height = DllStructGetData($tSize, "Y")
  284.     Next
  285.  
  286.     ; Check if $iMaxWidth has been both set and exceeded
  287.     If $iMaxWidth <> 0 And $iLine_Width > $iMaxWidth Then ; Wrapping required
  288.         ; For each Line
  289.         For $j = 1 To $asLines[0]
  290.             ; Size line unwrapped
  291.             $iLine_Length = StringLen($asLines[$j])
  292.             DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$j], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
  293.             If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
  294.             ; Check wrap status
  295.             If DllStructGetData($tSize, "X") < $iMaxWidth - 4 Then
  296.                 ; No wrap needed so count line and store
  297.                 $iLine_Count += 1
  298.                 $avSize_Info[0] &= $asLines[$j] & @CRLF
  299.             Else
  300.                 ; Wrap needed so zero counter for wrapped lines
  301.                 $iWrap_Count = 0
  302.                 ; Build line to max width
  303.                 While 1
  304.                     ; Zero line width
  305.                     $iLine_Width = 0
  306.                     ; Initialise pointer for end of word
  307.                     $iLast_Word = 0
  308.                     ; Add characters until EOL or maximum width reached
  309.                     For $i = 1 To StringLen($asLines[$j])
  310.                         ; Is this just past a word ending?
  311.                         If StringMid($asLines[$j], $i, 1) = " " Then $iLast_Word = $i - 1
  312.                         ; Increase line by one character
  313.                         $sTest_Line = StringMid($asLines[$j], 1, $i)
  314.                         ; Get line length
  315.                         $iLine_Length = StringLen($sTest_Line)
  316.                         DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sTest_Line, "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
  317.                         If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
  318.                         $iLine_Width = DllStructGetData($tSize, "X")
  319.                         ; If too long exit the loop
  320.                         If $iLine_Width >= $iMaxWidth - 4 Then ExitLoop
  321.                     Next
  322.                     ; End of the line of text?
  323.                     If $i > StringLen($asLines[$j]) Then
  324.                         ; Yes, so add final line to count
  325.                         $iWrap_Count += 1
  326.                         ; Store line
  327.                         $avSize_Info[0] &= $sTest_Line & @CRLF
  328.                         ExitLoop
  329.                     Else
  330.                         ; No, but add line just completed to count
  331.                         $iWrap_Count += 1
  332.                         ; Check at least 1 word completed or return error
  333.                         If $iLast_Word = 0 Then Return SetError(3, _StringSize_Error_Close(0, $hDC, $hFont, $hLabel), 0)
  334.                         ; Store line up to end of last word
  335.                         $avSize_Info[0] &= StringLeft($sTest_Line, $iLast_Word) & @CRLF
  336.                         ; Strip string to point reached
  337.                         $asLines[$j] = StringTrimLeft($asLines[$j], $iLast_Word)
  338.                         ; Trim leading whitespace
  339.                         $asLines[$j] = StringStripWS($asLines[$j], 1)
  340.                         ; Repeat with remaining characters in line
  341.                     EndIf
  342.                 WEnd
  343.                 ; Add the number of wrapped lines to the count
  344.                 $iLine_Count += $iWrap_Count
  345.             EndIf
  346.         Next
  347.         ; Reset any tab expansions
  348.         If $iExpTab Then
  349.             $avSize_Info[0] = StringRegExpReplace($avSize_Info[0], "\x20?XXXXXXXX", @TAB)
  350.         EndIf
  351.         ; Complete return array
  352.         $avSize_Info[1] = $iLine_Height
  353.         $avSize_Info[2] = $iMaxWidth
  354.         ; Convert lines to pixels and add drop margin
  355.         $avSize_Info[3] = ($iLine_Count * $iLine_Height) + 4
  356.     Else ; No wrapping required
  357.         ; Create return array (add drop margin to height)
  358.         Local $avSize_Info[4] = [$sText, $iLine_Height, $iLine_Width, ($asLines[0] * $iLine_Height) + 4]
  359.     EndIf
  360.  
  361.     ; Clear up
  362.     DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hPrevFont)
  363.     DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
  364.     DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
  365.     If $hLabel Then GUICtrlDelete($hLabel)
  366.  
  367.     Return $avSize_Info
  368.  
  369. EndFunc ;==>_StringSize
  370.  
  371. ; #INTERNAL_USE_ONLY#============================================================================================================
  372. ; Name...........: _StringSize_Error_Close
  373. ; Description ...: Releases DC and deleted font object if required after error
  374. ; Syntax ........: _StringSize_Error_Close ($iExtCode, $hDC, $hGUI)
  375. ; Parameters ....: $iExtCode   - code to return
  376. ;                  $hDC, $hGUI - handles as set in _StringSize function
  377. ; Return value ..: $iExtCode as passed
  378. ; Author ........: Melba23
  379. ; Modified.......:
  380. ; Remarks .......: This function is used internally by _StringSize
  381. ; ===============================================================================================================================
  382. Func _StringSize_Error_Close($iExtCode, $hDC = 0, $hFont = 0, $hLabel = 0)
  383.  
  384.     If $hFont <> 0 Then DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
  385.     If $hDC <> 0 Then DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
  386.     If $hLabel Then GUICtrlDelete($hLabel)
  387.  
  388.     Return $iExtCode
  389.  
  390. EndFunc ;=>_StringSize_Error_Close
  391.  
  392. ; #INTERNAL_USE_ONLY#============================================================================================================
  393. ; Name...........: _StringSize_DefaultFontName
  394. ; Description ...: Determines Windows default font
  395. ; Syntax ........: _StringSize_DefaultFontName()
  396. ; Parameters ....: None
  397. ; Return values .: Success - Returns name of system default font
  398. ;                  Failure - Returns "Tahoma"
  399. ; Author ........: Melba23, based on some original code by Larrydalooza
  400. ; Modified.......:
  401. ; Remarks .......: This function is used internally by _StringSize
  402. ; ===============================================================================================================================
  403. Func _StringSize_DefaultFontName()
  404.  
  405.     ; Get default system font data
  406.     Local $tNONCLIENTMETRICS = DllStructCreate("uint;int;int;int;int;int;byte[60];int;int;byte[60];int;int;byte[60];byte[60];byte[60]")
  407.     DLLStructSetData($tNONCLIENTMETRICS, 1, DllStructGetSize($tNONCLIENTMETRICS))
  408.     DLLCall("user32.dll", "int", "SystemParametersInfo", "int", 41, "int", DllStructGetSize($tNONCLIENTMETRICS), "ptr", DllStructGetPtr($tNONCLIENTMETRICS), "int", 0)
  409.     Local $tLOGFONT = DllStructCreate("long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32]", DLLStructGetPtr($tNONCLIENTMETRICS, 13))
  410.     If IsString(DllStructGetData($tLOGFONT, 14)) Then
  411.         Return DllStructGetData($tLOGFONT, 14)
  412.     Else
  413.         Return "Tahoma"
  414.     EndIf
  415.  
  416. EndFunc ;=>_StringSize_DefaultFontName
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement