Skip to content

Instantly share code, notes, and snippets.

@mattleibow
Last active February 15, 2017 04:01
Show Gist options
  • Save mattleibow/755eba3c8ff5eafb9549842a0abb0426 to your computer and use it in GitHub Desktop.
Save mattleibow/755eba3c8ff5eafb9549842a0abb0426 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var ctx = new WglContext();
ctx.MakeCurrent();
ctx.Destroy();
}
}
internal class WglContext
{
private static ushort gWC;
private static IntPtr hInstance;
private IntPtr fWindow;
private IntPtr fDeviceContext;
private IntPtr fGlRenderContext;
private IntPtr fPbufferContext;
static WglContext()
{
hInstance = Kernel32.GetModuleHandle(null);
if (hInstance == IntPtr.Zero)
{
throw new Exception("Could not get module handle.");
}
var wc = new WNDCLASS();
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = IntPtr.Zero;
wc.hCursor = User32.LoadCursor(IntPtr.Zero, (int)CursorIds.IDC_ARROW);
wc.hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)SystemIcons.IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC)User32.DefWindowProc;
wc.lpszClassName = "Griffin";
wc.lpszMenuName = null;
wc.style = ClassStyles.CS_HREDRAW | ClassStyles.CS_VREDRAW | ClassStyles.CS_OWNDC;
gWC = User32.RegisterClass(ref wc);
if (gWC == 0)
{
throw new Exception("Could not register window class.");
}
}
public WglContext()
{
fWindow = User32.CreateWindow(
"Griffin",
"The Invisible Man",
WindowStyles.WS_OVERLAPPEDWINDOW,
0, 0,
1, 1,
IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero);
if (fWindow == IntPtr.Zero)
{
throw new Exception($"Could not create window: '{Marshal.GetLastWin32Error()}'.");
}
fDeviceContext = User32.GetDC(fWindow);
if (fDeviceContext == IntPtr.Zero)
{
Destroy();
throw new Exception("Could not get device context.");
}
fPbufferContext = CreatePbufferContext(fDeviceContext, 0);
// HDC dc;
// HGLRC glrc;
// if (nullptr == fPbufferContext) {
// if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType))) {
// SkDebugf("Could not create rendering context.\n");
// this->destroyGLContext();
// return;
// }
// dc = fDeviceContext;
// glrc = fGlRenderContext;
// } else {
// ReleaseDC(fWindow, fDeviceContext);
// fDeviceContext = 0;
// DestroyWindow(fWindow);
// fWindow = 0;
// dc = fPbufferContext->getDC();
// glrc = fPbufferContext->getGLRC();
// }
}
public void MakeCurrent()
{
// if (!(wglMakeCurrent(dc, glrc))) {
// SkDebugf("Could not set the context.\n");
// this->destroyGLContext();
// return;
// }
// HDC dc;
// HGLRC glrc;
// if (nullptr == fPbufferContext) {
// dc = fDeviceContext;
// glrc = fGlRenderContext;
// } else {
// dc = fPbufferContext->getDC();
// glrc = fPbufferContext->getGLRC();
// }
// if (!wglMakeCurrent(dc, glrc)) {
// SkDebugf("Could not create rendering context.\n");
// }
}
public void SwapBuffers()
{
// HDC dc;
// if (nullptr == fPbufferContext) {
// dc = fDeviceContext;
// } else {
// dc = fPbufferContext->getDC();
// }
// if (!SwapBuffers(dc)) {
// SkDebugf("Could not complete SwapBuffers.\n");
// }
}
public void Destroy()
{
// SkSafeSetNull(fPbufferContext);
// if (fGlRenderContext != IntPtr.Zero) {
// wglDeleteContext(fGlRenderContext);
// fGlRenderContext = IntPtr.Zero;
// }
if (fWindow != IntPtr.Zero)
{
if (fDeviceContext != IntPtr.Zero)
{
User32.ReleaseDC(fWindow, fDeviceContext);
fDeviceContext = IntPtr.Zero;
}
User32.DestroyWindow(fWindow);
fWindow = IntPtr.Zero;
}
}
private IntPtr CreatePbufferContext(IntPtr parentDC, int msaaSampleCount)
{
var extensions = new WglExtensions();
if (!extensions.HasExtension(parentDC, "WGL_ARB_pixel_format") ||
!extensions.HasExtension(parentDC, "WGL_ARB_pbuffer"))
{
return IntPtr.Zero;
}
var iAttrs = new int[]
{
Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB,
Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE,
//Wgl.WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE),
Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE,
//Wgl.WGL_RED_BITS, 8,
//Wgl.WGL_GREEN_BITS, 8,
//Wgl.WGL_BLUE_BITS, 8,
//Wgl.WGL_ALPHA_BITS, 8,
//Wgl.WGL_STENCIL_BITS, 8,
Wgl.NONE, Wgl.NONE
};
var fAttrs = new float[2];
var piFormats = new int[1];
uint nFormats;
extensions.wglChoosePixelFormatARB(parentDC, iAttrs, fAttrs, (uint)piFormats.Length, piFormats, out nFormats);
if (nFormats == 0)
{
return IntPtr.Zero;
}
var pbuf = extensions.wglCreatePbufferARB(parentDC, piFormats[0], 1, 1, null);
if (pbuf != IntPtr.Zero)
{
//HDC dc = extensions.getPbufferDC(pbuf);
//if (dc)
//{
// HGLRC glrc = create_gl_context(dc, extensions, contextType);
// if (glrc)
// {
// return new SkWGLPbufferContext(pbuf, dc, glrc);
// }
// extensions.releasePbufferDC(pbuf, dc);
//}
extensions.wglDestroyPbufferARB(pbuf);
}
return IntPtr.Zero;
}
//static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType)
//{
// HDC prevDC = wglGetCurrentDC();
// HGLRC prevGLRC = wglGetCurrentContext();
// HGLRC glrc = nullptr;
// if (kGLES_SkWGLContextRequest == contextType)
// {
// if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile"))
// {
// wglMakeCurrent(prevDC, prevGLRC);
// return nullptr;
// }
// static const int glesAttribs[] = {
// WGL_CONTEXT_MAJOR_VERSION, 3,
// WGL_CONTEXT_MINOR_VERSION, 0,
// WGL_CONTEXT_PROFILE_MASK, WGL_CONTEXT_ES2_PROFILE_BIT,
// 0,
// };
// glrc = extensions.createContextAttribs(dc, nullptr, glesAttribs);
// if (nullptr == glrc)
// {
// wglMakeCurrent(prevDC, prevGLRC);
// return nullptr;
// }
// }
// else
// {
// if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
// extensions.hasExtension(dc, "WGL_ARB_create_context"))
// {
// static const int kCoreGLVersions[] = {
// 4, 3,
// 4, 2,
// 4, 1,
// 4, 0,
// 3, 3,
// 3, 2,
// };
// int coreProfileAttribs[] = {
// WGL_CONTEXT_MAJOR_VERSION, -1,
// WGL_CONTEXT_MINOR_VERSION, -1,
// WGL_CONTEXT_PROFILE_MASK, WGL_CONTEXT_CORE_PROFILE_BIT,
// 0,
// };
// for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v)
// {
// coreProfileAttribs[1] = kCoreGLVersions[2 * v];
// coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
// glrc = extensions.createContextAttribs(dc, nullptr, coreProfileAttribs);
// if (glrc)
// {
// break;
// }
// }
// }
// }
// if (nullptr == glrc)
// {
// glrc = wglCreateContext(dc);
// }
// SkASSERT(glrc);
// wglMakeCurrent(prevDC, prevGLRC);
// // This might help make the context non-vsynced.
// if (extensions.hasExtension(dc, "WGL_EXT_swap_control"))
// {
// extensions.swapInterval(-1);
// }
// return glrc;
//}
//HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor,
// SkWGLContextRequest contextType)
//{
// SkWGLExtensions extensions;
// if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format"))
// {
// return nullptr;
// }
// BOOL set = FALSE;
// int pixelFormatsToTry[] = { -1, -1 };
// get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, deepColor, pixelFormatsToTry);
// for (int f = 0;
// !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry);
// ++f)
// {
// PIXELFORMATDESCRIPTOR pfd;
// DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
// set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
// }
// if (!set)
// {
// return nullptr;
// }
// return create_gl_context(dc, extensions, contextType);
//}
}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr wglGetExtensionsStringARBDelegate(IntPtr dc);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool wglChoosePixelFormatARBDelegate(
IntPtr dc,
[In] int[] attribIList,
[In] float[] attribFList,
uint maxFormats,
[Out] int[] pixelFormats,
out uint numFormats);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr wglCreatePbufferARBDelegate(IntPtr dc, int pixelFormat, int width, int height, [In] int[] attribList);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool wglDestroyPbufferARBDelegate(IntPtr pbuffer);
internal class WglExtensions
{
public readonly wglGetExtensionsStringARBDelegate wglGetExtensionsStringARB;
public readonly wglChoosePixelFormatARBDelegate wglChoosePixelFormatARB;
public readonly wglCreatePbufferARBDelegate wglCreatePbufferARB;
public readonly wglDestroyPbufferARBDelegate wglDestroyPbufferARB;
public WglExtensions()
{
var prevDC = Wgl.wglGetCurrentDC();
var prevGLRC = Wgl.wglGetCurrentContext();
IntPtr dummyWND = CreateDummyWindow();
if (dummyWND != IntPtr.Zero)
{
var dummyPFD = new PIXELFORMATDESCRIPTOR();
dummyPFD.nSize = (ushort)Marshal.SizeOf(dummyPFD);
dummyPFD.nVersion = 1;
dummyPFD.dwFlags = Gdi32.PFD_DRAW_TO_WINDOW | Gdi32.PFD_SUPPORT_OPENGL;
dummyPFD.iPixelType = Gdi32.PFD_TYPE_RGBA;
dummyPFD.cColorBits = 32;
dummyPFD.cDepthBits = 24;
dummyPFD.cStencilBits = 8;
dummyPFD.iLayerType = Gdi32.PFD_MAIN_PLANE;
var dummyDC = User32.GetDC(dummyWND);
var dummyFormat = Gdi32.ChoosePixelFormat(dummyDC, ref dummyPFD);
Gdi32.SetPixelFormat(dummyDC, dummyFormat, ref dummyPFD);
var dummyGLRC = Wgl.wglCreateContext(dummyDC);
if (dummyGLRC == IntPtr.Zero)
{
throw new Exception("Could not create dummy GL context.");
}
Wgl.wglMakeCurrent(dummyDC, dummyGLRC);
wglGetExtensionsStringARB = Wgl.wglGetProcAddress<wglGetExtensionsStringARBDelegate>("wglGetExtensionsStringARB");
wglChoosePixelFormatARB = Wgl.wglGetProcAddress<wglChoosePixelFormatARBDelegate>("wglCreatePbufferARB");
wglCreatePbufferARB = Wgl.wglGetProcAddress<wglCreatePbufferARBDelegate>("wglCreatePbufferARB");
wglDestroyPbufferARB = Wgl.wglGetProcAddress<wglDestroyPbufferARBDelegate>("wglDestroyPbufferARB");
// GET_PROC(ChoosePixelFormat, ARB);
// GET_PROC(GetPixelFormatAttribiv, ARB);
// GET_PROC(GetPixelFormatAttribfv, ARB);
// GET_PROC(CreateContextAttribs, ARB);
// GET_PROC(SwapInterval, EXT);
// GET_PROC(GetPbufferDC, ARB);
// GET_PROC(ReleasePbufferDC, ARB);
Wgl.wglMakeCurrent(dummyDC, IntPtr.Zero);
Wgl.wglDeleteContext(dummyGLRC);
DestroyDummyWindow(dummyWND);
}
Wgl.wglMakeCurrent(prevDC, prevGLRC);
}
public bool HasExtension(IntPtr dc, string ext)
{
if (wglGetExtensionsStringARB == null)
{
return false;
}
if (ext == "WGL_ARB_extensions_string")
{
return true;
}
return Array.IndexOf(GetExtensionsARB(dc), ext) != -1;
}
private IntPtr CreateDummyWindow()
{
var module = Kernel32.GetModuleHandle(null);
IntPtr dummy;
var windowRect = new RECT
{
left = 0,
right = 8,
top = 0,
bottom = 8
};
var wc = new WNDCLASS
{
style = (ClassStyles.CS_HREDRAW | ClassStyles.CS_VREDRAW | ClassStyles.CS_OWNDC),
lpfnWndProc = (WNDPROC)User32.DefWindowProc,
cbClsExtra = 0,
cbWndExtra = 0,
hInstance = module,
hCursor = User32.LoadCursor(IntPtr.Zero, (int)CursorIds.IDC_ARROW),
hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)SystemIcons.IDI_WINLOGO),
hbrBackground = IntPtr.Zero,
lpszMenuName = null,
lpszClassName = "DummyClass"
};
if (User32.RegisterClass(ref wc) == 0)
{
throw new Exception("Could not register dummy class.");
}
User32.AdjustWindowRectEx(
ref windowRect,
WindowStyles.WS_SYSMENU,
false,
WindowStylesEx.WS_EX_CLIENTEDGE);
dummy = User32.CreateWindowEx(
WindowStylesEx.WS_EX_CLIENTEDGE,
"DummyClass",
"DummyWindow",
WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_SYSMENU,
0, 0,
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
IntPtr.Zero, IntPtr.Zero, module, IntPtr.Zero);
if (dummy == IntPtr.Zero)
{
User32.UnregisterClass("DummyClass", module);
throw new Exception("Could not create dummy window.");
}
User32.ShowWindow(dummy, ShowWindowCommands.SW_HIDE);
return dummy;
}
private void DestroyDummyWindow(IntPtr dummy)
{
User32.DestroyWindow(dummy);
var module = Kernel32.GetModuleHandle(null);
User32.UnregisterClass("DummyClass", module);
}
private string GetExtensionsStringARB(IntPtr dc)
{
return Marshal.PtrToStringAnsi(wglGetExtensionsStringARB(dc));
}
private string[] GetExtensionsARB(IntPtr dc)
{
var str = GetExtensionsStringARB(dc);
if (string.IsNullOrEmpty(str))
{
return new string[0];
}
return str.Split(' ');
}
}
internal class Wgl
{
private const string opengl32 = "opengl32.dll";
public const int NONE = 0;
public const int FALSE = 0;
public const int TRUE = 1;
public const int WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000;
public const int WGL_DRAW_TO_WINDOW_ARB = 0x2001;
public const int WGL_DRAW_TO_BITMAP_ARB = 0x2002;
public const int WGL_ACCELERATION_ARB = 0x2003;
public const int WGL_NEED_PALETTE_ARB = 0x2004;
public const int WGL_NEED_SYSTEM_PALETTE_ARB = 0x2005;
public const int WGL_SWAP_LAYER_BUFFERS_ARB = 0x2006;
public const int WGL_SWAP_METHOD_ARB = 0x2007;
public const int WGL_NUMBER_OVERLAYS_ARB = 0x2008;
public const int WGL_NUMBER_UNDERLAYS_ARB = 0x2009;
public const int WGL_TRANSPARENT_ARB = 0x200A;
public const int WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037;
public const int WGL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038;
public const int WGL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039;
public const int WGL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A;
public const int WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B;
public const int WGL_SHARE_DEPTH_ARB = 0x200C;
public const int WGL_SHARE_STENCIL_ARB = 0x200D;
public const int WGL_SHARE_ACCUM_ARB = 0x200E;
public const int WGL_SUPPORT_GDI_ARB = 0x200F;
public const int WGL_SUPPORT_OPENGL_ARB = 0x2010;
public const int WGL_DOUBLE_BUFFER_ARB = 0x2011;
public const int WGL_STEREO_ARB = 0x2012;
public const int WGL_PIXEL_TYPE_ARB = 0x2013;
public const int WGL_COLOR_BITS_ARB = 0x2014;
public const int WGL_RED_BITS_ARB = 0x2015;
public const int WGL_RED_SHIFT_ARB = 0x2016;
public const int WGL_GREEN_BITS_ARB = 0x2017;
public const int WGL_GREEN_SHIFT_ARB = 0x2018;
public const int WGL_BLUE_BITS_ARB = 0x2019;
public const int WGL_BLUE_SHIFT_ARB = 0x201A;
public const int WGL_ALPHA_BITS_ARB = 0x201B;
public const int WGL_ALPHA_SHIFT_ARB = 0x201C;
public const int WGL_ACCUM_BITS_ARB = 0x201D;
public const int WGL_ACCUM_RED_BITS_ARB = 0x201E;
public const int WGL_ACCUM_GREEN_BITS_ARB = 0x201F;
public const int WGL_ACCUM_BLUE_BITS_ARB = 0x2020;
public const int WGL_ACCUM_ALPHA_BITS_ARB = 0x2021;
public const int WGL_DEPTH_BITS_ARB = 0x2022;
public const int WGL_STENCIL_BITS_ARB = 0x2023;
public const int WGL_AUX_BUFFERS_ARB = 0x2024;
public const int WGL_NO_ACCELERATION_ARB = 0x2025;
public const int WGL_GENERIC_ACCELERATION_ARB = 0x2026;
public const int WGL_FULL_ACCELERATION_ARB = 0x2027;
public const int WGL_SWAP_EXCHANGE_ARB = 0x2028;
public const int WGL_SWAP_COPY_ARB = 0x2029;
public const int WGL_SWAP_UNDEFINED_ARB = 0x202A;
public const int WGL_TYPE_RGBA_ARB = 0x202B;
public const int WGL_TYPE_COLORINDEX_ARB = 0x202C;
[DllImport(opengl32)]
public static extern IntPtr wglGetCurrentDC();
[DllImport(opengl32)]
public static extern IntPtr wglGetCurrentContext();
[DllImport(opengl32)]
public static extern IntPtr wglCreateContext(IntPtr hDC);
[DllImport(opengl32)]
public static extern bool wglMakeCurrent(IntPtr hDC, IntPtr hRC);
[DllImport(opengl32)]
public static extern bool wglDeleteContext(IntPtr hRC);
[DllImport(opengl32)]
public static extern IntPtr wglGetProcAddress(string lpszProc);
public static T wglGetProcAddress<T>(string lpszProc)
{
var ptr = wglGetProcAddress(lpszProc);
if (ptr == IntPtr.Zero)
{
return default(T);
}
return (T)(object)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
}
}
internal enum ShowWindowCommands
{
SW_HIDE = 0,
}
internal enum SystemIcons
{
IDI_APPLICATION = 32512,
IDI_HAND = 32513,
IDI_QUESTION = 32514,
IDI_EXCLAMATION = 32515,
IDI_ASTERISK = 32516,
IDI_WINLOGO = 32517,
IDI_WARNING = IDI_EXCLAMATION,
IDI_ERROR = IDI_HAND,
IDI_INFORMATION = IDI_ASTERISK,
}
internal enum CursorIds : uint
{
IDC_ARROW = 32512,
IDC_IBEAM = 32513,
IDC_WAIT = 32514,
IDC_CROSS = 32515,
IDC_UPARROW = 32516,
IDC_SIZE = 32640,
IDC_ICON = 32641,
IDC_SIZENWSE = 32642,
IDC_SIZENESW = 32643,
IDC_SIZEWE = 32644,
IDC_SIZENS = 32645,
IDC_SIZEALL = 32646,
IDC_NO = 32648,
IDC_HAND = 32649,
IDC_APPSTARTING = 32650,
IDC_HELP = 32651
}
[Flags]
internal enum ClassStyles : uint
{
CS_VREDRAW = 0x1,
CS_HREDRAW = 0x2,
CS_DBLCLKS = 0x8,
CS_OWNDC = 0x20,
CS_CLASSDC = 0x40,
CS_PARENTDC = 0x80,
CS_NOCLOSE = 0x200,
CS_SAVEBITS = 0x800,
CS_BYTEALIGNCLIENT = 0x1000,
CS_BYTEALIGNWINDOW = 0x2000,
CS_GLOBALCLASS = 0x4000,
CS_IME = 0x10000,
CS_DROPSHADOW = 0x20000,
}
[StructLayout(LayoutKind.Sequential)]
internal struct WNDCLASS
{
public ClassStyles style;
[MarshalAs(UnmanagedType.FunctionPtr)]
public WNDPROC lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
[MarshalAs(UnmanagedType.LPStr)]
public string lpszMenuName;
[MarshalAs(UnmanagedType.LPStr)]
public string lpszClassName;
}
[Flags]
internal enum WindowStyles : uint
{
WS_BORDER = 0x800000,
WS_CAPTION = 0xc00000,
WS_CHILD = 0x40000000,
WS_CLIPCHILDREN = 0x2000000,
WS_CLIPSIBLINGS = 0x4000000,
WS_DISABLED = 0x8000000,
WS_DLGFRAME = 0x400000,
WS_GROUP = 0x20000,
WS_HSCROLL = 0x100000,
WS_MAXIMIZE = 0x1000000,
WS_MAXIMIZEBOX = 0x10000,
WS_MINIMIZE = 0x20000000,
WS_MINIMIZEBOX = 0x20000,
WS_OVERLAPPED = 0x0,
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
WS_POPUP = 0x80000000u,
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
WS_SIZEFRAME = 0x40000,
WS_SYSMENU = 0x80000,
WS_TABSTOP = 0x10000,
WS_VISIBLE = 0x10000000,
WS_VSCROLL = 0x200000
}
[Flags]
internal enum WindowStylesEx : uint
{
WS_EX_CLIENTEDGE = 0x00000200,
}
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
internal delegate IntPtr WNDPROC(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
internal class User32
{
private const string user32 = "user32.dll";
[DllImport(user32)]
public static extern ushort RegisterClass([In] ref WNDCLASS lpWndClass);
[DllImport(user32)]
public static extern bool UnregisterClass([MarshalAs(UnmanagedType.LPStr)] string lpClassName, IntPtr hInstance);
[DllImport(user32)]
public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
[DllImport(user32)]
public static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr lpIconName);
[DllImport("user32.dll")]
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
[DllImport(user32, SetLastError = true)]
public static extern IntPtr CreateWindowEx(WindowStylesEx dwExStyle, [MarshalAs(UnmanagedType.LPStr)] string lpClassName, [MarshalAs(UnmanagedType.LPStr)] string lpWindowName, WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
public static IntPtr CreateWindow([MarshalAs(UnmanagedType.LPStr)] string lpClassName, [MarshalAs(UnmanagedType.LPStr)] string lpWindowName, WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam)
{
return CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
[DllImport(user32)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport(user32)]
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport(user32)]
public static extern bool DestroyWindow(IntPtr hWnd);
[DllImport(user32)]
public static extern bool AdjustWindowRectEx(ref RECT lpRect, WindowStyles dwStyle, bool bMenu, WindowStylesEx dwExStyle);
[DllImport(user32)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
}
internal class Kernel32
{
private const string kernel32 = "kernel32.dll";
[DllImport(kernel32)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
}
internal class Gdi32
{
private const string gdi32 = "gdi32.dll";
public const byte PFD_TYPE_RGBA = 0;
public const byte PFD_MAIN_PLANE = 0;
public const uint PFD_DRAW_TO_WINDOW = 0x00000004;
public const uint PFD_SUPPORT_OPENGL = 0x00000020;
[DllImport(gdi32)]
public static extern bool SetPixelFormat(IntPtr hdc, int iPixelFormat, [In] ref PIXELFORMATDESCRIPTOR ppfd);
[DllImport(gdi32)]
public static extern int ChoosePixelFormat(IntPtr hdc, [In] ref PIXELFORMATDESCRIPTOR ppfd);
}
[StructLayout(LayoutKind.Sequential)]
internal struct PIXELFORMATDESCRIPTOR
{
public ushort nSize;
public ushort nVersion;
public uint dwFlags;
public byte iPixelType;
public byte cColorBits;
public byte cRedBits;
public byte cRedShift;
public byte cGreenBits;
public byte cGreenShift;
public byte cBlueBits;
public byte cBlueShift;
public byte cAlphaBits;
public byte cAlphaShift;
public byte cAccumBits;
public byte cAccumRedBits;
public byte cAccumGreenBits;
public byte cAccumBlueBits;
public byte cAccumAlphaBits;
public byte cDepthBits;
public byte cStencilBits;
public byte cAuxBuffers;
public byte iLayerType;
public byte bReserved;
public int dwLayerMask;
public int dwVisibleMask;
public int dwDamageMask;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment