SyncDirs after quick search becomes non-modal

Please report only one bug per message!

Moderators: white, Hacker, petermad, Stefan2

Post Reply
User avatar
Flint
Power Member
Power Member
Posts: 3487
Joined: 2003-10-27, 09:25 UTC
Location: Antalya, Turkey
Contact:

SyncDirs after quick search becomes non-modal

Post by *Flint »

1. Open SyncDirs dialog for some directories.
2. Press Compare .
3. Try to use Quick Search in the SyncDirs dialog.
4. Press Esc or click anywhere in the SyncDirs dialog to close Quick Search.
5. Now the SyncDirs in non-modal: you can set focus to the TC main window without closing SyncDirs.
Flint's Homepage: Full TC Russification Package, VirtualDisk, NTFS Links, NoClose Replacer, and other stuff!
 
Using TC 10.52 / Win10 x64
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

It's a great undocumented feature. :D

Oops, when I've opened two SyncDir windows and closed both, TC has crashed...

Code: Select all

Access violation at address 004FEBDB. Read of address 0000479F.
Access violation at address 004FEBDB. Read of address 0000479F
Windows 7 6.1 (Build 7600)

Please report this error to the Author, with a description
of what you were doing when this error occurred!

Windows exception: C0000005
Stack trace:
004FEBDB
44227C  5479B3  444F62  >422CC0  444523  422CC0
42838C  428424  6C53C9  
Raw:
4FEBCE  444491  422CC0  4348C2  443011  445231
4348C2  4445E5  444F62  444F85  422CC0  422CC0
68593E  5F99E5  5F9A09  444491  422CC0  44227C
55A15C  4452DB  42552D  445A3A  446B2C  559C0D
443011  445231  42499C  4445E5  444F62  444F85
422CC0  6C2174  557E0A  614975  5C0060  500072
4452BE  443011  445231  4445E5  444F62  444F85
422CC0  617B8E  443011  443011  445231  42499C
4445E5  444F62  444F85  422CC0  444523  422CC0
444491  422CC0  4452DB  445698  443011  445231

Press Ctrl+C to copy this report!
TC 7.56a.
User avatar
petermad
Power Member
Power Member
Posts: 14796
Joined: 2003-02-05, 20:24 UTC
Location: Denmark
Contact:

Post by *petermad »

confirmed - but the syncdir window stays in front of the TC main window.
License #524 (1994)
Danish Total Commander Translator
TC 11.03 32+64bit on Win XP 32bit & Win 7, 8.1 & 10 (22H2) 64bit, 'Everything' 1.5.0.1371a
TC 3.50 on Android 6 & 13
Try: TC Extended Menus | TC Languagebar | TC Dark Help | PHSM-Calendar
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48079
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Indeed it's dangerous to use this undocumented misfeature, because the sync tool uses parts of the main panel like existing plugin or ftp connections...
Author of Total Commander
https://www.ghisler.com
User avatar
Balderstrom
Power Member
Power Member
Posts: 2148
Joined: 2005-10-11, 10:10 UTC

Post by *Balderstrom »

I actually use the fact that the QuickSearch can be activated when a TC dialog is active for determining which File Panel is active - when TC itself is not the active window, or even when TC is minimized.

Code: Select all

/*
**	TC_QueryPanelID()
**
**	Return: HWND (ID) of the Active FileList Panel (TMyListBox#)
**
**	Input Parameters:			Output Parameters:
1&	cID2: ""					ID of L.Panel (if input activeLR<>1), else Source
2&	cID1: ""					ID of R.Panel (if input activeLR<>1), else Target
3	aWin: "WinTitle" or HWND	-
4&	activeLR: 0,1 (Boolean)		"Left" or "Right" (active Panel)
**
*/
LB_QueryPanelID(byRef cID2="", byRef cID1="", aWin="A", byRef activeLR=1)
{
	cID3:=0x1, dx:=0, aLR:=activeLR ;absolute:=(activeLR <> "S")
	if( aWin=="" && !winID:=WinActive("ahk_class TTOTAL_CMD"))
		return LB_QueryFocusedCtrlID( cID2, winID:="A" )
		
	onErrorExit(!winID:=WinExistA(aWin), "ERROR: Cannot Find Window [ " aWin " ]", A_ThisFunc)
	
	while( (cID2:=cID3) && LB_ControlGetID(cID3, "TMyListBox" (++dx), winID) && cID1:=cID2 )
			continue
	if( !ErrorLevel:=!(WinActive("A") == winID) )
	{
;		MsgBox, sending ESC...
		Send, {ESC}
		ControlGetFocus, activeLR, ahk_id %winID%
	}
	else
	{
		TC_CMD("cm_ShowQuickSearch", winID)
		WinWait, QUICKSEARCH ahk_class TQUICKSEARCH 
		WinGetPos,  tpX,,,, % "ahk_id " LB_ControlGetID( tp1, "TPanel1", winID )
		WinGetPos,  qsX,,,, % "ahk_id " qikS:=WinExist("QUICKSEARCH ahk_class TQUICKSEARCH")
		ControlSend,, {ESC}, ahk_id %qikS%
		activeLR:="TMyListBox" (qsX > tpX ? dx-2 : dx-1) ; ? "Right" : "Left")
	}
		
	LB_ControlGetID( cID3, activeLR, winID )
	activePanel:=activeLR
	if((activeLR:=(cID3 == cID1 ? "Right" : "Left")) && aLR && cID3 == cID1)
		LB_Swap(cID1, cID2)
;MsgBox, winID: %winID%`nActivePanel: %cID3% (%activePanel%) [%activeLR%]`nReturnValue: %cID2%`nOtherPanel:: %cID1%
return (cID2)
}
Specifically, the else block

Code: Select all

	else
	{
		TC_CMD("cm_ShowQuickSearch", winID)
		WinWait, QUICKSEARCH ahk_class TQUICKSEARCH 
		WinGetPos,  tpX,,,, % "ahk_id " LB_ControlGetID( tp1, "TPanel1", winID )
		WinGetPos,  qsX,,,, % "ahk_id " qikS:=WinExist("QUICKSEARCH ahk_class TQUICKSEARCH")
		ControlSend,, {ESC}, ahk_id %qikS%
		activeLR:="TMyListBox" (qsX > tpX ? dx-2 : dx-1) ; ? "Right" : "Left")
	}
And my TC_CD() command, just returns the dialog back to modal afterwards.

Code: Select all

TC_SendWMCopyData( cmdType, byRef cmd, byRef addParams="", aWin="A" )
{
Critical
	VarSetCapacity( CopyDataStruct, 12 )
	NumPut( Asc(SubStr(cmdType,1,1)) + 256 * Asc(SubStr(cmdType,2,1)), CopyDataStruct )
	NumPut( StrLen(cmd) + (cmdType="CD" ? 5 : 1), CopyDataStruct, 4 )
	NumPut( &cmd, CopyDataStruct, 8 )
	Loop, % (cmdType=="CD" ? 2 : 0)
		NumPut( Asc(SubStr(addParams, A_Index, 1)), cmd, StrLen(cmd) + A_Index, 1 )
	SendMessage, 0x4A,, &CopyDataStruct,, ahk_id %aWin%
return
}


TC_CD( src="", trg="", params="S", activateWin=FALSE, keepSelect=TRUE, aWin="ahk_class TTOTAL_CMD" )
{	
	
	onErrorExit( !src && !trg, "No Path Parameters.", A_ThisFunc )
	onErrorExit( !RegExMatch(params, "^(?|S([T])?|T([S])?|)$", param), "Invalid Parameters.", A_ThisFunc )
	onErrorExit( !(wID:=QueryWinID( aWin, TRUE )), "Cannot Find window: " aWin, A_ThisFunc )
	if( activateWin )
		WinActivate, ahk_id %wID%
	SplitPath(src, srcFile, srcPath)
	SplitPath(trg, trgFile, trgPath)
;	MsgBox, srcPath: %srcPath%`ntrgPath: %trgPath%
	if( (srcFile && !inStr(srcFile, "*") && !FileExist(src))||(trgFile && !inStr(trgFile, "*") && !FileExist(trg)) )
	{
		MsgBox, 0x4, % "No Such File", % "One of the files doesn't exist.`nStill open the parent folders?"
		ifMsgBox, NO
			return
	}
	aPanel:=LB_QueryPanelID( cID1, cID2, wID, activeLR:=inStr(params, "S"))
	aChild:=TC_WinEnableParent(wID, aChild:="")
	TC_SendWMCopyData( "CD", cmd:=((srcPath ? srcPath " `r" : "`r") (trgPath ? trgPath " " : "")), params:=(param2 ? "ST" : params), wID )
;MsgBox, params: %params%`ncmd: %cmd%
	if( !srcFile && !trgFile )
		return TC_WinEnableParent(wID, aChild, TRUE, retParent:=TRUE)
	
 	if(!(focusLR:=0) && activeLR=="Right" && (focusLR:=1) && !inStr(params, "S"))
		string:=(srcFile&&trgFile) ? "trg`nsrc" : trgFile ? "trg`n" : srcFile ? "`nsrc" : ""
	else
		string:=(srcFile&&trgFile) ? "src`ntrg" : srcFile ? "src`n" : trgFile ? "`ntrg" : ""

	Loop, Parse, string, `n
	{
		    
;		if((aPath:=A_LoopField "Path") == "Path")
;			continue
		if(!A_LoopField )
			continue
		if( A_Index == 2 )
		{
			if( WinGetVal("MinMax", wID) == -1 )
			{ ; Minimized
				WinActivate, % "ahk_id " wID
				TC_WinEnableParent(wID, aChild)
			}
			TC_CMD("cm_Focus" (focusLR ? "Left" : "Right"), wID, activateWin)
		}
		aPath:=A_LoopField "Path"
		while(  WinWaitTT( wID, MatchPaths(%aPath%, TC_QueryPathA(wID)), i:=6)  )
				continue
		aFile:=A_LoopField "File"
		TC_EMC("em_SELECTFILES " %aFile%, wID, activateWin )
		TC_CMD("cm_GotoNextSelected", wID, activateWin )

		if( !keepSelect )
			TC_CMD("cm_ClearAll", wID, activateWin )
		if( A_Index == 2 ) 
			TC_CMD("cm_Focus" (!focusLR ? "Left" : "Right"), wID, activateWin)
	}
	TC_WinEnableParent(wID, aChild, FALSE)
	WinActivate, ahk_id %aChild%
return wID
}

Code: Select all

TC_WinEnableParent(wID, childID="", onOFF=TRUE, retOwner=FALSE)
{
	if( (ownerID:=wID) && !childID )
	{
		childID:=DllCall("GetWindow", "uint", wID,    "int",3)	; 3 == GW_PREV
		ownerID:=DllCall("GetWindow", "uint", childID,"int",4)	; 4 == GW_OWNER
	}
	if( ownerID <> wID || childID == -1 )
		return (retOwner ? wID : -1)
	WinSet, % (onOFF ? "Enable"  : "Disable"),, ahk_id %ownerID%
	WinSet, % (onOFF ? "Disable" : "Enable" ),, ahk_id %childID%
	ControlSend,, % (onOFF ? "{ESC}" : ""),  ahk_id %ownerID%
return (retOwner ? ownerID : childID)
}
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Post by *MVV »

You may just load HideMenu module (e.g. via Autorun.wdx) and send a command to TC main window to check active panel (WM_USER+51 with following wParam: default IDs are IsLeftActive=65551 and IsRightActive=65552, may be redefined in ini), and it will return 0 or 1.
Post Reply