October 19, 2010

ClipMagic 4.0 Released

Filed under: Announcements — Marcus Tettmar @ 6:43 pm

ClipMagic - Clipboard Extender Way back in 1998 we released a handy little Windows Clipboard extender and information manager called ClipMagic. It lives over at http://www.clipmagic.com/ where today after far too long a new version was released.

If you’re not already familiar with ClipMagic it is a Windows clipboard monitor/viewer/extender/manager which stores every item you copy to the windows clipboard and allows you to edit clips, organize them, manipulate and filter them, assign hot keys to them, and provides useful features to make it easier to paste clips into other windows. It is also an information manager, as you can create clips manually, assign them to categories and quickly retrieve/paste them using hot keys. Web clips are stored with the URL of the page they came from, allowing you quick access back to the source.

Basically it speeds up your work. The big problem with the native Windows clipboard is that it only stores one item at a time. You know that feeling when you have to copy lots of items from one screen to another and you have to go back and forth? Then a bit later you realise you need an item you copied earlier but it was obliterated by a recent copy? Well ClipMagic removes all that, because ClipMagic remembers every clip and gives you quick ways to paste into the active application.

For those familiar with previous versions of ClipMagic you may not notice any major difference in version 4.0 at first. But the big change is that version 4.0 has a completely new database format which is faster and more reliable. V 4.0 is also fully compatible with Vista and Windows 7 and supports the new Vista/Win7 clipboard monitoring method, so if you’re using Vista/Win7 you can say good bye to the annoying clipboard chain problems.

ClipMagic 4.0 comes in two flavours. As well as the full featured version, with a 30 day trial, there’s also a free Lite version which just keeps a copy of all clips giving you access to them but with no editing, filtering or custom hot key features.

More Info
Downloads

October 18, 2010

Macro Scheduler 12.1.0 Now Available

Filed under: Announcements — Marcus Tettmar @ 12:08 pm

Macro Scheduler 12.1.0 is now available with the following fixes since my last update announcement:

  • Fixed: IGNORESPACES ignoring CRLFs and SPACES when on their own.
  • Fixed: StringReplace crashes if empty string passed in find parameter
  • Fixed: Occassional “cannot write to comdef.ini” error in standalone editor.
  • Fixed: CTRL-V etc not working in Watch List search box
  • Fixed: Some text missing from GetTextInRect / GetWindowTextEx where text overlaps (New Text Capture libs)
  • Added: Full complex expression support to Repeat and While (when expr between curly braces)
  • Added: -KEEPLOGOPEN command line parameter: keeps log file open during script execution (faster for installations with large number of simultaneous running scripts)
  • Change: If insufficient privileges to open a script for exclusive write access (or if script already being edited) will now ask if you want to open it read only

Workflow Designer and the SDK have also been updated to the same MacroScript version.

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

October 15, 2010

Display an Animated GIF on a Dialog

Filed under: Scripting — Marcus Tettmar @ 8:19 am

Forum regular JRL has come up with yet another great coding example, with a demonstration of how to jazz up your dialogs by displaying an animated image – a great way to represent progress of an activity.

Here it is.

In fact this example shows how any window can be embedded into a dialog by using the SetParent function. Take a look at JRL’s helpful comments to see how this works.

September 23, 2010

Success Story: MacroScript SDK bridges healthcare system boundaries

Filed under: Success Stories — Marcus Tettmar @ 3:56 pm

Are you a developer? Did you know that with our MacroScript SDK you can add the ability to run Macro Scheduler code right from within your own applications? The SDK lets you run Macro Scheduler scripts and code, as well as query Macro Scheduler script variables during code execution. The SDK gives you a more seamless way to run Macro Scheduler code and use Macro Scheduler capabilities within your own applications.

Steen Jakobsen of DM Software recently integrated the SDK into their Dialog Manager software. He kindly agreed to a case study.

Macro Scheduler made it very easy to integrate the SDK. The input parameters for the scripts are completely integrated and direct, and secure and reliable data transfer is being accomplished – all thanks to the brilliant architecture of the MacroScript SDK. …. We’ve saved the doctors and nurses enormous amounts of time, and at the same time, added very valuable and sophisticated calculation and decision support across five systems that otherwise have no link to one another. This can only be done with the unique Windows automation capabilities of Macro Scheduler combined with the tight integration with Dialog Manager.

Steen Jakobsen, DM Software

Read the Case Study here.

September 16, 2010

Making a Dialog or Window Stay On Top

Filed under: Automation, Scripting — Marcus Tettmar @ 1:45 pm

Edit: 23 March 2011. In Version 12 it is possible to make a dialog stay on top simply by setting the dialog’s FormStyle property to fsStayOnTop. The method outlined in this post is not necessary for v12 dialogs but will remain as it can be used for older versions and the same approach can be used for windows belonging to other processes.

A question that comes up every now and then is how to make a custom dialog stay “on top” of other windows even when it loses the focus. There is a way to do this by calling the Windows API function SetWindowPos. There are examples in the forums but for convenience here’s a version of one:

SRT>StayOnTop
  Let>HWND_TOPMOST=-1
  Let>HWND_NOTOPMOST=-2
  Let>SWP_NOSIZE=1
  Let>SWP_NOMOVE=2
  Let>SWP_NOACTIVATE=16
  Let>SWP_SHOWWINDOW=64
  Let>WindowHandle=%StayOnTop_var_1%
  Let>Flags={%SWP_NOACTIVATE% Or %SWP_SHOWWINDOW% Or %SWP_NOMOVE% Or %SWP_NOSIZE%}
  LibFunc>User32,SetWindowPos,swpr,%WindowHandle%,HWND_TOPMOST,0,0,0,0,Flags
END>StayOnTop

This subroutine takes a window handle and modifies the properties of that window to make it stay above other windows.

For example, if we had just opened Notepad and wanted to force it to stay on top we could do:

GetWindowHandle>Untitled - Notepad,hwndNotepad
GoSub>StayOnTop,hwndNotepad

Or to get the handle of the active window use GetActiveWindow with WIN_USEHANDLE set to 1.

To set one of your own custom dialogs to stay on top use:

GoSub>StayOnTop,DialogName.Handle

Don’t forget that we are at the mercy of Windows here (and possibly the developers of the app we’re trying to force to the top). It’s a bit rude to have a window floating around on top of other windows. And consider what would happen if another window is opened which is also set to stay on top in the same way? You can’t have two windows on top. So multiple “stay on top” windows will still overlap each other depending on which one has the focus. In short you can’t really guarantee that a window will always be on top.

September 15, 2010

Macro Scheduler 12.0.8 Update Available

Filed under: Announcements — Marcus Tettmar @ 10:07 am

Macro Scheduler 12.0.8 is now available with the following fixes since my last update announcement:

  • Fixed: SCRIPT_FILE / SCRIPT_DIR returning exename/dir when queried in macro called by compiled macro
  • Fixed: Variable Breakpoints not being recognised inside dialog event handler subroutines
  • Fixed: LDblClick / RDblClick not independent of left hand/right hand mouse settings (LDblCLick should always do primary button function)
  • Fixed: XLSetCell example in help file has missing Sheet name
  • Fixed: HTTPPost using multipart/form-data and binary encoding for all form data. Should be application/x-www-form-urlencoded unless sending files
  • Fixed: SK_IGNORECAPS incorrectly causing non alphabetic characters to be “shifted”
  • Fixed: Dialog Designer – sometimes changing property selection to dialog’s properties unexpectedly
  • Fixed: List out of bounds error when trying to edit a script which is already open in another editor or being edited by another user.
  • Fixed: Long delay when updating very long dialogs
  • Fixed: Exit command not returning specified exit code (always returning zero) in compiled macros
  • Fixed: Imported DLLs being unloaded at the end of a dialog event handler subroutine
  • Change: RunProgram now returning error code if an error occured instead of just -1 (now returns -1:errcode)
  • Added: possible workaround for Win7 regional settings bug which occurs on some systems

Workflow Designer and the SDK have also been updated to the same MacroScript version.

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

Accessing 64 bit System Folders – Turn off File System Redirection

Filed under: Automation, General — Marcus Tettmar @ 8:50 am

If you need to run a 64 bit system command, or a system command that requires access to the 64 bit system folders you may need to turn off File System Redirection.

To turn off File System Redirection call the snappily named Wow64DisableWow64FsRedirection function and remember to turn it back on with the equally memorable function Wow64RevertWow64FsRedirection.

For example:

//turn off File System Redirection
LibFunc>kernel32,Wow64DisableWow64FsRedirection,result,0

Let>RP_ADMIN=1
let>RP_WAIT=1
DeleteFile>%TEMP_DIR%\vss.txt
Run>"cmd.exe" /c vssadmin list shadowstorage  >> "%TEMP_DIR%\vss.txt"
ReadFile>%TEMP_DIR%\vss.txt,vss
MessageModal>vss

//revert File System Redirection
LibFunc>kernel32,Wow64RevertWow64FsRedirection,result,0

Recently someone running the 64 bit version of XP was having a problem running this innocuous looking code:

Run>c:\windows\system32\mstsc.exe

mstsc.exe is the remote desktop client. Macro Scheduler returned an error saying that c:\windows\system32\mstsc.exe could not be found, yet using Windows Explorer we could see mstsc.exe clearly in the system32 folder. The same code worked perfectly fine on a Win7 x64 system.

Eventually I realised what was happening. Because the OS was 64 bit and Macro Scheduler is 32 bit, Windows was redirecting “c:\windows\system32\” to “c:\windows\syswow64” – the 32 bit system folder. There should be a 32 bit version of mstsc.exe in there, but on this particular system it was missing (it may be that earlier versions of Remote Desktop on x64 did not install a 32 bit version). Hence the error that Macro Scheduler could not find the file. We quickly resolved this by turning off File System Redirection using the code above.

Although the current 32 bit version of Macro Scheduler runs on and is compatible with all 64 bit versions of Windows, a 64 bit version of Macro Scheduler is in the pipeline. Until then calling some system level functions may need the above treatment if those commands need to access the 64 bit subsystem. Macro Scheduler can happily execute and interact with 64 bit applications, but Windows will redirect references to some locations such as system32 unless File System Redirection is disabled.

September 14, 2010

September 8, 2010

Trigger Scripts

Filed under: Automation, Scripting — Marcus Tettmar @ 3:03 pm

Macro Scheduler has a number of scheduling features to allow you to specify when a macro should fire. One of these mechanisms is called a Trigger. There are several trigger types:

  • Window Event
  • File Event
  • Folder Event
  • Custom Event

A Window Event can be set to fire when a specified window appears or disappears. Similarly file events can be set to fire the macro when the specified file exists or ceases to exist. Folder events offer much the same (a folder exists or ceases to exist) but also a little more. A Folder event can also be configured which will fire the macro when a new file appears in the folder, or a file is removed from the folder.

New File Triggers

With a “New File in Folder” trigger the macro will fire whenever a new file appears in the folder, regardless of what that file is called. This can be very useful and is often used to detect incoming files for further processing. In a situation like this we would need to detect that a new file has appeared and then do something with it. Using the New File in Folder trigger will cause the macro to run, but then we need the macro to determine what that file is called. We can do that with a VBScript function which returns the newest file in a folder:

VBSTART
Function NewestFile(Folder)
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(Folder)
dPrevDate = "0"
For Each oFile In oFolder.Files
  If DateDiff("s", dPrevDate, oFile.DateLastModified) > 0 Then
    sNewestFile = oFile.Path
    dPrevDate = oFile.DateLastModified
  End If
Next
NewestFile = sNewestFile
End Function
VBEND

We can then call it like this:

VBEval>NewestFile("c:\downloads"),filename

This will return in filename the path of the newest file in the given folder. So if our macro is fired by a new file appearing in a folder it can then run this code to get that file’s path and do something with it.

Custom Triggers

Custom triggers allow you to create any kind of trigger you can think of by executing Macro Scheduler code. Maybe you want to monitor the contents of a text file or an INI file entry, a registry entry or the size of a specific file. If you can code the check in Macro Scheduler you can create a trigger out of it.

Custom triggers work by linking to a script (.scp) file which contain two subroutines. One subroutine is called Trigger and the other Reset. Initially the Trigger subroutine is called repeatedly until it sets MACRO_RESULT to TRUE. Thereupon Macro Scheduler calls the Reset routine instead until it too sets MACRO_RESULT to TRUE and the cycle then continues.

By way of an example lets say we want to trigger a macro based on the value of an INI file entry. Let’s say our INI file looks like this:

[MyStuff]
Color=red

Let’s say we want to trigger a macro to run when the Color entry in the INI file gets set to “blue”. Here’s our trigger script:

SRT>Trigger
  ReadIniFile>d:\files\myini.ini,MyStuff,Color,gColor
  If>gColor=blue
    Let>MACRO_RESULT=TRUE
  Endif
END>Trigger

SRT>Reset
  ReadIniFile>d:\files\myini.ini,MyStuff,Color,gColor
  If>gColor<>blue
    Let>MACRO_RESULT=TRUE
  Endif
END>Reset

So here the Trigger routine which is executed continually by the scheduler will return TRUE only if Color in the INI file becomes equal to “blue”. Thereupon the Reset routine will be executed which will reset the trigger when Color is no longer “blue”. After that the Trigger routine is executed again.

Since Trigger routines are run frequently on a very tight interval they should be kept as small as possible and should not be long running. Don’t make Trigger scripts that perform too much complicated processing or include delays as this could cause resource issues. Sometimes, for more complicated “triggers” or monitoring scripts you may be better off creating a looping macro or repeating macro. E.g. if you wanted to poll a POP3 server for an email message containing specific content this is a more time consuming process subject to network delays so would probably not be a good candidate for a Custom Trigger. Instead create a macro which checks the email every few minutes, or one that loops continuously.

August 24, 2010

Don’t Overwhelm your Target!

Filed under: Automation, Scripting — Marcus Tettmar @ 4:24 pm

When sending keystrokes to other applications remember that Macro Scheduler works much faster than a human being can type. Many applications do form field verification or background processing on the fly as the text is received. And most applications were designed on the assumption that a human being would be operating them. It may not have occurred to the developers that a robot might try to send a stream of text to the UI at the rate of 5000 characters a second!

With some applications if you try to send too many characters at once you may find that some of those characters fail to show up, or the string is truncated.

The solution should be obvious by now. That is to slow down the key send rate. You can do this easily by setting the SK_DELAY parameter which introduces a specified millisecond delay between each character.

Let>SK_DELAY=20
Send>long_string

Of course you could break the long string down into smaller chunks and insert a delay between them:

Send>part_1
Wait>0.3
Send>part_2
Wait>0.2
Send>part_3

But SK_DELAY is simpler and easier if you can’t control the length of the data easily.

A related issue I see every now and then is when “tabbing” from one field to another on a form. Pressing the tab key moves the focus to the next field, so we use this while sending data into a form. Sometimes we’ll encounter an application which needs a bit of time after a field has been focused before it can accept data, or the other way around. So sending Tab immediately after/before sending the data with no delay fails to work. Adding in a small delay between sending the data and the Tab solves it:

Send>field_data
Wait>0.3
Press Tab

Wait>0.3
Send>next_field
Wait>0.3
Press Tab

etc

Similarly when we need to tab through lots of fields at once without sending data we may try to save ourselves coding time by writing:

Press Tab * 10

But if the app needs time to react between each tab we may have to split that out into separate tabs with delays between them or replace with a repeat/until loop:

Let>tabs=0
Repeat>tabs
  Press Tab
  Wait>0.2
  Let>tabs=tabs+1
Until>tabs=10

As I’ve said many times before the most common causes of things not working as expected are either timing or focus. Macros run way faster than a human can type which is often beneficial but if things aren’t quite right start off by slowing the macro down a bit. You can always speed it up later!