|
| 1 | +import System; |
| 2 | +import System.Reflection; |
| 3 | +import System.Reflection.Emit; |
| 4 | +import System.Runtime.InteropServices; |
| 5 | +import System.Text; |
| 6 | +import System.Threading; |
| 7 | + |
| 8 | +// Invoke a Win32 P/Invoke call. |
| 9 | +function InvokeWin32(dllName:String, returnType:Type, |
| 10 | + methodName:String, parameterTypes:Type[], parameters:Object[]) |
| 11 | +{ |
| 12 | + var domain = AppDomain.CurrentDomain; |
| 13 | + var name = new System.Reflection.AssemblyName('PInvokeAssembly'); |
| 14 | + var assembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); |
| 15 | + var module = assembly.DefineDynamicModule('PInvokeModule'); |
| 16 | + var type = module.DefineType('PInvokeType',TypeAttributes.Public + TypeAttributes.BeforeFieldInit); |
| 17 | + |
| 18 | + var method = type.DefineMethod(methodName, MethodAttributes.Public + MethodAttributes.HideBySig + |
| 19 | + MethodAttributes.Static + MethodAttributes.PinvokeImpl, returnType, parameterTypes); |
| 20 | + |
| 21 | + var ctor = System.Runtime.InteropServices.DllImportAttribute.GetConstructor([Type.GetType("System.String")]); |
| 22 | + var attr = new System.Reflection.Emit.CustomAttributeBuilder(ctor, [dllName]); |
| 23 | + method.SetCustomAttribute(attr); |
| 24 | + |
| 25 | + var realType = type.CreateType(); |
| 26 | + return realType.InvokeMember(methodName, BindingFlags.Public + BindingFlags.Static + |
| 27 | + BindingFlags.InvokeMethod, null, null, parameters); |
| 28 | +} |
| 29 | + |
| 30 | +const WS_OVERLAPPED = 0x00000000; |
| 31 | +const WS_CAPTION = 0x00C00000; |
| 32 | +const WS_SYSMENU = 0x00080000; |
| 33 | +const WS_THICKFRAME = 0x00040000; |
| 34 | +const WS_MINIMIZEBOX = 0x00020000; |
| 35 | +const WS_MAXIMIZEBOX = 0x00010000; |
| 36 | +const WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; |
| 37 | +const WS_VISIBLE = 0x10000000; |
| 38 | +const WS_CHILD = 0x40000000; |
| 39 | + |
| 40 | +const CW_USEDEFAULT = -2147483648; |
| 41 | +const SW_SHOW = 5; |
| 42 | + |
| 43 | +const WM_PAINT = 0x000F; |
| 44 | +const WM_CLOSE = 0x0010; |
| 45 | +const WM_DESTROY = 0x0002; |
| 46 | + |
| 47 | +const SRCCOPY = 0x00CC0020; |
| 48 | +const WHITE_BRUSH = 0; |
| 49 | +const BLACK_BRUSH = 4; |
| 50 | + |
| 51 | +function GetModuleHandle(lpModuleName:String):IntPtr { |
| 52 | + var parameterTypes:Type[] = [Type.GetType("System.String")]; |
| 53 | + var parameters:Object[] = [lpModuleName]; |
| 54 | + return InvokeWin32("kernel32.dll", Type.GetType("System.IntPtr"), "GetModuleHandleA", parameterTypes, parameters); |
| 55 | +} |
| 56 | + |
| 57 | +function CreateWindowEx(dwExStyle:int, lpClassName:String, lpWindowName:String, |
| 58 | + dwStyle:int, x:int, y:int, nWidth:int, nHeight:int, |
| 59 | + hWndParent:IntPtr, hMenu:IntPtr, hInstance:IntPtr, lpParam:IntPtr):IntPtr { |
| 60 | + var parameterTypes:Type[] = [ |
| 61 | + Type.GetType("System.Int32"), |
| 62 | + Type.GetType("System.String"), |
| 63 | + Type.GetType("System.String"), |
| 64 | + Type.GetType("System.Int32"), |
| 65 | + Type.GetType("System.Int32"), |
| 66 | + Type.GetType("System.Int32"), |
| 67 | + Type.GetType("System.Int32"), |
| 68 | + Type.GetType("System.Int32"), |
| 69 | + Type.GetType("System.IntPtr"), |
| 70 | + Type.GetType("System.IntPtr"), |
| 71 | + Type.GetType("System.IntPtr"), |
| 72 | + Type.GetType("System.IntPtr") |
| 73 | + ]; |
| 74 | + var parameters:Object[] = [ |
| 75 | + dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, |
| 76 | + hWndParent, hMenu, hInstance, lpParam |
| 77 | + ]; |
| 78 | + return InvokeWin32("user32.dll", Type.GetType("System.IntPtr"), "CreateWindowExA", parameterTypes, parameters); |
| 79 | +} |
| 80 | + |
| 81 | +function ShowWindow(hWnd:IntPtr, nCmdShow:int):Boolean { |
| 82 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr"), Type.GetType("System.Int32")]; |
| 83 | + var parameters:Object[] = [hWnd, nCmdShow]; |
| 84 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "ShowWindow", parameterTypes, parameters); |
| 85 | +} |
| 86 | + |
| 87 | +function UpdateWindow(hWnd:IntPtr):Boolean { |
| 88 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 89 | + var parameters:Object[] = [hWnd]; |
| 90 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "UpdateWindow", parameterTypes, parameters); |
| 91 | +} |
| 92 | + |
| 93 | +function IsWindow(hWnd:IntPtr):Boolean { |
| 94 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 95 | + var parameters:Object[] = [hWnd]; |
| 96 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "IsWindow", parameterTypes, parameters); |
| 97 | +} |
| 98 | + |
| 99 | +function DestroyWindow(hWnd:IntPtr):Boolean { |
| 100 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 101 | + var parameters:Object[] = [hWnd]; |
| 102 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "DestroyWindow", parameterTypes, parameters); |
| 103 | +} |
| 104 | + |
| 105 | +function PostQuitMessage(nExitCode:int):void { |
| 106 | + var parameterTypes:Type[] = [Type.GetType("System.Int32")]; |
| 107 | + var parameters:Object[] = [nExitCode]; |
| 108 | + InvokeWin32("user32.dll", Type.GetType("System.Void"), "PostQuitMessage", parameterTypes, parameters); |
| 109 | +} |
| 110 | + |
| 111 | +function InvalidateRect(hWnd:IntPtr, lpRect:IntPtr, bErase:Boolean):Boolean { |
| 112 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr"), Type.GetType("System.IntPtr"), Type.GetType("System.Boolean")]; |
| 113 | + var parameters:Object[] = [hWnd, lpRect, bErase]; |
| 114 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "InvalidateRect", parameterTypes, parameters); |
| 115 | +} |
| 116 | + |
| 117 | +function GetDC(hWnd:IntPtr):IntPtr { |
| 118 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 119 | + var parameters:Object[] = [hWnd]; |
| 120 | + return InvokeWin32("user32.dll", Type.GetType("System.IntPtr"), "GetDC", parameterTypes, parameters); |
| 121 | +} |
| 122 | + |
| 123 | +function ReleaseDC(hWnd:IntPtr, hDC:IntPtr):int { |
| 124 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr"), Type.GetType("System.IntPtr")]; |
| 125 | + var parameters:Object[] = [hWnd, hDC]; |
| 126 | + return InvokeWin32("user32.dll", Type.GetType("System.Int32"), "ReleaseDC", parameterTypes, parameters); |
| 127 | +} |
| 128 | + |
| 129 | +function GetClientRect(hWnd:IntPtr, lpRect:IntPtr):Boolean { |
| 130 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr"), Type.GetType("System.IntPtr")]; |
| 131 | + var parameters:Object[] = [hWnd, lpRect]; |
| 132 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "GetClientRect", parameterTypes, parameters); |
| 133 | +} |
| 134 | + |
| 135 | +function FillRect(hdc:IntPtr, lprc:IntPtr, hbr:IntPtr):int { |
| 136 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr"), Type.GetType("System.IntPtr"), Type.GetType("System.IntPtr")]; |
| 137 | + var parameters:Object[] = [hdc, lprc, hbr]; |
| 138 | + return InvokeWin32("user32.dll", Type.GetType("System.Int32"), "FillRect", parameterTypes, parameters); |
| 139 | +} |
| 140 | + |
| 141 | +function GetStockObject(fnObject:int):IntPtr { |
| 142 | + var parameterTypes:Type[] = [Type.GetType("System.Int32")]; |
| 143 | + var parameters:Object[] = [fnObject]; |
| 144 | + return InvokeWin32("gdi32.dll", Type.GetType("System.IntPtr"), "GetStockObject", parameterTypes, parameters); |
| 145 | +} |
| 146 | + |
| 147 | +function TextOut(hdc:IntPtr, x:int, y:int, lpString:String, c:int):Boolean { |
| 148 | + var parameterTypes:Type[] = [ |
| 149 | + Type.GetType("System.IntPtr"), |
| 150 | + Type.GetType("System.Int32"), |
| 151 | + Type.GetType("System.Int32"), |
| 152 | + Type.GetType("System.String"), |
| 153 | + Type.GetType("System.Int32") |
| 154 | + ]; |
| 155 | + var parameters:Object[] = [hdc, x, y, lpString, c]; |
| 156 | + return InvokeWin32("gdi32.dll", Type.GetType("System.Boolean"), "TextOutA", parameterTypes, parameters); |
| 157 | +} |
| 158 | + |
| 159 | +function lstrlen(lpString:String):int { |
| 160 | + var parameterTypes:Type[] = [Type.GetType("System.String")]; |
| 161 | + var parameters:Object[] = [lpString]; |
| 162 | + return InvokeWin32("kernel32.dll", Type.GetType("System.Int32"), "lstrlenA", parameterTypes, parameters); |
| 163 | +} |
| 164 | + |
| 165 | +function PeekMessage(lpMsg:IntPtr, hWnd:IntPtr, wMsgFilterMin:uint, wMsgFilterMax:uint, wRemoveMsg:uint):Boolean { |
| 166 | + var parameterTypes:Type[] = [ |
| 167 | + Type.GetType("System.IntPtr"), |
| 168 | + Type.GetType("System.IntPtr"), |
| 169 | + Type.GetType("System.UInt32"), |
| 170 | + Type.GetType("System.UInt32"), |
| 171 | + Type.GetType("System.UInt32") |
| 172 | + ]; |
| 173 | + var parameters:Object[] = [lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg]; |
| 174 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "PeekMessageA", parameterTypes, parameters); |
| 175 | +} |
| 176 | + |
| 177 | +function GetMessage(lpMsg:IntPtr, hWnd:IntPtr, wMsgFilterMin:uint, wMsgFilterMax:uint):int { |
| 178 | + var parameterTypes:Type[] = [ |
| 179 | + Type.GetType("System.IntPtr"), |
| 180 | + Type.GetType("System.IntPtr"), |
| 181 | + Type.GetType("System.UInt32"), |
| 182 | + Type.GetType("System.UInt32") |
| 183 | + ]; |
| 184 | + var parameters:Object[] = [lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax]; |
| 185 | + return InvokeWin32("user32.dll", Type.GetType("System.Int32"), "GetMessageA", parameterTypes, parameters); |
| 186 | +} |
| 187 | + |
| 188 | +function TranslateMessage(lpMsg:IntPtr):Boolean { |
| 189 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 190 | + var parameters:Object[] = [lpMsg]; |
| 191 | + return InvokeWin32("user32.dll", Type.GetType("System.Boolean"), "TranslateMessage", parameterTypes, parameters); |
| 192 | +} |
| 193 | + |
| 194 | +function DispatchMessage(lpMsg:IntPtr):IntPtr { |
| 195 | + var parameterTypes:Type[] = [Type.GetType("System.IntPtr")]; |
| 196 | + var parameters:Object[] = [lpMsg]; |
| 197 | + return InvokeWin32("user32.dll", Type.GetType("System.IntPtr"), "DispatchMessageA", parameterTypes, parameters); |
| 198 | +} |
| 199 | + |
| 200 | +function SendMessage(hWnd:IntPtr, Msg:uint, wParam:IntPtr, lParam:IntPtr):IntPtr { |
| 201 | + var parameterTypes:Type[] = [ |
| 202 | + Type.GetType("System.IntPtr"), |
| 203 | + Type.GetType("System.UInt32"), |
| 204 | + Type.GetType("System.IntPtr"), |
| 205 | + Type.GetType("System.IntPtr") |
| 206 | + ]; |
| 207 | + var parameters:Object[] = [hWnd, Msg, wParam, lParam]; |
| 208 | + return InvokeWin32("user32.dll", Type.GetType("System.IntPtr"), "SendMessageA", parameterTypes, parameters); |
| 209 | +} |
| 210 | + |
| 211 | +function GetMessageFromMSG(msgPtr:IntPtr):uint { |
| 212 | + return Marshal.ReadInt32(msgPtr, 4); |
| 213 | +} |
| 214 | + |
| 215 | +function AllocateRect():IntPtr { |
| 216 | + var buffer = Marshal.AllocHGlobal(16); // Size of the RECT structure |
| 217 | + // Initialize with 0 |
| 218 | + for (var i = 0; i < 16; i++) { |
| 219 | + Marshal.WriteByte(buffer, i, 0); |
| 220 | + } |
| 221 | + return buffer; |
| 222 | +} |
| 223 | + |
| 224 | +function AllocateMsgStruct():IntPtr { |
| 225 | + var buffer = Marshal.AllocHGlobal(28); // Size of the MSG structure |
| 226 | + // Initialize with 0 |
| 227 | + for (var i = 0; i < 28; i++) { |
| 228 | + Marshal.WriteByte(buffer, i, 0); |
| 229 | + } |
| 230 | + return buffer; |
| 231 | +} |
| 232 | + |
| 233 | +function Main() { |
| 234 | + try { |
| 235 | + var hInstance = GetModuleHandle(null); |
| 236 | + var WINDOW_TITLE = "Hello, World!"; |
| 237 | + |
| 238 | + var hWnd = CreateWindowEx( |
| 239 | + 0, |
| 240 | + "STATIC", |
| 241 | + WINDOW_TITLE, |
| 242 | + WS_OVERLAPPEDWINDOW | WS_VISIBLE, |
| 243 | + CW_USEDEFAULT, CW_USEDEFAULT, |
| 244 | + 640, |
| 245 | + 480, |
| 246 | + IntPtr.Zero, |
| 247 | + IntPtr.Zero, |
| 248 | + hInstance, |
| 249 | + IntPtr.Zero |
| 250 | + ); |
| 251 | + |
| 252 | + if (hWnd == IntPtr.Zero) { |
| 253 | + return; |
| 254 | + } |
| 255 | + |
| 256 | + ShowWindow(hWnd, SW_SHOW); |
| 257 | + UpdateWindow(hWnd); |
| 258 | + |
| 259 | + var hdc = GetDC(hWnd); |
| 260 | + |
| 261 | + if (hdc != IntPtr.Zero) { |
| 262 | + var rect = AllocateRect(); |
| 263 | + GetClientRect(hWnd, rect); |
| 264 | + |
| 265 | + var hBrush = GetStockObject(WHITE_BRUSH); |
| 266 | + FillRect(hdc, rect, hBrush); |
| 267 | + |
| 268 | + var text = "Hello, Win32 GUI(JScript.NET) World!"; |
| 269 | + TextOut(hdc, 0, 0, text, lstrlen(text)); |
| 270 | + |
| 271 | + ReleaseDC(hWnd, hdc); |
| 272 | + Marshal.FreeHGlobal(rect); |
| 273 | + } |
| 274 | + |
| 275 | + var msgPtr = AllocateMsgStruct(); |
| 276 | + |
| 277 | + while (GetMessage(msgPtr, IntPtr.Zero, 0, 0) > 0) { |
| 278 | + TranslateMessage(msgPtr); |
| 279 | + DispatchMessage(msgPtr); |
| 280 | + |
| 281 | + if (!IsWindow(hWnd)) { |
| 282 | + break; |
| 283 | + } |
| 284 | + } |
| 285 | + |
| 286 | + Marshal.FreeHGlobal(msgPtr); |
| 287 | + |
| 288 | + } catch (e) { |
| 289 | + Console.WriteLine(e.Message); |
| 290 | + Console.WriteLine(e.StackTrace); |
| 291 | + } |
| 292 | +} |
| 293 | + |
| 294 | +Main(); |
0 commit comments