added debug printing of window styles, implemented Window.setBorderRounded, and fixed move resizing
This commit is contained in:
parent
c3ba2983dd
commit
ec7cc40d02
|
@ -15,6 +15,11 @@ public class Test {
|
|||
for(var window: windows) {
|
||||
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 window = engine.openWindow(new Vec2i(1280, 720), "Skunkworks");
|
||||
|
|
|
@ -27,6 +27,15 @@ public interface Dwm extends Library {
|
|||
WinDef.DWORD DWMWA_CLOAKED = new WinDef.DWORD(14);
|
||||
WinDef.DWORD DWMWA_FREEZE_REPRESENTATION = new WinDef.DWORD(15);
|
||||
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 DwmSetWindowAttribute(WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute, WinDef.DWORD cbAttribute);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.danitheskunk.skunkworks.windows;
|
|||
|
||||
|
||||
import com.danitheskunk.skunkworks.Util;
|
||||
import com.danitheskunk.skunkworks.Vec2i;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.*;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
@ -17,6 +18,105 @@ public class Window {
|
|||
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() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
char[] chars = new char[1024];
|
||||
|
@ -42,6 +142,21 @@ public class Window {
|
|||
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() {
|
||||
var tb = getTitleBarInfo();
|
||||
return (tb.rgstate[0] & User32Extra.STATE_SYSTEM_INVISIBLE) == 0;
|
||||
|
@ -73,18 +188,18 @@ public class Window {
|
|||
var user32 = User32Extra.INSTANCE;
|
||||
var dwm = Dwm.INSTANCE;
|
||||
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();
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
public boolean isInAltTabList() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var walk = user32.GetAncestor(hwnd, WinUser.GA_ROOTOWNER);
|
||||
WinDef.HWND test;
|
||||
|
||||
while(!(test = user32.GetLastActivePopup(walk)).equals(test)) {
|
||||
if(user32.IsWindowVisible(test))
|
||||
break;
|
||||
if(user32.IsWindowVisible(test)) break;
|
||||
walk = test;
|
||||
}
|
||||
var window = new Window(hwnd);
|
||||
|
@ -95,6 +210,41 @@ public class Window {
|
|||
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
|
||||
public static List<Window> getAllVisible() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
|
@ -104,13 +254,7 @@ public class Window {
|
|||
@Override
|
||||
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
|
||||
var window = new Window(hwnd);
|
||||
//if(user32.IsWindowVisible(hwnd) && user32.GetWindow(hwnd, new WinDef.DWORD(User32.GW_OWNER)) == null) {
|
||||
if(window.isInAltTabList()) {
|
||||
//if(title.length() > 0) {
|
||||
//windows.add(window.getTitle() + " -- " + window.getClassName());
|
||||
windows.add(window);
|
||||
//}
|
||||
}
|
||||
if(window.isInAltTabList()) windows.add(window);
|
||||
return true;
|
||||
}
|
||||
}, null);
|
||||
|
|
Loading…
Reference in New Issue