cleaning up desktop interactions. need to move things into individual files
This commit is contained in:
parent
5bf0e4c226
commit
1cb68f19a7
@ -84,14 +84,149 @@ interface DesktopController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WindowsDesktopController : DesktopController {
|
interface OSProxy{
|
||||||
|
fun getActiveWindowName(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows implementation of [DesktopController].
|
||||||
|
*
|
||||||
|
* This class provides methods to interact with the desktop on Windows
|
||||||
|
* by calling Win32 APIs.
|
||||||
|
*
|
||||||
|
* It implements the [DesktopController] interface to provide desktop
|
||||||
|
* functionality like getting the mouse pointer location on Windows.
|
||||||
|
*/
|
||||||
|
class WindowsDesktopController : DesktopController, OSProxy {
|
||||||
|
|
||||||
|
companion object{
|
||||||
|
/**
|
||||||
|
* Converts a native byte buffer to a String.
|
||||||
|
*
|
||||||
|
* This takes a byte array [byteBuffer] containing text from a native Win32 call,
|
||||||
|
* converts it to a String using JNA, and trims whitespace characters.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* val buffer = ByteArray(256)
|
||||||
|
* GetWindowTextA(hwnd, buffer, buffer.size) // Win32 call
|
||||||
|
*
|
||||||
|
* val windowTitle = nativeByteBufferToString(buffer)
|
||||||
|
* println(windowTitle) // Print title string
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param byteBuffer Byte array containing text from a native call
|
||||||
|
* @return The native text as a String
|
||||||
|
*/
|
||||||
|
private fun nativeByteBufferToString(byteBuffer: ByteArray): String{
|
||||||
|
// I guess this prunes anything that isn't on the ascii table?
|
||||||
|
val wText = Native.toString(byteBuffer).trim { it <= ' ' }
|
||||||
|
return wText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for calling Windows User32 API functions.
|
||||||
|
*
|
||||||
|
* This defines an interface extending StdCallLibrary to call native
|
||||||
|
* Windows User32 library functions like EnumWindows, GetWindowTextA etc.
|
||||||
|
*
|
||||||
|
* Classes can implement this interface to make direct calls to the
|
||||||
|
* User32 DLL on Windows.
|
||||||
|
*/
|
||||||
internal interface User32 : StdCallLibrary {
|
internal interface User32 : StdCallLibrary {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a Windows callback function to enumerate windows.
|
||||||
|
*
|
||||||
|
* This extends the StdCallLibrary.StdCallCallback to define a callback
|
||||||
|
* method that will be invoked by the Windows API EnumWindows function.
|
||||||
|
*
|
||||||
|
* The callback method accepts a window handle (HWND) and a user-defined
|
||||||
|
* pointer, and returns a Boolean indicating whether to continue enumeration.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
* ```
|
||||||
|
* val callback = object : WNDENUMPROC {
|
||||||
|
* override fun callback(hWnd: Pointer?, arg: Pointer?): Boolean {
|
||||||
|
* // Check if hWnd matches target window
|
||||||
|
* if (matchesTarget(hWnd)) {
|
||||||
|
* // Found target window, stop enumeration
|
||||||
|
* return false
|
||||||
|
* }
|
||||||
|
* // Keep enumerating
|
||||||
|
* return true
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param hWnd Window handle (HWND) for the current enumerated window.
|
||||||
|
* @param arg User-defined data pointer passed to EnumWindows.
|
||||||
|
* @return True to continue enumerating windows, false to stop.
|
||||||
|
*/
|
||||||
interface WNDENUMPROC : StdCallLibrary.StdCallCallback {
|
interface WNDENUMPROC : StdCallLibrary.StdCallCallback {
|
||||||
fun callback(hWnd: Pointer?, arg: Pointer?): Boolean
|
fun callback(hWnd: Pointer?, arg: Pointer?): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates windows on the system.
|
||||||
|
*
|
||||||
|
* This calls the Windows API EnumWindows function to enumerate all top-level windows.
|
||||||
|
*
|
||||||
|
* For each window, it calls the provided [WNDENUMPROC] callback function,
|
||||||
|
* passing the window handle [hWnd] and user-defined [userData] pointer.
|
||||||
|
*
|
||||||
|
* Enumeration can be stopped by returning false from the callback.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* val windows = mutableListOf<HWND>()
|
||||||
|
*
|
||||||
|
* val callback = object : WNDENUMPROC {
|
||||||
|
* override fun callback(hWnd: Pointer?, arg: Pointer?): Boolean {
|
||||||
|
* windows.add(hWnd) // Add hWnd to list
|
||||||
|
* return true // Continue enumerating
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* EnumWindows(callback, null) // Get all top-level windows
|
||||||
|
*
|
||||||
|
* println(windows) // Print list of HWNDs
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param lpEnumFunc The [WNDENUMPROC] callback to call for each window.
|
||||||
|
* @param userData Optional user-defined data to pass to the callback.
|
||||||
|
* @return True if successful, false otherwise.
|
||||||
|
*/
|
||||||
fun EnumWindows(lpEnumFunc: WNDENUMPROC?, userData: Pointer?): Boolean
|
fun EnumWindows(lpEnumFunc: WNDENUMPROC?, userData: Pointer?): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title text of the specified window.
|
||||||
|
*
|
||||||
|
* This calls the Win32 API GetWindowTextA function to get the title
|
||||||
|
* text for the window handle [hWnd].
|
||||||
|
*
|
||||||
|
* The window text is copied into the [lpString] buffer up to [nMaxCount] characters.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* val buffer = ByteArray(256)
|
||||||
|
* val hwnd = getWindowHandle() // get some HWND
|
||||||
|
*
|
||||||
|
* GetWindowTextA(hwnd, buffer, buffer.size)
|
||||||
|
*
|
||||||
|
* val windowTitle = String(buffer)
|
||||||
|
* println(windowTitle)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param hWnd The window handle (HWND).
|
||||||
|
* @param lpString The buffer to receive the window text.
|
||||||
|
* @param nMaxCount The maximum number of characters to copy to the buffer.
|
||||||
|
* @return The length of the window text (excluding null-terminator).
|
||||||
|
*/
|
||||||
fun GetWindowTextA(hWnd: Pointer?, lpString: ByteArray?, nMaxCount: Int): Int
|
fun GetWindowTextA(hWnd: Pointer?, lpString: ByteArray?, nMaxCount: Int): Int
|
||||||
|
|
||||||
fun GetForegroundWindow(): Pointer?
|
fun GetForegroundWindow(): Pointer?
|
||||||
@ -103,13 +238,28 @@ class WindowsDesktopController : DesktopController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentlyActiveWindowName(): String {
|
/**
|
||||||
|
* Gets the title of the active/foreground window.
|
||||||
|
*
|
||||||
|
* This calls Win32 APIs to get the handle of the foreground window,
|
||||||
|
* then gets its title text.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* val activeWindowName = getActiveWindowName()
|
||||||
|
*
|
||||||
|
* println(activeWindowName) // Prints foreground window title
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @return The title text of the current foreground window.
|
||||||
|
*/
|
||||||
|
override fun getActiveWindowName(): String {
|
||||||
val user32 = User32.INSTANCE
|
val user32 = User32.INSTANCE
|
||||||
|
val textBuffer = ByteArray(512)
|
||||||
|
|
||||||
val windowText = ByteArray(512)
|
user32.GetWindowTextA(user32.GetForegroundWindow(), textBuffer, 512)
|
||||||
val hWnd = user32.GetForegroundWindow()
|
|
||||||
user32.GetWindowTextA(hWnd, windowText, 512)
|
return nativeByteBufferToString(textBuffer)
|
||||||
val wText = Native.toString(windowText).trim { it <= ' ' } //i have no idea what this does
|
|
||||||
return wText
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,6 +64,6 @@ class DesktopControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
fun devTest(){
|
fun devTest(){
|
||||||
val c = WindowsDesktopController()
|
val c = WindowsDesktopController()
|
||||||
println("TEXT: ${ c.getCurrentlyActiveWindowName()}")
|
println("TEXT: ${ c.getActiveWindowName()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user