aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuutaW <17158086+Trumeet@users.noreply.github.com>2019-06-29 15:03:00 -0700
committerTrumeet <17158086+Trumeet@users.noreply.github.com>2019-06-29 15:03:00 -0700
commit18075a43d41d5084ac5ae57a75981e27f2041352 (patch)
tree80d1b1d74357738020711cda27113dd34a6d558b
parent4f95d2f5c379b9d49acbde750b27d4fa3aadbaf9 (diff)
downloadAero-18075a43d41d5084ac5ae57a75981e27f2041352.tar
Aero-18075a43d41d5084ac5ae57a75981e27f2041352.tar.gz
Aero-18075a43d41d5084ac5ae57a75981e27f2041352.tar.bz2
Aero-18075a43d41d5084ac5ae57a75981e27f2041352.zip
feat: add the Window modeuntagged-63164c155cfcfbc31358
Note: there are still some buts to be solved. For instance, the cursor displays as "loading" after displaying until moving outside from the painting area. The IDE cannot run the program in Window mode as well and while running the process is successfully created but no windows are displayed at all. Signed-off-by: Trumeet <17158086+Trumeet@users.noreply.github.com>
-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