#include #include #include #include #include #include Opt('MustDeclareVars', 1) Global $hGui = GUICreate('RAINBOW', 183, 285, -1, -1, BitOr($WS_POPUP, $WS_BORDER)); , $WS_CLIPCHILDREN)) ; excluding WS_CLIPCHILDREN here ↑ reduces glitching, but adds flickering Global $mButtons[] ; every "button" consists of 7 labels, so I made a map to store label IDs Global $aHotKeys = [] ; an array to relate accelerator keys and "buttons" Global $idTextLabel = GUICtrlCreateLabel('', 24, 32, 135, 25, $SS_SUNKEN + $SS_RIGHT + $SS_CENTERIMAGE) _AddHotKeys() ; futhfill $aHotKeys array. "Buttons" are identified by a string(map key), so I can add hotkeys, before creating "buttons" _RndBgColor() ; This ↑ function: ; changes main Gui & input field bkColor. _WinAPI_RedrawWindow applied, but I am not sure it is correct ; delets "buttons" if any exist. see Func _DeleteButtons() ; creates new "buttons", see _AddButtons() and _RAINBOW_CreateButton() main problems are in there I suppose ; can be calleb with 'RAINBOWnize Colors' button ↓ $mButtons['RND'] = _RAINBOW_CreateButton(24, 242, 'RAINBOWnize Colors', 135, 25, '_RndBgColor') GUISetState() Global $msg While 1 $msg = GUIGetMsg(1) Select Case $msg[0] = $GUI_EVENT_PRIMARYDOWN _Click() ; ↑ here I emulate default buttons click behavior. ; dont use _WinAPI_RedrawWindow, dont know if I need to ¯\_(ツ)_/¯. this func causes no glitches Case $msg[0] = $GUI_EVENT_SECONDARYDOWN _Move() ;RMB to move Gui, seen that in dozens of examples, nothing to see here Case $msg[0] = $GUI_EVENT_MOUSEMOVE _HoverCheck() ; ↑ here I emulate default buttons hover behavior. ; the main func is not the best code example, and it is not the problem ; but it calls _ButtonSwitch() whitch is main problem #2 I suppose Case _ArraySearch($aHotKeys, $msg[0]) > -1 _CallBack($msg[0], True) ; ↑ here I make "buttons" responde the hotkeys (Accelerators) with "True" parameter ; the main func is not the best code example, and it is not the problem ; but it calls _ButtonSwitch() whitch is main problem #2 (ㅠ﹏ㅠ) Case $msg[0] = $GUI_EVENT_CLOSE Exit EndSelect WEnd ; =============================================================================================================================== Func _Move() Local $nHover = GUIGetCursorInfo()[4] If Not($nHover = 0) Then Return 0 GUISetCursor(9) Local $nMouseX = MouseGetPos(0) Local $nMouseY = MouseGetPos(1) Local $nGuiX = WinGetPos($hGui)[0] - $nMouseX Local $nGuiY = WinGetPos($hGui)[1] - $nMouseY Do If Not(MouseGetPos(0) = $nMouseX) or Not(MouseGetPos(1) = $nMouseY) Then WinMove($hGui, '', MouseGetPos(0) + $nGuiX, $nGuiY + MouseGetPos(1)) $nMouseX = MouseGetPos(0) $nMouseY = MouseGetPos(1) EndIf Until GUIGetMsg(1)[0] = $GUI_EVENT_SECONDARYUP GUISetCursor() EndFunc ; =============================================================================================================================== Func _Click() Local $nHover = GUIGetCursorInfo()[4] ; storing id of a control, that is beneath the cursor If $nHover = 0 Then Return 0 Local $aKeys = MapKeys($mButtons) ; getting an array holding all custom button names For $sKey in MapKeys($mButtons) ; then for each "button" Local $aControl = $mButtons[$sKey] ; getting an array holding all "button" labels IDs If _ArraySearch($aControl, $nHover) > -1 Then ; if cursor hovers any of the "button" labels _Down($aControl) ; draw "pressed button" and wait for $GUI_EVENT_PRIMARYUP If $nHover = GUIGetCursorInfo()[4] And Not($aControl[7] = '') Then Call($aControl[7], $aControl[6]) ; ↑ when primary is up if cursor hovers the same "button" then ; call the "button" callback ($aControl[7]) and send "button" text($aControl[6]) as a parameter EndIf Next EndFunc ; =============================================================================================================================== Func _Down($aControl) Local $aTextPos = ControlGetPos($hGui, '', $aControl[6]) Local $aFramePos1 = ControlGetPos($hGui, '', $aControl[3]) Local $aFramePos2 = ControlGetPos($hGui, '', $aControl[5]) GUICtrlSetState($aControl[2], 32) GUICtrlSetState($aControl[4], 32) GUICtrlSetPos($aControl[3], $aFramePos1[0] - 1, $aFramePos1[1] - 1, $aFramePos1[2] + 2, $aFramePos1[3] + 2) GUICtrlSetPos($aControl[5], $aFramePos2[0] - 1, $aFramePos2[1] - 1, $aFramePos2[2] + 2, $aFramePos2[3] + 2) GUICtrlSetPos($aControl[6], $aTextPos[0]+1, $aTextPos[1]+1) Do Until GUIGetMsg(1)[0] = $GUI_EVENT_PRIMARYUP GUICtrlSetState($aControl[2], 16) GUICtrlSetState($aControl[4], 16) GUICtrlSetPos($aControl[3], $aFramePos1[0], $aFramePos1[1], $aFramePos1[2], $aFramePos1[3]) GUICtrlSetPos($aControl[5], $aFramePos2[0], $aFramePos2[1], $aFramePos2[2], $aFramePos2[3]) GUICtrlSetPos($aControl[6], $aTextPos[0], $aTextPos[1]) EndFunc ; =============================================================================================================================== Func _HoverCheck() Local Static $sCurrHover = '' Local $nHover = GUIGetCursorInfo()[4] Select Case Not $sCurrHover = '' And $nHover = 0 _ButtonSwitch($mButtons[$sCurrHover], -1) $sCurrHover = '' Return 0 Case Not $sCurrHover = '' If _ArraySearch($mButtons[$sCurrHover], $nHover) > -1 Then Return 0 _ButtonSwitch($mButtons[$sCurrHover], -1) $sCurrHover = '' Return 0 Case $nHover = 0 And $sCurrHover = '' Return 0 Case Else Local $aKeys = MapKeys($mButtons) For $sKey in MapKeys($mButtons) Local $aControl = $mButtons[$sKey] If _ArraySearch($aControl, $nHover) > -1 And $sCurrHover = '' Then _ButtonSwitch($aControl, 1) $sCurrHover = $sKey Return 0 EndIf Next EndSelect EndFunc ; =============================================================================================================================== Func _ButtonSwitch($aControl, $nState) For $i = 2 to 5 Local $aCtrlPos = ControlGetPos($hGui, '', $aControl[$i]) GUICtrlSetPos($aControl[$i], $aCtrlPos[0] + 1 * $nState, _ $aCtrlPos[1] + 1 * $nState, _ $aCtrlPos[2] - 2 * $nState, _ $aCtrlPos[3] - 2 * $nState) ; _WinAPI_RedrawWindow(ControlGetHandle($hGui, '', $aControl[$i])) ; "button" freezes without these lines, still not shure it is correct Next ; _WinAPI_RedrawWindow(ControlGetHandle($hGui, '', $aControl[6])) ; ୧༼ಠ益ಠ༽୨ EndFunc ; =============================================================================================================================== Func _RAINBOW_CreateButton($nX = 0, $nY = 0, $sText = '', $nWidth = 75, $nHeight = 25, $sFunc = '', $nHueShift = 0) Local $aButton[8] Local $nTextX, $nTextY $aButton[0] = GUICtrlCreateLabel('', $nX, $nY, $nWidth, $nHeight) _RAINBOW_GUICtrlSetBkColor(0x646464, $nHueShift) $aButton[1] = GUICtrlCreateLabel('', $nX+1, $nY+1, $nWidth-2, $nHeight-2) _RAINBOW_GUICtrlSetBkColor(0x696969, $nHueShift) $aButton[2] = GUICtrlCreateLabel('', $nX, $nY, $nWidth-1, $nHeight-1) _RAINBOW_GUICtrlSetBkColor(0xFAFAFA, $nHueShift) $aButton[3] = GUICtrlCreateLabel('', $nX+1, $nY+1, $nWidth-2, $nHeight-2) _RAINBOW_GUICtrlSetBkColor(0xA0A0A0, $nHueShift) $aButton[4] = GUICtrlCreateLabel('', $nX+1, $nY+1, $nWidth-3, $nHeight-3) _RAINBOW_GUICtrlSetBkColor(0xE3E3E3, $nHueShift) $aButton[5] = GUICtrlCreateLabel('', $nX+2, $nY+2, $nWidth-4, $nHeight-4) _RAINBOW_GUICtrlSetBkColor(0xF0F0F0, $nHueShift) ; I could add text to the label above, it glitches more though, so I use $aButton[6] for text $aButton[6] = GUICtrlCreateLabel($sText, $nX+3, $nY+3, $nWidth-8, $nHeight-8, $SS_CENTER + $SS_CENTERIMAGE) _RAINBOW_GUICtrlSetBkColor(0xF0F0F0, $nHueShift) ; ↓ this is where I need help. without this lines labels sometimes(!) do not get redrawn ; still dont think I am using it correctly ; For $i = 0 to 6 ; _WinAPI_RedrawWindow(ControlGetHandle($hGui, '', $aButton[$i])) ; Next $aButton[7] = $sFunc ; string that holds a callback function name Return $aButton EndFunc ; =============================================================================================================================== Func _RndBgColor($sNull = '') GUISetBkColor(_GetRandomColor()) GUICtrlSetBkColor($idTextLabel, _GetRandomColor()) ; _WinAPI_RedrawWindow(ControlGetHandle($hGui, '', $idTextLabel)) ; this ↑ is where i need help. without this line idTextLabel does not change color _DeleteButtons() _AddButtons(Random(0, 255, 1)) Return 0 EndFunc ; =============================================================================================================================== Func _GetRandomColor($iSaturation = 100, $iLuminance = 200) Local $nColor, $iHue _WinAPI_ColorRGBToHLS(Random(0, 0xFFFFFF, 1), $iHue, $iLuminance, $iSaturation) $iSaturation = 100 $iLuminance = 150 $nColor = _WinAPI_ColorHLSToRGB($iHue, $iLuminance, $iSaturation) Return $nColor EndFunc ; =============================================================================================================================== Func _RAINBOW_GUICtrlSetBkColor($nColor, $nHueShift = 0) Local $iHue, $iLuminance, $iSaturation If Not $nHueShift = 0 Then _WinAPI_ColorRGBToHLS($nColor, $iHue, $iLuminance, $iSaturation) $iSaturation = 150 $iHue += $nHueShift ; $iLuminance -= 50 $nColor = _WinAPI_ColorHLSToRGB($iHue, $iLuminance, $iSaturation) EndIf GUICtrlSetBkColor(-1, $nColor) EndFunc ; =============================================================================================================================== Func _CallBack($idCtrl, $bHotKey = False) Local Static $sM = '' If $bHotKey Then _ButtonSwitch($mButtons[GUICtrlRead($idCtrl)], 1) Sleep(100) EndIf Switch GUICtrlRead($idCtrl) Case 'CE' GUICtrlSetData($idTextLabel, '') Case 'MR' GUICtrlSetData($idTextLabel, $sM) Case 'MC' $sM = '' Case 'MS' $sM = ControlGetText($hGui, '', $idTextLabel) Case '=' GUICtrlSetData($idTextLabel, 'Calc is a lie.') Case Else GUICtrlSetData($idTextLabel, ControlGetText($hGui, '', $idTextLabel) & GUICtrlRead($idCtrl)) EndSwitch If $bHotKey Then _ButtonSwitch($mButtons[GUICtrlRead($idCtrl)], -1) EndFunc ; =============================================================================================================================== Func _AddButtons($nHueShift = 0) ; Local $aTexts = [['CE', 'MC', 'MS', 'MR', 'A', 'F', 'K', 'P'], _ ; ['7', '8', '9', '+', 'B', 'G', 'L', 'Q'], _ ; ['4', '5', '6', '-', 'C', 'H', 'M', 'R'], _ ; ['1', '2', '3', 'x', 'D', 'I', 'N', 'S'], _ ; ['0', '.', '=', '/', 'E', 'J', 'O', 'T']] Local $aTexts = [['CE', 'MC', 'MS', 'MR'], _ ['7', '8', '9', '+'], _ ['4', '5', '6', '-'], _ ['1', '2', '3', 'x'], _ ['0', '.', '=', '/']] For $i = 0 to UBound($aTexts, 1) - 1 For $n = 0 to UBound($aTexts, 2) - 1 $mButtons[$aTexts[$i][$n]] = _RAINBOW_CreateButton(24+$n*35, 67+$i*35, $aTexts[$i][$n], 30, 25, '_CallBack', $nHueShift) If ($nHueShift + 10) > 255 Then $nHueShift = 1 Else $nHueShift += 10 EndIf Next Next EndFunc ; =============================================================================================================================== Func _DeleteButtons() For $sKey in MapKeys($mButtons) If $sKey = 'RND' Then ContinueLoop For $id in $mButtons[$sKey] GUICtrlDelete($id) Next Next EndFunc ; =============================================================================================================================== Func _AddHotKeys() Local $idDummy, $sIds = '' Local $aAccelKeys = [['{NUMPAD0}', 0], ['{NUMPAD1}', 0], ['{NUMPAD2}', 0], _ ['{NUMPAD3}', 0], ['{NUMPAD4}', 0], ['{NUMPAD5}', 0], _ ['{NUMPAD6}', 0], ['{NUMPAD7}', 0], ['{NUMPAD8}', 0], _ ['{NUMPAD9}', 0], ['{NUMPADADD}', 0], ['{NUMPADSUB}', 0], _ ['{NUMPADMULT}', 0], ['{NUMPADDIV}', 0], ['{ENTER}', 0], _ ['{NUMPADDOT}', 0], ['{DEL}', 0]] Local $aAccelData = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '-', 'x', '/', '=', '.', 'CE'] For $i = 0 to 16 $idDummy = GUICtrlCreateDummy() GUICtrlSetData(-1, $aAccelData[$i]) $aAccelKeys[$i][1] = $idDummy $sIds &= $idDummy & '/' Next GUISetAccelerators($aAccelKeys) $sIds = StringLeft($sIds, StringLen($sIds) - 1) $aHotKeys = StringSplit($sIds, '/', 2) EndFunc ; ===============================================================================================================================