Picture swapping in GUI Problem: just working once

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Picture swapping in GUI Problem: just working once

Post by Spitzi » 10 Aug 2022, 15:23

I have a gui with multiple images, all the same size, an they are shown in a specific (alphabetical) order, since every image name is 01-somePicName.png, 02-somePicName.png. Now I would like to be able to swap two images in the gui by dragging from one to the other. The code then swaps the two images, but not by swapping the names of the files, but by swapping the index number (01, 02 etc) of those files. I need to do that because there is some more important information in the name of the picture, and that information has to stick with the picture... not sure if I am making myself clear here.

Anyway, I have the following code, which almost works:

Code: Select all

#SingleInstance Force

Gui, PopMenu:Add, Button, , some other gui element
Gui, PopMenu:Add, Picture, w100 h100 gImageClick vPicNumber_01, 01-exampleWithSomeMoreInfoWrittenInTheFileName.PNG
Gui, PopMenu:Add, Picture, w100 h100 gImageClick vPicNumber_02, 02-exampleWithSomeOtherMoreInfoWrittenInTheFileName.PNG
Gui, PopMenu:Add, Picture, w100 h100 gImageClick vPicNumber_03, 03-exampleWithSomeOtheAndEvenMoreInfoWrittenInTheFileName.PNG
Gui, PopMenu:Show, AutoSize
return

ImageClick() {

	clickedImageVarName := A_GuiControl																		; e.g. "PicNumber_04"
	MouseGetPos, , , ,clickedImageClassNN																	; the ClassNN of the Control, over which the mous is hovering
	GuiControlGet, clickedImagePath, PopMenu: , %clickedImageClassNN%										; get clickedImagePath 
	; MsgBox, clickedImage:%clickedImagePath%
	
	while (GetKeyState("LButton")) {																		; while LButton pressed
		ToolTip, Bild auf anderes Bild ziehen`, um zu vertauschen
	}
	ToolTip																									; delete tooltip again
	MouseGetPos, , , ,draggedToImageClassNN																	; the ClassNN of the Control, over which the mous is hovering now
	GuiControlGet, draggedToImageVarName, PopMenu:Name , %draggedToImageClassNN%							; the variable name of this control "PicNumberXY"
	if (Substr(draggedToImageVarName,1, 9) == "PicNumber")	{												; if it is a picture
		
		GuiControlGet, draggedToImagePath, PopMenu:, %draggedToImageClassNN%								; get draggedToImagePath
		msgBox % draggedToImagePath
		if (clickedImagePath != draggedToImagePath) {
			
			SplitPath, clickedImagePath, clickedImageName, clickedImageDir
			SplitPath, draggedToImagePath, draggedToImageName, draggedToImageDir
			clickedImageNumber := SubStr(clickedImageName, 1, 2)
			draggedToImageNumber := SubStr(draggedToImageName, 1, 2)
			newClickedImagePath :=  draggedToImageNumber . SubStr(clickedImageName, 3)
			newDraggedToImagePath := clickedImageNumber . SubStr(draggedToImageName, 3)
			
			FileMove, %clickedImagePath%, %newClickedImagePath%
			FileMove, %draggedToImagePath%, %newDraggedToImagePath%
		
			GuiControl, PopMenu:, %clickedImageVarName%, %newDraggedToImagePath%
			GuiControl, PopMenu:, %draggedToImageVarName%, %newClickedImagePath%
			

		}
	}
}


Esc:: ; Exit
GuiClose:
ExitApp
The first time the images on the gui get swapped, the filenames are updated, everything is cool. But when I drag/drop a second time, it does not work. Seems like the GuiControl command does update the image in the gui but not the value of that picture gui (which is the new path). Any help very appreciated.

Simon

User avatar
Xtra
Posts: 2744
Joined: 02 Oct 2015, 12:15

Re: Picture swapping in GUI Problem: just working once

Post by Xtra » 13 Aug 2022, 01:45

Use: FileExist() before using FileMove
ErrorLevel is set to the number of files that could not be moved due to an error, or 0 otherwise. However, if the source file is a single file (no wildcards) and it does not exist, ErrorLevel is set to 0. To detect this condition, use FileExist() or IfExist on the source file prior to moving it.
Then check ErrorLevel for filemove.

Code: Select all

FileMove, Source, Dest
if (ErrorLevel) {
    VarSetCapacity(Msg, A_PtrSize=8 ? 1024 : 512)
    DllCall("FormatMessage" . (A_IsUnicode ? "W" : "A"), "UInt", 0x00001000, "Ptr", 0, "UInt", Format("{:#x}",A_LastError), "UInt", 0x800, "Ptr", &Msg, "UInt", S, "str", "")
    MsgBox, 4112, FileMove Error, % Clipboard := StrGet(&Msg)
}
If no ErrorLevel issues then check all variable contents.
Show them all in a tooltip, write them to a file etc.
Run script until it does not work and see what the var contents are.
Debug until its working the way it's intended.

just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Picture swapping in GUI Problem: just working once

Post by just me » 13 Aug 2022, 04:23

Code: Select all

	GuiControlGet, clickedImagePath, PopMenu: , %clickedImageClassNN%										; get clickedImagePath
GuiControlGet, (Blank):

Picture: Retrieves the picture's file name as it was originally specified when the control was created. This name does not change even if a new picture file name is specified.

Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Re: Picture swapping in GUI Problem: just working once

Post by Spitzi » 15 Aug 2022, 02:53

Thanks @just me.

They say it's all in the documentation, and... it is! Thank you for pointing that out to me. This means I can't swap the pictures this way, that's a shame. My workaround so far was to recreate the gui from scratch every time an image is swapped. Which works, but with a flickering gui, which is not so nice. Any suggestion how to implement it without flickering?

Greets Simon

just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Picture swapping in GUI Problem: just working once

Post by just me » 15 Aug 2022, 03:20

Moin @Spitzi,

for example, you can try to use an array to maintain the relationships:

Code: Select all

#NoEnv
#SingleInstance Force
Pics =
(
01-exampleWithSomeMoreInfoWrittenInTheFileName.PNG
02-exampleWithSomeOtherMoreInfoWrittenInTheFileName.PNG
03-exampleWithSomeOtheAndEvenMoreInfoWrittenInTheFileName.PNG
)
PicArray := StrSplit(Pics, "`n")

Gui, PopMenu:Add, Button, , some other gui element
Gui, PopMenu:Add, Text, w400 h100 gImageClick vPicNumber_1, % PicArray[1]
Gui, PopMenu:Add, Text, w400 h100 gImageClick vPicNumber_2, % PicArray[2]
Gui, PopMenu:Add, Text, w400 h100 gImageClick vPicNumber_3, % PicArray[3]
Gui, PopMenu:Show, AutoSize
Return

PopMenuGuiEscape:
PopMenuGuiClose:
ExitApp

ImageClick() {
   Global PicArray
   HGUI := WinExist() ; the PopMenu GUI is set as the 'Last-Found Window', get its handle
   DragIndex := SubStr(A_GuiControl, 11) ; get the index part of the control name
   While (GetKeyState("LButton")) { ; while LButton pressed
      ToolTip, Bild auf anderes Bild ziehen`, um zu vertauschen
      Sleep, 100
   }
   ToolTip
   MouseGetPos, , , Win, CtrlClassNN
   ; MsgBox, %HGUI% - %Win% - %CtrlClassNN%
   If (Win = HGUI) && (CtrlClassNN <> "") {
      GuiControlGet, CtrlName, Name, %CtrlClassNN%
      ; MsgBox, %CtrlName%
      If (SubStr(CtrlName, 1, 10) = "PicNumber_") {
         DropIndex := SubStr(CtrlName, 11)
         If (DragIndex <> DropIndex) { ; swap the images
            DropImage := PicArray[DropIndex]
            DragImage := PicArray[DragIndex]
            MsgBox, 0, Swap, %DragImage%`n<>`n%DropImage%
            PicArray[DragIndex] := DropImage
            GuiControl, , PicNumber_%DragIndex%, %DropImage%
            PicArray[DropIndex] := DragImage
            GuiControl, , PicNumber_%DropIndex%, %DragImage%
            ; ...
            ; other actions
            ; ...
         }
      }
   }
}
I used text controls instead of pics to demonstrate the method.

Post Reply

Return to “Ask for Help (v1)”