Community
    • Login

    Function Completion: cycle through choices

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    autocompletefunction hint
    16 Posts 4 Posters 1.0k 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.
    • EkopalypseE
      Ekopalypse @Michael Vincent
      last edited by Ekopalypse

      @Michael-Vincent

      from Npp import notepad, editor, editor1, SCINTILLANOTIFICATION
      import ctypes
      from ctypes import wintypes
      
      # def on_calltip_click(args):
          # if args['position'] == 1:
              # print('backward')
          # elif args['position'] == 2:
              # print('forward')
              
      
              
      # editor.callbackSync(on_calltip_click, [SCINTILLANOTIFICATION.CALLTIPCLICK])
      
      
      class NMHDR(ctypes.Structure):
          _fields_ = [('hwndFrom', wintypes.HWND),
                      ('idFrom',   ctypes.c_size_t),
                      ('code',     wintypes.UINT)]
          def __init__(self, hwnd, id, code):
              self.hwndFrom = hwnd
              self.idFrom = id
              self.code = code
      
      
      Sci_Position = ctypes.c_size_t
      class SCNOTIFICATION(ctypes.Structure):
          _fields_ = [('nmhdr', NMHDR),
                      ('position', Sci_Position),
                      ('ch', wintypes.INT),
                      ('modifiers', wintypes.INT),
                      ('modificationType', wintypes.INT),
                      ('text', wintypes.LPCSTR),
                      ('length', Sci_Position),
                      ('linesAdded', Sci_Position),
                      ('message', wintypes.INT),
                      ('wParam', wintypes.WPARAM),
                      ('lParam', wintypes.LPARAM),
                      ('line', Sci_Position),
                      ('foldLevelNow', wintypes.INT),
                      ('foldLevelPrev', wintypes.INT),
                      ('margin', wintypes.INT),
                      ('listType', wintypes.INT),
                      ('x', wintypes.INT),
                      ('y', wintypes.INT),
                      ('token', wintypes.INT),
                      ('annotationLinesAdded', Sci_Position),
                      ('updated', wintypes.INT),
                      ('listCompletionMethod', wintypes.INT)]
      
      SendMessage = ctypes.windll.user32.SendMessageW
      SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
      SendMessage.restype = wintypes.LPARAM
      
      
      nmhdr = NMHDR(editor1.hwnd, 0, SCINTILLANOTIFICATION.CALLTIPCLICK)
      notification = SCNOTIFICATION()
      notification.nmhdr = nmhdr
      notification.position = 2
      
      WM_NOTIFY = 0x4e
      SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))
      

      I have not checked if the fields in the supplied nmhdr structure are really set correctly.

      Michael VincentM 1 Reply Last reply Reply Quote 2
      • Michael VincentM
        Michael Vincent @Ekopalypse
        last edited by

        @Ekopalypse said in Function Completion: cycle through choices:

        SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))

        Trying this out, I get an error:

        Traceback (most recent call last):
          File "C:\usr\bin\npp64\plugins\Config\PythonScript\scripts\callTipClick.py", line 67, in <module>
            SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))
        ctypes.ArgumentError: argument 4: <class 'OverflowError'>: int too long to convert
        

        Cheers.

        Michael VincentM 1 Reply Last reply Reply Quote 0
        • Michael VincentM
          Michael Vincent @Michael Vincent
          last edited by

          @Michael-Vincent
          @Ekopalypse

          Fixed (probably should have noted I’m on 64-bit):

          SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.c_longlong(ctypes.addressof(notification)))
          

          Cheers.

          Michael VincentM 1 Reply Last reply Reply Quote 1
          • Michael VincentM
            Michael Vincent @Michael Vincent
            last edited by

            @Michael-Vincent said in Function Completion: cycle through choices:

            @Michael-Vincent
            @Ekopalypse
            Fixed (probably should have noted I’m on 64-bit):
            @PeterJones

            Works nicely now:

            callTipClick.py:

            from Npp import notepad, editor, editor1, editor2, SCINTILLANOTIFICATION
            import ctypes
            from ctypes import wintypes
            
            class NMHDR(ctypes.Structure):
                _fields_ = [('hwndFrom', wintypes.HWND),
                            ('idFrom',   ctypes.c_size_t),
                            ('code',     wintypes.UINT)]
                def __init__(self, hwnd, id, code):
                    self.hwndFrom = hwnd
                    self.idFrom = id
                    self.code = code
            
            Sci_Position = ctypes.c_size_t
            class SCNOTIFICATION(ctypes.Structure):
                _fields_ = [('nmhdr', NMHDR),
                            ('position', Sci_Position),
                            ('ch', wintypes.INT),
                            ('modifiers', wintypes.INT),
                            ('modificationType', wintypes.INT),
                            ('text', wintypes.LPCSTR),
                            ('length', Sci_Position),
                            ('linesAdded', Sci_Position),
                            ('message', wintypes.INT),
                            ('wParam', wintypes.WPARAM),
                            ('lParam', wintypes.LPARAM),
                            ('line', Sci_Position),
                            ('foldLevelNow', wintypes.INT),
                            ('foldLevelPrev', wintypes.INT),
                            ('margin', wintypes.INT),
                            ('listType', wintypes.INT),
                            ('x', wintypes.INT),
                            ('y', wintypes.INT),
                            ('token', wintypes.INT),
                            ('annotationLinesAdded', Sci_Position),
                            ('updated', wintypes.INT),
                            ('listCompletionMethod', wintypes.INT)]
            
            if editor.callTipActive():
                SendMessage = ctypes.windll.user32.SendMessageW
                SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                SendMessage.restype = wintypes.LPARAM
            
                hwnd = notepad.getCurrentView()
                if hwnd == 0:
                    hwnd = editor1.hwnd
                else:
                    hwnd = editor2.hwnd
            
                nmhdr = NMHDR(hwnd, 0, SCINTILLANOTIFICATION.CALLTIPCLICK)
                notification = SCNOTIFICATION()
                notification.nmhdr = nmhdr
                notification.position = 2
            
                WM_NOTIFY = 0x4e
                SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.c_longlong(ctypes.addressof(notification)))
            

            NOTE: This relies in your PythonScript startup having some logic to get the editor1 and 2 HWND and create those variables I use in the script.

            Then I just added this to my PythonScript menu and added a shortcut to it. Works like a charm:

            2d96ab2c-905a-4950-8392-42959a3e4c78-image.png

            Cheers.

            EkopalypseE Michael VincentM 2 Replies Last reply Reply Quote 2
            • EkopalypseE
              Ekopalypse @Michael Vincent
              last edited by

              @Michael-Vincent

              I am also working with x64 bit.
              The problem could be that you already have a SendMessage function declaration somewhere in your used Python script codes, which is defined slightly different.

              >>> from ctypes import wintypes
              
              >>> wintypes.LPARAM
              <class 'ctypes.c_longlong'>
              

              wintypes.LPARAM is already a c_longlong, so this cast would not be necessary, since the whole point of

              SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
              SendMessage.restype = wintypes.LPARAM
              

              is to give Python the information how to interpret certain variables.

              Michael VincentM 1 Reply Last reply Reply Quote 3
              • Michael VincentM
                Michael Vincent @Ekopalypse
                last edited by

                @Ekopalypse said in Function Completion: cycle through choices:

                The problem could be that you already have a SendMessage function declaration somewhere in your used Python script codes, which is defined slightly different.

                Indeed, you are correct, and I’ve fixed it so your original code:

                    SendMessage(notepad.hwnd, WM_NOTIFY, 0, ctypes.addressof(notification))
                

                WORKS!

                Cheers.

                1 Reply Last reply Reply Quote 1
                • Michael VincentM
                  Michael Vincent @Michael Vincent
                  last edited by

                  @Michael-Vincent said in Function Completion: cycle through choices:

                  SendMessage.argtype = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                  

                  Note this line should be:

                  SendMessage.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM]
                  

                  Note: argtypes

                  Cheers.

                  1 Reply Last reply Reply Quote 2
                  • Michael VincentM
                    Michael Vincent @PeterJones
                    last edited by

                    @PeterJones said in Function Completion: cycle through choices:

                    @Ekopalypse & @guy038 ,
                    Thanks for the confirmation. I thought as much, but wanted to make sure.
                    Issue #11950 created

                    PR #12017 created.

                    Cheers.

                    Michael VincentM 1 Reply Last reply Reply Quote 1
                    • Michael VincentM
                      Michael Vincent @Michael Vincent
                      last edited by

                      @Michael-Vincent said in Function Completion: cycle through choices:

                      PR #12017 created.
                      Cheers.

                      @PeterJones
                      @Ekopalypse
                      @guy038

                      DONE! - via commit 8519003

                      Cheers.

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

                        @Michael-Vincent - cool, a nice one, thx.

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