如何使用Kotlin / Native应用程序将字符串写入剪贴板(Windows OS)?

时间:2019-06-18 06:43:25

标签: kotlin clipboard kotlin-native

我是Kotlin的新手,正在使用Kotlin / Native在Windows上制作命令行.exe。该应用程序应从文本文件读取并在屏幕上逐行打印。当到达文件的最后一行时,应将其放在剪贴板中。

aFile.txt看起来像这样:

one
two
three
...
...
the last line

和到目前为止的代码read.kt(科特林/母语)是这样的:

import kotlinx.cinterop.*
import platform.posix.*

fun main(args: Array<String>) {

    if (args.size != 1) {
        println("Usage: read.exe <file.txt>")
        return
    }

    val fileName = args[0]
    val file = fopen(fileName, "r")

    if (file == null) {
        perror("cannot open input file $fileName")
        return
    }

    try {
        memScoped {
            val bufferLength = 64 * 1024
            val buffer = allocArray<ByteVar>(bufferLength)

            do {
                val nextLine = fgets(buffer, bufferLength, file)?.toKString()
                if (nextLine == null || nextLine.isEmpty()) break
                print("${nextLine}")
            } while (true)

        }
    } finally {
        fclose(file)
    }

}


上面的代码在屏幕上打印每一行,但是如何在计算机的剪贴板中写入字符串"the last line"?如果可能的话,我正在寻找本机(不是Java)解决方案。

非常感谢您。


  

更新:

很显然,这不是我一直在寻找的解决方案,但我还不明白他们在说什么(https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclipboarddata)。

作为临时解决方案,我可以使用system()echoclip通过以下代码获得所需的信息:

system("echo ${nextLine} | clip")
print("${nextLine}")

2 个答案:

答案 0 :(得分:1)

在Windows中,您可以通过WinAPI使用剪贴板,如您所见there。参考文献指出,您必须使用winuser.h标头中的函数。据我所知,此标头包含在windows.h中,因此它在您的platform.windows.*包中。您可以通过选中Kotlin / Native repository files来批准。


为弄清楚我的意思,我写了这个platform.windows.*用法的小例子。您可以将此函数添加到代码中,并在需要复制某些字符串时调用它。

import platform.windows.*

fun toClipboard(lastLine:String?){
    val len = lastLine!!.length + 1
    val hMem = GlobalAlloc(GMEM_MOVEABLE, len.toULong())
    memcpy(GlobalLock(hMem), lastLine.cstr, len.toULong())
    GlobalUnlock(hMem)
    val hwnd = HWND_TOP
    OpenClipboard(hwnd)
    EmptyClipboard()
    SetClipboardData(CF_TEXT, hMem)
    CloseClipboard()
}

答案 1 :(得分:0)

尝试以下操作:

extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    private PageViewModel pageViewModel;
    private FragmentMainBinding binding;

    public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(ARG_SECTION_NUMBER, index);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pageViewModel = new ViewModelProvider(this).get(PageViewModel.class);
        int index = 1;
        if (getArguments() != null) {
            index = getArguments().getInt(ARG_SECTION_NUMBER);
        }
        pageViewModel.setIndex(index);
    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        binding = FragmentMainBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        final TextView textView = binding.sectionLabel;
        pageViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        return root;
    }