simbo Posted January 2, 2008 Share Posted January 2, 2008 Hello All, and Happy New Year I've written a program with a number of input boxes that the user can type into. They may wish to paste something in from the clipboard. The challenge is that I don't want the user to be able to paste straight in, I want to first check the clipboard and possibly format it in some way before either letting it be pasted straight in or using guictrlsetdata to put the formatted version into the input box they've just tried to paste into. How do I capture the paste command? I'm guessing it's something to do with GUIRegisterMsg and $WM_PASTE, but I can't seem to work it out I'm thinking something like this:- #include <GUIConstants.au3> $my_gui=GUICreate("Type or paste some stuff",700,500,-1,-1,$WS_THICKFRAME,-1) guisetstate (@SW_SHOW) $my_input=GUICtrlCreateInput("",20,20,400,250) GUIRegisterMsg($WM_PASTE, 'do_clever_stuff_with_clipboard') While 1 $gm = GUIGetMsg() Switch $gm Case -3; $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func do_clever_stuff_with_clipboard() $clipboard=ClipGet() ;generally fiddle about with $clipboard ; then either send("^v") or GUICtrlSetData($my_input,$clipboard) EndFunc Many thanks in advance Simbo Link to comment Share on other sites More sharing options...
rover Posted January 2, 2008 Share Posted January 2, 2008 perhaps just monitor the input controls and compare to current clipboard contents so if content of one of the inputs is same as clipboard then reformat the text and guictrlsetdata the input. The $WM_PASTE message I think has to be sifted out of WM_COMMAND messages maybe someone will jump in here and give a more informed answer. #include <GUIConstants.au3> $gui = GUICreate("GUI input", 320, 120, @DesktopWidth / 2 - 160, @DesktopHeight / 2 - 45) $ret = GUICtrlCreateInput("", 10, 35, 300, 20) $btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20) GUISetState() $Timer = TimerInit() While 1 $msg = GUIGetMsg() Switch $msg Case $btn MsgBox(0, "", GUICtrlRead($ret)) Exit Case $GUI_EVENT_CLOSE Exit EndSwitch If TimerDiff($Timer) >= 100 Then $intext = GUICtrlRead($ret) $cliptext = ClipGet() If $intext = $cliptext Then ; do string manipulation here GUICtrlSetData($ret, "Info: " & $intext) ; pasting into message box will append text 'Info:' EndIf $Timer = TimerInit() EndIf WEnd I see fascists... Link to comment Share on other sites More sharing options...
Siao Posted January 2, 2008 Share Posted January 2, 2008 (edited) GuiRegisterMsg lets you work with messages of the main window. To work with messages of controls (such as in your case WM_PASTE to edit control), you need to subclass that control. expandcollapse popup#include <GUIConstants.au3> #Include <GuiEdit.au3> $hGui = GUICreate("Type or paste some stuff",400,200,-1,-1,$WS_THICKFRAME,-1) $cInput = GUICtrlCreateInput("",20,20,360,20) $cInput2 = GUICtrlCreateInput("",20,50,360,20) $wProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr") $wProcOld = _WinSubclass(GUICtrlGetHandle($cInput), DllCallbackGetPtr($wProcNew)) _WinSubclass(GUICtrlGetHandle($cInput2), DllCallbackGetPtr($wProcNew)) ;_WinSubclass(GUICtrlGetHandle($cInput3), DllCallbackGetPtr($wProcNew)) and so on GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func do_clever_stuff_with_clipboard($hWnd) $sData = ClipGet() If @error Then Return 0;clip data is not text or clip empty ;do whatever $sData = StringUpper($sData) ;set text GUICtrlSetData(_WinAPI_GetDlgCtrlID($hWnd), $sData);or _GUICtrlEdit_SetText($hWnd, $sData) Return 1 EndFunc Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam) Switch $uiMsg Case $WM_PASTE Return do_clever_stuff_with_clipboard($hWnd) EndSwitch ;pass the unhandled messages to default WindowProc Return _CallWindowProc($wProcOld, $hWnd, $uiMsg, $wParam, $lParam) EndFunc Func _CallWindowProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam) Local $aRet = DllCall('user32.dll', 'int', 'CallWindowProc', 'ptr', $lpPrevWndFunc, 'hwnd', $hWnd, 'uint', $Msg, 'wparam', $wParam, 'lparam', $lParam) Return $aRet[0] EndFunc ;-- Wrapper for SetWindowLong API Func _WinSubclass($hWnd, $lpNewWindowProc) ;#define GWL_WNDPROC (-4) Local $aTmp, $sFunc = "SetWindowLong" If @Unicode Then $sFunc &= "W" $aTmp = DllCall("user32.dll", "ptr", $sFunc, "hwnd", $hWnd, "int", -4, "ptr", $lpNewWindowProc) If @error Then Return SetError(1, 0, 0) If $aTmp[0] = 0 Then Return SetError(1, 0, 0) Return $aTmp[0] EndFunc ;==>_WinSubclass As for what to do once you get to that WM_PASTE, you can do whichever way you like. Get the clipboard and set the data to control yourself like in the example above, or modify the clipboard directly and proceed with the default handler. Edited January 2, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
simbo Posted January 2, 2008 Author Share Posted January 2, 2008 GuiRegisterMsg lets you work with messages of the main window. To work with messages of controls (such as in your case WM_PASTE to edit control), you need to subclass that control. expandcollapse popup#include <GUIConstants.au3> $hGui = GUICreate("Type or paste some stuff",400,200,-1,-1,$WS_THICKFRAME,-1) $cInput = GUICtrlCreateInput("",20,20,360,20) $hInput = GUICtrlGetHandle($cInput) $wProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr") $wProcOld = _WinSubclass($hInput, DllCallbackGetPtr($wProcNew)) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func do_clever_stuff_with_clipboard() $sData = ClipGet() If @error Then Return 0;clip data is not text or clip empty ;do whatever $sData = StringUpper($sData) ;set text GUICtrlSetData($cInput, $sData) Return 1 EndFunc Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam) Switch $uiMsg Case $WM_PASTE Return do_clever_stuff_with_clipboard() EndSwitch ;pass the unhandled messages to default WindowProc Return _CallWindowProc($wProcOld, $hInput, $uiMsg, $wParam, $lParam) EndFunc Func _CallWindowProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam) Local $aRet = DllCall('user32.dll', 'int', 'CallWindowProc', 'ptr', $lpPrevWndFunc, 'hwnd', $hWnd, 'uint', $Msg, 'wparam', $wParam, 'lparam', $lParam) Return $aRet[0] EndFunc ;-- Wrapper for SetWindowLong API Func _WinSubclass($hWnd, $lpNewWindowProc) ;#define GWL_WNDPROC (-4) Local $aTmp, $sFunc = "SetWindowLong" If @Unicode Then $sFunc &= "W" $aTmp = DllCall("user32.dll", "ptr", $sFunc, "hwnd", $hWnd, "int", -4, "ptr", $lpNewWindowProc) If @error Then Return SetError(1, 0, 0) If $aTmp[0] = 0 Then Return SetError(1, 0, 0) Return $aTmp[0] EndFunc ;==>_WinSubclass As for what to do once you get to that WM_PASTE, you can do whichever way you like. Get the clipboard and set the data to control yourself like in the example above, or modify the clipboard directly and proceed with the default handler. Thanks very much for that Siao - you've hit the proverbial nail on the head I can't pretend to be clever enough to really understand how it works!! (although I've had a good go using the help file) I perhaps should have put more input boxes in my example as my program uses several. I've tried altering your code to assign the boxes to an array, a bit like this:- for $i=0 to 9 $cInput[$i] = GUICtrlCreateInput("",20,30*$i,360,20) $hInput[$i] = GUICtrlGetHandle($cInput[$i]) next - but I'm in over my head! Is such a thing possible? Any help would be much appreciated as it's the last thing I've got to do on my program (probably because I've been putting it off!) Thanks again, Simbo Link to comment Share on other sites More sharing options...
Siao Posted January 2, 2008 Share Posted January 2, 2008 (edited) Ok, modified example in my post above to work with multiple input controls... Edited January 2, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
GEOSoft Posted January 2, 2008 Share Posted January 2, 2008 There is always the simple method If GUICtrlRead($myInput) == ClipGet() Then MsgBox(0, "CHEATER!", "You tried to cheat me by pasting from the clipboard") GUICtrlSetData($myInput, "") ClipPut("") GUICtrlSetState($myInput, 512) Else MsgBox(0, "OK", "You passed the acid test") EndIf George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
simbo Posted January 11, 2008 Author Share Posted January 11, 2008 Ok, modified example in my post above to work with multiple input controls...Thanks very much Siao, I'm still not entirely with it, but I've got it to work!I'd have been there forever trying to figure that out.Best wishesMatt Link to comment Share on other sites More sharing options...
LarryDalooza Posted January 11, 2008 Share Posted January 11, 2008 There is some API called SetClipboardViewer or something also... worth a research... Lar. AutoIt has helped make me wealthy Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now