-
-
Save zerofancy/83db2f1c9f9cd26073661253904f9698 to your computer and use it in GitHub Desktop.
封装JNA MessageBox方法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package top.ntutn.ui | |
import com.sun.jna.Pointer | |
import com.sun.jna.platform.win32.WinDef | |
import kotlinx.coroutines.Dispatchers | |
import kotlinx.coroutines.GlobalScope | |
import kotlinx.coroutines.launch | |
import kotlinx.coroutines.withContext | |
import top.ntutn.util.User32Extend | |
import top.ntutn.util.User32ExtendFlags | |
class JNAMessageBox { | |
companion object { | |
fun builder(hWnd: Long? = null, buildBlock: Builder.() -> Unit) = Builder(hWnd).apply(buildBlock) | |
} | |
enum class ButtonFlags(val value: Long) { | |
ABOUT_RETRY_IGNORE(User32ExtendFlags.MB_ABORTRETRYIGNORE), | |
CANCEL_TRY_CONTINUE(User32ExtendFlags.MB_CANCELTRYCONTINUE), | |
OK(User32ExtendFlags.MB_OK), | |
OK_CANCEL(User32ExtendFlags.MB_OKCANCEL), | |
RETRY_CANCEL(User32ExtendFlags.MB_RETRYCANCEL), | |
YES_NO(User32ExtendFlags.MB_YESNO), | |
YES_NO_CANCEL(User32ExtendFlags.MB_YESNOCANCEL), | |
} | |
enum class IconFlags(val value: Long) { | |
NONE(0), | |
WARNING(User32ExtendFlags.MB_ICONWARNING), | |
INFORMATION(User32ExtendFlags.MB_ICONINFORMATION), | |
QUESTION(User32ExtendFlags.MB_ICONQUESTION), | |
ERROR(User32ExtendFlags.MB_ICONERROR) | |
} | |
enum class DefaultButton(val value: Long) { | |
FIRST(User32ExtendFlags.MB_DEFBUTTON1), | |
SECOND(User32ExtendFlags.MB_DEFBUTTON2), | |
THIRD(User32ExtendFlags.MB_DEFBUTTON3), | |
FORTH(User32ExtendFlags.MB_DEFBUTTON4) | |
} | |
enum class Return(val value: Int) { | |
ABOUT(User32ExtendFlags.MB_RETURN_IDABORT), | |
CANCEL(User32ExtendFlags.MB_RETURN_IDCANCEL), | |
CONTINUE(User32ExtendFlags.MB_RETURN_IDCONTINUE), | |
IGNORE(User32ExtendFlags.MB_RETURN_IDIGNORE), | |
NO(User32ExtendFlags.MB_RETURN_IDNO), | |
OK(User32ExtendFlags.MB_RETURN_IDOK), | |
RETRY(User32ExtendFlags.MB_RETURN_IDRETRY), | |
TRY_AGAIN(User32ExtendFlags.MB_RETURN_IDTRYAGAIN), | |
YES(User32ExtendFlags.MB_RETURN_IDYES) | |
} | |
class Builder(hWnd: Long? = null) { | |
val building = JNAMessageBox() | |
init { | |
building.hWnd = hWnd | |
} | |
fun noIcon() = apply { | |
building.iconFlags = IconFlags.NONE | |
} | |
fun informationIcon() = apply { | |
building.iconFlags = IconFlags.INFORMATION | |
} | |
fun warningIcon() = apply { | |
building.iconFlags = IconFlags.WARNING | |
} | |
fun errorIcon() = apply { | |
building.iconFlags = IconFlags.ERROR | |
} | |
fun content(text: String, title: String) = apply { | |
building.text = text | |
building.title = title | |
} | |
fun buttonAboutRetryIgnore( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
aboutCallback: (() -> Unit)? = null, | |
retryCallback: (() -> Unit)? = null, | |
ignoreCallback: (() -> Unit)? = null | |
) = apply { | |
building.buttonFlags = ButtonFlags.ABOUT_RETRY_IGNORE | |
building.defaultButton = defaultButton | |
building.callbacks[Return.ABOUT] = aboutCallback | |
building.callbacks[Return.RETRY] = retryCallback | |
building.callbacks[Return.IGNORE] = ignoreCallback | |
} | |
fun buttonCancelTryContinue( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
cancelCallback: (() -> Unit)? = null, | |
tryCallback: (() -> Unit)? = null, | |
continueCallback: (() -> Unit)? = null | |
) = apply { | |
building.buttonFlags = ButtonFlags.CANCEL_TRY_CONTINUE | |
building.defaultButton = defaultButton | |
building.callbacks[Return.CANCEL] = cancelCallback | |
building.callbacks[Return.TRY_AGAIN] = tryCallback | |
building.callbacks[Return.CONTINUE] = continueCallback | |
} | |
fun buttonOk(okCallback: (() -> Unit)? = null) = apply { | |
building.buttonFlags = ButtonFlags.OK | |
building.defaultButton = DefaultButton.FIRST | |
building.callbacks[Return.OK] = okCallback | |
} | |
fun buttonOkCancel( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
okCallback: (() -> Unit)? = null, | |
cancelCallback: (() -> Unit)? = null | |
) = apply { | |
building.buttonFlags = ButtonFlags.OK_CANCEL | |
building.defaultButton = defaultButton | |
building.callbacks[Return.OK] = okCallback | |
building.callbacks[Return.CANCEL] = cancelCallback | |
} | |
fun retryCancel( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
retryCallback: (() -> Unit)? = null, | |
cancelCallback: (() -> Unit)? = null | |
) = apply { | |
building.buttonFlags = ButtonFlags.RETRY_CANCEL | |
building.defaultButton = defaultButton | |
building.callbacks[Return.RETRY] = retryCallback | |
building.callbacks[Return.CANCEL] = cancelCallback | |
} | |
fun yesNo( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
yesCallback: (() -> Unit)? = null, | |
noCallback: (() -> Unit)? = null | |
) = | |
apply { | |
building.buttonFlags = ButtonFlags.YES_NO | |
building.defaultButton = defaultButton | |
building.callbacks[Return.YES] = yesCallback | |
building.callbacks[Return.NO] = noCallback | |
} | |
fun yesNoCancel( | |
defaultButton: DefaultButton = DefaultButton.FIRST, | |
yesCallback: (() -> Unit)? = null, | |
noCallback: (() -> Unit)? = null, | |
cancelCallback: (() -> Unit)? = null | |
) = apply { | |
building.buttonFlags = ButtonFlags.YES_NO_CANCEL | |
building.defaultButton = defaultButton | |
building.callbacks[Return.YES] = yesCallback | |
building.callbacks[Return.NO] = noCallback | |
building.callbacks[Return.CANCEL] = cancelCallback | |
} | |
fun build() = building | |
} | |
var hWnd: Long? = null | |
var title = "" | |
var text = "" | |
var buttonFlags = ButtonFlags.OK | |
var iconFlags = IconFlags.NONE | |
var defaultButton = DefaultButton.FIRST | |
var isTopMost = false | |
private val uType: Long | |
get() { | |
var tmp = buttonFlags.value or iconFlags.value or defaultButton.value | |
if (isTopMost) { | |
tmp = tmp or User32ExtendFlags.MB_TOPMOST | |
} | |
return tmp | |
} | |
val callbacks = hashMapOf<Return, (() -> Unit)?>() | |
fun showSync() { | |
val res = User32Extend.instance.MessageBox(WinDef.HWND(hWnd?.let { Pointer(it) }), text, title, uType) | |
val returnValue = Return.entries.find { it.value == res } ?: return | |
callbacks[returnValue]?.invoke() | |
} | |
suspend fun showInIOScope() = withContext(Dispatchers.IO) { | |
User32Extend.instance.MessageBox(WinDef.HWND(hWnd?.let { Pointer(it) }), text, title, uType) | |
} | |
fun showAsync() = GlobalScope.launch { | |
val res = showInIOScope() | |
val returnValue = Return.entries.find { it.value == res } ?: return@launch | |
callbacks[returnValue]?.invoke() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package top.ntutn.util | |
import com.sun.jna.Native | |
import com.sun.jna.platform.win32.User32 | |
import com.sun.jna.platform.win32.WinDef.HWND | |
import com.sun.jna.win32.W32APIOptions | |
interface User32Extend: User32 { | |
companion object { | |
val instance: User32Extend = Native.load("user32", User32Extend::class.java, W32APIOptions.DEFAULT_OPTIONS) | |
} | |
/** | |
* int MessageBox( | |
* [in, optional] HWND hWnd, | |
* [in, optional] LPCTSTR lpText, | |
* [in, optional] LPCTSTR lpCaption, | |
* [in] UINT uType | |
* ); | |
*/ | |
fun MessageBox(hWnd: HWND, lpText: String, lpCaption: String, uType: Long): Int | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package top.ntutn.util | |
object User32ExtendFlags { | |
const val MB_ABORTRETRYIGNORE = 0x00000002L | |
const val MB_CANCELTRYCONTINUE = 0x00000006L | |
@Deprecated("It's hard to handle WM_HELP message in Java/Kotlin") | |
const val MB_HELP = 0x00004000L | |
const val MB_OK = 0x00000000L | |
const val MB_OKCANCEL = 0x00000001L | |
const val MB_RETRYCANCEL = 0x00000005L | |
const val MB_YESNO = 0x00000004L | |
const val MB_YESNOCANCEL = 0x00000003L | |
const val MB_ICONEXCLAMATION = 0x00000030L | |
const val MB_ICONWARNING = 0x00000030L | |
const val MB_ICONINFORMATION = 0x00000040L | |
const val MB_ICONASTERISK = 0x00000040L | |
const val MB_ICONQUESTION = 0x00000020L | |
const val MB_ICONSTOP = 0x00000010L | |
const val MB_ICONERROR = 0x00000010L | |
const val MB_ICONHAND = 0x00000010L | |
const val MB_DEFBUTTON1 = 0x00000000L | |
const val MB_DEFBUTTON2 = 0x00000100L | |
const val MB_DEFBUTTON3 = 0x00000200L | |
const val MB_DEFBUTTON4 = 0x00000300L | |
const val MB_APPLMODAL = 0x00000000L | |
const val MB_SYSTEMMODAL = 0x00001000L | |
const val MB_TASKMODAL = 0x00002000L | |
const val MB_DEFAULT_DESKTOP_ONLY = 0x00020000L | |
const val MB_RIGHT = 0x00080000L | |
const val MB_RTLREADING = 0x00100000L | |
const val MB_SETFOREGROUND = 0x00010000L | |
const val MB_TOPMOST = 0x00040000L | |
const val MB_SERVICE_NOTIFICATION = 0x00200000L | |
const val MB_RETURN_IDABORT = 3 | |
const val MB_RETURN_IDCANCEL = 2 | |
const val MB_RETURN_IDCONTINUE = 11 | |
const val MB_RETURN_IDIGNORE = 5 | |
const val MB_RETURN_IDNO = 7 | |
const val MB_RETURN_IDOK = 1 | |
const val MB_RETURN_IDRETRY = 4 | |
const val MB_RETURN_IDTRYAGAIN = 10 | |
const val MB_RETURN_IDYES = 6 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment