Interaktion mit Notepad++

    • Offizieller Beitrag

    OK, Danke. Hab die Fehler jetzt mit 'L' behoben.
    Jetzt ist mir nur noch unklar, wieso für "#ifdef UNICODE..." die Fehlermeldung 'BOOL' does not name a type
    erscheint. Wo ist da der Zusammenhang mit UNICODE. Denn bevor ich die Buildoption gesetzt hatte ist dieser Code nicht beanstandet worden.

  • Bevor UNICODE nicht definiert war, hat der Compiler diesen Code einfach übersprungen. Ich weiß gerade aber nicht, warum das nicht funktioniert.

    Edit: Mach mal #include "windows.h" auch in der .cpp-Datei.

    Einmal editiert, zuletzt von progandy (20. März 2011 um 00:56)

    • Offizieller Beitrag

    Ich habe mal testweise von

    Code
    extern "C" __declspec(dllexport) BOOL isUnicode();

    auf

    Code
    extern "C" __declspec(dllexport) int isUnicode();

    geändert. Nun gab es keine Fehler mehr.

    Aber... Notepad++ meint noch immer es ist ein ANSI-PlugIn. Ich krieg hier noch die Krise... :wacko:

  • Hmm, wie sieht das im Dependency Walker aus? Wenn der Name nicht genau isUnicode ist, dann geht es nicht. Versuche dann mal __cdecl oder eben --add-stdcall-alias als Linker-Option (oder war es beim Compiler?)

    • Offizieller Beitrag

    So, Dank progandys kräftiger Aufklärungsarbeit :thumbup: habe ich nun das PlugIn so fertigstellen können, dass es von Notepad++ akzeptiert wird.
    Aber... die gewünschte Funktionalität ist noch nicht da.
    Die Fenstererstellung/-aktivierung scheint das Problem zu sein. Denn selbst wenn ich das (sonst nicht sichtbare) Fenster mittels ShowWindow(hWnd, iCmdShow); einfach mal anzeigen lassen will, erscheint es nicht.
    Hier die entsprechende *.cpp

    Spoiler anzeigen


    Was mache ich da noch falsch?

    Ich habe den kpl. Code (erstellt aus einem DemoPlugIn) mal gezipt als Codeblock-Projekt angehängt.

    • Offizieller Beitrag

    Ich habe jetzt den Aufruf der WinMain in die InitFunktion eingefügt:

    Code
    void pluginInit(HANDLE hModule)
    {
        WinMain(GetModuleHandle(0), NULL, "CmdLine", SW_HIDE);
    }

    Kann ich Parameter 3 (szCmdLine) mit dem erfundenen Wert belegen? Oder was muß dort sonst hin?
    Im Moment zeigt das noch keine Wirkung.
    Auch wenn ich SW_SHOW übergebe und zusätzlich OnTop setze (SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); ist nix zu sehen. :S

  • pluginInit wird wohl nicht aufgerufen. Ich denke, die DLLMain sollte ungefähr so aussehen:

    • Offizieller Beitrag

    Da ich mit dem Fenster nicht weiter gekommen bin, habe ich nun einen anderen Weg gewählt: Die Scintilla-Fenster sind ja Childs des Npp-Fensters und lassen sich auf diese Weise ermitteln.
    Nun kann ich auf das Scintilla-Handle zugreifen.
    Da Notepad aber in einem eigenen Adressraum rumgeistert, muß ich die Speicherzugriffe separat steuern. Dazu habe ich mir Funktionen erstellt.
    Im folgenden Bsp. will ich den gesamten Text einer Zeile mit der Funktion "SCI_GETLINE($iLine)" ausgeben. Jedoch bekomme ich als Rückgabe ausschließlich ein Fragezeichenkette. :wacko:
    Eine Untersuchung der Scintilla-Fenster mit Winspector zeigte mir dann, dass dies wohl der Fenstertitel ist. Da fehlt mir jeoch jeder Bezug zu, wieso dort der Fenstertitel statt des Zeileninhalts erscheint.
    Hat da jemand eine Idee?

    Spoiler anzeigen
    [autoit]


    #Include-once
    #Include <SendMessage.au3>
    #Include <Memory.au3>
    #Include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $hWndScintilla = _GetScintillaHwnd()
    If Not $hWndScintilla Then Exit MsgBox(0, 'Fehler', 'Keine Notepad++ Instanz gestartet.')
    Global Const $SCI_GETLINE = 2153
    Global Const $SCI_LINELENGTH = 2350

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret = SCI_GETLINE(1) ; Zeilennummern in Npp sind Nullbasiert
    ConsoleWrite('@@ DEBUG_Line: ' & @ScriptLineNumber & ', Var: $ret >> ' & $ret & ' ; @error: ' & @error & ', @extended: ' & @extended & @LF) ; Debug To Console

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetScintillaHwnd($iInstance=1)
    Local $hScintilla = 0, $PID_Npp = WinGetProcess('[CLASS:Notepad++]')
    Local $optOld = Opt('WinSearchChildren', 1)
    Local $aWin = WinList('[CLASS:Scintilla;INSTANCE:' & $iInstance & ']')
    Opt('WinSearchChildren', $optOld)
    For $i = 1 To $aWin[0][0]
    If WinGetProcess($aWin[$i][1]) = $PID_Npp Then
    $hScintilla = $aWin[$i][1]
    ExitLoop
    EndIf
    Next
    Return $hScintilla
    EndFunc ;==>_GetScintillaHwnd

    [/autoit] [autoit][/autoit] [autoit]

    Func SCI_GETLINE($iLine) ; FAIL
    Local $iLen = SCI_LINELENGTH($iLine), $sText
    Local $aNppMem = _AllocateNppMem($iLen)
    _SendMessage($hWndScintilla, $SCI_GETLINE, $iLine, $aNppMem[1])
    $sText = _ReadFromNppMem($aNppMem[0], $aNppMem[1], $iLen)
    Return $sText
    EndFunc ;==>SCI_GETLINE

    [/autoit] [autoit][/autoit] [autoit]

    Func SCI_LINELENGTH($iLine) ; OK
    Return _SendMessage($hWndScintilla, $SCI_LINELENGTH, $iLine)
    EndFunc ;==>SCI_LINELENGTH

    [/autoit] [autoit][/autoit] [autoit]

    Func _AllocateNppMem($iSize) ; MemPointer -- nach Nutzung freisetzen!!
    Local Const $PROCESS_VM_OPERATION = 0x0008, $PROCESS_VM_READ = 0x010, $PROCESS_VM_WRITE = 0x020
    Local $VMFLAGS = BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ, $PROCESS_VM_WRITE)
    Local $PID = WinGetProcess('[CLASS:Notepad++]')
    _WinAPI_GetWindowThreadProcessId($hWndScintilla, $PID)
    Local $hProcess = _WinAPI_OpenProcess($VMFLAGS, False, $PID)
    Local $pMem = _MemVirtualAllocEx($hProcess, 0, $iSize, BitOR($MEM_RESERVE, $MEM_COMMIT), $PAGE_READWRITE)
    Local $aNppMem[2] = [$hProcess,$pMem]
    Return $aNppMem
    EndFunc ;==>_AllocateNppMem

    [/autoit] [autoit][/autoit] [autoit]

    Func _ReadFromNppMem($hProcess, $pMem, $iSize) ; $iSize = Anz. zu lesender Zeichen
    Local $sBuffer = DllStructCreate('wchar[' & $iSize +1 & ']'), $iRead
    _WinAPI_ReadProcessMemory($hProcess, $pMem, DllStructGetPtr($sBuffer), $iSize, $iRead) ; Return True, OK
    $sBuffer = StringLeft(DllStructGetData($sBuffer, 1), $iRead)
    _MemVirtualFreeEx($hProcess, $pMem, $iSize +1, $MEM_RELEASE)
    Return $sBuffer
    EndFunc ;==>_ReadFromNppMem

    [/autoit]