Universal Viewer QuickView script

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: Hacker, petermad, Stefan2, white

User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

I just finished. It works OK.

The link:
http:\\www.r-moth.com\code\test2.rar

HOW it works:

1. When you press CTRL Q first time, Test app will be opened

2. When you move with up/down, file name will be set

3. When you call CTRL Q again, TestApp will close.


NOTE:
1. When you press CTRL Q first time file name will not be sent. This is a bug, but I don't have time to work on it now.

2. size and position are not changed but I implemented function that will return currently active Panel. You will see it in a TestApp title. That was the hard part anyway. Repositioning is easier, when you know controls name, but I didn't set that for now

3. You should implement parameters for position, width and height, hide caption and hide menu. I realised that this must be done to achive fluent start (otherwise, you will see when I move the window from AHK, I tested this)

4. I will later implement everything else (other keys, options etc...)

5. On the first line is variable holding the name of the app. Now it is set to TestMsg.exe. You change this to the Viewer.exe (full path). If you put the script in the directory with the Viewer.exe, you can just set the name of the exe (like I did with TestMsg).


Now you can finally implement things in Viewer itself. After that post me this new version on your test folder, so I can do the rest.


Have fun.
I go to play World of Warcraft now. See you there.
Habemus majkam!
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

V1.4.6:
http://atorg.net.ru/temp/TestMsg.rar
See Readme!

PS
You have error in ahk. It passes filename with trailing spaces, so Viewer's mode autodetection doesn't work.
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

I will check it out.
I will post news here when I have some.

BTW: why do I need TestMsg now ?
PS: not some spectacular bug :)
Habemus majkam!
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

Hej Alex.

We have some problems.
First, describe what exactly you do with plugins when you receive the file name.

Although it works nice, and even in this stage much better then TCs QuickView, I also noticed flickering. Do you close plugins like Ghisler ? :)

And another one: sometimes, when I move quickly some files are displayed as garbage ?! For instance I place several images and move. I see some, and some are garbage. The same with other file formats. It appears to be random, because when I move again, different pictures are garabaged. I tested with SGviewer (suddenly fit to window doesn't work) and font viewer.

I didn't tested parameters yet

Anyway, if you care this to be perfect, you must send me me the source, so I can discover problems on my own and even make some changes. Or we can continue this way. It's up to you.
Habemus majkam!
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

BTW: why do I need TestMsg now ?
Now it show filenames quoted, so you can see, if it's passed with tr. spaces.
We have some problems.
First, describe what exactly you do with plugins when you receive the file name.

Although it works nice, and even in this stage much better then TCs QuickView, I also noticed flickering. Do you close plugins like Ghisler ?
When I receive name:
- I hide all unneeded controls and close opened plugin (what is "like Ghisler"?)
- I determine view mode
- if some plugin matched, it's opened. If not, matched internal control is shown.
And another one: sometimes, when I move quickly some files are displayed as garbage ?!
Don't know.
Do you use SendMessage, not PostMessage?
Anyway, if you care this to be perfect, you must send me me the source, so I can discover problems on my own and even make some changes.
Source is already open.
See homepage (link in signature).
I'll post update.
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

Source:
http://atorg.net.ru/temp/ATViewer.zip
Do you use SendMessage, not PostMessage?
And did you fix tr. spaces?
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

First, a new version of script that will position the window and use your params.

Code: Select all

g_Viewer = Viewer.exe
g_mode = 2

;---------------------------------------------------------------------------

#ifWinActive ahk_class TTOTAL_CMD
^q::
	bOpen := !bOpen
	if (bOpen)
	{
		OpenViewer()
		SendCurrentFile()
	}
	else
		CloseViewer()
return

;---------------------------------------------------------------------------

~Down::
~Up::
	if (bOpen)
		SendCurrentFile()
return

;---------------------------------------------------------------------------

OpenViewer()
{
	global g_ViewerPID, g_Viewer

	panel := GetActivePanel()
	ControlGetPos cx, cy, cw, ch, %panel%, ahk_class TTOTAL_CMD
	WinGetPos x, y, , , ahk_class TTOTAL_CMD
	
	vX := x + cx
	vY := y + cy
	rect = %vX%,%vY%,%cw%,%ch%
	
	Run %g_Viewer% /Q /P=%rect%, , ,g_ViewerPID
	WinWait ahk_pid %g_ViewerPID%
	
	WinActivate, ahk_class TTOTAL_CMD
}

;---------------------------------------------------------------------------

CloseViewer()
{
	global 
	WinClose ahk_pid %g_ViewerPID%
}

;---------------------------------------------------------------------------
SendCurrentFile()
{
	global 

;	ifWinNotExist ahk_pid %g_ViewerPID%
;	{
;		MsgBox Viewer is closed. Exiting Quick View
;		bOpen := false
;		return
;	}

	name := GetName(g_mode)
	SendMessageToViewer( name )
}

SendMessageToViewer(fName)
{
	global
	len := StrLen(fName)

	VarSetCapacity(CopyDataStruct, 12, 0) ;3x4
	InsertInteger(100, CopyDataStruct, 0)
	InsertInteger(len + 1, CopyDataStruct, 4)
	InsertInteger(&fName,  CopyDataStruct, 8)
	
	SendMessage, 0x4a, 100, &CopyDataStruct,, ahk_pid %g_ViewerPID%
}

;---------------------------------------------------------------------------

GetName(method)
{
	;using clipboard
	if (method = 1)
	{
		SendTCCommand(2018) ;"cm_CopyFullNamesToClip"
		return clipboard
	}

	;using command line
	if (method = 2)
	{
		ControlSend Edit1, ^+{ENTER}, ahk_class TTOTAL_CMD
		ControlGetText name, Edit1, ahk_class TTOTAL_CMD
		ControlSend Edit1, {ESC}, ahk_class TTOTAL_CMD

		StringLeft c, name, 1
		if c = "
			StringMid name, name, 2, % StrLen(name) - 3
		return name
	}

	msgbox what are you doing ?
}

;---------------------------------------------------------------------------
#ifWinActive

^r::
	reload
return

;---------------------------------------------------------------------------
SendTCCommand(cmd, wait=1)
{
	if (wait)
		SendMessage 1075, cmd, 0, , ahk_class TTOTAL_CMD
	else
		PostMessage 1075, cmd, 0, , ahk_class TTOTAL_CMD
}


;---------------------------------------------------------------------------

GetActivePanel()
{
	ControlGetText pLeft,    TMyPanel5, ahk_class TTOTAL_CMD
	ControlGetText pCurrent, TMyPanel2, ahk_class TTOTAL_CMD

	StringReplace pCurrent, pCurrent, >

			

	StringGetPos idx, pLeft, \, R
	StringMid  pLeft, pLeft, 1, idx

	if StrLen(pLeft) = 2
		pLeft = %pLeft%\

	if (pLeft = pCurrent)
		return "TMyListBox1"
	else
		return "TMyListBox2"
}

ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
{
	Loop %pSize%  
		result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
	if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
		return result  
	return -(0xFFFFFFFF - result + 1)
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
{
	Loop %pSize% 
		DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
Please don't move TC window for now :) I just realised that whole siaset of things must be implemented and hooked: moving, closing, resizing... Total Commander.

Second, I don't have trailing space here :) But I will check again.

Second, you must NOT, NOT, NOT close the current plugin, IF IF IF the next file is the same type, that is, handled by the same plugin, don't close it, but call its Load function again. I hope this will reduce flicker, but it may not, since Lister API is not good. (and all other APIs)

Second, WM_COPYDATA can be sent only with SendMessage.


Second, ... no third.... if flicker is still visible after those changes, I will have to change your code and think some workaround, since Ghisler will surely not do.

Second, "like Ghisler" means: see my topic about Lister flickering.
Habemus majkam!
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

And, finally, what do you think about it, until now ?
Habemus majkam!
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

Second, I don't have trailing space here But I will check again.
I have. Run TestMsg.exe and move over files, you'll see "Filename ". Because of this the garbage may be (mode detection fails).
And, finally, what do you think about it, until now ?
It's good idea.
A little change to Viewer, but a good feature.
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

Second, you must NOT, NOT, NOT close the current plugin, IF IF IF the next file is the same type, that is, handled by the same plugin, don't close it, but call its Load function again. I hope this will reduce flicker, but it may not, since Lister API is not good.
No, I can't. Can't call ListLoad wihout prev. call of ListClose.
ListLoad *cannot* reload file to the opened window.
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

2majkinetor !
I have an idea for you.
Why not to make WLX that will do the same (run Viewer.exe with /Q and position its window over panel). ;)

No problems with hotkeys and repositioning will be.
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

Positioning is not the problem....

Minor thing...

THe bigest problem is fickering.. we must solve that.

Your idea is very good.
Habemus majkam!
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

Positioning is not the problem....
The problem is to catch all events when you need to reposition.
WLX don't have this problem.
THe bigest problem is fickering.. we must solve that.
Don't know how. :)
Your idea is very good.
Will you rewrite script to plugin?
User avatar
majkinetor !
Power Member
Power Member
Posts: 1580
Joined: 2006-01-18, 07:56 UTC
Contact:

Post by *majkinetor ! »

Not for now.
If I solve flickering, I will do everything to promote Viewer, and to anti-promote Lister.

But, with flickering, there are no benefits of Viewer comparing to Lister, when we talk about QuickView. Of course, it is better in all other sense, since you can run plugins standalone.

I will see what I can do about this, when I find time.

One of the ideas is to update plugin API on our own, to add new functions that will eliminate flickering, and to announce that to plugin authors. I don't know how that would be accepted so I will first try to analyse everything and to see if there is some workaround. Maybe if we do this, and if plugin authors suppor this, Ghisler might set that oficial.

>>The problem is to catch all events when you need to reposition.
Like I said, this is minor problem (well, I don't know exactly is it minor in AHK, but if I rewrite it in dll using Delphi or VS, I can interecept TC movement and move Viewer even before TC is moved. This is just a make-up anyway. I can even live with current version of QV if I manage it to work nicely on file change.

The only difference I noted until now, is that when you hold the up/down arrow, TC will not show anything in QuickView, while Viewer in QV mode will show every file.

Tell me, why you can't call Load again, if you recognise that next file is handled by the same plugin ? I realise that ListClose must be called to close the bufferes and so, but you don't have to unload dll and to load it again.
I am looking in SDK now, and I don't understand why you must close plugin. I guess leaving the plugin open will not reduce flickering in full, because plugin will still not know that it is open, but it might help further reducing it.

But I really mean that as a last measure we can promote upgraded API ourselves.
Habemus majkam!
User avatar
Alextp
Power Member
Power Member
Posts: 2321
Joined: 2004-08-16, 22:35 UTC
Location: Russian Federation
Contact:

Post by *Alextp »

Ok, let's want for Ghisler's answer.
Tell me, why you can't call Load again, if you recognise that next file is handled by the same plugin ? I realise that ListClose must be called to close the bufferes and so, but you don't have to unload dll and to load it again.
I am looking in SDK now, and I don't understand why you must close plugin.
I don't unload DLL on file change, just do ListClose.

Why - because ListLoad creates new instance of plugin object, that *must* be freed. If I call ListLoad again, 2 insts of plugin objects will be created and we'll need to call ListCloseWindow twice for it.

ListLoad *don't* pass filename to already opened object, in most plugins it creates new object.
Post Reply