Click here to Skip to main content
Click here to Skip to main content

Clipboard ActiveX for Image Copy/Paste into Web Forms

By , 11 May 2008
 

Introduction

One of my client requirements was to use Windows copy/paste functionality on Web forms for Images. The client wished to have CTRL+V to paste any image on the client machine or on the clipboard. I just did some Googling and got few modules performing individual tasks. I modified them as per my requirements. The ActiveX gives the following functionalities:

  • Copy Image files from client machine and paste it into our Web forms
  • Upload that image onto our server
  • Use any image content like Microsoft Paint to use cropped part of any image, or Print Screen etc.

Note: My requirement was for using multiple DIVs on forms to use these functionalities, and hence you will find some conditions in JavaScript code in the demo project.

Requirements

As this is a very basic ActiveX control, it has not been signed yet. So in order to use this activeX, you need to Add your site to "Trusted Sites" as well as reduce your browser security levels down so that your browser can use unsigned ActiveX controls for the time being.

You can do this by going to Tools >> Options >> Security >> Trusted Sites.

If you are uploading an image to the server, your Web site requires one folder called Upload with appropriate privileges.

Using the Code

This whole implementation is full use of JavaScripts. I am showing you the important ones here. Form's BODY tag is calling the KeyPress() event, and that function calls the fnCall() function which performs the core operation of Copy/Paste.

Code Description for Demo Project

The HttpUtil1.aspx page is used to upload the pasted image onto the server. postVar is used to pass the query string values to that httpUtil page, id is used to create a sub folder under the Upload folder and will upload a file into it. You can use any generated random number to create different folders each time.

 strURL = strURL + "/HttpUtil1.aspx";
                        postVar = "id=1";

This ActiveX creates temporary files on the client's machine. It only creates files if the user has not copied any existing image (like Paint cut or Print Screen etc). The path where it creates those files can be configured from the code below:

// Getting the Physical path on which the images will be stored on client machine.
var PhysicalPathForTempImage = "c:\\Amit\\";

Below is the call to the ActiveX method to create and save clipboard image onto the client's machine which later can be uploaded onto the server.

var strFilePath = objActiveX.getCopiedImage(PhysicalPathForTempImage);

After pasting the image into DIV, we can upload that onto the server with the same ActiveX. We cannot directly upload the image using any server code or JavaScript since what we have on hand is just fileName, instead of any fileUpload object containing image stream or something like that. So that uploading logic has been shifted into ActiveX logic.

response = objActiveX.UploadFiles(strFileName,strURL,postVar);

Code Description for ActiveX Project

I have used the basic USE32 for clipboard operations and kernel32 for GlobalAlloc, GlobalFree, GlobalLock, etc.

' Clipboard routines.
Private Declare Function OpenClipboard Lib "USER32" (ByVal hWnd As Long) As Long
Private Declare Function CloseClipboard Lib "USER32" () As Long
Private Declare Function SetClipboardData Lib "USER32" _
    (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function GetClipboardData Lib "USER32" (ByVal wFormat As Long) As Long

' Global memory routines.
Private Declare Function GlobalAlloc Lib "kernel32" _
    (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)

Below is the call to SaveAsJPG module to save the image content into an image file. This saves the file in very compressed size, unlike if we use the SavePicture() method of VB 6.0 which saves files around 2-3 MB in size, while this module saves a file around 60-80 KB of size.

Call SaveAsJPG.SaveJPG(Clipboard.GetData(vbCFBitmap), strTargetFilePath)

In order to upload the pasted image, this ActiveX method sends an HTTP Request to the httpUtil.aspx page to save the image contents to server.

Function UploadFiles(strFileName1 As String, strUrl As String, _
    Optional postVar As String, _
    Optional strUserName As String, Optional strPassword As String) As String

' Set the user name and password.
        WinHttpReq.SetCredentials strUserName, strPassword, _
        HTTPREQUEST_SETCREDENTIALS_FOR_SERVER

Points of Interest

When I started merging different modules into ActiveX, I lost link of the module to save the image in compressed mode, and hence my images were generating with a bulky size. I searched a lot to get that module. Finally, I found it from my Google history which I browsed few months ago. Thanks to Google for keeping my browsed links.

History

  • 11th May, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

AmitChampaneri
Software Developer (Senior) Elan Emerging Technologies Pvt Ltd.
India India
Member
I am a master graduate from Ahmedabad,India.I am in programming since last 2 years,and i love this job of programmer and wanted to do programming for lifetime.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNot working on issmemberaltanaltan22 May '13 - 2:54 
hi,
 
When i run this code on my local project this is work properly. But i add my project on iss to run i receive an error.
 
var strFilePath = objActiveX.getCopiedImage(PhysicalPathForTempImage);
//this line getCopiedImage undefined
BugDemo Problem [modified]membersmurpetx26 Dec '12 - 20:08 
how can i view the uploaded image after uploading it ? im using window snipping tool for image to copy in clipboard. Unsure | :~ i mean how would i able to save the temp filename to my server database ? Sleepy | :zzz:
Sigh | :sigh:
 
Demo works great on my local machine, but when i implement it in server. temp picture always save on client side not on server side. I to work on about saving directly the image from clipboard to server. Any kind of help about my problem would be really appreciated. Thumbs Up | :thumbsup:
 
Jan 24, 2013 - Can't upload the pasted image onto the server.
 
function uplImages()
  {                                          
    flagUploadingStarted = true;
      // Uploading Image 1 if its present.
    if(document.getElementById("<%= hdnImageFileName1.ClientID %>").value != "")
    {       
       // Keep getting Error here says  "Object Required."
       uploadImage1(document.getElementById("<%= hdnImageFileName1.ClientId %>").value) 
    }
   }
 
i try : alert(response)
and i get the html/Javascript content of HttpUtil1.aspx in alert box. Cry | :((

modified 23 Jan '13 - 20:44.

Questionget the file pathmemberMember 927009611 Oct '12 - 19:13 
Hello Amit,
 
Your demo works very well on my PC.
I save screenshot in temporary folder and folder destination.
 
My situation : I would like send a issue tracking form with screenshot via sharepoint (c#).
I can't find any solution like yours for insert with easy ctrl+v a clipboard screenshot into IE.
IE insert only clipboard text...
 
My question :
When i save a form with a screenshot with your solution, how can I view this screenshot when i will read the form after ?
Do you think, the form can record the screenshot AND the filepath in the same time ?
May be with PhysicalPathForTempImage ?
 
Bonus :
How to use multiple screenshot in the same time ?
 
I'm newbie on VB, then thank you for your easy explanation Wink | ;)
Sorry for my english also, is not my maternal language.
 
Guillaume.
AnswerRe: get the file pathmembersmurpetx23 Jan '13 - 21:03 
Hello ! I have the same situation as you, i can save temp file(which is already in .jpeg format) on client machine. But the thing is i couldn't get it done to save onto the web server. I wanna ask you if you already save the picture onto the server? and How ? Dead | X|
GeneralRe: get the file pathmemberMember 927009624 Jan '13 - 11:54 
Hello,
 
I abandoned this solution.
I developed my own sharepoint wsp solution.
It works fine under Internet Explorer.
It is simple and requires little code.
I do not have time to give more details.
I use an AUTOit script and a login command in my wsp to create a network drive under client computer from a folder on sharepoint server.
 
If i have more time, I will send you more details later.
Best regards.
Guillaume.
 

My AUTOit Script (in French...)
;Fonctionnement du script
;créer un folder accessible depuis le _layouts pour accéder à l'appli de capture et stocker les printscreens
;sous windows seven on peut mapper une picturelibrary. Boggué sous winXp accessible en tant que WebFolder seulement
;le bouton de sharepoint lance le mapping et accède à l'appli de capture
;on ouvre l'image sous IExplorer pour copier/coller
#include <IE.au3>
#include <ScreenCapture.au3>
#include <ClipBoard.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Misc.au3>
#include <Date.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
 

Opt("TrayIconHide", 0) ;0=show, 1=hide tray icon
 
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sJPG_File, $img
 
MsgBox(0, "Lancement Application Capture", "Lancement de l'application Capture écran",2)
 
$hMain_GUI = GUICreate("Capture écran", 300, 60)
WinSetOnTop($hMain_GUI, "", 1)
 
$hRect_Button   = GUICtrlCreateButton("1. Sélectionnez la zone",  5, 25, 125, 30)
$hCancel_Button = GUICtrlCreateButton("2. Arrêtez la capture",    170, 25, 125, 30)
$Label1 = GUICtrlCreateLabel("Positionnez-vous sur l'écran puis, cliquez sur le bouton 1 ou 2", 5, 5, 302, 17)
GUISetState()
 
While 1
 
    Switch GUIGetMsg()
 
        Case $GUI_EVENT_CLOSE, $hCancel_Button
            Exit
        Case $hRect_Button
            GUISetState(@SW_HIDE, $hMain_GUI)
            Mark_Rect()
			Local $img = _ScreenCapture_Capture()
            $sJPG_File = @YEAR & "-" & @MON & "-" & @MDAY & "-" & @HOUR & "h" & @MIN & "m" & ".jpg"
            _ScreenCapture_Capture("M:\\" & $sJPG_File, $iX1, $iY1, $iX2, $iY2, False)
 
Local $script_browser = _IECreate()
_IENavigate($script_browser, "http://dbo-vmt-shrp10/_layouts/ScreenShotButton/" & $sJPG_File)
    
Send("!{SPACE}")
Sleep(500)
Send("{n}") ; touche n pour windows french. Touche x pour windows english
MouseClick("left")
Send("^a")
Sleep(500)
Send("^c")
Sleep(500)
Send("!{F4}")
 
MsgBox(0, "Capture écran", "Utilisez les touches Ctrl + V pour coller votre capture")
Exit ;close printscreen area executable
EndSwitch
 
	WEnd
 
; -------------
 
Func Mark_Rect()
 
    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")
 
    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 50)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)
 
    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd
 
    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]
 
    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)
 
        $aMouse_Pos = MouseGetPos()
 
        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf
 
        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)
 
        Sleep(10)
 
    WEnd
 
    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]
 
    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf
 
    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)
 
EndFunc   ;==>Mark_Rect
 
Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)
 
    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)
 
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)
 
    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)
 
    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)
 
EndFunc
 

 


GeneralRe: get the file pathmembersmurpetx24 Jan '13 - 14:13 
Thanks for the reply man.
 
is it the same as here ? i mean, Paste image from clipboard to web form and save it onto the server ?
 

i'll give it a shot to try out what you said. Thumbs Up | :thumbsup:
GeneralRe: get the file pathmemberMember 927009624 Jan '13 - 15:21 
Smurpetx,
 
1. I click on form button from sharepoint
2. autoit script start (and create a network link to folder on shrepoint server)
3. I click on button select area
4. I save image on server
5. I load image from server into IExplorer (important ! At this time IExplorer authorize to use copy/paste image clipboard...Otherwise copy/paste clipboard image from Word or grabscreen is disable by MS for security... )
6. At the end I use shortcut ctrl+v to paste my image (save and read from server) into sharepoint form.
 
I'm not sure I answered your question ?
Best regards.
Guillaume.
GeneralRe: get the file pathmembersmurpetx24 Jan '13 - 16:38 
Well, im quite new at PHP/Javascript so im having a hard time understanding what did you do, but its worth trying though.
 
i have a question related on your first post
 
"(1) I save screenshot in temporary folder and (2) folder destination."
 
(1) when you paste the img to the div using ClipboardActiveX.dll , it will save onto the path PhysicalPathForTempImage in the Client Side, (2) What "folder destination" you pointing out ? folder in the server ? .
 
Thanks for the help. I'll try the sharepoint.Thumbs Up | :thumbsup: Laugh | :laugh:
QuestiontroublememberTodor Ivanov Ginchev27 Jul '12 - 3:56 
The ActiveX works quite as expected, untill I've placed in over dns and IIS. I keep getting 401.2 access denied error when I try to upload the locally saved picture to my server.
 
Interestingly, when I use url like http://localhost.... it runs fine.
 
Any ideas would be greatly appreciated, as the activeX is worth using generally...
QuestionTrying to run the demomemberMember 797599112 Oct '11 - 7:05 
Hey can anyone give me an idea of how to make this demo..i am kind of new to visual studio, i had it installed in my system..i am trying to figure out how to run this demo, and actually use this code in my form..can anyone help??Confused | :confused:

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 11 May 2008
Article Copyright 2008 by AmitChampaneri
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid