sgp wrote (on 21.08.2006 19:20):
> Nope, same problem. Can you post it in this thread, please?
Very strange. I hope long lines don't get wrapped.. much.
---------------------------
;[**scr_ThumbMin]
; with this simple call, you can test this script by double-clicking
@ThumbMinEntryPoint
jump ThumbMin
Quit
; CUSTOMIZE THIS SCRIPTLET IF YOU LIKE
;
; This script makes a screenshot of a given window and minimizes it to a big
desktop "thumbnail".
;
; A screenshot should be in the same folder and/or archive where you found this
file
;
; Thumbnails are organized similar to Windows
; i.e. from top left to bottom, and then next column, and so on
; and always the first empty place is used.
;
; If you define an entry in your "HookWindowsEvents" list,
; thumbnails of unminimized and closed windows are cleared (see
@ThumbMinCleanup)
;
; Note that for minimization events "HookWindowsEvents" is called
; *after* a window is minimized, so we can't handle minimization via
"HookWindowsEvents"
;
; To call this script manually use .<this_script's_name>@ThumbMin( [caption
list] )
; The caption list is optional, if omitted active window is used
;
; To call this script via the Min-button,
; add the following to your Mousetrap.ini/Plugins.ini MouseTrapActive section:
;
; ThumbMin1=0,0,0,a=HTMINBUTTON,LMD,,,,0,1,0,0,0
;
ThumbMin2=0,0,0,a=HTMINBUTTON,LMU,,,.<this_script's_name>@ThumbMin(%ahan%),0,1,0,0,0
;
;
; Requirements:
; - PowerPro v4.5.0.6 or higher with the usual plugins: win, float, vec, etc.
;
; - the PCRE plugin (for splitting long labels to multiple lines)
;
; - optional: MouseTrap (for left/right mouse dragging, Min-button handling)
;
;
; TODO: When not using smartcrop, icons of windows which don't conform to given
ratio are cropped
; TODO: Catching Minimize-all events which are triggered outside PowerPro (this
might be not possible)
; TODO: If you change configuration via PProConf, all thumbnails are closed!
This is almost a showstopper!
; The solution to this problem should be simple and concise.
;
;
;
; Many thanks to Alan Martin and Mockey for their ideas and code contributions!
; Also thanks to sgp (acs322000) for her/his bug reports!
; Without their feedback, this script would be very crude and ugly.
;
;
;
; To register this script after 30 days, please transfer $40... just kidding!
;
; Ideas, flames, thanks, and
; especially feedback regarding the TODO-items are most welcome!
;
; Author: descent 49 aka Cüneyt
; 20060821, v1.0b4
;
; Changes from 1.0b1 to 1.0b2:
; - Using win.tofile in v4.5.0.6 no external programs are needed anymore
; the old implementation using IrfanView/ImageMagick is deleted to simplify
the script
; - Removed s_use_leftdrag & s_use_rightdrag, now left drag is used by default
; - Z-order is restored after the capture
; - Bars can be pinned to the desktop now (always on bottom), note you can't
drag pinned bars
; - Many non-changing variables are declared as static now
; - All configurable variables are moved into @ThumbMinInitialize
; - Thumbnail size is completely configurable now, you're not bound to 4:3 ratio
; - Smart-cropping to make windows fill the thumbnail optimally
; - Debugging mode can be activated; note that this affects grid placement!
; - A method to minimize all windows on the current vdesk is added (ThumbMinAll)
; - Transparency effect is added
;
; Changes from 1.0b2 to 1.0b3:
; - Fixed problem with filepaths containing spaces
; - Fixed 2 misnamed variables
; - Added @ThumbMinGetBarName to reduce duplicated code
; - Minor changes
;
; Changes from 1.0b3 to 1.0b4:
; - Added @ThumbMinEntryPoint for quick evaluation of this script
; - Changed the trailing character for overflowing labels to ~
; - Labels can be shown optionally always or only on mouseover
; - Labels and tooltips can be updated dynamically now
; - You can bypass the capturing procedure by supplying a 2nd parameter
; to @ThumbMin or by defining a global variable gvThumbMinBypass
; e.g. [EMAIL PROTECTED]("", if(running_under_vmware, 1))
; - Thumbnails are "thrown" to the back, even if they're not pinned to the
desktop
;
;
; contact me via the Yahoo PowerPro group
;
; THIS SCRIPTLET IS CALLED AUTOMATICALLY THE FIRST TIME
;
; CUSTOMIZE THIS SCRIPTLET IF YOU WISH
;
; adjusts the settings and initializes internal variables
; call this script again if you change settings
@ThumbMinInitialize
; thumbnail size
Static s_thumbx = 200
Static s_thumby = 150
; crop images smartly to fit them into given ratio
Static s_use_smartcrop = 1
; margins from the desktop borders and the grid-spacing
Static s_margin_left = 10
Static s_margin_top = 40
Static s_margin_right = 10
Static s_margin_bottom = 10
Static s_padding = 10
; font info for the labels
; a list of charsets can be found under Help -> Creating Skins, empty for
default
Static s_fontname = "Trebuchet MS"
Static s_fontextra = "Italic Bold"
Static s_fontsize = 16
Static s_fontcharset = ""
; labels are split after this many chars and lines; adjust it according to
your font
Static s_linelength = 15
Static s_linesmax = 4
; you can periodically update the labels (using *Info)
Static s_dynamic_labels = 1
; labels can be always visible or only on mouseover
Static s_labels_visible = 1
; align thumbnails to grid
Static s_auto_arrange = 1
; make thumbnails always on bottom
Static s_pin_to_desktop = 0
; for generated files use one of these directories; note the trailing
slash!
;Static s_outpath = scriptfolder ++ ?#\# ;; use this script's
directory
;Static s_outpath = ?#D:\Temp\# ;; use a specific
directory
Static s_outpath = env("Temp") ++ ?#\# ;; use the
temp-directory from user environment
Static s_outfileprefix = s_outpath ++ "pp_thumb_"
; actions for left/right/middle-clicks
Static s_lcaction = "@ThumbMinLCAction"
Static s_rcaction = "@ThumbMinRCAction"
Static s_mcaction = "@ThumbMinMCAction"
; double-click timeout, in millisecs
Static s_dcTimeout = 500
; transparency value for inactive thumbnails
Static s_transval = 128
; using this switch some additional messages are shown
Static s_debug = 0
;
;
; NO CHANGE AFTER THIS LINE IS NECESSARY
;
;
; number of grid elements
Static s_maxrows = (yscreen - s_margin_top - s_margin_bottom +
s_padding) / (s_thumby + s_padding)
Static s_maxcols = (xscreen - s_margin_left - s_margin_right +
s_padding) / (s_thumbx + s_padding)
; this array holds which slots on the desktop grid are allocated currently
Static s_Grid
If(vec.exists(s_Grid))
vec.destroy(s_Grid)
s_Grid = vec.create2D(s_maxrows, s_maxcols)
; line break for multiple tooltip lines
Static s_LB = esc(?"\r\n", ?"\")
; this variable acts as a semaphore and avoids concurrent runs
Static s_TMRunning = 0
; notify others
Static s_TMInitialized = 1
Quit
; CALL THIS SCRIPTLET IF THINGS GO AWRY
;
; customize this if you like
@ThumbMinReset
Static s_TMInitialized = 0
Static s_TMRunning = 0
If(vec.exists(s_Grid))
vec.destroy(s_Grid)
file.deletenorecycle(s_outfileprefix++"*.*")
Quit
; CALL THIS SCRIPTLET TO MINIMIZE MULTIPLE WINDOWS
;
; gets a list of all visible windows and minimizes them one by one
; note that concurrency is taken into account in @ThumbMin, not here
@ThumbMinAll
Local _winlist = win.handlelist("~c=PowerProToolbar,*SystemMeter
Plugin,c=Progman")
Local _handle
For(i=1; ; i++)
_handle = word(_winlist, i)
If(not _handle)
Break
If(not win.minned(_handle))
[EMAIL PROTECTED](_handle)
EndFor
Quit
; CALL THIS SCRIPTLET TO MINIMIZE SINGLE WINDOWS
;
; if a caption list is given, the 1st window matching that list is used
; if nothing is given, the active window is minimized
; e.g. .<this_script's_name>@ThumbMin("=notepad")
@ThumbMin
If(not s_TMInitialized)
[EMAIL PROTECTED]
; wait until the semaphore is released
Wait.for(not s_TMRunning)
; increment the semaphore
s_TMRunning++
; get information about the to be minimized window
Local _handle = ifelse(arg(1), win.handle(arg(1)),
win.handle("active"))
Local _bypass = ifelse(arg(2) || gvThumbMinBypass, 1, 0)
; you can just minimize the window and quit
If(_bypass)Do
win.minimize(_handle)
s_TMRunning--
Quit
EndIf
Local _class = win.class(_handle)
Local _exename = win.exename(_handle)
Local _exepath = win.exepath(_handle)
Local _caption = win.caption(_handle)
Local _wastop = win.topmost(_handle)
; set thumbnail-specific paths and names
Local _outfilename= s_outfileprefix ++ _exename ++ "_(" ++ _handle ++
"-0x" ++ win.hex(_handle) ++ ")"
Local _outthumb = _outfilename ++ ".bmp"
Local _outskin = _outfilename ++ ".txt"
Local _dynbarname = [EMAIL PROTECTED](_handle)
If(s_debug)Do
win.debug("handle (hex):", _handle, "(0x"++win.hex(_handle)++")")
win.debug("exename:", _exename)
win.debug("caption:", _caption)
win.debug("class:", _class)
EndIf
If(not _handle || _class eq "PowerProToolbar" || _class eq "Progman")Do
s_TMRunning--
Quit
EndIf
; final positions of the minimized windows
Local _barleft, _bartop
; internal variables
Local i, j
; get rid of the mouse pointer temporarily
win.mouse("save ab " ++ xscreen ++ " " ++ yscreen)
; avoid overlapping windows
win.ontop(_handle, 1)
; without this nap, strange problems with focusing occur
wait sleep 1
; convert and rescale the window
If(s_use_smartcrop)Do
Local _winw = win.width(_handle)
Local _winh = win.height(_handle)
Local _rect
Local _AR = float.divide(s_thumbx, s_thumby)
If(float.divide(_winw, _winh) > _AR)Do ;; crop right side
_rect = win.makerect(win.left(_handle), win.top(_handle),
win.left(_handle) + float.mul(_winh, _AR), win.bottom(_handle))
ElseIf(float.divide(_winw, _winh) < _AR) ;; crop bottom side
_rect = win.makerect(win.left(_handle), win.top(_handle),
win.right(_handle), win.top(_handle) + float.divide(_winw, _AR))
Else ;; perfect aspect ratio,
highly unlikely
_rect = win.makerect(win.left(_handle), win.top(_handle),
win.right(_handle), win.bottom(_handle))
EndIf
If(s_debug)
win.debug(_AR, _winw++"x"++_winh, " AR:", float.divide(_winw,
_winh), _rect)
win.recttofile(_rect, _outthumb, s_thumbx, s_thumby)
Else
win.tofile(_handle, _outthumb, s_thumbx, s_thumby)
EndIf
; make the window not-on-top, minimize it and restore the mouse position
If(not _wastop)
win.ontop(_handle, 0)
win.minimize(_handle)
win.mouse("restore")
; create the skin file
Local fhskin = file.open(_outskin, "w")
If(fhskin)Do
fhskin.writeline(?"*skin")
fhskin.writeline(" This file is automatically generated by " ++
scriptfolder ++ ?"\" ++ scriptname ++ "(.powerpro/.txt)")
fhskin.writeline(" You can safely delete this file, and accompanying
.bmp file with the same name")
fhskin.writeline(?"*bar width " ++ s_thumbx ++ " height " ++ s_thumby
++ ?# background "# ++ _outthumb ++ ?#"#)
fhskin.writeline(?"*ButtonDefault cursor hand.cur")
fhskin.writeline(?"*button id next top 0 left 0 width " ++
(s_thumbx-2) ++ " height 36 iconleft 8 icontop 4 no3d")
fhskin.writeline(?"*button id next top 36 left 2 width " ++
(s_thumbx-2) ++ " height " ++ (s_thumby-36) ++ " textpos multi textpos bottom
textleft 6 texttop 10 no3d"++ifelse(s_labels_visible,""," textover"))
fhskin.close()
Else
Do("Message", scriptname ++ ?#: Cannot create skin file!#)
s_TMRunning--
Quit(1)
EndIf
; create the bar or empty it if needed
cl.create(_dynbarname, 1)
; one could possibly set some bar properties below in the skin file as
well, you decide
cl.setproperties(_dynbarname, ?"Format1 = Position: Floating IconSize: 32
Transparent: 0 FlatFlat TextUnder Tooltips AllVDesks AutoShowBar TextCenter
HoverClick")
cl.addproperties(_dynbarname, ?"Skin = " ++ _outskin)
cl.addproperties(_dynbarname, ?"FontName = " ++ s_fontname)
cl.addproperties(_dynbarname, ?"FontInfo = " ++ s_fontextra ++ " Size: "
++ s_fontsize ++ ifelse(s_fontcharset, " Charset: "++s_fontcharset, ""))
; this item is for the icon
cl.insert(_dynbarname, 0)
cl.setwidth(_dynbarname, 0, s_thumbx)
cl.seticon(_dynbarname, 0, _exepath, 0)
; this item is for the label
cl.insert(_dynbarname, 1)
; split the label into multiple lines
; DEBUG: _caption =
"_123456789_223456789_323456789_423456789_523456789_623456789_723456789_823456789"
If(s_dynamic_labels)Do
cl.setlabel(_dynbarname, 1, ;;+
"*Info expr(
(ifelse(length(win.caption("++_handle++"))>"++(s_linelength*s_linesmax)++",
select(win.caption("++_handle++"), "++(s_linelength*s_linesmax - 1)++?#)++"~",
win.caption(#++_handle++")) ) [?#^.{1,"++s_linelength++"}#])")
Else
cl.setlabel(_dynbarname, 1, ;;+
(ifelse(length(_caption) > s_linelength*s_linesmax,
select(_caption, s_linelength*s_linesmax - 1)++"~", _caption)) ;;+
[?#^.{1,# ++ s_linelength ++ ?#}#])
EndIf
; common properties
For(i=0; i<2; i++)
If(s_dynamic_labels)Do
cl.settooltip(_dynbarname, i, "*Info " ++ _exename ++ " (handle: "
++ _handle ++ "-0x" ++ win.hex(_handle) ++ ", class: " ++ _class ++ ")" ++ s_LB
++ "expr(win.caption("++_handle++"))")
Else
cl.settooltip(_dynbarname, i, _exename ++ " (handle: " ++ _handle
++ "-0x" ++ win.hex(_handle) ++ ", class: " ++ _class ++ ")" ++ s_LB ++
_caption)
EndIf
cl.SetHover(_dynbarname, i, 2) ;; we'll use middle hover for
mouseover effect
cl.addleft(_dynbarname, i, cb(s_lcaction, _handle, _dynbarname))
cl.addright(_dynbarname, i, cb(s_rcaction, _handle, _dynbarname))
cl.addmiddle(_dynbarname, i, cb(s_mcaction, _handle, _dynbarname))
EndFor
; find an empty slot
Local _slotcol = -1
Local _slotrow = -1
If(s_auto_arrange)Do
For(i = 0; i < s_maxcols; i++)
For(j = 0; j < s_maxrows; j++)
If(not s_Grid[j,i])Do
_slotcol = i
_slotrow = j
s_Grid[j,i] = _handle
Break
EndIf
EndFor
; if an empty slot is found, do not search further
; this is needed because Break quits only one level of For-loop
If(_slotcol != -1 and _slotrow != -1)
Break
EndFor
; error if we can't find any empty slot
If(_slotcol == -1 and _slotrow == -1)Do
Message Run out of grid, please restore some windows
s_TMRunning--
Quit(1)
EndIf
_barleft = s_margin_left + _slotcol * (s_thumbx + s_padding)
_bartop = s_margin_top + _slotrow * (s_thumby + s_padding)
Else
_barleft = (xscreen - s_thumbx) / 2
_bartop = (yscreen - s_thumby) / 2
EndIf
; finally show the bar
bar.show(_dynbarname)
; and position it
win.back(_dynbarname)
win.move(_dynbarname, _barleft, _bartop)
; and make it transparent
If(s_transval)
win.trans(_dynbarname, s_transval)
; pin the bar to the desktop (always on bottom)
If(s_pin_to_desktop)
[EMAIL PROTECTED](_dynbarname)
If(s_debug)Do
win.debug("_barleft:", _barleft, "_bartop:", _bartop)
For(i = 0; i < s_maxcols; i++)
For(j = 0; j < s_maxrows; j++)
If(s_Grid[j,i])
win.debug("s_Grid["++j++","++i++"]:", s_Grid[j,i],
win.hex(s_Grid[j,i]), win.caption(s_Grid[j,i]))
EndFor
EndFor
EndIf
; dynamic mousetrap entry for left drag
; note that if you're using the IfDoubleClick technique, you can't use
Format Drag
mousetrap.AddEntry(_dynbarname,
?#1,0,0,ANY,MMV,,#++_dynbarname++?#,win.move(%phan%\,%sx%-%ldrx%\,%sy%-%ldry%),1,0,0,0,0,#)
; these are normally not needed, uncomment if you experience refreshing
problems
;cl.refresh(_dynbarname)
;cl.redisplay(_dynbarname)
; as soon as the bar is shown, we don't need these files anymore
file.deletenorecycle(_outthumb)
file.deletenorecycle(_outskin)
; decrement the semaphore
s_TMRunning--
Quit
; CUSTOMIZE THIS SCRIPTLET IF YOU WISH
;
; left click actions (singleleft to drag, doubleleft to restore)
; this is a modified version of Alex Peters' "IfDoubleClick" technique (lately
"OnMultiClick")
@ThumbMinLCAction
Args _handle, _barname
; single leftclick variant goes here
;[EMAIL PROTECTED](_handle, _barname)
; double click variant goes here
; this variable checks if the timeout has passed
Static _rcce
If(not event.exists(_rcce))Do
_rcce = event.createMS(s_dcTimeout, 1, "")
Else
[EMAIL PROTECTED](_handle, _barname)
event.destroy(_rcce)
EndIf
Quit
; CUSTOMIZE THIS SCRIPTLET IF YOU WISH
;
; sample right click action
; closes the application & the bar, and cleans up
; using the technique above, you could also convert the trigger to
RightDoubleClick
@ThumbMinRCAction
Args _handle, _barname
[EMAIL PROTECTED](_handle, _barname)
; without the following line, closed programs start minimized(!) the next
time they're run
; but it also causes a short flash on the desktop
win.close(_handle)
Quit
; CUSTOMIZE THIS SCRIPTLET IF YOU WISH
;
; sample middle "click" action
; this one is used for mouseover (hover) effects
@ThumbMinMCAction
Args _handle, _barname
If(not s_transval)
Quit
win.trans(_barname, 0)
wait.for(win.mainhandlefrompoint(xmouse, ymouse) != win.handle(_barname))
win.trans(_barname, s_transval)
Quit
; TO USE THIS SCRIPTLET, CHANGES IN PPROCONF ARE NECESSARY
;
; this scriptlet closes a bar if any minimized window is unminimized
; by other means than clicking the thumbnail
; in order to use this scriptlet, start PProConf, define a new list called
"HookWindowsEvents"
; and add a new item (you could have multiple items in that list) with the
following command:
; .<this_script's_name>@ThumbMinClenaup(arg(1),arg(2))
@ThumbMinCleanup
Args _event, _handle
If(s_debug)
win.debug("hooked event:", _handle, win.caption(_handle), _event)
If(_event == 1 or _event == 4)Do
; the following check would be normally redundant
; but some programs such as Firefox, Thunderbird are reported as being
restored
; even though they are minimized
If(win.minned(_handle))
Quit
If(s_debug)
win.debug("hooked event-inner:", _handle, win.caption(_handle),
time, _event)
[EMAIL PROTECTED](_handle, [EMAIL PROTECTED](_handle))
EndIf
Quit
; YOU DO NOT NEED TO CALL THIS SCRIPTLET MANUALLY
;
; this one restores the windows and cleans up the environment
@ThumbminRestore
Args _handle, _barname
If(s_debug)
win.debug("restoring:", _handle, win.caption(_handle))
; close the bar and clean the cl-list
If(visiblewindow(_barname))
bar.close(_barname)
If(cl.exists(_barname))
cl.removeall(_barname)
; restore the window
win.show(_handle, ifelse(win.minned(_handle), 1, 2))
; remove the mousetrap entry
mousetrap.RemEntry([EMAIL PROTECTED](_handle))
; clear the slot
If(not vec.exists(s_Grid))
Quit
For(Local i = 0; i < s_Grid.length; i++)
If(s_Grid[i] == arg(1))
s_Grid[i] = 0
EndFor
Quit
; YOU DO NOT NEED TO CALL THIS SCRIPTLET MANUALLY
;
; returns a unique bar name for a given handle
@ThumbMinGetBarName
Args _handle
Quit("_cl_"++_handle)
; YOU DO NOT NEED TO CALL THIS SCRIPTLET MANUALLY
;
; pins the given window to the desktop, making it effectively "always on bottom"
; this is my first attempt using dll-plugin, so be nice to me
; note that you can't drag or right-click bars which are pinned with this script
@PinToDesktop
Local _handle = ifelse(arg(1), win.handle(arg(1)), win.handle("under"))
Local _sddv = dll.call("FindWindowEx|i i s i", win.handle("c=Progman"), 0,
"shelldll_defview", 0)
Local _slv = dll.call("FindWindowEx|i i s i", _sddv, 0, "syslistview32",
0)
Local dummy = dll.call("SetParent|i i", _handle, _slv)
Quit
Attention: PowerPro's Web site has moved: http://www.ppro.org
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/power-pro/
<*> To unsubscribe from this group, send an email to:
[EMAIL PROTECTED]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/