Search code examples
kotlinclipboardkotlin-native

How to write a string to clipboard (Windows OS) with a Kotlin/Native application?


I'm very new to Kotlin and making a command line .exe, on Windows using Kotlin/Native. The application should read from a text file and print on screen, line by line. When it reaches the last line of the file, it should put it in the clipboard.

aFile.txt looks something like this:

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

and the code read.kt (Kotlin/Native) I have so far is this:

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 code above prints each line on the screen, but how do I write the string "the last line" in the computer's clipboard? I'm looking for a native (not Java) solution if that's possible.

Thank you very much.


Update:

Obviously, this is not the solution I was looking for, but I don't understand yet what are they talking about here (https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setclipboarddata).

As a temporary fix, I was able to get what I needed using system(), echo and clip with code like this:

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

Solution

  • In Windows, you can work with the Clipboard through WinAPI, as you can see there. The reference says, that you got to use functions from the winuser.h header. This header is included in windows.h, as far as I know, so it is in your platform.windows.* package. You can approve it by checking Kotlin/Native repository files.


    To clarify, what I meant, I wrote this small example of platform.windows.* usage. You can add this function to your code, and call it when you got to copy some string.

    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()
    }