I must say that since I started this topic i am happy with AHK´s progress.
But still come back to this topic because I noticed that not only the dllCall but also the NumPut is very slow. I remembered SKAN´s code in the beginning using just one dllCcall and creating the bitmap array with NumPut. Using this code as test, I included a common slider, but soon I saw that this is a slow control. I asume it`s a API control, so nothing to do with AHK. So I created a custom control as in following code.
Only try this on a relative fast computer. On mine it takes 20 seconds to load 256 bitmaps (on my old mmx 233, 5 minutes).After loaded the colorpicker works smoothly.
Code:
#NoEnv
ATC:=A_TickCount
SetBatchLines -1
DetectHiddenWindows, On
Gui, +ToolWindow +LastFound
Gui = WinExist()
hDC:=DllCall("GetDC",UInt,Gui)
Gui, Font, s12 w200, Arial
Gui, Add, Text, x290 y261 w10 h20 gMoveIt, >
Gui, Add, Text, x320 y261 w10 h20 gMoveIt, <
Gui, Add, Text, x300 y15 w20 h256 0x120E hWndhPic
Gui, Add, Text, x20 y15 w256 h256 0x120E hWndhPic2 gSelColor
;Draw blue slider picture.
VarSetCapacity(bi,40,0),VarSetCapacity(spa,20480,0)
NumPut(40,bi,0),NumPut(20,bi,4),NumPut(256,bi,8)
NumPut(1,bi,12,"UShort"),NumPut(24,bi,14,"UShort"),NumPut(20480,bi,20)
blue := 0,offset := &spa
Loop, 256 {
blue++
Loop, 20 {
Offset := NumPut(blue , Offset +0 ) -1
}
}
hBMP2 := DllCall( "CreateDIBitmap", UInt,hDC, UInt,&bi, Int,4,UInt,&spa, UInt,&bi,UInt,0 )
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP2,, ahk_id %hPic%
;Prepare structure
W:=256
H:=256
Bit:=24
Byt:=W*H*4 ;(Bit/8)
VarSetCapacity(bmInfo,40,0)
VarSetCapacity(colorarray,Byt,0)
NumPut( 40,bmInfo,0 ) ; Size in bytes of bmInfo structure (40 bytes).
NumPut( W,bmInfo,4 )
NumPut( H,bmInfo,8 )
NumPut( 1,bmInfo,12,"UShort" ) ; The number of color planes. Always 1 in current bitmaps
NumPut( Bit,bmInfo,14,"UShort" ) ; The number of data bits of a single pixel.
NumPut( Byt,bmInfo,20 ) ; Size of bitmap
SplashTextOn , 400, 60,ColorPicker ,Please wait a few seconds...minutes??
;Creating 256 bitmaps increasing blue value
blue := 0,
Loop 256
{
red:=0,OffSet := &colorarray
Loop 256
{
red++, green:=0
Loop 256
Offset := NumPut(((red<<16)|(green++<<8)|blue) , Offset +0 ) -1
}
hBMP%blue% := DllCall( "CreateDIBitmap", UInt,hDC, UInt,&bmInfo, Int,4,UInt,&colorArray, UInt,&bmInfo,UInt,0 )
blue++
}
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP0,, ahk_id %hPic2%
SplashTextOff
Gui, Show, w340 h288, % "ColorPicker [ " (A_TickCount-ATC) "ms ]"
return
MoveIt:
xpos := 290
xpos2 := 320
loop {
GetKeyState, OutputVar, LButton
If OutPutVar = U
break
MouseGetPos, xps, ypos, id, control
ypos -= 29
If ypos > 261
ypos := 261
If ypos < 7
ypos := 7
GuiControl, Move,>,x%xpos% y%ypos%
GuiControl, Move,<,x%xpos2% y%ypos%
blue := 256 - (ypos - 6)
If blue <> %oldBlue%
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP%blue%,, ahk_id %hPic2%
oldBlue := blue
}
return
SelColor:
MouseGetPos, X, Y
PixelGetColor,Color, X, Y, RGB
Tooltip % SubStr(Color,-5)
SetTimer, TooltipOff, -2000
Return
ToolTipOff:
ToolTip
Return
GuiClose:
ExitApp
Lexicos wrote low level code creating array, but unfortunatly it doesn´t work anymore with the newest fast beta version. Anyway you could not change the blue value with it. So I made a dll to do this.
If you want to try it, you can download it at
http://www.autohotkey.net/~pil/MakeColorArray.dlland use it with slightly modified code
Code:
NoEnv
ATC:=A_TickCount
SetBatchLines -1
DetectHiddenWindows, On
Gui, +ToolWindow +LastFound
Gui = WinExist()
hDC:=DllCall("GetDC",UInt,Gui)
Gui, Font, s12 w200, Arial
Gui, Add, Text, x290 y261 w10 h20 gMoveIt, >
Gui, Add, Text, x320 y261 w10 h20 gMoveIt, <
Gui, Add, Text, x300 y15 w20 h256 0x120E hWndhPic
Gui, Add, Text, x20 y15 w256 h256 0x120E hWndhPic2 gSelColor
;Draw blue slider picture.
VarSetCapacity(bi,40,0),VarSetCapacity(spa,20480,0)
NumPut(40,bi,0),NumPut(20,bi,4),NumPut(256,bi,8)
NumPut(1,bi,12,"UShort"),NumPut(24,bi,14,"UShort"),NumPut(20480,bi,20)
blue := 0,offset := &spa
Loop, 256 {
blue++
Loop, 20 {
Offset := NumPut(blue , Offset +0 ) -1
}
}
hBMP2 := DllCall( "CreateDIBitmap", UInt,hDC, UInt,&bi, Int,4,UInt,&spa, UInt,&bi,UInt,0 )
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP2,, ahk_id %hPic%
;Prepare structure
W:=256
H:=256
Bit:=24
Byt:=W*H*4 ;(Bit/8)
VarSetCapacity(bmInfo,40,0)
VarSetCapacity(colorarray,Byt,0)
NumPut( 40,bmInfo,0 ) ; Size in bytes of bmInfo structure (40 bytes).
NumPut( W,bmInfo,4 )
NumPut( H,bmInfo,8 )
NumPut( 1,bmInfo,12,"UShort" ) ; The number of color planes. Always 1 in current bitmaps
NumPut( Bit,bmInfo,14,"UShort" ) ; The number of data bits of a single pixel.
NumPut( Byt,bmInfo,20 ) ; Size of bitmap
SplashTextOn , 400, 60,ColorPicker ,Please wait a few seconds...minutes??
;Creating 256 bitmaps increasing blue value
hModule := DllCall("LoadLibrary", "str", "MakeColorArray.dll")
blue := 0,
Loop 256
{
addressColorArray := DllCall("MakeColorArray.dll\MakeArray" ,"char", blue)
;red:=0,OffSet := &colorarray
hBMP%blue% := DllCall( "CreateDIBitmap", UInt,hDC, UInt,&bmInfo, Int,4,UInt,addressColorArray, UInt,&bmInfo,UInt,0 )
blue++
}
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP0,, ahk_id %hPic2%
SplashTextOff
Gui, Show, w340 h288, % "ColorPicker [ " (A_TickCount-ATC) "ms ]"
return
MoveIt:
xpos := 290
xpos2 := 320
loop {
GetKeyState, OutputVar, LButton
If OutPutVar = U
break
MouseGetPos, xps, ypos, id, control
ypos -= 29
If ypos > 261
ypos := 261
If ypos < 7
ypos := 7
GuiControl, Move,>,x%xpos% y%ypos%
GuiControl, Move,<,x%xpos2% y%ypos%
blue := 256 - (ypos - 6)
If blue <> %oldBlue%
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP%blue%,, ahk_id %hPic2%
oldBlue := blue
}
return
SelColor:
MouseGetPos, X, Y
PixelGetColor,Color, X, Y, RGB
Tooltip % SubStr(Color,-5)
SetTimer, TooltipOff, -2000
Return
ToolTipOff:
ToolTip
Return
GuiClose:
ExitApp
As you can see in a few seconds the bitmaps are loaded.
It is not faster because slider picture is included in total time.
PS any one an idea about how to get rid of flickering?
Noel