Last active
February 15, 2017 04:01
-
-
Save mattleibow/755eba3c8ff5eafb9549842a0abb0426 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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