Way to tell if clipboard has column-block in it before pasting?



  • Hello all,

    Is there a way to tell if clipboard has column-block in it without actually pasting? I’m speaking in a Pythonscript context…can I tell before I do an editor.paste() function call if what I will be pasting is something that was a column-block selection at the point it was copied to the clipboard?

    Thanks!



  • @Alan-Kilborn

    more or less - depends what exactly should be done.
    What comes first into my mind is using editor.selectionIsRectangle.
    If it returns True it is column mode but this of course means the selection is
    still active.

    If this doesn’t answer your question you may provide more infos how your script
    should work exactly.

    Cheers
    Claudia



  • @Claudia-Frank

    Thank you for your reply. I was thinking in terms of possibly the selection being made some time ago, i.e., not currently active, maybe there is another selection currently active for drag-and-drop movement purpose…the point is, nothing has been copied to the clipboard since the column block was. So the column block is still there, and N++ knows it…but can I also know it from my script somehow?



  • @Alan-Kilborn

    actually I think npp doesn’t know it but scintilla does.

    In theory you should be able to do it

    1. Install a clipboard watcher (ctypes and windows api required)
    2. whenever clipboard data changes, check if selection was rectangle

    But I still don’t get the point why it is necessary to do it as scintilla is handling it for you.

    Cheers
    Claudia



  • @Claudia-Frank

    Hi Claudia, I forgot about this for a while. :(

    But now I’m interested again.

    I looked up how to install a clipboard viewer in the chain using C and the Windows API, and I am a little familiar with Python’s ctypes, but I don’t really see how to put it all together. The first thing I’m confused on is the hwnd I would use…but I’m sure there’s more. Can you possibly show me how to do this? TIA…



  • @Alan-Kilborn

    Hi Alan,

    I guess it is the hwnd from npp which you can get by using FindWindow API call.
    and in order to receive the WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD messages
    you need to register a hook like I did here.

    Don’t forget to pass the message to the next viewer in chain like described in this example.

    Note, there is also an win32clipboard module available which could make it more easy just make sure
    it is installed in a directory which is resolved by sys.path.

    I’m kinda unsure how a “linux” clipboard would act but let me know if I should give it a try.

    Cheers
    Claudia



  • @Alan-Kilborn & @Claudia-Frank ,

    Here’s HookForClipboardUpdate.py that provides the desired functionality.

    import ctypes, os
    from ctypes.wintypes import LONG, HWND, UINT, WPARAM, LPARAM
    
    SetWindowLong = ctypes.windll.user32.SetWindowLongA
    CallWindowProc = ctypes.windll.user32.CallWindowProcA
    FindWindow = ctypes.windll.user32.FindWindowA
    AddClipboardFormatListener = ctypes.windll.user32.AddClipboardFormatListener
    RemoveClipboardFormatListener = ctypes.windll.user32.RemoveClipboardFormatListener
    IsClipboardFormatAvailable = ctypes.windll.user32.IsClipboardFormatAvailable
    
    WndProcType = ctypes.WINFUNCTYPE(LONG, HWND, UINT, WPARAM, LPARAM)
    
    GWL_WNDPROC = -4
    WM_CLIPBOARDUPDATE = 0x31D
    CF_TEXT = 1
    CF_UNICODETEXT = 13
    
    class Hook():
    
        def __init__(self):
            self.nppHandle = FindWindow('Notepad++', None)
    
        def register(self):
            self.newWndProc = WndProcType(self.MyWndProc)
            self.oldWndProc = SetWindowLong(self.nppHandle, GWL_WNDPROC, self.newWndProc)
            console.editor.setProperty('oldWndProc', self.oldWndProc)
            AddClipboardFormatListener(self.nppHandle)
            print "registered"
    
        def unregister(self):
            self.prevWndProc = console.editor.getProperty('oldWndProc')
            dummy = SetWindowLong(self.nppHandle, GWL_WNDPROC, int(self.prevWndProc))
            RemoveClipboardFormatListener(self.nppHandle)
            print "unregistered"
    
        def MyWndProc(self, hWnd, msg, wParam, lParam):
            if msg == WM_CLIPBOARDUPDATE:
                self.clipboardUpdate()
            return CallWindowProc(self.oldWndProc, hWnd, msg, wParam, lParam)
    
        def clipboardUpdate(self):
            print "got clipboard update"
            if IsClipboardFormatAvailable(CF_TEXT) or IsClipboardFormatAvailable(CF_UNICODETEXT):
                print "clipboard contains text"
                print "selection is {}rectangular".format('' if editor.selectionIsRectangle() else 'NOT ')
    
    _hook = Hook()
    
    if console.editor.getProperty('Hookstatus') != '1':
        console.editor.setProperty('Hookstatus', '1')
        _hook.register()
    else:
        console.editor.setProperty('Hookstatus', '0')
        _hook.unregister()
    

    @Alan-Kilborn , at the point where the above program prints whether or not the clipboard text is rectangular or not, set a global variable that reflects the setting, that your other script(s) can then query.

    If this (or ANY) posting was useful, don’t post a “thanks”, just upvote ( click the ^ in the ^ 0 v area on the right ).


  • Banned

    This post is deleted!


  • @Scott-Sumner

    and this works under linux/wine as well. :-)
    Another nice one.

    Cheers
    Claudia


Log in to reply