AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

is a glowing gui even possible?

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
butterflysix
Guest





PostPosted: Thu May 08, 2008 7:59 am    Post subject: is a glowing gui even possible? Reply with quote

Hello, can a GUI, 200x200 be made to flow & glow between 4 colors smoothly, with a speed control in a loop?? I know this sounds strange, but I am wanting to use this for an effect and think this might be snazzy, but have no clue how to run this. Could someone help please?
Back to top
Z Gecko
Guest





PostPosted: Thu May 08, 2008 3:59 pm    Post subject: Reply with quote

I am not shure what "glow and flow" actually is,
but a gui can change its color:
Code:
Gui, Show, w200 h200, Fader
SetFormat, integer, hex
loop, 1000
{
   Var += 16
   Gui, Color, %Var%
   sleep, 100
}


only the hex-math is a little bit tricky,
youīll see, the demo shader is rather crappy.
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 6084

PostPosted: Thu May 08, 2008 4:30 pm    Post subject: Reply with quote

I got curious and wanted to try.
The following changes colors as BLACK > BLUE > CYAN > WHITE > YELLOW > RED

Code:
Gui -Caption +Border +AlwaysOnTop
Gui, Show, w200 h200
VarSetCapacity( CLR, 4,0 )
 
Loop
  {
       ; Incrementing COLORREF
       
       pos := 0, ctr := 0
       Loop  % 256 * 3
        {
          ctr += 1
          if ctr > 255
             ctr := 0, pos += 1
          NumPut( ctr, CLR, pos, "UChar" )
          Gui, Color, % Color( NumGet( CLR ) )
          Sleep, 1
        } 

       ; Decrementing COLORREF
       
       pos := 0, ctr := 255
       Loop  % 256 * 3
        {
          ctr -= 1
          if ctr < 0
             ctr := 255, pos += 1
          NumPut( ctr, CLR, pos, "UChar" )
          Gui, Color, % Color( NumGet( CLR ) )
          Sleep, 1
        }
  }


Return                                      ;  // end of auto-execute section //

Color( i )
{
  setformat, integer, hex
  i += 0x1000000
  setformat, integer, decimal
  return substr( i, 0-5 )
}   


Please try to improvise it on your own.

Smile
Back to top
View user's profile Send private message
Z Gecko
Guest





PostPosted: Thu May 08, 2008 5:36 pm    Post subject: Reply with quote

very cool, SKAN!

i am still trying to understand what you exactly did.
especially the math in the Color-function is confusing me.
could you comment it a bit, especially the part where you do
i += 0x1000000 and substr( i, 0-5 ) ?
Back to top
butterflysix
Guest





PostPosted: Thu May 08, 2008 5:38 pm    Post subject: Reply with quote

Hey there SKAN.... I can only say Bravo!!! (insert loud clapping here). That is so extremely cool and smooth. May I please ask, .... , how did you got the colors? I cannot understand that Color( i ) sub-function. Do you have a exact procedure you can let me know to somehow insert fixed color patterns, like Olive, Red, Green to Orange --- for example? Smile :Smile
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 6084

PostPosted: Thu May 08, 2008 6:36 pm    Post subject: Reply with quote

Z Gecko wrote:
very cool, SKAN!

i am still trying to understand what you exactly did.
especially the math in the Color-function is confusing me.
could you comment it a bit, especially the part where you do
i += 0x1000000 and substr( i, 0-5 ) ?


It was a technique introduced by Laszlo in this post : GetSysColor()

Case:

Colorref for BlueGreen ( Cyan ) is 65535
if we convert it to hex we get 0xffff ( leading two zeroes missing ) and to format it to 00FFFF :-

Code:
BlueGreen := 65535 ; 0x00FFFF

SetFormat, Integer, Hex
BlueGreen += 0
MsgBox, % BlueGreen    ; will be 0xffff whereas we need 0x00FFFF

BlueGreen += 0x1000000 ; one followed by six zeroes
MsgBox, % BlueGreen    ; will be 0x100FFFF

BlueGreen := SubStr( BlueGreen, -5 ) ; retrieve the last six chars - that is - ignore the leading 0x1
StringUpper, BlueGreen, BlueGreen    ; convert to upper case
MsgBox, % BlueGreen    ; will be 00FFFF

SetFormat, Integer, Decimal


Re: SubStr()

To retrieve a number of ending characters from a string we can pass a negative number - for example if we need to retrieve the last 2 chars from "Zippo()" : SubStr( "Zippo()", -1 )

Quote:
substr( i, 0-5 )


0-5 is overdone. It should be just -5 Embarassed
Bad adaptation from this post:



Smile
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 6084

PostPosted: Thu May 08, 2008 6:45 pm    Post subject: Reply with quote

butterflysix wrote:
Do you have a exact procedure you can let me know to somehow insert fixed color patterns, like Olive, Red, Green to Orange --- for example? Smile :Smile


I am poor in maths Embarassed

here is a slightly different version that shows the colorref in the GUI so you can see how the rotation is done:

Code:
Gui -Caption +Border +AlwaysOnTop
Gui, Font, S10, Courier New
Gui, Add, Text, w60 h20 +Border 0x6
Gui, Add, Text, xp yp w60 h20 vColor +0x201 +BackgroundTrans
Gui, Show, w200 h200

VarSetCapacity( CLR, 4,0 )
 
Loop
  {
       ; Incrementing COLORREF
       
       pos := 0, ctr := 0
       Loop  % 256 * 3
        {
          ctr += 1
          if ctr > 255
             ctr := 0, pos += 1
          NumPut( ctr, CLR, pos, "UChar" )
          Color := Color( NumGet( CLR ) )
          GuiControl,, Color, %Color%
          Gui, Color, % Color
          Sleep, 10
        } 

       ; Decrementing COLORREF
       
       pos := 0, ctr := 255
       Loop  % 256 * 3
        {
          ctr -= 1
          if ctr < 0
             ctr := 255, pos += 1
          NumPut( ctr, CLR, pos, "UChar" )
          Color := Color( NumGet( CLR ) )
          GuiControl,, Color, %Color%
          Gui, Color, % Color
          Sleep, 10
        }
  }


Return                                      ;  // end of auto-execute section //

Color( i )
{
  setformat, integer, hex
  i += 0x1000000
  setformat, integer, decimal
  return DllCall( "CharUpperA", Str,substr( i, -5 ), Str )
}



I can explain about colorref / numput() / numget() if you want so that you can do it yourself.

Smile
Back to top
View user's profile Send private message
Z Gecko
Guest





PostPosted: Thu May 08, 2008 7:27 pm    Post subject: Reply with quote

thank you, SKAN!
i understand now much better what you did.
I didnīt realize that a negative StartingPos will make SubStr take the chars from the right-side.

btw: i found out that Gui, Color will work without the leading zeros, too.
Code:
Gui, Color, E4
Gui, Show, w100 h100 x100 y100
Gui, 2: Color, 0000E4
Gui, 2: Show, w100 h100 x200 y200
Back to top
butterflysix
Guest





PostPosted: Thu May 08, 2008 7:40 pm    Post subject: Reply with quote

SKAN, that would be so cool & awesome. Thank you for your time. If you can give me a basis for comparison, I think I can figure out how to do what I was seeking. I surmise from what you suggest this will not be so easy, but I am 100% up for the challenge! Smile What do I need to look at or think about with the colorref, + those two functions numput() / numget()? Smile So, I mean, if I wanted to start with RED @ FF0000 and then lets say cycle to YELLOW @ FFF600... maybe if you explain the math or what I need to think about to accomplish that within the Color ( ) function.... Any help would be greatly appreciated & thank you in advance! Have very good day.


If anyone else has any pointers that would be sweet
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 6084

PostPosted: Thu May 08, 2008 7:55 pm    Post subject: Reply with quote

Z Gecko wrote:
btw: i found out that Gui, Color will work without the leading zeros, too.


Sure! .. and I was aware of that.
I was using a tooltip to see whether the code was rotating the colorref properly and so I needed a properly formatted hex. Wink

@butterflysix: be informed that with bitshifting, you can have more compact code.. but NumGet/NumPut is more convenient to understand.

Allow me sometime and I will post a short tut.

Smile
Back to top
View user's profile Send private message
butterflysix
Guest





PostPosted: Thu May 08, 2008 7:58 pm    Post subject: Reply with quote

thank you skan, that is awesome for you to help me with this, i appreciate it Smile
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 6084

PostPosted: Thu May 08, 2008 11:23 pm    Post subject: Reply with quote

Abusing NumGet() and Numput() to alter ASCII value of memory bytes

Intro: In most of the programming languages, you have to declare the data type while creating a variable whereas in AHK there is only one type of data it handle by default: null terminated strings
With introduction of DllCall(), structure handling became difficult and so NumGet() and NumPut() were introduced to read/write - from/to memory.

This topic is outdated after introduction of NumGet() / NumPut(), but most of the examples would still work: How to manipulate Binary data with Pointers ?

A single byte of memory can contain only the 256 ASCII values from 0 through 255. Refer wikipedia for the chart : http://en.wikipedia.org/wiki/ASCII

So, when we initialise a variable, like: Var := "SKAN"
AHK creates Var, which uses 5 bytes and stores these ascii values: 83,75,65,78,0

The first byte ( Byte 1 ) of a variable would be referred in NumGet() / NumPut() as OffSet 0

83 is ASCII value of "S" and is stored at offset 0 of Var
75 is ASCII value of "K" and is stored at offset 1 of Var
65 is ASCII value of "A" and is stored at offset 2 of Var
78 is ASCII value of "N" and is stored at offset 3 of Var
0 is ASCII value "Null" and is stored at offset 4 of Var and let knows AHK's string commands to stop reading ahead.

In other words, if not for null, AHK string commands would never know where to stop.

NumGet() and NumPut()

Quote:
NumGet(VarOrAddress [, Offset = 0, Type = "UInt"]) [v1.0.47+]: Returns the binary number stored at the specified address+offset. For VarOrAddress, passing MyVar is equivalent to passing &MyVar. However, omitting the "&" performs better and ensures that the target address is valid (invalid addresses return ""). By contrast, anything other than a naked variable passed to VarOrAddress is treated as a raw address; consequently, specifying MyVar+0 forces the number in MyVar to be used instead of the address of MyVar itself. For Type, specify UInt, Int, Int64, Short, UShort, Char, UChar, Double, or Float (though unlike DllCall, these must be enclosed in quotes when used as literal strings); for details see DllCall Types.

NumPut(Number, VarOrAddress [, Offset = 0, Type = "UInt"]) [v1.0.47+]: Stores Number in binary format at the specified address+offset and returns the address to the right of the item just written. For VarOrAddress, passing MyVar is equivalent to passing &MyVar. However, omitting the "&" performs better and ensures that the target address is valid (invalid addresses return ""). By contrast, anything other than a naked variable passed to VarOrAddress is treated as a raw address; consequently, specifying MyVar+0 forces the number in MyVar to be used instead of the address of MyVar itself. For Type, specify UInt, Int, Int64, Short, UShort, Char, UChar, Double, or Float (though unlike DllCall, these must be enclosed in quotes when used as literal strings); for details see DllCall Types. If an integer is too large to fit in the specified Type, its most significant bytes are ignored; e.g. NumPut(257, var, 0, "Char") would store the number 1.


To reduce complexity, let me avoid explaining how this NumGet/NumPut stuff works and just say that we can read the binary values as follows:

To Read/Write 1 byte of memory we pass "UChar" as a parameter
To Read/Write 2 bytes of memory we pass "UShort" as a parameter
To Read/Write 4 bytes of memory we pass "UInt" as a parameter

COLORREF

One byte of data is 8 bits and a COLORREF is 32 bit and would occupy 4 bytes when NumPut() into a variable.

AHK uses RGB color containing three components Red, Green and Blue
Each component will contain a value between 0 - 255. We have already seen that 1 byte of memory can hold only a value between 0 through 255 and so a RGB color can contain :

The minimum color value of 0x0x0 = 0 ( 0x000000 )
and maximum color value of (256x256x256)-1 = 16777215 ( 0xFFFFFF )

Okay, Lets experiment by creating a variable:

Code:
; TASK: Create a 4 byte variable containing the string "SKAN"

; Method 1

Var1 := "SKAN"
MsgBox,0,Method 1,% Var1 "`n`nUInt:" NumGet( Var1, 0, "UInt" )   ; will be 1312901971

; Method 2

VarSetCapacity( Var2, 4 )             ; create an empty variable sized 4 bytes
NumPut( 1312901971, Var2, 0, "UInt" ) ; Put UInt 1312901971 to Var2
VarSetCapacity( Var2, -1 )            ; reset the var size 

MsgBox,0,Method 2, % Var2             ; Presto! Var2 is "SKAN"


; Method 3

; Refer wikipedia ASCII : http://en.wikipedia.org/wiki/ASCII
Var3 := Chr(83) . Chr(75) . Chr(65) . Chr(78)
MsgBox,0,Method 3, % Var3


; Method 4

VarSetCapacity( Var4, 5, 0 )          ; create an empty variable sized 4 bytes
NumPut( 83, Var4, 0, "UChar" )        ; Put ASCII 83 in Var4 @ offset 0 AKA Byte 1
NumPut( 75, Var4, 1, "UChar" )        ; Put ASCII 75 in Var4 @ offset 1 AKA Byte 2
NumPut( 65, Var4, 2, "UChar" )        ; Put ASCII 65 in Var4 @ offset 2 AKA Byte 3
NumPut( 78, Var4, 3, "UChar" )        ; Put ASCII 78 in Var4 @ offset 3 AKA Byte 4
VarSetCapacity( Var4, -1 )            ; reset the var size 

MsgBox,0,Method 4, % Var4


In the above example we see the usage of Chr() function to convert an ASCII value to a Character. To do the opposite, that is, to convert a Character to its respective ASCII value we can use Asc() function.

Code:
MsgBox, % Asc( "A" )
MsgBox, % Chr( 65 )
MsgBox, % Asc( Chr( 65 ) )


Here is how we can use NumGet() and Numput() to alter a byte of data directly in memory variable:

Code:
Var := "SKAN"

NumPut( Asc("I"), Var, 2, "UChar" ) ; Put "I" @ offset 2 ( AKA byte 3 ) of Var
VarSetCapacity( Var, -1 )           ; Reset Var

MsgBox, % Var                       ; will show "SKIN"


Lets try incrementing characters with a 10 byte variable :

Code:
Gui, Font, S24 , Courier New
Gui, Add, Text, w330 h50 vName +0x1201, ??????????
Gui, Show,, Character Incrementation with Numget() / NumPut()

Target := "AUTOHOTKEY"
StringSplit, T, Target

Loop
 {
   Ctr += 1
   If ( Ctr > StrLen( Target ) )
      Break
 
   Loop
    {
      GuiControlGet, Name
      Asc := NumGet( Name, Ctr-1, "UChar" )
      If ( Asc < Asc(T%Ctr%) )
        {
         NumPut( Asc+1, Name, Ctr-1, "UChar" )
         VarSetCapacity( Name, -1 )
         GuiControl,, Name, %Name%
        }
      Else
         Break
      Sleep 40
    }


Return


butterflysiz wrote:
start with RED @ FF0000 and then lets say cycle to YELLOW @ FFF600


When we NumPut( 0xFF0000, CLR, 0, "UInt" )
CLR would contain these 4 ASCII values: 0,0,255,0
We can ignore the last byte as we are dealing with only the first three bytes which represents the components Blue, Green and Red.
We have to specifically increment the Green component which is at Offset 1 ( Byte 2 ) until it reaches 0xF6 ( decimal is 246 )

It can be done as follows:

Code:
VarSetCapacity( CLR, 4, 0 )
NumPut( 0xFF0000, CLR, 0, "UInt" )


MsgBox,0, RGB Value
      ,    % NumGet( CLR, 2, "UChar" )
      . ","  NumGet( CLR, 1, "UChar" )
      . ","  NumGet( CLR, 0, "UChar" )

; The above will show :  255,0,0

Green := 0xF6 + 0 ; add zero to convert it into decimal

MsgBox,0, 0xF6, The green component should be: %Green%

Gui, Color, % Color( NumGet( CLR, 0, "UInt" ) )
Gui -Caption +Border +AlwaysOnTop
Gui, Show, w200 h200

Loop {
      Target := NumGet( CLR, 1, "UChar" )     ; Offset 1 ( Byte 2 ) is Green value
      If ( Target >= Green )                  ; Target attained
         Break                                ; .. so break the loop
      else
         {
           Target += 1                        ; increment Target by 1
           NumPut( Target, CLR, 1, "UChar" )  ; Put Target value @ Offset 1 ( Byte 2 ) 
           Gui, Color, % Color( NumGet( CLR, 0, "UInt" ) )
           Sleep 10           
         }
     } 

Color( i )
{
  setformat, integer, hex
  i += 0x1000000
  setformat, integer, decimal
  return DllCall( "CharUpperA", Str,substr( i, -5 ), Str )


I hope you can handle your requirement by self..

Regards, Smile

Smile


Last edited by SKAN on Fri May 09, 2008 8:57 am; edited 1 time in total
Back to top
View user's profile Send private message
Z Gecko
Guest





PostPosted: Fri May 09, 2008 4:35 am    Post subject: Reply with quote

Wow, a full tutorial,
god explanation and very cool examples Idea ,
thank you again, SKAN!

with my new knowledge, it was easy to make a
color-changer, that transforms any given color in any other given color.
But itīs still not the smothest way Sad
Code:
startcolor = 0x008000 ;Green
targetcolor = 0x0000FF ;Blue

Gui, Color, %startcolor%
Gui, Add, Text, x10 w70 h20 +Border, %startcolor%
Gui, Add, Text, x+5 vcurrcolor w70 h20 +Border, %startcolor%
Gui, Add, Text, x+5 w70 h20 +Border, %targetcolor%
Gui, Show, w240 h240
loop
{
   startcolor := transformcolor(startcolor, targetcolor)
   Gui, Color, %startcolor%
   GuiControl, , currcolor, %startcolor%
   sleep, 50
   if (startcolor = targetcolor)
      break
}
return



transformcolor( startcolor, targetcolor)
{
   VarSetCapacity( SCLR, 4, 0 )
   VarSetCapacity( TCLR, 4, 0 )
   NumPut( startcolor, SCLR, 0, "UInt" )
   NumPut( targetcolor, TCLR, 0, "UInt" )
   R_color := NumGet( SCLR, 2, "UChar" )
    G_color := NumGet( SCLR, 1, "UChar" )
    B_color := NumGet( SCLR, 0, "UChar" )
   R_target := NumGet( TCLR, 2, "UChar" )
    G_target := NumGet( TCLR, 1, "UChar" )
    B_target := NumGet( TCLR, 0, "UChar" )
    if ( R_color < R_target )
       R_color += 1
    if ( R_color > R_target )
       R_color -= 1
    if ( G_color < G_target )
       G_color += 1
    if ( G_color > G_target )
       G_color -= 1
    if ( B_color < B_target )
       B_color += 1
    if ( B_color > B_target )
       B_color -= 1
    NumPut( R_color, SCLR, 2, "UChar" )
    NumPut( G_color, SCLR, 1, "UChar" )
    NumPut( B_color, SCLR, 0, "UChar" )
    newcolor := "0x" . Color( NumGet( SCLR, 0, "UInt" ) )
    return newcolor
}

Color( i )
{
  setformat, integer, hex
  i += 0x1000000
  setformat, integer, decimal
  return DllCall( "CharUpperA", Str,substr( i, -5 ), Str )
Back to top
butterflysix
Guest





PostPosted: Fri May 09, 2008 1:44 pm    Post subject: Reply with quote

Hey thanks Z GECKO that is brilliant, and much appreciative for the tutorial as well SKAN! It was a very good read.

Have a nice weekend~ Very Happy
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group