aboutsummaryrefslogtreecommitdiff
path: root/src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt')
-rw-r--r--src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt168
1 files changed, 132 insertions, 36 deletions
diff --git a/src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt b/src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt
index 6f5f5d3..c2f6e3d 100644
--- a/src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt
+++ b/src/mingwMain/kotlin/moe/yuuta/aero/Aero.kt
@@ -6,52 +6,127 @@ import platform.windows.*
fun main() {
SetProcessDPIAware()
- val dlgImpl = cValue<DLGTEMPLATE> {
- style = (WS_OVERLAPPEDWINDOW or
- DS_CENTER or
- DS_MODALFRAME).convert()
- dwExtendedStyle = 0.convert()
- cdit = 0.convert()
- x = 0
- y = 0
- cx = 400
- cy = 200
+ val hInstance = GetModuleHandleA(null)
+ val nCmdShow = memScoped {
+ val startUpInfo = nativeHeap.alloc<_STARTUPINFOA>()
+ GetStartupInfoA(startUpInfo.ptr)
+ val nCmdShow = startUpInfo.wShowWindow
+ nativeHeap.free(startUpInfo)
+ return@memScoped nCmdShow.convert<Int>()
}
+
+ val className = "Main Window Class"
+
memScoped {
- return@memScoped DialogBoxIndirectParamW(GetModuleHandleA(null),
- dlgImpl.ptr,
- null,
- staticCFunction(::dlgProc) as DLGPROC,
- 0)
+ val wc = cValue<WNDCLASSA> {
+ lpfnWndProc = staticCFunction(::windowProc)
+ this.hInstance = hInstance
+ lpszClassName = className.cstr.ptr
+ }
+ RegisterClassA(wc.ptr)
+ return@memScoped wc
+ }
+
+ val hwnd = CreateWindowExA(
+ 0.convert(),
+ className,
+ "", // Filling texts will get the white background of the label
+ WS_OVERLAPPEDWINDOW.convert(),
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ null,
+ null,
+ hInstance,
+ null
+ )
+
+ val forceDialogEnv = memScoped {
+ val buffer = nativeHeap.allocArray<CHARVar>(MAX_PATH)
+ GetEnvironmentVariableA("AERO_DEMO_FORCE_DIALOG",
+ buffer,
+ MAX_PATH
+ )
+ val env = buffer.toKString()
+ nativeHeap.free(buffer)
+ return@memScoped env
+ }
+
+ if (hwnd == null || (forceDialogEnv == "true")) {
+ memScoped {
+ // Fallback
+ val dlgImpl = cValue<DLGTEMPLATE> {
+ style = (WS_OVERLAPPEDWINDOW or
+ DS_CENTER or
+ DS_MODALFRAME).convert()
+ dwExtendedStyle = 0.convert()
+ cdit = 0.convert()
+ x = 0
+ y = 0
+ cx = 400
+ cy = 200
+ }
+ return@memScoped DialogBoxIndirectParamW(hInstance,
+ dlgImpl.ptr,
+ null,
+ staticCFunction(::dlgProc),
+ 0)
+ }
+ } else {
+ ShowWindow(hwnd, nCmdShow)
+ msgLoop()
+ }
+}
+
+fun msgLoop() {
+ memScoped {
+ val msg = nativeHeap.alloc<MSG>()
+ while (GetMessageA(msg.ptr,
+ null,
+ 0.convert(),
+ 0.convert()) != 0) {
+ TranslateMessage(msg.ptr)
+ DispatchMessageA(msg.ptr)
+ }
+ // The queue quits
+ nativeHeap.free(msg)
}
}
-fun dlgProc(hDlg: HWND,
+fun windowProc(hwnd: HWND?,
+ uMsg: UINT,
+ wParam: WPARAM,
+ lParam: LPARAM): LRESULT {
+ return when (uMsg.convert<Int>()) {
+ WM_CREATE -> {
+ setAero(hwnd)
+ 1
+ }
+ WM_DESTROY -> {
+ PostQuitMessage(0)
+ 1
+ }
+ WM_PAINT -> {
+ val ps = nativeHeap.alloc<PAINTSTRUCT>()
+ val hdc = BeginPaint(hwnd, ps.ptr)
+ FillRect(hdc,
+ ps.rcPaint.ptr,
+ GetStockObject(BLACK_BRUSH) as HBRUSH)
+ EndPaint(hwnd, ps.ptr)
+ nativeHeap.free(ps)
+ 1
+ }
+ else -> {
+ DefWindowProcA(hwnd, uMsg, wParam, lParam)
+ }
+ }
+}
+
+fun dlgProc(hDlg: HWND?,
message: UINT,
wParam: WPARAM,
lParam: LPARAM): INT_PTR {
when (message.convert<Int>()) {
WM_INITDIALOG -> {
- val hUser = GetModuleHandleW("user32.dll")
- if (hUser != null) {
- val setWindowCompositionAttribute = GetProcAddress(hUser, "SetWindowCompositionAttribute") as pfnSetWindowCompositionAttribute?
- if (setWindowCompositionAttribute != null) {
- val accent = cValue<ACCENT_POLICY> {
- AccentState = ACCENT_ENABLE_BLURBEHIND
- AccentFlags = 0.convert()
- GradientColor = 0.convert()
- AnimationId = 0.convert()
- }
- memScoped {
- val data = cValue<WINDOWCOMPOSITIONATTRIBDATA> {
- Attrib = WCA_ACCENT_POLICY
- pvData = accent.ptr
- cbData = accent.size.convert()
- }
- setWindowCompositionAttribute(hDlg, data.ptr)
- }
- }
- }
+ setAero(hDlg)
return true.toByte().toLong()
}
WM_COMMAND -> {
@@ -65,4 +140,25 @@ fun dlgProc(hDlg: HWND,
return false.toByte().toLong()
}
}
+}
+
+fun setAero(hwnd: HWND?) {
+ val hUser = GetModuleHandleW("user32.dll") ?: return
+ val setWindowCompositionAttribute = GetProcAddress(hUser,
+ "SetWindowCompositionAttribute")
+ as pfnSetWindowCompositionAttribute? ?: return
+ val accent = cValue<ACCENT_POLICY> {
+ AccentState = ACCENT_ENABLE_BLURBEHIND
+ AccentFlags = 0.convert()
+ GradientColor = 0.convert()
+ AnimationId = 0.convert()
+ }
+ memScoped {
+ val data = cValue<WINDOWCOMPOSITIONATTRIBDATA> {
+ Attrib = WCA_ACCENT_POLICY
+ pvData = accent.ptr
+ cbData = accent.size.convert()
+ }
+ setWindowCompositionAttribute(hwnd, data.ptr)
+ }
} \ No newline at end of file