zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

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 }