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