Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
spddl committed Jan 31, 2022
1 parent e49c967 commit f205da5
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 0 deletions.
Binary file added disableDWMactivitys.exe
Binary file not shown.
76 changes: 76 additions & 0 deletions dwmapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"syscall"
"unsafe"

"github.com/lxn/win"
)

// https://github.com/KaiCoder/router/blob/712947901108692a53d37f0098cea3cd66de24c6/gopath/src/github.com/shirou/w32/dwmapi.go
var (
moddwmapi = syscall.NewLazyDLL("dwmapi.dll")

procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
)

// C:\Windows\System32\rundll32.exe dwmapi.dll,DwmEnableMMCSS 0

// https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmenablecomposition#parameters

type DWMWINDOWATTRIBUTE int32

const (
DWMWA_NCRENDERING_ENABLED DWMWINDOWATTRIBUTE = 1
DWMWA_NCRENDERING_POLICY DWMWINDOWATTRIBUTE = 2
DWMWA_TRANSITIONS_FORCEDISABLED DWMWINDOWATTRIBUTE = 3
DWMWA_ALLOW_NCPAINT DWMWINDOWATTRIBUTE = 4
DWMWA_CAPTION_BUTTON_BOUNDS DWMWINDOWATTRIBUTE = 5
DWMWA_NONCLIENT_RTL_LAYOUT DWMWINDOWATTRIBUTE = 6
DWMWA_FORCE_ICONIC_REPRESENTATION DWMWINDOWATTRIBUTE = 7
DWMWA_FLIP3D_POLICY DWMWINDOWATTRIBUTE = 8
DWMWA_EXTENDED_FRAME_BOUNDS DWMWINDOWATTRIBUTE = 9
DWMWA_HAS_ICONIC_BITMAP DWMWINDOWATTRIBUTE = 10
DWMWA_DISALLOW_PEEK DWMWINDOWATTRIBUTE = 11
DWMWA_EXCLUDED_FROM_PEEK DWMWINDOWATTRIBUTE = 12
DWMWA_CLOAK DWMWINDOWATTRIBUTE = 13
DWMWA_CLOAKED DWMWINDOWATTRIBUTE = 14
DWMWA_FREEZE_REPRESENTATION DWMWINDOWATTRIBUTE = 15
DWMWA_PASSIVE_UPDATE_MODE DWMWINDOWATTRIBUTE = 16
DWMWA_LAST DWMWINDOWATTRIBUTE = 17
)

type DWMNCRENDERINGPOLICY int32

const (
DWMNCRP_USEWINDOWSTYLE DWMNCRENDERINGPOLICY = 0
DWMNCRP_DISABLED DWMNCRENDERINGPOLICY = 1
DWMNCRP_ENABLED DWMNCRENDERINGPOLICY = 2
DWMNCRP_LAST DWMNCRENDERINGPOLICY = 3
)

type (
// HANDLE uintptr
// HWND HANDLE
LPCVOID unsafe.Pointer
HRESULT int32
)

func DwmSetWindowAttribute(hWnd win.HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute *DWMNCRENDERINGPOLICY, cbAttribute uint32) int32 {
ret, _, _ := procDwmSetWindowAttribute.Call(
uintptr(hWnd),
uintptr(dwAttribute),
uintptr(unsafe.Pointer(pvAttribute)),
uintptr(cbAttribute))
return int32(ret)
}

func DwmGetWindowAttribute(hWnd win.HWND, dwAttribute DWMWINDOWATTRIBUTE, pvAttribute *DWMNCRENDERINGPOLICY, cbAttribute uint32) int32 {
ret, _, _ := procDwmGetWindowAttribute.Call(
uintptr(hWnd),
uintptr(dwAttribute),
uintptr(unsafe.Pointer(pvAttribute)),
uintptr(cbAttribute))
return int32(ret)
}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module disableDWMactivitys

go 1.17

require github.com/lxn/win v0.0.0-20210218163916-a377121e959e

require golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
54 changes: 54 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"log"
"syscall"
"unsafe"

"github.com/lxn/win"
)

func main() {
listener = &Listener{}
go startListenerMessageLoop()

list, err := GetAllWindows()
if err != nil {
log.Fatal(err)
}

for _, h := range list {
hwnd := win.HWND(h)
if getDWMactive(hwnd) {
// https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
var policyParameter = DWMNCRP_DISABLED
// Use with DwmSetWindowAttribute. Sets the non-client rendering policy. The pvAttribute parameter points to a value from the DWMNCRENDERINGPOLICY enumeration.
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &policyParameter, 8) // unsafe.Sizeof(int(0))

policyParameter = DWMNCRP_DISABLED
// Use with DwmSetWindowAttribute. Forces the window to display an iconic thumbnail or peek representation (a static bitmap), even if a live or snapshot representation of the window is available. This value is normally set during a window's creation, and not changed throughout the window's lifetime. Some scenarios, however, might require the value to change over time. The pvAttribute parameter points to a value of type BOOL. TRUE to require a iconic thumbnail or peek representation; otherwise, FALSE.
DwmSetWindowAttribute(hwnd, DWMWA_FORCE_ICONIC_REPRESENTATION, &policyParameter, 8) // unsafe.Sizeof(int(0))
}
}

select {}
}

func GetAllWindows() ([]syscall.Handle, error) {
var hwndList []syscall.Handle
cb := syscall.NewCallback(func(h syscall.Handle, p uintptr) uintptr {
hwndList = append(hwndList, h)
return 1 // continue enumeration
})
EnumWindows(cb, 0)

return hwndList, nil
}

func getDWMactive(hWnd win.HWND) bool {
var isNCRenderingEnabled = DWMNCRP_USEWINDOWSTYLE
if DwmGetWindowAttribute(hWnd, DWMWA_NCRENDERING_ENABLED, &isNCRenderingEnabled, uint32(unsafe.Sizeof(isNCRenderingEnabled))) != 0 { // unsafe.Sizeof(int(0))
log.Println("getDWMactive Err", hWnd)
}
return isNCRenderingEnabled == 1
}
107 changes: 107 additions & 0 deletions newActiveWindow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"log"
"sync"

"github.com/lxn/win"
)

var listener *Listener

type Listener struct {
AllPIDs map[uint32]struct{}
EVENT_OBJECT_CREATE win.HWINEVENTHOOK
EVENT_SYSTEM_FOREGROUND win.HWINEVENTHOOK
EVENT_OBJECT_DESTROY win.HWINEVENTHOOK
mutex sync.Mutex
}

const (
OBJID_WINDOW = 0
CHILDID_SELF = 0
WM_APPEXIT = 0x0400 + 1
ProcessQueryInformation = 0x0400 // https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
)

// newActiveWindowCallback is passed to Windows to be called whenever the active window changes.
// When it is called it will attempt to find the process of an associated handle, then get the executable associated with that.
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wineventproc
func (l *Listener) newActiveWindowCallback(
hWinEventHook win.HWINEVENTHOOK, // Handle to an event hook function. This value is returned by SetWinEventHook when the hook function is installed and is specific to each instance of the hook function.
event uint32, // Specifies the event that occurred. This value is one of the event constants.
hwnd win.HWND, // Handle to the window that generates the event, or NULL if no window is associated with the event. For example, the mouse pointer is not associated with a window.
idObject int32, // Identifies the object associated with the event. This is one of the object identifiers or a custom object ID.
idChild int32, // Identifies whether the event was triggered by an object or a child element of the object. If this value is CHILDID_SELF, the event was triggered by the object; otherwise, this value is the child ID of the element that triggered the event.
idEventThread uint32,
dwmsEventTime uint32, // Specifies the time, in milliseconds, that the event was generated.
) (ret uintptr) {
l.mutex.Lock()
defer l.mutex.Unlock()

if idObject != OBJID_WINDOW || idChild != CHILDID_SELF {
return
}

if event == win.EVENT_OBJECT_CREATE {
return
}

if hwnd == 0 {
return
}

if getDWMactive(hwnd) {
// https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
var policyParameter = DWMNCRP_DISABLED
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &policyParameter, 8) // unsafe.Sizeof(int(0))
DwmSetWindowAttribute(hwnd, DWMWA_FORCE_ICONIC_REPRESENTATION, &policyParameter, 8) // unsafe.Sizeof(int(0))
}

return 0
}

func startListenerMessageLoop() {
var err error
EVENT_OBJECT_CREATE, err := setActiveWindowWinEventHook(listener.newActiveWindowCallback, win.EVENT_OBJECT_CREATE)
if err != nil {
_ = err
panic(err)
}
defer win.UnhookWinEvent(EVENT_OBJECT_CREATE)

EVENT_SYSTEM_FOREGROUND, err := setActiveWindowWinEventHook(listener.newActiveWindowCallback, win.EVENT_SYSTEM_FOREGROUND)
if err != nil {
panic(err)
}
defer win.UnhookWinEvent(EVENT_SYSTEM_FOREGROUND)

var msg win.MSG
for win.GetMessage(&msg, 0, 0, 0) != 0 {
log.Println(msg)
if msg.Message == WM_APPEXIT {
break
}
win.TranslateMessage(&msg)
win.DispatchMessage(&msg)
}
}

// setActiveWindowWinEventHook is for informing windows which function should be called whenever a
// foreground window has changed. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook
func setActiveWindowWinEventHook(callbackFunction win.WINEVENTPROC, event uint32) (win.HWINEVENTHOOK, error) {
ret, err := win.SetWinEventHook(
event, // Specifies the event constant for the lowest event value in the range of events that are handled by the hook function. This parameter can be set to EVENT_MIN to indicate the lowest possible event value.
event, // Specifies the event constant for the highest event value in the range of events that are handled by the hook function. This parameter can be set to EVENT_MAX to indicate the highest possible event value.
0, // Handle to the DLL that contains the hook function at lpfnWinEventProc, if the WINEVENT_INCONTEXT flag is specified in the dwFlags parameter. If the hook function is not located in a DLL, or if the WINEVENT_OUTOFCONTEXT flag is specified, this parameter is NULL.
callbackFunction, // Pointer to the event hook function. For more information about this function, see WinEventProc.
0, // Specifies the ID of the process from which the hook function receives events. Specify zero (0) to receive events from all processes on the current desktop.
0, // Specifies the ID of the thread from which the hook function receives events. If this parameter is zero, the hook function is associated with all existing threads on the current desktop.
win.WINEVENT_OUTOFCONTEXT|win.WINEVENT_SKIPOWNPROCESS, // Flag values that specify the location of the hook function and of the events to be skipped. The following flags are valid:
)
if ret == 0 {
return 0, err
}

return ret, nil
}
22 changes: 22 additions & 0 deletions user32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"syscall"
)

var (
user32 = syscall.NewLazyDLL("user32.dll")
procEnumWindows = user32.NewProc("EnumWindows")
)

func EnumWindows(enumFunc uintptr, lparam uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(lparam), 0)
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
8 changes: 8 additions & 0 deletions workspace.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}

0 comments on commit f205da5

Please sign in to comment.