hideconsole_windows.go (2772B)
1 // Copyright 2017 The Ebiten Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package glfw 16 17 import ( 18 "fmt" 19 "unsafe" 20 21 "golang.org/x/sys/windows" 22 ) 23 24 const ( 25 processQueryLimitedInformation = 0x1000 26 ) 27 28 var ( 29 kernel32 = windows.NewLazySystemDLL("kernel32.dll") 30 user32 = windows.NewLazySystemDLL("user32.dll") 31 32 getCurrentProcessIdProc = kernel32.NewProc("GetCurrentProcessId") 33 getConsoleWindowProc = kernel32.NewProc("GetConsoleWindow") 34 getWindowThreadProcessIdProc = user32.NewProc("GetWindowThreadProcessId") 35 showWindowAsyncProc = user32.NewProc("ShowWindowAsync") 36 ) 37 38 func getCurrentProcessId() (uint32, error) { 39 r, _, e := getCurrentProcessIdProc.Call() 40 if e != nil && e.(windows.Errno) != 0 { 41 return 0, fmt.Errorf("ui: GetCurrentProcessId failed: %d", e) 42 } 43 return uint32(r), nil 44 } 45 46 func getWindowThreadProcessId(hwnd uintptr) (uint32, error) { 47 pid := uint32(0) 48 r, _, e := getWindowThreadProcessIdProc.Call(hwnd, uintptr(unsafe.Pointer(&pid))) 49 if r == 0 { 50 return 0, fmt.Errorf("ui: GetWindowThreadProcessId failed: %d", e) 51 } 52 return pid, nil 53 } 54 55 func getConsoleWindow() (uintptr, error) { 56 r, _, e := getConsoleWindowProc.Call() 57 if e != nil && e.(windows.Errno) != 0 { 58 return 0, fmt.Errorf("ui: GetConsoleWindow failed: %d", e) 59 } 60 return r, nil 61 } 62 63 func showWindowAsync(hwnd uintptr, show int) error { 64 if _, _, e := showWindowAsyncProc.Call(hwnd, uintptr(show)); e != nil && e.(windows.Errno) != 0 { 65 return fmt.Errorf("ui: ShowWindowAsync failed: %d", e) 66 } 67 return nil 68 } 69 70 // hideConsoleWindowOnWindows will hide the console window that is showing when 71 // compiling on Windows without specifying the '-ldflags "-Hwindowsgui"' flag. 72 func hideConsoleWindowOnWindows() { 73 pid, err := getCurrentProcessId() 74 if err != nil { 75 // Ignore errors because: 76 // 1. It is not critical if the console can't be hid. 77 // 2. There is nothing to do when errors happen. 78 return 79 } 80 w, err := getConsoleWindow() 81 if err != nil { 82 // Ignore errors 83 return 84 } 85 // Get the process ID of the console's creator. 86 cpid, err := getWindowThreadProcessId(w) 87 if err != nil { 88 // Ignore errors 89 return 90 } 91 if pid == cpid { 92 // The current process created its own console. Hide this. 93 showWindowAsync(w, windows.SW_HIDE) 94 } 95 }