Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Gui Picture Change (GuiControl vs. Gui, Add, Pic)


  • Please log in to reply
10 replies to this topic
Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

When changing pictures with GuiControl, there is a noticeable flicker between changes.  If I use Gui, Add, Pic, this flicker disappears.  I do not want this flicker between changes.

 

The following code below changes pictures without the flicker... HOWEVER, the intended pic is not the correct one (one pic behind based on the dropdownlist).  How could I adjust the below code so that the pic appears with the correct dropdown choice?

 

Gui, Add, Pic, x20 y200 vpic_get, C:\s1.png
Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w400 h400
return

Choicer:
Gui, Submit, nohide
if ColorChoice = A
    Gui, Add, Pic, x20 y200, C:\s1.png
if ColorChoice = B
    Gui, Add, Pic, x20 y200, C:\s2.png
if ColorChoice = c
    Gui, Add, Pic, x20 y200, C:\s3.png
Gui, Submit, nohide
return
 

 

 

Here is my intended result... but the image change has a flicker due to using GuiControl

 

Gui, Add, Pic, x20 y200 vpic_get, C:\s1.png
Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w400 h400
return

Choicer:
Gui, Submit, nohide
if ColorChoice = A
    GuiControl,, pic_get, C:\s1.png
if ColorChoice = B
    GuiControl,, pic_get, C:\s2.png
if ColorChoice = c
    GuiControl,, pic_get, C:\s3.png
return
 

 

 

If there are any other ideas to change the pic... eg. fading options between pics, I would be interested.



Sjc1000
  • Members
  • 572 posts
  • Last active: Mar 11 2017 11:41 AM
  • Joined: 06 Feb 2012

Hi Xx7,

 

You can use this little trick to pretty much eliminate the flicker ( unless you click fast ).

 

 

 

Pic1        := "S:\2013-02-10_14.07.33.png"
Pic2        := "S:\2013-02-10_14.10.57.png"




Gui, Add,         Picture, w200 h200 gClick vPicture, %Pic1%
Gui, Show,
return




Click:
    GuiControl, -Redraw,     Picture
    GuiControl,,             Picture, %Pic2%
    GuiControl, +Redraw,    Picture
    
    KeyWait, LButton, Up
    
    GuiControl, -Redraw,     Picture
    GuiControl,,             Picture, %Pic1%
    GuiControl, +Redraw,    Picture
Return
 

 

Thanks to FrostByte, he showed me this trick..

 

EDIT: You can also make the GUI black, it will still flicker but it wont hurt your eyes when it happens..


Sjc1000 - Insert inspirational quote here!

PLEASE find me on the IRC if you have questions. I'm never on the forum anymore.

 


Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009

The problem is that you can't control when the screen is refreshed,  

and adding of changing an image takes a relatively long period of time.

 

Btw, how big are your images ??

 

I'm not sure of this idea, but why not try adding a "sleep, 20" at the beginning and end of "Choicer:"

This added sleep might allow for needed screen refresh.

 

 

An alternate method that >might< reduce flicker is to use hide/show on the images.

 

I gave an example of using 2 images here, you might want to try it out

http://www.autohotke...st/#entry454668

 

 

In the case where you need 3 or more images I think there needs to be some pre-planning.

 

Say your images were 1,2,3 and they were all placed in the same location with 1 on top then 2 and 3

 

If all the images were hidden, you would see the background of the gui.

If all the images were visible, you would see whichever one was "on top" i.e. 1

If you hide 1 then 2 is visible.    If you then hide 2, image 3 would be visible.

 

If you go back to 1, then you only need to show 1.

But after 1, if you then need to see 2, then you must show 2 and then hide 1.

 

I haven't though a whole lot beyond the above steps, but at the small rate

 

 



Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011
The images are small... about 10kb each.  I tried the example in the link, but there was still some flicker.
 
Maybe if I play around with the layering below, it could be useful.  Is there anyway to FADE them in and out at the same time?

 

folder_a := "C:\test"
Gui, Add, Pic, x20 y200 vpic_get1, %folder_a%\s1.png
Gui, Add, Pic, x20 y200 vpic_get2, %folder_a%\s2.png
Gui, Add, Pic, x20 y200 vpic_get3, %folder_a%\s3.png
Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w400 h400
return

Choicer:
Sleep, 20
Gui, Submit, nohide

if ColorChoice = A
{
    GuiControl, Show, pic_get1
    GuiControl, Hide, pic_get2
    GuiControl, Hide, pic_get3
}
if ColorChoice = B
{
    GuiControl, Show, pic_get2
    GuiControl, Hide, pic_get1
    GuiControl, Hide, pic_get3
}
if ColorChoice = c
{
    GuiControl, Show, pic_get3
    GuiControl, Hide, pic_get1
    GuiControl, Hide, pic_get2
}
Sleep, 20
return
 

 



Jackie Sztuk _Blackholyman
  • Spam Officer
  • 3757 posts
  • Last active: Apr 03 2016 08:47 PM
  • Joined: 28 Feb 2012
Trie out the gdi+ lib http://www.autohotke...ary-145-by-tic/

example:
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

; Start gdi+
If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

folder_a := "C:\test"
Gui, 2: Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, 2: Show, w400 h400
gosub, choicer
return



Choicer:
Sleep, 20

GuiControlGet, ColorChoice, 2:, ColorChoice

if ColorChoice = A
{
pBitmap := Gdip_CreateBitmapFromFile(folder_a . "\s1.png")
}
if ColorChoice = B
{
pBitmap := Gdip_CreateBitmapFromFile(folder_a . "\s2.png")
}
if ColorChoice = c
{
pBitmap := Gdip_CreateBitmapFromFile(folder_a . "\s3.png")
}

; Check to ensure we actually got a bitmap from the file, in case the file was corrupt or some other error occured
If !pBitmap
{
	MsgBox, 48, File loading error!, Could not load the image specified
	ExitApp
}

; Get the width and height of the bitmap we have just created from the file
; This will be the dimensions that the file is
Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
; We are creating this "canvas" at half the size of the actual image
; We are halving it because we want the image to show in a gui on the screen at half its dimensions
hbm := CreateDIBSection(Width//2, Height//2)

; Get a device context compatible with the screen
hdc := CreateCompatibleDC()

; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)

; We do not need SmoothingMode as we did in previous examples for drawing an image
; Instead we must set InterpolationMode. This specifies how a file will be resized (the quality of the resize)
; Interpolation mode has been set to HighQualityBicubic = 7
Gdip_SetInterpolationMode(G, 7)

; DrawImage will draw the bitmap we took from the file into the graphics of the bitmap we created
; We are wanting to draw the entire image, but at half its size
; Coordinates are therefore taken from (0,0) of the source bitmap and also into the destination bitmap
; The source height and width are specified, and also the destination width and height (half the original)
; Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh, Matrix)
; d is for destination and s is for source. We will not talk about the matrix yet (this is for changing colours when drawing)
Gdip_DrawImage(G, pBitmap, 0, 0, Width//2, Height//2, 0, 0, Width, Height)

; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier (half of the original image)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width//2, Height//2)


; Select the object back into the hdc
SelectObject(hdc, obm)

; Now the bitmap may be deleted
DeleteObject(hbm)

; Also the device context related to the bitmap may be deleted
DeleteDC(hdc)

; The graphics may now be deleted
Gdip_DeleteGraphics(G)

; The bitmap we made from the image may be deleted
Gdip_DisposeImage(pBitmap)
Return

;#######################################################################

Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return
Hope it helps
Helping%20you%20learn%20autohotkey.jpg?d

[AHK] Version. 1.1+ [CLOUD] DropBox ; Copy [WEBSITE] Blog ; About

Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

Thanks for examples!  For Gdip, how could put the layered window ontop of the regular GUI so that they move in unison? 

 

 

The below works well, however, I have 1000's of pics and then it appears that I'll have to create a variable for each pic?  Are there any drawbacks to including MANY pics in a gui?

folder_a := "C:\test"
Gui, Add, Pic, x20 y200 vpic_get3, %folder_a%\s3.png
Gui, Add, Pic, x20 y200 vpic_get2, %folder_a%\s2.png
Gui, Add, Pic, x20 y200 vpic_get1, %folder_a%\s1.png
Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w400 h400
return

Choicer:
Gui, Submit, nohide
if ColorChoice = A
    GuiControl, +Redraw, pic_get1
if ColorChoice = B
    GuiControl, +Redraw, pic_get2
if ColorChoice = c
    GuiControl, +Redraw, pic_get3
return
 


Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

Ok, this looks pretty good so far...

folder_a := "C:\test"

var_num := 1
Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w400 h400
return


Choicer:
Gui, Submit, nohide
if ColorChoice = A
{
    Gui, Add, Pic, x20 y200 vpic_get%var_num%, %folder_a%\s1.png
    GuiControl, -Redraw, pic_get%var_num%
}
if ColorChoice = B
{
    Gui, Add, Pic, x20 y200 vpic_get%var_num%, %folder_a%\s2.png
    GuiControl, -Redraw, pic_get%var_num%
}
if ColorChoice = C
{
    Gui, Add, Pic, x20 y200 vpic_get%var_num%, %folder_a%\s3.png
    GuiControl, -redraw, pic_get%var_num%
}
var_num++
return


Linear Spoon
  • Members
  • 842 posts
  • Last active: Sep 29 2015 03:56 AM
  • Joined: 29 Oct 2011

Is it your intention to create overlapped picture controls? Gui, add is actually creating new controls, not replacing the existing one. That's why you have the GuiControl command to change it.

 

Run this code and watch your memory usage in task manager shoot up, it's called a memory leak.

Loop,
 Gui, Add, picture, vpic%A_Index%, mypicture.png   ;This picture has to exist for the leak to be obvious

Join us at the new forum - http://www.ahkscript.org/

 


Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

No definitely not my intention to overlap.  Just want a smooth transistion. :)



Linear Spoon
  • Members
  • 842 posts
  • Last active: Sep 29 2015 03:56 AM
  • Joined: 29 Oct 2011

Also, if you don't want to use layered windows with gdip.ahk, you can also make it work with picture controls. 

 

I don't think there's a way to 'fade in' the image without a lot of work. For me this code changes images with almost no 'flash' between images. (but then again so does GuiControl)

#include gdip.ahk
folder_a := "C:\test"

;Start up gdip
pToken := Gdip_Startup()

;+0xE is necessary for setimage
;If you set an explicit size for the control (ex w100 h100),
;you can use +0x40 to fit the image to the control
Gui, Add, Pic, x20 y200 hwndhpControl +0xE 

Gui, Add, DropDownList, x40 y150 w170 vColorChoice gChoicer, A||B|C
Gui, Show, w300 h300

;To shutdown gdip before the program closes
OnExit, exit
return


exit:
  Gdip_Shutdown(pToken)
  Exitapp
return

Choicer:
Gui, Submit, nohide

;Perhaps you have a different naming scheme, this was the format of my images
pBitmap := Gdip_CreateBitmapFromFile(folder_a "\" ColorChoice ".png")

;SetImage won't take pBitmap
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)

;hpControl is the hwnd of the picture control, hBitmap is the image from the disk
;This is what actually puts the image into the picture control.
SetImage(hpControl, hBitmap)

;Free memory
DeleteObject(hBitmap)
Gdip_DisposeImage(pBitmap)
return

Join us at the new forum - http://www.ahkscript.org/

 


Xx7
  • Members
  • 674 posts
  • Last active: Mar 24 2015 10:48 PM
  • Joined: 19 Apr 2011

Thanks Linear Spoon, that works great!