Golang实现Notepad++ Windows插件开发 - MSVC项目指南

Golang实现Notepad++ Windows插件开发 - MSVC项目指南 我想用Go语言为Notepad++开发一个自定义插件,并希望将下面链接中提供的Microsoft Visual Studio C++项目模板通过Cgo转换为Go语言,以生成所需的DLL文件。

有人能帮我使用Cgo将这个项目转换为Go吗(如果Go能够实现的话)?

注意:这将是一个用于对Notepad++窗口内的文本进行自定义处理的插件(不是Notepad++的Go语言源代码格式化工具,我知道那个已经存在了)。

Releases · npp-plugins/plugintemplate

Releases · npp-plugins/plugintemplate

为npp-plugins/plugintemplate的开发做出贡献,请在GitHub上创建一个账户。


更多关于Golang实现Notepad++ Windows插件开发 - MSVC项目指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现Notepad++ Windows插件开发 - MSVC项目指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Cgo将Notepad++插件模板转换为Go是可行的,但需要处理Windows DLL导出和C++兼容性问题。以下是关键步骤和示例代码:

1. 定义Cgo导出函数

创建main.go文件,定义必需的DLL导出函数:

//go:build windows
// +build windows

package main

import "C"
import (
    "unsafe"
)

//export isUnicode
func isUnicode() bool {
    return true
}

//export getName
func getName() *C.char {
    return C.CString("GoPlugin")
}

//export getFuncsArray
func getFuncsArray() uintptr {
    return uintptr(unsafe.Pointer(&pluginFuncs[0]))
}

//export beNotified
func beNotified(notifyCode uintptr) {
    // 处理通知消息
}

//export messageProc
func messageProc(msg uintptr, wParam uintptr, lParam uintptr) uintptr {
    return 1
}

//export setInfo
func setInfo(nppHandle uintptr, sciHandle uintptr) {
    // 保存句柄供后续使用
}

func main() {
    // DLL入口点,Go不需要实现
}

2. 定义插件函数结构

type ShortcutKey struct {
    isCtrl  bool
    isAlt   bool
    isShift bool
    key     byte
}

type FuncItem struct {
    itemName    *C.char
    pFunc       uintptr
    cmdID       int32
    init2Check  bool
    pShKey      *ShortcutKey
}

var pluginFuncs = []FuncItem{
    {
        itemName:   C.CString("Go Process Text"),
        pFunc:      uintptr(C.processText),
        cmdID:      0,
        init2Check: false,
    },
}

3. 实现文本处理函数

//export processText
func processText() {
    // 获取当前Scintilla句柄
    sciHandle := getCurrentScintilla()
    
    // 获取文本长度
    length := C.SendMessageW(sciHandle, SCI_GETLENGTH, 0, 0)
    
    // 分配缓冲区
    buffer := make([]uint16, length+1)
    
    // 获取文本
    C.SendMessageW(sciHandle, SCI_GETTEXT, 
        C.WPARAM(length+1), 
        C.LPARAM(unsafe.Pointer(&buffer[0])))
    
    // 转换为Go字符串
    text := syscall.UTF16ToString(buffer)
    
    // 自定义处理(示例:转换为大写)
    processed := strings.ToUpper(text)
    
    // 写回文本
    C.SendMessageW(sciHandle, SCI_SETTEXT, 0, 
        C.LPARAM(unsafe.Pointer(syscall.StringToUTF16Ptr(processed))))
}

4. Windows API封装

// #cgo windows LDFLAGS: -luser32
// #include <windows.h>
import "C"

const (
    SCI_GETLENGTH = 2006
    SCI_GETTEXT   = 2002
    SCI_SETTEXT   = 2181
)

var (
    user32           = syscall.NewLazyDLL("user32.dll")
    sendMessageW     = user32.NewProc("SendMessageW")
)

func C.SendMessageW(hWnd C.HWND, msg C.UINT, wParam C.WPARAM, lParam C.LPARAM) C.LRESULT {
    ret, _, _ := sendMessageW.Call(
        uintptr(hWnd),
        uintptr(msg),
        uintptr(wParam),
        uintptr(lParam),
    )
    return C.LRESULT(ret)
}

5. 编译命令

创建build.bat编译脚本:

@echo off
set CGO_ENABLED=1
set GOOS=windows
set GOARCH=amd64

go build -buildmode=c-shared -o GoPlugin.dll

6. 插件安装

  1. 将生成的GoPlugin.dll复制到Notepad++的plugins目录
  2. 创建GoPlugin子目录
  3. 在子目录中放置任何需要的配置文件

注意事项:

  • Go的垃圾回收器与C++内存管理需要小心处理
  • 字符串转换需要正确使用C.CStringC.GoString
  • 确保导出函数使用//export指令
  • 处理Windows消息循环时避免阻塞

这个实现提供了基本的插件框架,你可以扩展processText函数来实现具体的文本处理逻辑。

回到顶部