added debug printing of window styles, implemented Window.setBorderRounded, and fixed move resizing

This commit is contained in:
DaniTheSkunk 2022-09-27 14:42:14 +02:00
parent c3ba2983dd
commit ec7cc40d02
4 changed files with 187 additions and 10 deletions

View File

@ -15,6 +15,11 @@ public class Test {
for(var window: windows) { for(var window: windows) {
System.out.printf("%s -- %s -- %s\n", window.getTitle(), window.getClassName(), window.getExecutableName()); System.out.printf("%s -- %s -- %s\n", window.getTitle(), window.getClassName(), window.getExecutableName());
} }
windows.get(0).setBorder(true);
windows.get(0).setBorderRounded(false);
windows.get(0).move(new Vec2i(1280, 720), new Vec2i(2560, 1440));
windows.get(0).debugPrintStyles();
windows.get(0).debugPrintStylesEx();
/* /*
var engine = new Engine(); var engine = new Engine();
var window = engine.openWindow(new Vec2i(1280, 720), "Skunkworks"); var window = engine.openWindow(new Vec2i(1280, 720), "Skunkworks");

View File

@ -27,6 +27,15 @@ public interface Dwm extends Library {
WinDef.DWORD DWMWA_CLOAKED = new WinDef.DWORD(14); WinDef.DWORD DWMWA_CLOAKED = new WinDef.DWORD(14);
WinDef.DWORD DWMWA_FREEZE_REPRESENTATION = new WinDef.DWORD(15); WinDef.DWORD DWMWA_FREEZE_REPRESENTATION = new WinDef.DWORD(15);
WinDef.DWORD DWMWA_LAST = new WinDef.DWORD(16); WinDef.DWORD DWMWA_LAST = new WinDef.DWORD(16);
WinDef.DWORD DWMWA_WINDOW_CORNER_PREFERENCE = new WinDef.DWORD(33);
//todo: fix/complete DWMWA list
WinDef.DWORD DWMWCP_DEFAULT = new WinDef.DWORD(0);
WinDef.DWORD DWMWCP_DONOTROUND = new WinDef.DWORD(1);
WinDef.DWORD DWMWCP_ROUND = new WinDef.DWORD(2);
WinDef.DWORD DWMWCP_ROUNDSMALL = new WinDef.DWORD(3);
WinNT.HRESULT DwmExtendFrameIntoClientArea(WinDef.HWND hwnd, MARGINS pMarInset);
WinNT.HRESULT DwmGetWindowAttribute(WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute, WinDef.DWORD cbAttribute); WinNT.HRESULT DwmGetWindowAttribute(WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute, WinDef.DWORD cbAttribute);
WinNT.HRESULT DwmSetWindowAttribute(WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute, WinDef.DWORD cbAttribute);
} }

View File

@ -0,0 +1,19 @@
package com.danitheskunk.skunkworks.windows;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;
public class MARGINS extends Structure implements Structure.ByReference {
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("cxLeftWidth", "cxRightWidth", "cyTopHeight", "cyBottomHeight");
}
}

View File

@ -2,6 +2,7 @@ package com.danitheskunk.skunkworks.windows;
import com.danitheskunk.skunkworks.Util; import com.danitheskunk.skunkworks.Util;
import com.danitheskunk.skunkworks.Vec2i;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*; import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.IntByReference;
@ -17,6 +18,105 @@ public class Window {
this.hwnd = hwnd; this.hwnd = hwnd;
} }
public void debugPrintStyles() {
var str = new StringBuilder();
var style = getStyle();
str.append("Window Styles: ");
if((style & User32.WS_BORDER) != 0) str.append("ws_border, ");
if((style & User32.WS_CAPTION) != 0) str.append("ws_caption, ");
if((style & User32.WS_CHILD) != 0) str.append("ws_child, ");
if((style & User32.WS_CHILDWINDOW) != 0) str.append("ws_childwindow, ");
if((style & User32.WS_CLIPCHILDREN) != 0) str.append("ws_clipchildren, ");
if((style & User32.WS_CLIPSIBLINGS) != 0) str.append("ws_clipsiblings, ");
if((style & User32.WS_DISABLED) != 0) str.append("ws_disabled, ");
if((style & User32.WS_DLGFRAME) != 0) str.append("ws_dlgframe, ");
if((style & User32.WS_GROUP) != 0) str.append("ws_group, ");
if((style & User32.WS_HSCROLL) != 0) str.append("ws_hscroll, ");
if((style & User32.WS_ICONIC) != 0) str.append("ws_iconic, ");
if((style & User32.WS_MAXIMIZE) != 0) str.append("ws_maximize, ");
if((style & User32.WS_MAXIMIZEBOX) != 0) str.append("ws_maximizebox, ");
if((style & User32.WS_MINIMIZE) != 0) str.append("ws_minimize, ");
if((style & User32.WS_MINIMIZEBOX) != 0) str.append("ws_minimizebox, ");
if((style & User32.WS_OVERLAPPED) != 0) str.append("ws_overlapped, ");
if((style & User32.WS_POPUP) != 0) str.append("ws_popup, ");
if((style & User32.WS_SIZEBOX) != 0) str.append("ws_sizebox, ");
if((style & User32.WS_SYSMENU) != 0) str.append("ws_sysmenu, ");
if((style & User32.WS_TABSTOP) != 0) str.append("ws_tabstop, ");
if((style & User32.WS_THICKFRAME) != 0) str.append("ws_thickframe, ");
if((style & User32.WS_TILED) != 0) str.append("ws_tiled, ");
if((style & User32.WS_VISIBLE) != 0) str.append("ws_visible, ");
if((style & User32.WS_VSCROLL) != 0) str.append("ws_vscroll, ");
System.out.println(str.toString());
}
public void debugPrintStylesEx() {
var str = new StringBuilder();
var style = getStyleEx();
str.append("Window Styles EX: ");
if((style & User32Extra.WS_EX_ACCEPTFILES) != 0) str.append("ws_ex_acceptfiles, ");
if((style & User32Extra.WS_EX_APPWINDOW) != 0) str.append("ws_ex_appwindow, ");
if((style & User32Extra.WS_EX_CLIENTEDGE) != 0) str.append("ws_ex_clientedge, ");
if((style & User32Extra.WS_EX_COMPOSITED) != 0) str.append("ws_ex_composited, ");
if((style & User32Extra.WS_EX_CONTEXTHELP) != 0) str.append("ws_ex_contexthelp, ");
if((style & User32Extra.WS_EX_CONTROLPARENT) != 0) str.append("ws_ex_controlparent, ");
if((style & User32Extra.WS_EX_DLGMODALFRAME) != 0) str.append("ws_ex_dlgmodalframe, ");
if((style & User32Extra.WS_EX_LAYERED) != 0) str.append("ws_ex_layered, ");
if((style & User32Extra.WS_EX_LAYOUTRTL) != 0) str.append("ws_ex_layoutrtl, ");
if((style & User32Extra.WS_EX_LEFT) != 0) str.append("ws_ex_left, ");
if((style & User32Extra.WS_EX_LEFTSCROLLBAR) != 0) str.append("ws_ex_leftscrollbar, ");
if((style & User32Extra.WS_EX_LTRREADING) != 0) str.append("ws_ex_ltrreading, ");
if((style & User32Extra.WS_EX_MDICHILD) != 0) str.append("ws_ex_mdichild, ");
if((style & User32Extra.WS_EX_NOACTIVATE) != 0) str.append("ws_ex_noactivate, ");
if((style & User32Extra.WS_EX_NOINHERITLAYOUT) != 0) str.append("ws_ex_noinheritedlayout, ");
if((style & User32Extra.WS_EX_NOPARENTNOTIFY) != 0) str.append("ws_ex_noparentnotify, ");
if((style & User32Extra.WS_EX_NOREDIRECTIONBITMAP) != 0) str.append("ws_ex_noredirectionbitmap, ");
if((style & User32Extra.WS_EX_RIGHT) != 0) str.append("ws_ex_right, ");
if((style & User32Extra.WS_EX_RIGHTSCROLLBAR) != 0) str.append("ws_ex_rightscrollbar, ");
if((style & User32Extra.WS_EX_RTLREADING) != 0) str.append("ws_ex_rtlreading, ");
if((style & User32Extra.WS_EX_STATICEDGE) != 0) str.append("ws_ex_staticedge, ");
if((style & User32Extra.WS_EX_TOOLWINDOW) != 0) str.append("ws_ex_toolwindow, ");
if((style & User32Extra.WS_EX_TOPMOST) != 0) str.append("ws_ex_topmost, ");
if((style & User32Extra.WS_EX_TRANSPARENT) != 0) str.append("ws_ex_transparent, ");
if((style & User32Extra.WS_EX_WINDOWEDGE) != 0) str.append("ws_ex_windowedge, ");
System.out.println(str.toString());
}
public void setBorder(boolean border) {
var STYLES = User32Extra.WS_CAPTION | User32Extra.WS_THICKFRAME | User32Extra.WS_MINIMIZEBOX | User32Extra.WS_SYSMENU;
//var STYLES = User32Extra.WS_THICKFRAME | User32Extra.WS_MINIMIZEBOX | User32Extra.WS_SYSMENU;
var STYLESEX = User32Extra.WS_EX_DLGMODALFRAME | User32Extra.WS_EX_CLIENTEDGE | User32Extra.WS_EX_STATICEDGE;
//var STYLES = User32Extra.WS_POPUP;
var style = getStyle();
var styleex = getStyleEx();
if(border) {
style |= STYLES;
styleex |= STYLESEX;
} else {
style &= ~STYLES;
styleex &= ~STYLESEX;
}
setStyle(style);
setStyleEx(styleex);
var dwm = Dwm.INSTANCE;
var margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 0;
margins.cyTopHeight = 0;
margins.cyBottomHeight = 0;
dwm.DwmExtendFrameIntoClientArea(hwnd, margins);
}
public void setBorderRounded(boolean rounded) {
var round = rounded ? Dwm.DWMWCP_ROUND : Dwm.DWMWCP_DONOTROUND;
var roundref = new WinDef.DWORDByReference(round);
Dwm.INSTANCE.DwmSetWindowAttribute(hwnd, Dwm.DWMWA_WINDOW_CORNER_PREFERENCE, roundref.getPointer(), new WinDef.DWORD(WinDef.DWORD.SIZE));
}
public String getClassName() { public String getClassName() {
var user32 = User32Extra.INSTANCE; var user32 = User32Extra.INSTANCE;
char[] chars = new char[1024]; char[] chars = new char[1024];
@ -42,6 +142,21 @@ public class Window {
return user32.GetWindowLong(hwnd, WinUser.GWL_STYLE); return user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
} }
private void setStyle(int style) {
var user32 = User32Extra.INSTANCE;
user32.SetWindowLong(hwnd, WinUser.GWL_STYLE, style);
}
private int getStyleEx() {
var user32 = User32Extra.INSTANCE;
return user32.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
}
private void setStyleEx(int style) {
var user32 = User32Extra.INSTANCE;
user32.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, style);
}
private boolean isTitleBarVisible() { private boolean isTitleBarVisible() {
var tb = getTitleBarInfo(); var tb = getTitleBarInfo();
return (tb.rgstate[0] & User32Extra.STATE_SYSTEM_INVISIBLE) == 0; return (tb.rgstate[0] & User32Extra.STATE_SYSTEM_INVISIBLE) == 0;
@ -73,18 +188,18 @@ public class Window {
var user32 = User32Extra.INSTANCE; var user32 = User32Extra.INSTANCE;
var dwm = Dwm.INSTANCE; var dwm = Dwm.INSTANCE;
var out = new IntByReference(); var out = new IntByReference();
dwm.DwmGetWindowAttribute(hwnd, Dwm.DWMWA_CLOAKED, out.getPointer(), new WinDef.DWORD(WinDef.DWORD.SIZE)); //dwm.DwmGetWindowAttribute(hwnd, Dwm.DWMWA_CLOAKED, out.getPointer(), new WinDef.DWORD(WinDef.DWORD.SIZE));
var val = out.getValue(); var val = out.getValue();
return val != 0; return val != 0;
} }
public boolean isInAltTabList() { public boolean isInAltTabList() {
var user32 = User32Extra.INSTANCE; var user32 = User32Extra.INSTANCE;
var walk = user32.GetAncestor(hwnd, WinUser.GA_ROOTOWNER); var walk = user32.GetAncestor(hwnd, WinUser.GA_ROOTOWNER);
WinDef.HWND test; WinDef.HWND test;
while(!(test = user32.GetLastActivePopup(walk)).equals(test)) { while(!(test = user32.GetLastActivePopup(walk)).equals(test)) {
if(user32.IsWindowVisible(test)) if(user32.IsWindowVisible(test)) break;
break;
walk = test; walk = test;
} }
var window = new Window(hwnd); var window = new Window(hwnd);
@ -95,6 +210,41 @@ public class Window {
return (getStyle() & User32Extra.WS_EX_TOOLWINDOW) != 0; return (getStyle() & User32Extra.WS_EX_TOOLWINDOW) != 0;
} }
public void move(Vec2i pos, Vec2i size) {
var user32 = User32Extra.INSTANCE;
var dwm = Dwm.INSTANCE;
var rect_with_shadow = new WinDef.RECT();
var rect_without_shadow = new WinDef.RECT();
var rect = new WinDef.RECT();
user32.GetWindowRect(hwnd, rect_with_shadow);
dwm.DwmGetWindowAttribute(hwnd, Dwm.DWMWA_EXTENDED_FRAME_BOUNDS, rect_without_shadow.getPointer(), new WinDef.DWORD(rect_without_shadow.size()));
rect_without_shadow.read();
var left_shadow = rect_without_shadow.left - rect_with_shadow.left;
var right_shadow = rect_with_shadow.right - rect_without_shadow.right;
var top_shadow = rect_without_shadow.top - rect_with_shadow.top;
var bottom_shaddow = rect_with_shadow.bottom - rect_without_shadow.bottom;
rect.left = pos.getX() - left_shadow;
rect.top = pos.getY() - top_shadow;
rect.right = pos.getX() + size.getX() + right_shadow;
rect.bottom = pos.getY() + size.getY() + bottom_shaddow;
//user32.AdjustWindowRect(rect, new WinDef.DWORD(WinUser.WS_OVERLAPPEDWINDOW), new WinDef.BOOL(false));
//var style = getStyle();
//var styleex = getStyleEx();
//style &= ~(User32Extra.WS_CAPTION | User32Extra.WS_MINIMIZEBOX | User32Extra.WS_SYSMENU);
//styleex &= ~(User32Extra.WS_EX_DLGMODALFRAME | User32Extra.WS_EX_CLIENTEDGE | User32Extra.WS_EX_STATICEDGE);
//style |= User32Extra.WS_POPUP;
//user32.AdjustWindowRectEx(rect, new WinDef.DWORD(style), new WinDef.BOOL(false), new WinDef.DWORD(styleex));
user32.MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true);
//user32.MoveWindow(hwnd, pos.getX(), pos.getY(), size.getX(), size.getY(), true);
user32.SetWindowPos(hwnd, null, 0, 0, 0, 0, WinUser.SWP_FRAMECHANGED | WinUser.SWP_NOZORDER | WinUser.SWP_NOOWNERZORDER | WinUser.SWP_NOMOVE | WinUser.SWP_NOSIZE | WinUser.SWP_NOACTIVATE);
}
//static functions //static functions
public static List<Window> getAllVisible() { public static List<Window> getAllVisible() {
var user32 = User32Extra.INSTANCE; var user32 = User32Extra.INSTANCE;
@ -104,13 +254,7 @@ public class Window {
@Override @Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) { public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
var window = new Window(hwnd); var window = new Window(hwnd);
//if(user32.IsWindowVisible(hwnd) && user32.GetWindow(hwnd, new WinDef.DWORD(User32.GW_OWNER)) == null) { if(window.isInAltTabList()) windows.add(window);
if(window.isInAltTabList()) {
//if(title.length() > 0) {
//windows.add(window.getTitle() + " -- " + window.getClassName());
windows.add(window);
//}
}
return true; return true;
} }
}, null); }, null);