Detect Image Data on Windows Clipboard plus Save and Restore
Moderators: JRL, Dorian (MJT support)
Detect Image Data on Windows Clipboard plus Save and Restore
Hi Support,
How can I use the Windows Clipboard to pull in text that a user has highlighted in an application...
without loosing image data that may already exist on the clipboard? Here's an example:
//Save existing clipboard content
GetClipboard>SAVED_CLIPBOARD
//Initialize null variable
Let>NULL=
//Clear clipboard
PutClipboard>NULL
//Capture highlighted text to clipboard
Press CTRL
Send Character/Text>c
Release CTRL
Wait>0.2
GetClipboard>HIGHLIGHTED_TEXT
If>HIGHLIGHTED_TEXT=NULL,Done
//Highlighted text was found so process here
MessageModal>HIGHLIGHTED_TEXT
//etc. etc.
Label>Done
//Restore clipboard
PutClipboard>SAVED_CLIPBOARD
This works well as long as there is only text in the clipboard.
Whatever was in the clipboard before the script runs, is restored when the script exits.
However, if there was image data in the clipboard, the image data is lost.
Is there any way to save the current contents of the clipboard to memory somewhere
(no matter what it holds, text, image, text & image, etc) and then later restore the saved clipboard contents?
Maybe something in VB? Anyone have any ideas on this one?
How can I use the Windows Clipboard to pull in text that a user has highlighted in an application...
without loosing image data that may already exist on the clipboard? Here's an example:
//Save existing clipboard content
GetClipboard>SAVED_CLIPBOARD
//Initialize null variable
Let>NULL=
//Clear clipboard
PutClipboard>NULL
//Capture highlighted text to clipboard
Press CTRL
Send Character/Text>c
Release CTRL
Wait>0.2
GetClipboard>HIGHLIGHTED_TEXT
If>HIGHLIGHTED_TEXT=NULL,Done
//Highlighted text was found so process here
MessageModal>HIGHLIGHTED_TEXT
//etc. etc.
Label>Done
//Restore clipboard
PutClipboard>SAVED_CLIPBOARD
This works well as long as there is only text in the clipboard.
Whatever was in the clipboard before the script runs, is restored when the script exits.
However, if there was image data in the clipboard, the image data is lost.
Is there any way to save the current contents of the clipboard to memory somewhere
(no matter what it holds, text, image, text & image, etc) and then later restore the saved clipboard contents?
Maybe something in VB? Anyone have any ideas on this one?
Last edited by jpuziano on Fri Mar 03, 2006 7:58 pm, edited 4 times in total.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

Hi Support,
I think I am making progress... I found the Win32 API CountClipboardFormats Function
LibFunc>user32,CountClipboardFormats,ccf
I stepped through it with the debugger and when it hit the LibFunc line above, it produced an error:
LibFunc>user32,CountClipboardFormatsA,ccf
...which worked better, no Access violation error but still no return value
and the debugger showed that no variables were created.
Can you show me how to call this Function? Perhaps it is unusual because it requires no parameters?
Is that "A" added onto the end of the function name a kind of special Macro Scheduler syntax?
Not all the examples shown in the LibFunc Help file examples tack the "A" on.
Is there a way we can know when we should add it and when not to?
Also, in the Help file for LibFunc, you have this example code for Get Active Window Title:
Let>WIN_USEHANDLE=1
GetActiveWindow>win,x,y
LibFunc>user32,GetWindowTextLengthA,wtlen,win
Let>buffer_SIZE=wtlen
LibFunc>user32,GetWindowTextA,gwt,win,buffer,wtlen
MessageModal>Window Text: %gwt_2%
I copied that code, created a macro, pasted that in and put a hotkey on it.
I tapped the hotkey while the Macro Scheduler main window was up and it returned the window title just fine.
However, when Notepad was up, the window title it returned was one char short, returning "Untitled - Notepa".
On reading about GetWindowText, it says that there is a NULL char at the end that must be accounted for...
so if I increment wtlen by 1 before calling GetWindowText, I can get the whole title...
but I still can't see why it works as-is and pulls the whole title when run against the Macro Scheduler Main window??!!??
Heeeeeeelp......
I think I am making progress... I found the Win32 API CountClipboardFormats Function
...but I really need your help in calling it from Macro Scheduler. I tried the following...CountClipboardFormats Function
-------------------------------------
The CountClipboardFormats function retrieves the number of different data formats currently on the clipboard.
Syntax
int CountClipboardFormats(
VOID
);
Parameters
This function has no parameters.
Return Value
If the function succeeds, the return value is the number of different data formats currently on the clipboard.
LibFunc>user32,CountClipboardFormats,ccf
I stepped through it with the debugger and when it hit the LibFunc line above, it produced an error:
I noticed in the Help file on LibFunc, most of the Function names have "A" tacked on the end so I tried that as well...Access violation at address 0012E32C. Read of address 00000012.
LibFunc>user32,CountClipboardFormatsA,ccf
...which worked better, no Access violation error but still no return value
and the debugger showed that no variables were created.
Can you show me how to call this Function? Perhaps it is unusual because it requires no parameters?
Is that "A" added onto the end of the function name a kind of special Macro Scheduler syntax?
Not all the examples shown in the LibFunc Help file examples tack the "A" on.
Is there a way we can know when we should add it and when not to?
Also, in the Help file for LibFunc, you have this example code for Get Active Window Title:
Let>WIN_USEHANDLE=1
GetActiveWindow>win,x,y
LibFunc>user32,GetWindowTextLengthA,wtlen,win
Let>buffer_SIZE=wtlen
LibFunc>user32,GetWindowTextA,gwt,win,buffer,wtlen
MessageModal>Window Text: %gwt_2%
I copied that code, created a macro, pasted that in and put a hotkey on it.
I tapped the hotkey while the Macro Scheduler main window was up and it returned the window title just fine.
However, when Notepad was up, the window title it returned was one char short, returning "Untitled - Notepa".
On reading about GetWindowText, it says that there is a NULL char at the end that must be accounted for...
so if I increment wtlen by 1 before calling GetWindowText, I can get the whole title...
but I still can't see why it works as-is and pulls the whole title when run against the Macro Scheduler Main window??!!??
Heeeeeeelp......
Last edited by jpuziano on Fri Feb 24, 2006 10:38 pm, edited 3 times in total.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
Not quite sure how you think that will help. You know the clipboard has multiple formats already. There is NO way in Macro Scheduler to get only the format you want, modify it and put it back without destroying the other formats. Macro Scheduler only works with cf_text formats and when it puts stuff back on the clipboard it puts text. Anything already there will be replaced by the text. You won't get anywhere trying to use the clipboard apis in Macro Scheduler.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
- Bob Hansen
- Automation Wizard
- Posts: 2475
- Joined: Tue Sep 24, 2002 3:47 am
- Location: Salem, New Hampshire, US
- Contact:
- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
Which is now free!Me_again wrote:Maybe ClipMagic
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
I just picked CountClipboardFormats because it seemed simple. If I can successfully call this one, I should be able to call any of the other 16 different clipboard API calls and do what I need to do... but it didn't work and I would still like your help in making this call work for starters...mtettmar wrote:Not quite sure how you think that will help. You know the clipboard has multiple formats already.
Yes, I understand that GetClipBoard and PutClipBoard only handle text and PutClipBoard will destroy whatever data was on the clipboard previously. However, I'm not trying to use Macro Scheduler commands. I'm trying to use LibFunc to make Win32 API calls that can handle other clipboard data formats besides text.mtettmar wrote:There is NO way in Macro Scheduler to get only the format you want, modify it and put it back without destroying the other formats. Macro Scheduler only works with cf_text formats and when it puts stuff back on the clipboard it puts text. Anything already there will be replaced by the text.
Why not? I'm thinking Microsoft wrote those API calls to give developers full control over the clipboard, to do anything they needed to do. Your ClipMagic can save image data from the clipboard... perhaps it does that by making the appropriate API calls?mtettmar wrote:You won't get anywhere trying to use the clipboard apis in Macro Scheduler.
Or, are you saying that LibFunc at present can only call "certain" functions within a dll, perhaps ones you're predefined? If the clipboard functions are out-of-reach, please let me know.
But if they're not, please help me get this first call working:
LibFunc>user32,CountClipboardFormats,ccf
or... is there supposed to be an "A" tacked on like this?
LibFunc>user32,CountClipboardFormatsA,ccf
Hmm... I hope its not just that I have to make some other preparitory call first... didn't seem like it to me reading Microsoft's docs.
That "A" is making me crazy by the way... I can't find any info saying what the "A" is for. Again, is this a special "Macro Scheduler" version of the function name?
Thanks for your patience Marcus. I'm looking forward to better understanding how to make Win32 API calls from Macro Scheduler.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
Macro Scheduler's LibFunc command works with DLL functions that accept integer and string (pchar) variables and return integers.
For starters CountClipBoardFormats doesn't want any variables - that's what VOID means. And, at present, LibFunc will only work if there is at least one variable. In time we can improve on that, but right now I'm afraid that's a fact.
In any case to do anything clever with the clipboard you will soon find you need more than just the functions you have seen, which look simple. For example, GetClipboardData gets a HANDLE to an item of data. What will you do with that? Well, you would use the GlobalLock function to lock the memory object and return a pointer to the first byte of the data. The data can then be accessed. But Macro Scheduler/LibFunc does not handle pointers, so you're stuffed at the first hurdle.
Even if you could do that I have still missed crucial stages out such as calls to EnumClipboardFormats, IsClipboardFormatAvailable and RegisterClipboardFormat. And what would you propose to do about image data? Macro Scheduler doesn't provide any way to store bitmap data, so I'm not even sure how you would temporarily store the image data.
If I have understood you correctly you want to get all the available types of data off the clipboard, store them, modify one (or more) of them, and then put them all back. Macro Scheduler does not provide any way to store the data and mirror the clipboard contents.
I think you have found a limit of Macro Scheduler here! If you want to program complex Windows API functions at this kind of level, and you clearly seem ready for the challenge, then perhaps it is time to go and pick up a copy of Visual Studio 2005 (you can get the Express version free) and start coding this in VB,C# or C++. Why not make a library that you can then call with Macro Scheduler?
Also, feel free to post an enhancement suggestion if you feel there is something here that would benefit Macro Scheduler generally. Maybe the new function would be something like:
UpdatePartialClipboard>CLIP_FORMAT,data
e.g.
UpdatePartialClipboard>CF_TEXT,New Data
So what that would do is find the CF_TEXT format on the clipboard, replace it with "New Data" but leave all other formats intact.
I guess this is feasible, but I'd have to study the API more closely. And to add a new function it needs to be something that would benefit the wider userbase.
For starters CountClipBoardFormats doesn't want any variables - that's what VOID means. And, at present, LibFunc will only work if there is at least one variable. In time we can improve on that, but right now I'm afraid that's a fact.
In any case to do anything clever with the clipboard you will soon find you need more than just the functions you have seen, which look simple. For example, GetClipboardData gets a HANDLE to an item of data. What will you do with that? Well, you would use the GlobalLock function to lock the memory object and return a pointer to the first byte of the data. The data can then be accessed. But Macro Scheduler/LibFunc does not handle pointers, so you're stuffed at the first hurdle.
Even if you could do that I have still missed crucial stages out such as calls to EnumClipboardFormats, IsClipboardFormatAvailable and RegisterClipboardFormat. And what would you propose to do about image data? Macro Scheduler doesn't provide any way to store bitmap data, so I'm not even sure how you would temporarily store the image data.
If I have understood you correctly you want to get all the available types of data off the clipboard, store them, modify one (or more) of them, and then put them all back. Macro Scheduler does not provide any way to store the data and mirror the clipboard contents.
I think you have found a limit of Macro Scheduler here! If you want to program complex Windows API functions at this kind of level, and you clearly seem ready for the challenge, then perhaps it is time to go and pick up a copy of Visual Studio 2005 (you can get the Express version free) and start coding this in VB,C# or C++. Why not make a library that you can then call with Macro Scheduler?
Also, feel free to post an enhancement suggestion if you feel there is something here that would benefit Macro Scheduler generally. Maybe the new function would be something like:
UpdatePartialClipboard>CLIP_FORMAT,data
e.g.
UpdatePartialClipboard>CF_TEXT,New Data
So what that would do is find the CF_TEXT format on the clipboard, replace it with "New Data" but leave all other formats intact.
I guess this is feasible, but I'd have to study the API more closely. And to add a new function it needs to be something that would benefit the wider userbase.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
Hi Marcus,
Thanks for the more in-depth answer, that's what I was looking for.
I didn't know LibFunc needs at least one variable to work. The Help file shows it like this:
LibFunc>module,function,resultvar,[[ref:]var1][,[ref:]var2][,...][,[ref:]varn]
...and those [square brackets] I've always taken to mean optional parameters... so I assumed variables were optional.
Please update the Help file on LibFunc to say that only API calls that take at least one variable can be called and maybe remove that one set of square brackets or better yet...
Please enhance LibFunc to handle this. There must be a great many API functions that don't take variables so this should have wide appeal and as a side benefit... you wouldn't have to change the documentation.
Before Macro: Clipboard contents undetermined, could be empty or contain many data types.
During Macro: I want to:
1) Save current clipboard contents somehow, to a variable or to memory or to disk, somewhere, anywhere, just as long as it is a complete copy of whatever might happen to be in the clipboard.
2) Do some processing... key thing here is I'll be using the clipboard (to move text) so the original clipboard contents will be overwritten.
3) Restore the saved clipboard contents and end macro.
After Macro: Clipboard contains exactly what it did before the macro ran.
Notice I'm not changing the saved clipboard contents, I only want to take a snapshot, then later restore it. As an enhancement idea, would the following two new commands be possible?
TakeClipBoardSnapShot
- takes no variables
- writes to a structure in memory created by Macro Scheduler
- multiple calls possible but each call overwrites the same data structure (can keep only one snapshot in memory)
- must be called before RestoreClipBoardfromSnapShot
RestoreClipBoardfromSnapShot
- takes no variables
- reads from a structure in memory created by Macro Scheduler
- multiple calls possible
- if TakeClipBoardSnapShot has not yet been called, it could just do nothing and/or throw an error, set a system variable to indicate an error, etc.
But in case that is asking for too much
I would be happy just being able to call the Win32 API IsClipboardFormatAvailable Function.
I could repeatedly call this API function for each clipboard data format I wanted to check. If nothing was in there or only text formats, then I could restore the clipboard using existing GetClipBoard and PutClipBoard. If I found image formats I cared about, I could popup a warning to the user...
Let>FORMAT=CF_TEXT
Let>FORMAT_SIZE=7
LibFunc>user32,IsClipboardFormatAvailable,RESULT,FORMAT
I made sure the clipboard was empty, then ran that code. The debugger showed the following variables were created:
RESULT_1=CF_TEXT
RESULT=0
So far so good, 0 is supposed to indicate that there is no data on the clipboard in the specified format. So then I copied some text, verified it was in the clipboard then ran the code again... and got exactly the same results, same variables with the same values were created. I tried this for the CF_UNICODETEXT and CF_OEMTEXT formats as well with the same results.
Arrrrrrrrrg.....
Is there something I am not doing correctly? How can I call the Win32 API IsClipboardFormatAvailable Function and actually get back something other than a zero?
Again, your patience and help with the wily windows API is most appreciated.
Thanks for the more in-depth answer, that's what I was looking for.
mtettmar wrote:Macro Scheduler's LibFunc command works with DLL functions that accept integer and string (pchar) variables and return integers.
For starters CountClipBoardFormats doesn't want any variables - that's what VOID means. And, at present, LibFunc will only work if there is at least one variable. In time we can improve on that, but right now I'm afraid that's a fact.

LibFunc>module,function,resultvar,[[ref:]var1][,[ref:]var2][,...][,[ref:]varn]
...and those [square brackets] I've always taken to mean optional parameters... so I assumed variables were optional.



Wow, that sounds powerful (hey I would take it if I could get it) but I don't need to modify. Consider the following states:mtettmar wrote:If I have understood you correctly you want to get all the available types of data off the clipboard, store them, modify one (or more) of them, and then put them all back. Macro Scheduler does not provide any way to store the data and mirror the clipboard contents.
Before Macro: Clipboard contents undetermined, could be empty or contain many data types.
During Macro: I want to:
1) Save current clipboard contents somehow, to a variable or to memory or to disk, somewhere, anywhere, just as long as it is a complete copy of whatever might happen to be in the clipboard.
2) Do some processing... key thing here is I'll be using the clipboard (to move text) so the original clipboard contents will be overwritten.
3) Restore the saved clipboard contents and end macro.
After Macro: Clipboard contains exactly what it did before the macro ran.
Notice I'm not changing the saved clipboard contents, I only want to take a snapshot, then later restore it. As an enhancement idea, would the following two new commands be possible?
TakeClipBoardSnapShot
- takes no variables
- writes to a structure in memory created by Macro Scheduler
- multiple calls possible but each call overwrites the same data structure (can keep only one snapshot in memory)
- must be called before RestoreClipBoardfromSnapShot
RestoreClipBoardfromSnapShot
- takes no variables
- reads from a structure in memory created by Macro Scheduler
- multiple calls possible
- if TakeClipBoardSnapShot has not yet been called, it could just do nothing and/or throw an error, set a system variable to indicate an error, etc.
But in case that is asking for too much

Microsoft's Website wrote:IsClipboardFormatAvailable Function
------------------------------------------
The IsClipboardFormatAvailable function determines whether the clipboard contains data in the specified format.
Syntax
BOOL IsClipboardFormatAvailable(
UINT format
);
Parameters
format
[in] Specifies a standard or registered clipboard format.
For a description of the standard clipboard formats, see Standard Clipboard Formats.
Return Value
If the clipboard format is available, the return value is nonzero.
If the clipboard format is not available, the return value is zero. To get extended error information, call GetLastError.
I could repeatedly call this API function for each clipboard data format I wanted to check. If nothing was in there or only text formats, then I could restore the clipboard using existing GetClipBoard and PutClipBoard. If I found image formats I cared about, I could popup a warning to the user...
OK so I tried to use it like this...Warning Message wrote:Image data detected on the Windows clipboard. Image will be lost if you continue. Continue? Yes/No
Let>FORMAT=CF_TEXT
Let>FORMAT_SIZE=7
LibFunc>user32,IsClipboardFormatAvailable,RESULT,FORMAT
I made sure the clipboard was empty, then ran that code. The debugger showed the following variables were created:
RESULT_1=CF_TEXT
RESULT=0
So far so good, 0 is supposed to indicate that there is no data on the clipboard in the specified format. So then I copied some text, verified it was in the clipboard then ran the code again... and got exactly the same results, same variables with the same values were created. I tried this for the CF_UNICODETEXT and CF_OEMTEXT formats as well with the same results.

Is there something I am not doing correctly? How can I call the Win32 API IsClipboardFormatAvailable Function and actually get back something other than a zero?
Again, your patience and help with the wily windows API is most appreciated.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
Actually, I'm wrong, I just double checked - LibFunc does work with no parameters. But it only works with integer and string parms.jpuziano wrote:The Help file shows it like this:
LibFunc>module,function,resultvar,[[ref:]var1][,[ref:]var2][,...][,[ref:]varn]
...and those [square brackets] I've always taken to mean optional parameters... so I assumed variables were optional.
CF_TEXT, CF_UNICODETEXT and CF_OEMTEXT, etc, are not strings - they are numeric values. So you will get errors as you are trying to pass a string when an integer is expected. Look again at the definition you posted - format is type unit (unsigned integer). In the include files for various development languages they are predefined. In Macro Scheduler you need to define them. So your code should be:Let>FORMAT=CF_TEXT
Let>FORMAT_SIZE=7
LibFunc>user32,IsClipboardFormatAvailable,RESULT,FORMAT
So far so good, 0 is supposed to indicate that there is no data on the clipboard in the specified format. So then I copied some text, verified it was in the clipboard then ran the code again... and got exactly the same results, same variables with the same values were created. I tried this for the CF_UNICODETEXT and CF_OEMTEXT formats as well with the same results.Arrrrrrrrrg.....
Let>CF_TEXT=1
Let>CF_UNICODETEXT=13
Let>CF_OEMTEXT=7
LibFunc>user32,IsClipboardFormatAvailable,RESULT,CF_TEXT
But you are wasting your time here. If you have text on the clipboard you will almost certainly always get a result of 1 if you ask if any of those formats is available, since the text is always available in any of those formats! So, again, I'm not sure what you expect to achieve here.
While I am happy to help as much as I can, I do think we are dangerously close to breaching the scope of Macro Scheduler support here. I don't have the time to teach classes in the Win32 API. There are other, better, places to learn about the Windows API.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
Thank you, that was the problem alright... should have seen that, sorry.mtettmar wrote:CF_TEXT, CF_UNICODETEXT and CF_OEMTEXT, etc, are not strings - they are numeric values. So you will get errors as you are trying to pass a string when an integer is expected. Look again at the definition you posted - format is type unit (unsigned integer). In the include files for various development languages they are predefined. In Macro Scheduler you need to define them. So your code should be:
Let>CF_TEXT=1
Let>CF_UNICODETEXT=13
Let>CF_OEMTEXT=7
LibFunc>user32,IsClipboardFormatAvailable,RESULT,CF_TEXT
Again, just trying to get the API call working, I never cared much about text formats, I need to be able to detect if an image is in the clipboard. If it holds an image, alert the user, if not, carry on.mtettmar wrote:But you are wasting your time here. If you have text on the clipboard you will almost certainly always get a result of 1 if you ask if any of those formats is available, since the text is always available in any of those formats! So, again, I'm not sure what you expect to achieve here.
Not a problem, have it working now, see next post for the code...mtettmar wrote:While I am happy to help as much as I can, I do think we are dangerously close to breaching the scope of Macro Scheduler support here. I don't have the time to teach classes in the Win32 API. There are other, better, places to learn about the Windows API.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

Code: Select all
//Clipboard Format Lister
//Copy your image data to the clipboard then run this macro
//to determine the Clipboard Format it is using to store the data
//Initialize CF array with UNKNOWN
Let>k=0
Repeat>k
Add>k,1
Let>CF[%k%]=UNKNOWN
Until>k=256
//Initialize CF array with known Clipboard Formats
Let>CF[1]=CF_TEXT
Let>CF[2]=CF_BITMAP
Let>CF[3]=CF_METAFILEPICT
Let>CF[4]=CF_SYLK
Let>CF[5]=CF_DIF
Let>CF[6]=CF_TIFF
Let>CF[7]=CF_OEMTEXT
Let>CF[8]=CF_DIB
Let>CF[9]=CF_PALETTE
Let>CF[10]=CF_PENDATA
Let>CF[11]=CF_RIFF
Let>CF[12]=CF_WAVE
Let>CF[13]=CF_UNICODETEXT
Let>CF[14]=CF_ENHMETAFILE
Let>CF[15]=CF_HDROP
Let>CF[16]=CF_LOCALE
Let>CF[128]=CF_OWNERDISPLAY
Let>CF[129]=CF_DSPTEXT
Let>CF[130]=CF_DSPBITMAP
Let>CF[131]=CF_DSPMETAFILEPICT
Let>CF[142]=CF_DSPENHMETAFILE
//Use Win32 API call to see which clipboard formats are available
//A non-zero return value indicates format is available
Let>FORMAT=0
Let>OUTPUT=Found these data formats on clipboard:%CRLF%%CRLF%
Repeat>FORMAT
Add>FORMAT,1
LibFunc>user32,IsClipboardFormatAvailable,RESULT,FORMAT
If>RESULT=0,Skip
Let>FORMAT_NAME=CF[%FORMAT%]
ConCat>OUTPUT,%FORMAT_NAME% (%FORMAT%)%CRLF%
Label>Skip
Until>FORMAT=256
MessageModal>%OUTPUT%
Code: Select all
//Test for CF_BITMAP format data on clipboard
LibFunc>user32,IsClipboardFormatAvailable,RESULT,2
If>RESULT=0,Carry_On
//Image found on Clipboard so alert user
Ask>Warning - Image found on Clipboard%CRLF%will be lost if you continue.%CRLF%%CRLF%Click "Yes" to continue (image will be lost)%CRLF%or click "No" to abort and view your clipboard,continue
If>continue=YES,Carry_On
//Display Clipboard (Windows 2000)
Run>C:\WINNT\system32\clipbrd.exe
GoTo>End
Label>Carry_On
//rest of code continues here...
//
Label>End
If the user decides to abort and view their clipboard, I have it fire up the clipboard viewer. If you are not running Windows 2000, search for clipbrd.exe on your system to find where it is or google "clipboard viewer" and/or "clipbook" for more info.
Thanks again Marcus for your help and patience on this one... and all the others who post much useful code on these forums.

jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -

jpuziano,
I've been following this post with interest. Waiting to see what you and Marcus work out. I am not a programmer and know very little about how graphic images are processed within the operating system. (I can use copy and paste.) I've been surprised by Marcus' responses regarding the difficulty of dealing with graphic images. I believe him, he's rarely wrong. However the MS function "ScreenCapture" can grab a specified section of screen, save it to a file and put it into the clipboard. If Marcus can do that, why can't he also take whatever is already in the clipboard and write it to a file. The other needed process would be to take the file and put it into the clipboard which is obviously the reverse process and quite possibly more difficult.
You appear to have done quite a bit of work with this. Now that you've worked out a solution I have discovered a different way to handle this problem that may or may not appeal to you. It requires the use of an image processing software called IrFanView. It is freeware and can be downloaded here:
http://www.irfanview.com
As I was reading your last post this morning, it occured to me that IrFanView has command line parameters that might be able to save the clipboard to a file and retrieve the file back into the clipboard transparently. So I checked it out and I'm posting your script with alterations to use IrFanView to do just that. Sorry it didn't occur to me before today but better late than never...(?)
To use this, IrFanView needs to be installed in its default directory, C:\Program Files\IrfanView.
Hope that you or someone else finds this useful,
Dick
Edit-1
Replaced the filename ~sreenshot~.jpg with ~screenshot~.jpg in the following script.
Edit-2
Reposted script with HTML turned off
I've been following this post with interest. Waiting to see what you and Marcus work out. I am not a programmer and know very little about how graphic images are processed within the operating system. (I can use copy and paste.) I've been surprised by Marcus' responses regarding the difficulty of dealing with graphic images. I believe him, he's rarely wrong. However the MS function "ScreenCapture" can grab a specified section of screen, save it to a file and put it into the clipboard. If Marcus can do that, why can't he also take whatever is already in the clipboard and write it to a file. The other needed process would be to take the file and put it into the clipboard which is obviously the reverse process and quite possibly more difficult.
You appear to have done quite a bit of work with this. Now that you've worked out a solution I have discovered a different way to handle this problem that may or may not appeal to you. It requires the use of an image processing software called IrFanView. It is freeware and can be downloaded here:
http://www.irfanview.com
As I was reading your last post this morning, it occured to me that IrFanView has command line parameters that might be able to save the clipboard to a file and retrieve the file back into the clipboard transparently. So I checked it out and I'm posting your script with alterations to use IrFanView to do just that. Sorry it didn't occur to me before today but better late than never...(?)
To use this, IrFanView needs to be installed in its default directory, C:\Program Files\IrfanView.
Hope that you or someone else finds this useful,
Dick
Edit-1
Replaced the filename ~sreenshot~.jpg with ~screenshot~.jpg in the following script.
Edit-2
Reposted script with HTML turned off
Code: Select all
//Check for IrFanView
IfFileExists>C:\Program Files\IrfanView\i_view32.exe
Goto>start
Else
MDL>IrFanView is not installed or is not installed in the default directory.%CRLF%Processing will cease...
Goto>End
EndIF
//Delete clipboard save image file if it preexists
Label>start
IfFileExists>c:\~screenshot~.jpg
DeleteFile>c:\~screenshot~.jpg
EndIf
//Clipboard Format Lister
//Copy your image data to the clipboard then run this macro
//to determine the Clipboard Format it is using to store the data
//Initialize CF array with UNKNOWN
Let>k=0
Repeat>k
Add>k,1
Let>CF[%k%]=UNKNOWN
Until>k=256
//Initialize CF array with known Clipboard Formats
Let>CF[1]=CF_TEXT
Let>CF[2]=CF_BITMAP
Let>CF[3]=CF_METAFILEPICT
Let>CF[4]=CF_SYLK
Let>CF[5]=CF_DIF
Let>CF[6]=CF_TIFF
Let>CF[7]=CF_OEMTEXT
Let>CF[8]=CF_DIB
Let>CF[9]=CF_PALETTE
Let>CF[10]=CF_PENDATA
Let>CF[11]=CF_RIFF
Let>CF[12]=CF_WAVE
Let>CF[13]=CF_UNICODETEXT
Let>CF[14]=CF_ENHMETAFILE
Let>CF[15]=CF_HDROP
Let>CF[16]=CF_LOCALE
Let>CF[128]=CF_OWNERDISPLAY
Let>CF[129]=CF_DSPTEXT
Let>CF[130]=CF_DSPBITMAP
Let>CF[131]=CF_DSPMETAFILEPICT
Let>CF[142]=CF_DSPENHMETAFILE
//Use Win32 API call to see which clipboard formats are available
//A non-zero return value indicates format is available
Let>FORMAT=0
Let>OUTPUT=Found these data formats on clipboard:%CRLF%%CRLF%
Repeat>FORMAT
Add>FORMAT,1
LibFunc>user32,IsClipboardFormatAvailable,RESULT,FORMAT
If>RESULT=0,Skip
Let>FORMAT_NAME=CF[%FORMAT%]
ConCat>OUTPUT,%FORMAT_NAME% (%FORMAT%)%CRLF%
Label>Skip
Until>FORMAT=256
MessageModal>%OUTPUT%
//Test for CF_BITMAP format data on clipboard
LibFunc>user32,IsClipboardFormatAvailable,RESULT,2
If>RESULT=0,Carry_On
//Image found on Clipboard save it.
Let>RP_WAIT=1
Let>RP_WINDOWMODE=2
Run>cmd /c "C:\Program Files\IrfanView\i_view32.exe" /clippaste /convert=c:\~screenshot~.jpg
//Image found on Clipboard so alert user
//Ask>Warning - Image found on Clipboard%CRLF%will be lost if you continue.%CRLF%%CRLF%Click "Yes" to continue (image will be lost)%CRLF%or click "No" to abort and view your clipboard,continue
//If>continue=YES,Carry_On
//Display Clipboard (Windows 2000)
//Run>C:\WINNT\system32\clipbrd.exe
//GoTo>End
Label>Carry_On
PutClipBoard>Hello jpuziano !!
MDL>Clipboard has been saved to a file. And clipboard has been overwritten with text.%CRLF%Check clipboard contents to confirm.
//rest of code continues here...
//
//
//
//code complete. put image back in clipboard.
IfFileExists>c:\~screenshot~.jpg
Let>RP_WAIT=1
Let>RP_WINDOWMODE=2
//
// WARNING
//
// The /killmesoftly parameter will close all instances of IrFanView
//
//
Run>cmd /c "C:\Program Files\IrfanView\i_view32.exe" c:\~screenshot~.jpg /clipcopy /killmesoftly
DeleteFile>c:\~screenshot~.jpg
EndIf
Label>End
Last edited by JRL on Wed Oct 11, 2006 9:11 pm, edited 3 times in total.
- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
Dick,
I wasn't saying it isn't something that can be added as standard functionality - retrieving image items from the clipboard and putting them back is fairly easy. But I was saying that it can't be done easily with existing Macro Scheduler code. The issue was to do with the limitations surrounding the use of the API, and clipboard, within Macro Scheduler as it stands. I did in fact propose a new command that would do what was required.
I wasn't saying it isn't something that can be added as standard functionality - retrieving image items from the clipboard and putting them back is fairly easy. But I was saying that it can't be done easily with existing Macro Scheduler code. The issue was to do with the limitations surrounding the use of the API, and clipboard, within Macro Scheduler as it stands. I did in fact propose a new command that would do what was required.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
Hi JRL,
Thank you very much for sharing that.
I can use the Win32 API call to detect the image on the clipboard... and now using Irfanview, I can save also save it to a file and restore it to the clipboard just before exiting the macro.
This is fine for my machine but the macro I am working on is one that will be used in compiled form by users that cannot install Irfanview because their LAN folks keep things locked down so unfortunately, this solution won't work for them.
Marcus, you say in the above post that Clipboard Image Save-To-File and Restore-From-File ability wouldn't be that hard to add.... so I will add this as an enhancement idea in the enhancement forum. Thanks for helping me to get the API call working and thanks JRL for the Irfanview save/restore solution... much appreciated.
Thank you very much for sharing that.
I can use the Win32 API call to detect the image on the clipboard... and now using Irfanview, I can save also save it to a file and restore it to the clipboard just before exiting the macro.
This is fine for my machine but the macro I am working on is one that will be used in compiled form by users that cannot install Irfanview because their LAN folks keep things locked down so unfortunately, this solution won't work for them.
Marcus, you say in the above post that Clipboard Image Save-To-File and Restore-From-File ability wouldn't be that hard to add.... so I will add this as an enhancement idea in the enhancement forum. Thanks for helping me to get the API call working and thanks JRL for the Irfanview save/restore solution... much appreciated.
jpuziano
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post -
