Sign in to follow this  
Followers 0
InunoTaishou

More _Color UDFs

1 post in this topic

After spending 15 minutes last night trying to get the RGB from an ARGB color I had remembered BitXOR. After figuring that one out I set forth a clean way to increase and decrease an individual color component in a color (without having to do something like Hex(_ColorGetRed(0xFF0000) - 10, 2). I don't really know a lot about Bit operations so it was interesting to see how it works and finally figured it out when I was looking closely at how the Color UDF got the Red, green, and blue components from a color.

; #Functions# ===================================================================================================================
; _ColorRGB             - Return the RGB color of the individual components.
; _ColorARGB            - Return the ARGB color of the individual components.
; _ColorGetAlpha        - Returns the alpha value of the color. 0 - 255
; _ColorAdjustAlpha     - Adjust (increase or decrease) the alpha component of a color.
; _ColorAdjustRed       - Adjust (increase or decrease) the red component of a color.
; _ColorAdjustGreen     - Adjust (increase or decrease) the green component of a color.
; _ColorAdjustBlue      - Adjust (increase or decrease) the blue component of a color.
; ===============================================================================================================================

Func _ColorRGB($iR, $iG, $iB, Const $_iCurrentExtended = @extended)
    Return SetExtended($_iCurrentExtended, BitOR(BitShift($iR, -16), BitShift($iG, -8), $iB))
EndFunc   ;==>_ColorRGB

Func _ColorARGB($iA, $iR, $iG, $iB, Const $_iCurrentExtended = @extended)
    Return SetExtended($_iCurrentExtended, BitOR(BitShift($iA, -24), BitShift($iR, -16), BitShift($iG, -8), $iB))
EndFunc   ;==>_ColorARGB

Func _ColorGetAlpha($iColor, Const $_iCurrentExtended = @extended)
    If (Not BitAND($iColor, 0xFF000000)) Then Return SetError(1, 0, 0)
    Return SetExtended($_iCurrentExtended, BitAND(BitShift($iColor, 24), 0xFF))
EndFunc   ;==>_ColorGetAlpha

Func _ColorAdjustAlpha($iColor, $iAmount, Const $_iCurrentExtended = @extended)
    If (Not BitAND($iColor, 0xFF000000) And $iAmount < 0) Then Return SetError(1, 0, $iColor)
    Local $iA = BitAND(BitShift($iColor, 24), 0xFF)
    If ($iAmount < 0 And $iA + $iAmount < 0) Then $iAmount = -$iA
    If ($iAmount > 0 And $iA = 255) Then Return $iColor
    If ($iAmount > 0 And $iA + $iAmount > 255) Then $iAmount = Abs($iA - $iAmount)
    Return SetExtended($_iCurrentExtended, $iColor + BitShift($iAmount, -24))
EndFunc   ;==>_ColorAdjustAlpha

Func _ColorAdjustRed($iColor, $iAmount, Const $_iCurrentExtended = @extended)
    If (Not BitAND($iColor, 0xFF0000) And $iAmount < 0) Then Return SetError(1, 0, $iColor)
    Local $iR = BitAND(BitShift($iColor, 16), 0xFF)
    If ($iAmount < 0 And $iR + $iAmount < 0) Then $iAmount = -$iR
    If ($iAmount > 0 And $iR = 255) Then Return $iColor
    If ($iAmount > 0 And $iR + $iAmount > 255) Then $iAmount = Abs($iR - $iAmount)
    Return SetExtended($_iCurrentExtended, $iColor + BitShift($iAmount, -16))
EndFunc   ;==>_ColorAdjustRed

Func _ColorAdjustGreen($iColor, $iAmount, Const $_iCurrentExtended = @extended)
    If (Not BitAND($iColor, 0xFF00) And $iAmount < 0) Then Return SetError(1, 0, $iColor)
    Local $iG = BitAND(BitShift($iColor, 8), 0xFF)
    If ($iAmount < 0 And $iG + $iAmount < 0) Then $iAmount = -$iG
    If ($iAmount > 0 And $iG = 255) Then Return $iColor
    If ($iAmount > 0 And $iG + $iAmount > 255) Then $iAmount = Abs($iG - $iAmount)
    Return SetExtended($_iCurrentExtended, $iColor + BitShift($iAmount, -8))
EndFunc   ;==>_ColorAdjustGreen

Func _ColorAdjustBlue($iColor, $iAmount, Const $_iCurrentExtended = @extended)
    If (Not BitAND($iColor, 0xFF) And $iAmount < 0) Then Return SetError(1, 0, $iColor)
    Local $iB = BitAND($iColor, 0xFF)
    If ($iAmount < 0 And $iB + $iAmount < 0) Then $iAmount = -$iB
    If ($iAmount > 0 And $iB = 255) Then Return $iColor
    If ($iAmount > 0 And $iB + $iAmount > 255) Then $iAmount = Abs($iB - $iAmount)
    Return SetExtended($_iCurrentExtended, $iColor + $iAmount)
EndFunc   ;==>_ColorAdjustBlue

A quick example using them.

Global $iBaseRGB = 0x00FFFF
Global $iBaseARGB = 0xC8000000
Global $iBaseAlpha = _ColorGetAlpha($iBaseARGB)
Global $iRemoveG = _ColorAdjustGreen($iBaseRGB, -255)
Global $iRemoveGB = _ColorAdjustBlue($iRemoveG, -255)
Global $iRemoveGBAddR = _ColorAdjustRed($iRemoveGB, 255)
Global $iRemoveGBAddRA = _ColorAdjustAlpha($iRemoveGBAddR, $iBaseAlpha)

MsgBox("", "Adjusting colors", "Base RGB color: 0x" & Hex($iBaseRGB, 6) & @CRLF & _
        "Remove Green component: 0x" & Hex($iRemoveG, 6) & @CRLF & _
        "Remove Blue component: 0x" & Hex($iRemoveGB, 6) & @CRLF & _
        "Add Red component: 0x" & Hex($iRemoveGBAddR, 6) & @CRLF & @CRLF & _
        "Base ARGB color: 0x" & Hex($iBaseARGB, 8) & @CRLF & _
        "Alpha for $iBaseAlpha: 0x" & Hex($iBaseAlpha, 2) & @CRLF & _
        "Add $iBaseAlpha to $iRemoveGBAddR: 0x" & Hex($iRemoveGBAddRA, 8) & @CRLF & _
        "Max Alpha for $iRemoveGBAddRA: 0x" & Hex(_ColorAdjustAlpha($iRemoveGBAddRA, 255)) & @CRLF & @CRLF & _
        "RGB for Red 31, Green 31, Blue 31: 0x" & Hex(_ColorRGB(31, 31, 31), 6) & @CRLF & _
        "ARGB for Alpha 255, Red 42, Green 42, and Blue 42: 0x" & Hex(_ColorARGB(255, 42, 42, 42), 8))

All my bit operations and math should be right, I tested each function. No need to calculate how much you need to add, or subtract, to a component to max, or 0, it. Just use the max value (255 or -255).

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
Sign in to follow this  
Followers 0

  • Similar Content

    • AndyS19
      By AndyS19
      I have a listview with 3 columns and I want to set the 3rd column's color based on the item's 'Param' value, but even though I set up for the 3rd column, the entire row always gets the color.
      My test code is below, but here is the pertinent code:
      Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam, $ilParam Local $hWndFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $iDrawStage, $tCustDraw $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage') Switch $iDrawStage Case BitOR(0, $CDDS_ITEMPREPAINT) ;, $CDDS_SUBITEM) setItemColor($tCustDraw, $hWndFrom) Return $CDRF_NOTIFYSUBITEMDRAW EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func setItemColor($tCustDraw, $hWnd) Local $iIndex, $color, $iSubitem $iIndex = DllStructGetData($tCustDraw, 'dwItemSpec') ; item number $color = _GUICtrlListView_GetItemParam($hWnd, $iIndex) $iSubitem = DllStructGetData($tCustDraw, 'iSubItem') ; Here, I want to only change the color of the 3rd col, and not the 1st and 2nd cols DllStructSetData($tCustDraw, 'iSubItem', 2) ; always use the 3rd column (the 'sample' col) logmsg("+++: setItemColor($tCustDraw, 0x" & Hex($hWnd) & ") entered ... " _ & ", $iIndex = " & $iIndex & ", $iSubItem = " & $iSubitem & ", $color = " & Hex($color)) DllStructSetData($tCustDraw, 'clrText', $color) ; set the Text color DllStructSetData($tCustDraw, 'clrTextBk', bitnot($color)) ; set the background color EndFunc ;==>setItemColor Func logmsg($msg, $lnum = @ScriptLineNumber) ConsoleWrite("+++:" & $lnum & ": " & $msg & @CRLF) EndFunc ;==>logmsg
      Here is the full test code:
      #include-once ;#cs #NoTrayIcon #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #AutoIt3Wrapper_UseX64=N Opt("GUICloseOnESC", 1) ; ESC closes GUI? (0 = no, 1 = yes) Opt("GUIOnEventMode", 1) ; Change to OnEvent mode Opt('MustDeclareVars', 1) OnAutoItExitRegister("_test_exit") Opt("GUIEventOptions", 1) ;0=default, 1=just notification, 2=GuiCtrlRead tab index Opt("WinTitleMatchMode", -2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase #include <GuiListBox.au3> #include <ListViewConstants.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <ColorConstants.au3> Global $__MCP_obj, $__MCP_GUI_hWnd, $idListView, $hListView Global $hMainWin test() Exit Func test() $hMainWin = GUICreate("Test window", 120, 100, @DesktopWidth / 2, -1) GUICtrlCreateButton("Hwnd", 10, 10, 40, 20) GUICtrlSetOnEvent(-1, "handle_1stTEST_btn") GUICtrlCreateButton("ID", 50, 10, 40, 20) GUICtrlSetOnEvent(-1, "handle_2ndTEST_btn") GUISetOnEvent($GUI_EVENT_CLOSE, "_test_exit") GUISetState(@SW_SHOW) While (1) Sleep(17) WEnd EndFunc ;==>test Func _myColorPicker($obj) logmsg("+++: $obj = 0x" & Hex($obj) & @CRLF) Local $flags = 0 Local $ww, $wh, $x, $y, $w, $h $__MCP_obj = $obj $ww = 350 $wh = 500 $x = 200 $y = 150 $__MCP_GUI_hWnd = GUICreate("myColorPicker", $ww, $wh, $x, $y, $flags) $x = 10 $y = 10 $w = 150 $h = 20 GUICtrlCreateButton("Set caller's color", $x, $y, $w, $h) GUICtrlSetOnEvent(-1, "__MCP_handle_SetColor_btn") $y += $h + 5 $w = $ww - 25 $h = $wh - 100 $idListView = GUICtrlCreateListView("", $x, $y, $w, $h, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) $hListView = GUICtrlGetHandle($idListView) $x = $ww / 2 - 50 $y = $wh - 60 $w = 100 $h = 25 GUICtrlCreateButton("Quit Popup", $x, $y, $w, $h) GUICtrlSetOnEvent(-1, "__MCP_handle_QUIT_btn") GUICtrlSetFont($idListView, 8.5, -1, -1, "courier new") _GUICtrlListView_AddColumn($idListView, "Name", 100) _GUICtrlListView_AddColumn($idListView, "Value", 100) _GUICtrlListView_AddColumn($idListView, "Sample", 100) _GUICtrlListView_SetColumnWidth($idListView, 0, 100) _GUICtrlListView_SetColumnWidth($idListView, 1, 80) logmsg("+++: $idListView = " & $idListView) logmsg("+++: $hListView = 0x" & Hex($hListView)) __MCP_populateListView($hListView) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState(@SW_SHOW, $__MCP_GUI_hWnd) EndFunc ;==>_myColorPicker Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam, $ilParam Local $hWndFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $iDrawStage, $tCustDraw $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage') Switch $iDrawStage Case BitOR(0, $CDDS_ITEMPREPAINT) ;, $CDDS_SUBITEM) setItemColor($tCustDraw, $hWndFrom) Return $CDRF_NOTIFYSUBITEMDRAW EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func setItemColor($tCustDraw, $hWnd) Local $iIndex, $color, $iSubitem $iIndex = DllStructGetData($tCustDraw, 'dwItemSpec') ; item number $color = _GUICtrlListView_GetItemParam($hWnd, $iIndex) $iSubitem = DllStructGetData($tCustDraw, 'iSubItem') ; Here, I want to only change the color of the 3rd col, and not the 1st and 2nd cols DllStructSetData($tCustDraw, 'iSubItem', 2) ; always use the 3rd column (the 'sample' col) logmsg("+++: setItemColor($tCustDraw, 0x" & Hex($hWnd) & ") entered ... " _ & ", $iIndex = " & $iIndex & ", $iSubItem = " & $iSubitem & ", $color = " & Hex($color)) DllStructSetData($tCustDraw, 'clrText', $color) ; set the Text color DllStructSetData($tCustDraw, 'clrTextBk', bitnot($color)) ; set the background color EndFunc ;==>setItemColor Func logmsg($msg, $lnum = @ScriptLineNumber) ConsoleWrite("+++:" & $lnum & ": " & $msg & @CRLF) EndFunc ;==>logmsg Func __MCP_exit() GUIDelete($__MCP_GUI_hWnd) EndFunc ;==>__MCP_exit Func __MCP_handle_SetColor_btn() If (IsHWnd($__MCP_obj)) Then GUISetBkColor($COLOR_BLUE, $__MCP_obj) Else GUICtrlSetBkColor($__MCP_obj, $COLOR_BLUE) EndIf EndFunc ;==>__MCP_handle_SetColor_btn Func __MCP_populateListView($hWnd) Local $text, $parts, $iIndex Local Static $aItems[] = [ _ "BLACK | " & $CLR_BLACK & "|" & "", _ "BLUE | " & $CLR_BLUE & "|" & "", _ "RED | " & $CLR_RED & "|" & "", _ "WHITE | " & $CLR_WHITE & "|" & "", _ "YELLOW | " & $CLR_YELLOW & "|" & "" _ ] _GUICtrlListView_BeginUpdate($hWnd) _GUICtrlListView_DeleteAllItems($hWnd) For $ndx = 0 To UBound($aItems) - 1 $text = $aItems[$ndx] $parts = StringSplit($text, "|", 2) $parts[0] = StringStripWS($parts[0], 3) $parts[2] = StringStripWS($parts[2], 3) $iIndex = _GUICtrlListView_AddItem($hWnd, $parts[0], -1, $parts[1]) _GUICtrlListView_AddSubItem($hWnd, $iIndex, Hex($parts[1]), 1) _GUICtrlListView_AddSubItem($hWnd, $iIndex, $parts[0], 2) Next _GUICtrlListView_EndUpdate($hWnd) EndFunc ;==>__MCP_populateListView Func __MCP_handle_QUIT_btn() GUIDelete($__MCP_GUI_hWnd) EndFunc ;==>__MCP_handle_QUIT_btn Func handle_1stTEST_btn() _myColorPicker($hMainWin) EndFunc ;==>handle_1stTEST_btn Func handle_2ndTEST_btn() _myColorPicker(@GUI_CtrlId) EndFunc ;==>handle_2ndTEST_btn Func _test_exit() Exit EndFunc ;==>_test_exit  
    • astrionn
      By astrionn
      So I had this Idea of creating a tooltip which shows me my ping.
      That itself was made quickly and I thought too add a couple features.
      I want the tooltip background to be a different color depending on the ping. (good ping is green, medium ping is yellow,...)
      So how do I color in a tooltip? google brought me to this: 
       
      where in the comments I found this:
      $s = "LOW" ToolTip($s, 0, 0, "Battery Information");, $icon) $H_TOOLTIP1 = WinGetHandle($s) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $H_TOOLTIP1, "wstr", "", "wstr", "") DllCall("user32.dll", "int", "SendMessage", "hwnd", $H_TOOLTIP1, "int", 1043, "int", 2552550, "int", 0) Sleep(1000) Which I then used in my code with different color codes... Trial and Error brought me these that I wanted to use:
       
      The Problem is if I loop through my code it only sets the color for the 1st loop and then sticks to it.
      The real problem is tho that I don't exactly understand the dllcalls... And I guess that's why it isn't working
      So if someone would be so awesome to explain to me how they work, or at least can give me a list of these parameters then I would really appreciate that and learn something new
      Obviously a solution to my problem is awesome aswell ^^
      I run this under Windows 8.1
      There is my code in a paste.
      https://pastebin.com/q525f7mS
    • cosmos
      By cosmos
      I must be missing something but I can't seem to work out how to open the standard Windows Color dialog box?
      Basically the equivalent of InputBox but for colors (so that the user can select a color). I think there are some external UDFs for this, but are there any ways of doing it with included UDFs, standard AutoIt functions or interfacing with Windows directly?
      Usage info: I'm making a database-like program and there are Categories (which work similar to Tables), and the user will be able to select unique colors for Categories so when they display multiple Categories at once (like displaying multiple Tables with similar columns in one list ) they can easily differentiate the Categories at quick glance.
      Thanks!
    • chacoya121
      By chacoya121
      Local $count = 1 Local $x1= 100,$y1 = 100,$x2 = 110,$y2 = 110 $area = ($x2+$x1)*($y2+$y1) Local $array[$area][2] For $i = $x1 to $x2 Step 1 For $j = $y1 to $y2 Step 1 $color = PixelGetColor($i,$j) $scolor = Hex($color,6) $array[$count][2] = [$scolor,1] $position = _ArraySearch($array,$scolor,0,0,0,0,1) If $array[$position][0] = $scolor Then $array[$position][1] +=1 Else $count += 1 EndIf Next Next _ArrayDisplay($array) plz help adjust and shrink it down soo confusing playing with array
    • Miliardsto
      By Miliardsto
      Hello i have problem with function PixelGetColor. On my computer it working fine but in some cases it not working.
      And Im clicking on the active window on red color and it give me the same color still. But in other computers when clicking on the same color red it gives other values and returned color in MsgBox is not red.
      Dont know is it a real main thing what causing problem but,
      I noticed that problem was on one windows 10.
      I have windows 8 and working well. On other windows 10 works well to
      Maybe it is caused by windows aero or something like that
      How to deal with it?
      There is a code
      HotKeySet("{PAUSE}", "MouseCord") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func MouseCord() Global $MousePos = MouseGetPos() $clickedColor = PixelGetColor($MousePos[0], $MousePos[1]) MsgBox(0, "Done", $clickedColor) EndFunc