Community
    • Login

    Copying file itself into clipboard in Notepad++

    Scheduled Pinned Locked Moved General Discussion
    23 Posts 6 Posters 2.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Alan KilbornA
      Alan Kilborn
      last edited by Alan Kilborn

      @mkupper

      I’m sorry but I think you are still (mostly) way off base. :-(


      OK, since @Ekopalypse hasn’t chimed in, I’m going to go ahead and post this code that I think originated with him and somehow made its way to me, possibly via a third party.
      I’m not sure about anything, because I (unusually) have no extra notes about it. :-(

      I tested this script code and it worked for me under PythonScript 3.x, but I can see some possible holes in the script just giving it a glance-over, so users beware.

      It copies the active tab to the clipboard as a file.

      import ctypes
      from ctypes import wintypes
      
      CF_HDROP = 15
      GHND = 66
      
      OpenClipboard = ctypes.windll.user32.OpenClipboard
      OpenClipboard.argtypes = [ wintypes.HWND ]
      OpenClipboard.restype = wintypes.BOOL
      
      EmptyClipboard = ctypes.windll.user32.EmptyClipboard
      EmptyClipboard.argtypes = []
      EmptyClipboard.restype = wintypes.BOOL
      
      SetClipboardData = ctypes.windll.user32.SetClipboardData
      SetClipboardData.argtypes = [ wintypes.UINT, wintypes.HANDLE ]
      SetClipboardData.restype = wintypes.HANDLE
      
      CloseClipboard = ctypes.windll.user32.CloseClipboard
      CloseClipboard.argtypes = []
      CloseClipboard.restype = wintypes.BOOL
      
      GlobalLock = ctypes.windll.kernel32.GlobalLock
      GlobalLock.argtypes = [ wintypes.HGLOBAL ]
      GlobalLock.restype = wintypes.LPVOID
      
      GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
      GlobalAlloc.argtypes = [wintypes.UINT, ctypes.c_size_t]
      GlobalAlloc.restype = wintypes.HGLOBAL
      
      GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
      GlobalUnlock.argtypes = [ wintypes.HGLOBAL ]
      GlobalUnlock.restype = wintypes.BOOL
      
      memcpy = ctypes.cdll.msvcrt.memcpy
      memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]
      
      class POINT(ctypes.Structure):
          _fields_ = [
              ('x', wintypes.LONG),
              ('y', wintypes.LONG)
          ]
      
      class DROPFILES(ctypes.Structure):
          _fields_ = [
              ('pFiles', wintypes.DWORD),
              ('pt', POINT),
              ('fNC', wintypes.BOOL),
              ('fWide', wintypes.BOOL),
          ]
      
      def dump_mem(addr, size):
          mem = list((ctypes.c_ubyte * size).from_address(addr))
          print(mem)
      
      def main():
          path = ctypes.create_unicode_buffer(notepad.getCurrentFilename())
          path_size = ctypes.sizeof(path)
          df_size = ctypes.sizeof(DROPFILES)
          total_size = df_size + path_size
      
          df = DROPFILES()
          df.pFiles = df_size
          df.fWide = True
      
          h_global_mem = GlobalAlloc(GHND, total_size)  # allocate enough memory to hold the df struct and the full path
          if h_global_mem:
              lp_global_mem = GlobalLock(h_global_mem)  # lock and get the pointer to the memory
              memcpy(lp_global_mem, addressof(df), df_size)  # first copy the df struct
              memcpy(lp_global_mem+df_size, addressof(path), path_size)  # now copy the full path name
              dump_mem(lp_global_mem, total_size)
              GlobalUnlock(h_global_mem)
              res = OpenClipboard(0)
              if res:
                  EmptyClipboard()
                  SetClipboardData(CF_HDROP, h_global_mem)
                  CloseClipboard()
              else:
                  print('ERROR OpenClipboard', res)
      
          else:
              print('ERROR GlobalAlloc', h_global_mem)
      
      main()
      
      mkupperM 1 Reply Last reply Reply Quote 2
      • mkupperM
        mkupper @Alan Kilborn
        last edited by

        @Alan-Kilborn Is that for Python 3? I got an error with Python 2.7:

        Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:19:08) [MSC v.1500 32 bit (Intel)]
        Initialisation took 375ms
        Ready.
        Traceback (most recent call last):
          File "C:\Users\MKupper\AppData\Roaming\Notepad++\plugins\Config\PythonScript\scripts\FileClipboard.py", line 84, in <module>
            main()
          File "C:\Users\MKupper\AppData\Roaming\Notepad++\plugins\Config\PythonScript\scripts\FileClipboard.py", line 69, in main
            memcpy(lp_global_mem, addressof(df), df_size)  # first copy the df struct
        NameError: global name 'addressof' is not defined
        
        1 Reply Last reply Reply Quote 1
        • EkopalypseE
          Ekopalypse
          last edited by

          @Alan-Kilborn - Sorry I’m late to the party, but real life is keeping me very busy at the moment. :-(
          I looked through my script, but no, it doesn’t seem to be mine … maybe it’s one of the scripts that fell victim to my hard disk failure and that I hadn’t backed up. But I can’t really remember that I ever needed this either. Anyway … but your script works :)

          @mkupper - Python doesn’t know where to look for the method. Change addressof t0 ctypes.addressof and I assume it will work with PS2 too.

          1 Reply Last reply Reply Quote 4
          • Alexander AnisimovA
            Alexander Anisimov
            last edited by

            Given the above geneltmen’s exposition, it look slike it does not worth it, and any solution would be too complex to implement for this. Probably just use right mouse button -> open file folder, then ctrl+c

            Thanks everybody

            Alan KilbornA 1 Reply Last reply Reply Quote 0
            • Alan KilbornA
              Alan Kilborn @Alexander Anisimov
              last edited by

              @Alexander-Anisimov said in Copying file itself into clipboard in Notepad++:

              any solution would be too complex to implement for this

              Hmm, solution provided.
              Set up the ability to run the given script, then assign whatever free keycombo you want for it.
              There are details about using scripting HERE.

              mkupperM 1 Reply Last reply Reply Quote 1
              • mkupperM
                mkupper @Alan Kilborn
                last edited by

                @Alan-Kilborn said in Copying file itself into clipboard in Notepad++:

                @Alexander-Anisimov said in Copying file itself into clipboard in Notepad++:

                any solution would be too complex to implement for this

                Hmm, solution provided.

                The solution that was provided only puts an CF_HDROP format blob into the clipboard. On my WIndows 11 machine that’s not enough information to then do a Paste in Windows Explorer and for a copy of the file to appear. However, if the OP only needs or desires an CF_HDROP then yes, the PythonScript provided does that.

                If someone wants or needs for Notepad++ to better emulate the behavior for when someone does a copy/paste of files from one Windows Explorer window to another then the solution will need to include more blobs in the package that’s uploaded into the clipboard. On my Windows 11 machine a “Copy” uploads the 16 blobs that I mentioned in a previous post to this forum thread. Some of those 16 are likely redundant meaning we don’t need all 16 for a paste to work. CF_HDROP is one of the pre-defined clipboard blobs and thus is among the low hanging fruit of the 16. Many of the blobs that Windows Explorer uses are not pre-defined. To inject them into the clipboard as part of a package of blobs you need to first translate the blob name, which is well known, into the current blob numbers being used by Windows Explorer and you add them to the clipboard using the numbers.

                The blob numbers change from time to time. For example, today I did a copy from Windows Explorer and while the list of blobs looks the same as what I got a couple of days ago I see that
                $DataObjectAttributes$ changed from 49905/0xC2F1 to 49647/0xC1EF and
                $DataObjectAttributesRequiringElevation$ changed from 49981/0xC33D to 49997/0xC34D.

                In looking over the list I believe the numbers assigned to 15 of the 16 blobs will change from time to time. The only one that’s constant is CF_HDROP (blob format number 15/0x000F) which is pre-defined. The numbers change because Windows Explorer (explorer.exe) registers the blob names with the clipboard system and gets a blob number or handle for that name back from the clipboard when you log in. Other background processes also are registering names with the clipboard system and getting handles to them. Blob handle numbers can, and likely will, change when you reboot a machine.

                Alan KilbornA EkopalypseE 2 Replies Last reply Reply Quote 1
                • Alan KilbornA
                  Alan Kilborn @mkupper
                  last edited by Alan Kilborn

                  @mkupper said in Copying file itself into clipboard in Notepad++:

                  On my WIndows 11 machine that’s not enough information to then do a Paste in Windows Explorer and for a copy of the file to appear.

                  Well, exactly that worked for me. And I think it worked for Ekopalypse based on what he said.

                  When I run the script to “copy” the data, Ditto (a clipboard manager) shows:

                  edac709a-8e33-4b1d-ab87-128df5156378-image.png

                  (Note that when I took the screenshot, the file-copy was Ditto entry number 2, not 1.)
                  It sure LOOKS like the copy was a file, from the Ditto data. I’m not sure what the funky characters are, likely binary data that Ditto isn’t interpreting for good presentation to the user.

                  But I’m not “selling” the script as appropriate for everyone; I didn’t write it and haven’t looked super-hard at it. As I said, I was reluctant to post it in the first place, given I didn’t know its origins (I still think it was an Eko creation!).

                  If some feel the script isn’t robust or doesn’t work, feel free to take on the task of improving it.

                  1 Reply Last reply Reply Quote 3
                  • EkopalypseE
                    Ekopalypse @mkupper
                    last edited by

                    @mkupper

                    Maybe I’m missing something but it seems to work for me as well.

                    Notepad++ v8.7.1   (64-bit)
                    Build time : Oct 31 2024 - 00:48:56
                    Path : D:\Tests\npp\_latest\x64\notepad++.exe
                    Command Line : 
                    Admin mode : OFF
                    Local Conf mode : ON
                    Cloud Config : OFF
                    Periodic Backup : ON
                    OS Name : Windows 11 Pro (64-bit)
                    OS Version : 24H2
                    OS Build : 26100.1742
                    Current ANSI codepage : 1252
                    Plugins : 
                        mimeTools (3.1)
                        NppConverter (4.6)
                        NppExport (0.4)
                        PythonScript (2)
                    
                    

                    test_drop.gif

                    1 Reply Last reply Reply Quote 2
                    • PeterJonesP
                      PeterJones
                      last edited by

                      (ugh. I accidentally pasted a CF_HDROP while writing my reply, rather than pasting the text I meant, and it confused my browser and I lost the active page, including the whole post I had written. so now I am recreating it :-( )

                      After the OP re-asked this question, and I directed him here, I decided to try it out (since I don’t think I tried it last Autumn).

                      My first experiments were unsuccessful.

                      First, like @mkupper, I had problems with addressof, but unlike @mkupper, I am using PythonScript 3.0.22, so it wasn’t a PS2 issue. Still, that was easy enough to fix.

                      Second, for the first file I tried, having just the CF_HDROP and trying to paste in Windows Explorer did nothing.
                      But looking at @ekopalypse’s video, I noticed he had a pretty simple file path, so I tried with a different file, and that one worked.

                      I see that the script is doing the dump_mem to show the structure used, so here’s some information about the differences in the sequences

                      • Destination directory: C:\Users\pryrt\Downloads\
                      • Source File (works): C:\Users\pryrt\AppData\Local\Temp\test.txt
                        • dump_mem => pythonscript console:
                          [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 67, 0, 58, 0, 92, 0, 85, 0, 115, 0, 101, 0, 114, 0, 115, 0, 92, 0, 112, 0, 114, 0, 121, 0, 114, 0, 116, 0, 92, 0, 65, 0, 112, 0, 112, 0, 68, 0, 97, 0, 116, 0, 97, 0, 92, 0, 76, 0, 111, 0, 99, 0, 97, 0, 108, 0, 92, 0, 84, 0, 101, 0, 109, 0, 112, 0, 92, 0, 116, 0, 101, 0, 115, 0, 116, 0, 46, 0, 116, 0, 120, 0, 116, 0, 0, 0]
                          
                      • Source File (fails): C:\Users\pryrt\AppData\Roaming\Notepad++\plugins\config\PythonScript\scripts\nppCommunity\26xxx\26260-Clipboard_CF_HDROP_Alans.py
                        • dump_mem => pythonscript console:
                          [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 67, 0, 58, 0, 92, 0, 85, 0, 115, 0, 101, 0, 114, 0, 115, 0, 92, 0, 112, 0, 114, 0, 121, 0, 114, 0, 116, 0, 92, 0, 65, 0, 112, 0, 112, 0, 68, 0, 97, 0, 116, 0, 97, 0, 92, 0, 82, 0, 111, 0, 97, 0, 109, 0, 105, 0, 110, 0, 103, 0, 92, 0, 78, 0, 111, 0, 116, 0, 101, 0, 112, 0, 97, 0, 100, 0, 43, 0, 43, 0, 92, 0, 112, 0, 108, 0, 117, 0, 103, 0, 105, 0, 110, 0, 115, 0, 92, 0, 99, 0, 111, 0, 110, 0, 102, 0, 105, 0, 103, 0, 92, 0, 80, 0, 121, 0, 116, 0, 104, 0, 111, 0, 110, 0, 83, 0, 99, 0, 114, 0, 105, 0, 112, 0, 116, 0, 92, 0, 115, 0, 99, 0, 114, 0, 105, 0, 112, 0, 116, 0, 115, 0, 92, 0, 110, 0, 112, 0, 112, 0, 67, 0, 111, 0, 109, 0, 109, 0, 117, 0, 110, 0, 105, 0, 116, 0, 121, 0, 92, 0, 50, 0, 54, 0, 120, 0, 120, 0, 120, 0, 92, 0, 50, 0, 54, 0, 50, 0, 54, 0, 48, 0, 45, 0, 67, 0, 108, 0, 105, 0, 112, 0, 98, 0, 111, 0, 97, 0, 114, 0, 100, 0, 95, 0, 67, 0, 70, 0, 95, 0, 72, 0, 68, 0, 82, 0, 79, 0, 80, 0, 95, 0, 65, 0, 108, 0, 97, 0, 110, 0, 115, 0, 46, 0, 112, 0, 121, 0, 0, 0]
                          
                          

                      So then I went to c:\TEMP and made a bunch of files (1, 12, 123, … 123456789x, 123456789x1, … up to the MAX_PATH limit ), and changed the destination directory to C:\Users\pryrt\Downloads\testfolder\

                      I tried with 1 and 12 and they both worked…

                      [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 99, 0, 58, 0, 92, 0, 84, 0, 69, 0, 77, 0, 80, 0, 92, 0, 49, 0, 0, 0]
                      [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 99, 0, 58, 0, 92, 0, 84, 0, 69, 0, 77, 0, 80, 0, 92, 0, 49, 0, 50, 0, 0, 0]
                      

                      I didn’t want to test everything, so I skipped forward to 123456789x1

                      [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 99, 0, 58, 0, 92, 0, 84, 0, 69, 0, 77, 0, 80, 0, 92, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 0, 0]
                      

                      but it didn’t work when I pasted.

                      (Just to be clear: there is never an error in PythonScript shown; I am just showing the dump, in case there is useful information about the difference there. On a “working” run, I get the dump shown, and when I paste in my destination directory, it copies the file, or asks if I want to overwrite the file, depending on whether the file exists or not; on “didn’t work” runs, when I paste in the destination directory, apparently nothing happens – no new file is pasted, no request to overwrite, no Windows popup; just nothing happens. And I can confirm on those that the CF_HDROP still looks the same )

                      Then I went to the last file, with the biggest name, and it worked:

                      [20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 99, 0, 58, 0, 92, 0, 84, 0, 69, 0, 77, 0, 80, 0, 92, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 120, 0, 0, 0]
                      

                      … so it’s not path length alone.

                      Then I went back to 123456789x1, and this time when I pasted in the destination directory, it worked.

                      I went to some random files, and switched back to the 123456789x1 file: most of the time, I was able to copy it, but rarely, I was not. Then I went to c:\TEMP\post.md (this post that I’m typing up – not going to lose my work a second time), and after about a dozen times of trying (closing/reopening file, doing another file in between), it wasn’t working; but just after typing it up that “no matter how many times” I tried, it failed, then I do it one last time, and now post.md pastes just fine.

                      I cannot tell what the difference is, but Windows 11 seems to be flakey on the CF_HDROP. I don’t know if the other fields that @mkupper mentioned would make it more reliable, or if there’s some pauses or delays that the script could insert in order to get it more reliable, or whether it’s 100% up to Win11’s whims. Anyway, that’s what I saw as I experimented with this script.

                      EkopalypseE 2 Replies Last reply Reply Quote 2
                      • fml2F
                        fml2
                        last edited by

                        There is a program called Far Manager, it’s an open source console based file manager. It has the capability to “copy” files so that they can be later “pasted” in Windows Explorer. Maybe we could look how they do it?

                        1 Reply Last reply Reply Quote 1
                        • EkopalypseE
                          Ekopalypse @PeterJones
                          last edited by

                          @PeterJones
                          hmm … if it sometimes works and sometimes doesn’t, then I suspect an alignment problem. I’ll have a look later today and see if that’s the case.

                          @fml2
                          thx, yes, that might be helpful.

                          1 Reply Last reply Reply Quote 2
                          • EkopalypseE
                            Ekopalypse @PeterJones
                            last edited by

                            @PeterJones

                            I ASSUME the issue is a missing pair of null chars?

                            def main():
                                path = ctypes.create_unicode_buffer(notepad.getCurrentFilename())
                                path_size = ctypes.sizeof(path)
                                df_size = ctypes.sizeof(DROPFILES)
                                total_size = df_size + path_size + 2  # The data that follows the structure is a double null-terminated list of file names.
                            
                                df = DROPFILES()
                                df.pFiles = df_size
                                df.fWide = True
                            
                                h_global_mem = GlobalAlloc(GHND, total_size)  # allocate enough memory to hold the df struct and the full path
                                if h_global_mem:
                                    lp_global_mem = GlobalLock(h_global_mem)  # lock and get the pointer to the memory
                                    memcpy(lp_global_mem, addressof(df), df_size)  # first copy the df struct
                                    memcpy(lp_global_mem+df_size, addressof(path), path_size)  # now copy the full path name
                                    dump_mem(lp_global_mem, total_size)
                                    GlobalUnlock(h_global_mem)
                                    res = OpenClipboard(notepad.hwnd)  # but 0 should be fine as well
                                    if res:
                                        if not EmptyClipboard():
                                            print('ERROR EmptyClipboard failed')
                                        if SetClipboardData(CF_HDROP, h_global_mem) is None:
                                            print('ERROR SetClipboardData failed')
                                        CloseClipboard()
                                    else:
                                        print('ERROR OpenClipboard', res)
                                else:
                                    print('ERROR GlobalAlloc', h_global_mem)
                            
                            PeterJonesP 1 Reply Last reply Reply Quote 2
                            • PeterJonesP
                              PeterJones @Ekopalypse
                              last edited by

                              @Ekopalypse ,

                              yes, adding in the extra NULLs seems to have solved it. I just tried a couple dozen times, and the copy-from-Notepad++/paste-in-Explorer worked every time now.


                              @Alexander-Anisimov ,

                              I don’t know if you’ll be back again after I redirected you back to this conversation, but if you are, it’s not as hard as you seemed to conclude last Autumn.

                              The instructions would be:

                              1. Setup the PythonScript plugin as described in our FAQ
                              2. Use the updated script (derived from @Alan-Kilborn’s November 4th post, with the addressof fix mentioned, and replace the def main: ... section with the value from @Ekopalypse’s most reccent post). So that you don’t have to update the script yourself, the bottom of this post will contain the fully-updated script.
                              3. If you want, follow the instructions in the FAQ to give it a keyboard shortcut

                              From now on, running that script from the Plugin > PythonScript > Scripts menu (or your defined keyboard shortcut) will put the file into the clipboard in the right way so that you can move to Windows Explorer and paste the file to the new location.


                              # encoding=utf-8
                              # https://community.notepad-plus-plus.org/post/97676
                              import ctypes
                              from ctypes import wintypes
                              from Npp import notepad
                              
                              CF_HDROP = 15
                              GHND = 66
                              
                              OpenClipboard = ctypes.windll.user32.OpenClipboard
                              OpenClipboard.argtypes = [ wintypes.HWND ]
                              OpenClipboard.restype = wintypes.BOOL
                              
                              EmptyClipboard = ctypes.windll.user32.EmptyClipboard
                              EmptyClipboard.argtypes = []
                              EmptyClipboard.restype = wintypes.BOOL
                              
                              SetClipboardData = ctypes.windll.user32.SetClipboardData
                              SetClipboardData.argtypes = [ wintypes.UINT, wintypes.HANDLE ]
                              SetClipboardData.restype = wintypes.HANDLE
                              
                              CloseClipboard = ctypes.windll.user32.CloseClipboard
                              CloseClipboard.argtypes = []
                              CloseClipboard.restype = wintypes.BOOL
                              
                              GlobalLock = ctypes.windll.kernel32.GlobalLock
                              GlobalLock.argtypes = [ wintypes.HGLOBAL ]
                              GlobalLock.restype = wintypes.LPVOID
                              
                              GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
                              GlobalAlloc.argtypes = [wintypes.UINT, ctypes.c_size_t]
                              GlobalAlloc.restype = wintypes.HGLOBAL
                              
                              GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
                              GlobalUnlock.argtypes = [ wintypes.HGLOBAL ]
                              GlobalUnlock.restype = wintypes.BOOL
                              
                              memcpy = ctypes.cdll.msvcrt.memcpy
                              memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]
                              
                              addressof = ctypes.addressof
                              
                              class POINT(ctypes.Structure):
                                  _fields_ = [
                                      ('x', wintypes.LONG),
                                      ('y', wintypes.LONG)
                                  ]
                              
                              class DROPFILES(ctypes.Structure):
                                  _fields_ = [
                                      ('pFiles', wintypes.DWORD),
                                      ('pt', POINT),
                                      ('fNC', wintypes.BOOL),
                                      ('fWide', wintypes.BOOL),
                                  ]
                              
                              def dump_mem(addr, size):
                                  mem = list((ctypes.c_ubyte * size).from_address(addr))
                                  print(mem)
                              
                              def main():
                                  path = ctypes.create_unicode_buffer(notepad.getCurrentFilename())
                                  path_size = ctypes.sizeof(path)
                                  df_size = ctypes.sizeof(DROPFILES)
                                  total_size = df_size + path_size + 2  # The data that follows the structure is a double null-terminated list of file names.
                              
                                  df = DROPFILES()
                                  df.pFiles = df_size
                                  df.fWide = True
                              
                                  h_global_mem = GlobalAlloc(GHND, total_size)  # allocate enough memory to hold the df struct and the full path
                                  if h_global_mem:
                                      lp_global_mem = GlobalLock(h_global_mem)  # lock and get the pointer to the memory
                                      memcpy(lp_global_mem, addressof(df), df_size)  # first copy the df struct
                                      memcpy(lp_global_mem+df_size, addressof(path), path_size)  # now copy the full path name
                                      dump_mem(lp_global_mem, total_size)
                                      GlobalUnlock(h_global_mem)
                                      res = OpenClipboard(notepad.hwnd)  # but 0 should be fine as well
                                      if res:
                                          if not EmptyClipboard():
                                              print('ERROR EmptyClipboard failed')
                                          if SetClipboardData(CF_HDROP, h_global_mem) is None:
                                              print('ERROR SetClipboardData failed')
                                          CloseClipboard()
                                      else:
                                          print('ERROR OpenClipboard', res)
                                  else:
                                      print('ERROR GlobalAlloc', h_global_mem)
                              
                              main()
                              

                              @Alexander-Anisimov , If you ever come back, I hope this helps. (Otherwise, I hope the fully-updated version helps some other user who wants this feature.)

                              Alexander AnisimovA 1 Reply Last reply Reply Quote 3
                              • Alexander AnisimovA
                                Alexander Anisimov @PeterJones
                                last edited by

                                @PeterJones Thank you, so I just put the script in, but how can I bind a hotkey something like Ctrl+Shift+C to it?

                                PeterJonesP 1 Reply Last reply Reply Quote 0
                                • PeterJonesP
                                  PeterJones @Alexander Anisimov
                                  last edited by

                                  @Alexander-Anisimov said in Copying file itself into clipboard in Notepad++:

                                  how can I bind a hotkey something like Ctrl+Shift+C to it?

                                  That’s explained in the FAQ. Search that page for “shortcut” (step 4 of the instructions) if you didn’t notice it.

                                  1 Reply Last reply Reply Quote 2
                                  • First post
                                    Last post
                                  The Community of users of the Notepad++ text editor.
                                  Powered by NodeBB | Contributors