Ungroup multiple instances from taskbar, use native pinvoke for clipboard.

This commit is contained in:
UnknownShadow200 2017-08-13 19:18:59 +10:00
parent ad7c213630
commit bf19bae85a
3 changed files with 109 additions and 20 deletions

View File

@ -57,13 +57,13 @@ namespace ClassicalSharp {
// TODO: retry when clipboard returns null.
public string ClipboardText {
get {
if (OpenTK.Configuration.RunningOnMacOS)
if (!OpenTK.Configuration.RunningOnLinux)
return GetClipboardText();
else
return Clipboard.GetText();
}
set {
if (OpenTK.Configuration.RunningOnMacOS)
if (!OpenTK.Configuration.RunningOnLinux)
SetClipboardText(value);
else
Clipboard.SetText(value);

View File

@ -3,7 +3,7 @@
* Contributions from Erik Ylvisaker
* See license.txt for license info
*/
#endregion
#endregion
using System;
using System.Drawing;
@ -16,6 +16,9 @@ namespace OpenTK.Platform.Windows {
internal static class API {
[DllImport("shell32.dll")]
public static extern int SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID);
[DllImport("user32.dll"), SuppressUnmanagedCodeSecurity]
internal static extern bool SetWindowPos(IntPtr handle, IntPtr insertAfter, int x, int y, int cx, int cy, SetWindowPosFlags flags);
@ -27,10 +30,10 @@ namespace OpenTK.Platform.Windows {
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr CreateWindowEx(ExtendedWindowStyle ExStyle, IntPtr ClassAtom, IntPtr WindowName, WindowStyle Style,
int X, int Y, int Width, int Height, IntPtr HandleToParentWindow, IntPtr Menu, IntPtr Instance, IntPtr Param);
int X, int Y, int Width, int Height, IntPtr HandleToParentWindow, IntPtr Menu, IntPtr Instance, IntPtr Param);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern bool DestroyWindow(IntPtr windowHandle);
internal static extern bool DestroyWindow(IntPtr windowHandle);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto), SuppressUnmanagedCodeSecurity]
internal static extern ushort RegisterClassEx(ref ExtendedWindowClass window_class);
@ -80,6 +83,7 @@ namespace OpenTK.Platform.Windows {
[DllImport("User32.dll", CharSet = CharSet.Auto), SuppressUnmanagedCodeSecurity]
public extern static IntPtr DefWindowProc(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll"), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr GetDC(IntPtr hwnd);
@ -97,6 +101,7 @@ namespace OpenTK.Platform.Windows {
[DllImport("gdi32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern bool SwapBuffers(IntPtr dc);
[DllImport("kernel32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr LoadLibrary(string dllName);
@ -104,9 +109,6 @@ namespace OpenTK.Platform.Windows {
[DllImport("kernel32", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern uint MapVirtualKey(VirtualKeys vkey, MapVirtualKeyType uMapType);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow);
@ -120,9 +122,6 @@ namespace OpenTK.Platform.Windows {
[DllImport("user32.dll"), SuppressUnmanagedCodeSecurity]
public static extern bool IsWindowVisible(IntPtr intPtr);
[DllImport("user32.dll"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern bool SetForegroundWindow(IntPtr hWnd);
@ -137,6 +136,38 @@ namespace OpenTK.Platform.Windows {
internal static extern bool EnumDisplaySettings([MarshalAs(UnmanagedType.LPTStr)] string device_name,
int graphics_mode, [In, Out] DeviceMode device_mode);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern bool EmptyClipboard();
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern bool CloseClipboard();
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetClipboardData(uint uFormat);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GlobalFree(IntPtr hMem);
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
public static extern bool GlobalUnlock(IntPtr hMem);
[DllImport("user32.dll"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName);
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern bool TrackMouseEvent(ref TrackMouseEventStructure lpEventTrack);
@ -151,6 +182,9 @@ namespace OpenTK.Platform.Windows {
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern ushort GetKeyState( int code );
[DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
internal static extern uint MapVirtualKey(VirtualKeys vkey, MapVirtualKeyType uMapType);
}
internal struct Constants {
@ -302,7 +336,7 @@ namespace OpenTK.Platform.Windows {
internal static int SizeInBytes = Marshal.SizeOf(default(WindowClass));
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct ExtendedWindowClass
{
@ -507,7 +541,7 @@ namespace OpenTK.Platform.Windows {
DRAW_TO_WINDOW = 0x04,
SUPPORT_OPENGL = 0x20,
DEPTH_DONTCARE = 0x20000000,
}
}
internal enum PixelType : byte {
RGBA = 0,
@ -623,11 +657,11 @@ namespace OpenTK.Platform.Windows {
}
enum MouseKeys {
None = 0x00, //No mouse button was pressed.
Left = 0x01, // The left mouse button was pressed.
Right = 0x02, // The right mouse button was pressed.
Middle = 0x10, // The middle mouse button was pressed.
XButton1 = 0x20, // The first XButton was pressed.
None = 0x00, //No mouse button was pressed.
Left = 0x01, // The left mouse button was pressed.
Right = 0x02, // The right mouse button was pressed.
Middle = 0x10, // The middle mouse button was pressed.
XButton1 = 0x20, // The first XButton was pressed.
XButton2 = 0x40, // The second XButton was pressed.
}

View File

@ -29,6 +29,7 @@ using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using OpenTK.Input;
namespace OpenTK.Platform.Windows
@ -64,9 +65,17 @@ namespace OpenTK.Platform.Windows
public WinGLNative(int x, int y, int width, int height, string title, DisplayDevice device) {
WindowProcedureDelegate = WindowProcedure;
UngroupFromTaskbar();
window = new WinWindowInfo(CreateWindow(x, y, width, height, title, device));
exists = true;
}
void UngroupFromTaskbar() {
Version version = Environment.OSVersion.Version;
if ((version.Major > 6) || (version.Major == 6 && version.Minor >= 1)) {
API.SetCurrentProcessExplicitAppUserModelID("ClassicalSharp_" + new Random().Next());
}
}
unsafe IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) {
switch (message) {
@ -438,9 +447,55 @@ namespace OpenTK.Platform.Windows
suppress_resize--;
}
public string GetClipboardText() { return ""; }
const uint GMEM_MOVEABLE = 2;
const uint CF_UNICODETEXT = 13;
public unsafe string GetClipboardText() {
// retry up to 10 times
for (int i = 0; i < 10; i++) {
if (API.OpenClipboard(window.WindowHandle)) {
IntPtr hGlobal = API.GetClipboardData(CF_UNICODETEXT);
if (hGlobal == IntPtr.Zero) { API.CloseClipboard(); return ""; }
IntPtr src = API.GlobalLock(hGlobal);
string value = new String((char*)src);
API.GlobalUnlock(hGlobal);
API.CloseClipboard();
return value;
}
Thread.Sleep(100);
}
return "";
}
public void SetClipboardText( string value ) { }
public unsafe void SetClipboardText( string value ) {
UIntPtr dstSize = (UIntPtr)((value.Length + 1) * Marshal.SystemDefaultCharSize);
// retry up to 10 times
for (int i = 0; i < 10; i++) {
if (API.OpenClipboard(window.WindowHandle)) {
IntPtr hGlobal = API.GlobalAlloc(GMEM_MOVEABLE, dstSize);
if (hGlobal == IntPtr.Zero) { API.CloseClipboard(); return; }
IntPtr dst = API.GlobalLock(hGlobal);
fixed (char* src = value) {
CopyString((IntPtr)src, dst, value.Length);
}
API.GlobalUnlock(hGlobal);
API.EmptyClipboard();
API.SetClipboardData(CF_UNICODETEXT, hGlobal);
API.CloseClipboard();
return;
}
Thread.Sleep(100);
}
}
unsafe static void CopyString(IntPtr src, IntPtr dst, int numChars) {
char* src2 = (char*)src, dst2 = (char*)dst;
for (int i = 0; i < numChars; i++) { dst2[i] = src2[i]; }
dst2[numChars] = '\0';
}
public Rectangle Bounds {
get { return bounds; }