├── .gitattributes ├── .vscode ├── extensions.json └── settings.json ├── user32 ├── mod.ts ├── dll.ts ├── CreateWindow.ts └── MessageBox.ts ├── kernel32 ├── mod.ts ├── dll.ts ├── GetLastError.ts └── FormatMessage.ts ├── img └── screen_messagebox.png ├── mod.ts ├── examples ├── GetLastError.ts ├── CreateWindow.ts ├── MessageBox.ts └── FormatMessage.ts ├── .github └── workflows │ └── ci.yml ├── README.md ├── LICENSE └── util.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["denoland.vscode-deno"] 3 | } 4 | -------------------------------------------------------------------------------- /user32/mod.ts: -------------------------------------------------------------------------------- 1 | export * from "./MessageBox.ts"; 2 | export * from "./CreateWindow.ts"; 3 | -------------------------------------------------------------------------------- /kernel32/mod.ts: -------------------------------------------------------------------------------- 1 | export * from "./GetLastError.ts"; 2 | export * from "./FormatMessage.ts"; 3 | -------------------------------------------------------------------------------- /img/screen_messagebox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justjavac/deno_win32/HEAD/img/screen_messagebox.png -------------------------------------------------------------------------------- /mod.ts: -------------------------------------------------------------------------------- 1 | export * from "./util.ts"; 2 | export * from "./user32/mod.ts"; 3 | export * from "./kernel32/mod.ts"; 4 | -------------------------------------------------------------------------------- /examples/GetLastError.ts: -------------------------------------------------------------------------------- 1 | import * as win32 from "../mod.ts"; 2 | 3 | const lastError = win32.GetLastError(); 4 | 5 | console.log("GetLastError: %d", lastError); 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.lint": true, 4 | "deno.unstable": true, 5 | "deno.suggest.imports.hosts": { 6 | "https://deno.land": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/CreateWindow.ts: -------------------------------------------------------------------------------- 1 | import * as win32 from "../mod.ts"; 2 | 3 | const windowID = win32.CreateWindow( 4 | 0, 5 | "hello xxx", 6 | "world xxx", 7 | 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000, 8 | 0, 9 | 0, 10 | 500, 11 | 500, 12 | null, 13 | null, 14 | null, 15 | null, 16 | ); 17 | 18 | console.log(windowID); 19 | -------------------------------------------------------------------------------- /kernel32/dll.ts: -------------------------------------------------------------------------------- 1 | const dll = Deno.dlopen("kernel32.dll", { 2 | GetLastError: { 3 | parameters: [], 4 | result: "i64", 5 | }, 6 | FormatMessageW: { 7 | parameters: ["i64", "pointer", "i64", "i64", "pointer", "i64", "pointer"], 8 | result: "i64", 9 | }, 10 | }); 11 | 12 | function close() { 13 | dll.close(); 14 | } 15 | 16 | export { close, dll }; 17 | -------------------------------------------------------------------------------- /examples/MessageBox.ts: -------------------------------------------------------------------------------- 1 | import * as win32 from "../mod.ts"; 2 | 3 | const msgboxID = win32.MessageBox( 4 | null, 5 | "Hello World\n你好,世界\nこんにちは世界\nBonjour le monde\nمرحبا بالعالم", 6 | "Deno FFI", 7 | win32.MB_YESNO | win32.MB_ICONWARNING, 8 | ); 9 | 10 | switch (msgboxID) { 11 | case win32.IDYES: 12 | console.log("yes"); 13 | break; 14 | case win32.IDNO: 15 | console.log("no"); 16 | break; 17 | default: 18 | console.error("unreachable"); 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: build 8 | runs-on: windows-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Setup Deno 13 | uses: denoland/setup-deno@v1 14 | 15 | - name: Format 16 | run: deno fmt --check 17 | 18 | - name: Check 19 | run: deno check --unstable --remote mod.ts 20 | 21 | - name: Lint 22 | run: deno lint 23 | 24 | - name: Tests 25 | run: echo "how to test???" 26 | -------------------------------------------------------------------------------- /kernel32/GetLastError.ts: -------------------------------------------------------------------------------- 1 | import { dll } from "./dll.ts"; 2 | 3 | /** 4 | * Retrieves the calling thread's last-error code value. The last-error code is 5 | * maintained on a per-thread basis. Multiple threads do not overwrite each 6 | * other's last-error code. 7 | * 8 | * @see https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror 9 | * 10 | * @returns The return value is the calling thread's last-error code. 11 | */ 12 | export function GetLastError(): bigint { 13 | return dll.symbols.GetLastError(); 14 | } 15 | -------------------------------------------------------------------------------- /user32/dll.ts: -------------------------------------------------------------------------------- 1 | const dll = Deno.dlopen( 2 | "user32.dll", 3 | { 4 | MessageBoxW: { 5 | parameters: ["pointer", "pointer", "pointer", "u64"], 6 | result: "i32", 7 | }, 8 | CreateWindowExW: { 9 | parameters: [ 10 | "u64", 11 | "pointer", 12 | "pointer", 13 | "u64", 14 | "i32", 15 | "i32", 16 | "i32", 17 | "i32", 18 | "pointer", 19 | "pointer", 20 | "pointer", 21 | "pointer", 22 | ], 23 | result: "pointer", 24 | }, 25 | } as const, 26 | ); 27 | 28 | function close() { 29 | dll.close(); 30 | } 31 | 32 | export { close, dll }; 33 | -------------------------------------------------------------------------------- /user32/CreateWindow.ts: -------------------------------------------------------------------------------- 1 | import { cstr2ptrW } from "../util.ts"; 2 | import { dll } from "./dll.ts"; 3 | 4 | export function CreateWindow( 5 | dwExStyle: number, 6 | lpClassName: string, 7 | lpWindowName: string, 8 | dwStyle: number, 9 | x: number, 10 | y: number, 11 | nWidth: number, 12 | nHeight: number, 13 | hWndParent: bigint | null, 14 | hMenu: bigint | null, 15 | hInstance: bigint | null, 16 | lpParam: bigint | null, 17 | ): bigint | null { 18 | return dll.symbols.CreateWindowExW( 19 | dwExStyle, 20 | cstr2ptrW(lpClassName), 21 | cstr2ptrW(lpWindowName), 22 | dwStyle, 23 | x, 24 | y, 25 | nWidth, 26 | nHeight, 27 | hWndParent, 28 | hMenu, 29 | hInstance, 30 | lpParam, 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deno_win32 2 | 3 | Wraps some of the most common **Win32** API calls using FFI to make them 4 | accessible to Deno. 5 | 6 | ## Usage 7 | 8 | Write your apps that use the Windows API directly from Deno, by wrapping common 9 | Win32 APIs using Deno FFI. 10 | 11 | flags: 12 | 13 | - `--allow-ffi`: Requires ffi access to "user32.dll", "kernel32", etc... 14 | - `--unstable`: FFI is unstable feature 15 | 16 | ## Examples 17 | 18 | ```bash 19 | deno run --allow-ffi --unstable https://deno.land/x/win32/examples/MessageBox.ts 20 | ``` 21 | 22 | You will see: 23 | 24 | ![](./img/screen_messagebox.png) 25 | 26 | ### License 27 | 28 | [deno_win32](https://github.com/denoffi/deno_win32) is released under the MIT 29 | License. See the bundled [LICENSE](./LICENSE) file for details. 30 | -------------------------------------------------------------------------------- /examples/FormatMessage.ts: -------------------------------------------------------------------------------- 1 | import * as win32 from "../mod.ts"; 2 | 3 | const windowID = win32.CreateWindow( 4 | 0, 5 | "hello xxx", 6 | "world xxx", 7 | 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000, 8 | 0, 9 | 0, 10 | 500, 11 | 500, 12 | new Deno.UnsafePointer(0n), 13 | new Deno.UnsafePointer(0n), 14 | new Deno.UnsafePointer(0n), 15 | new Deno.UnsafePointer(0n), 16 | ); 17 | 18 | console.log("CreateWindow: %d", windowID); 19 | 20 | const dwMessageId = win32.GetLastError(); 21 | 22 | console.log("GetLastError: %d", dwMessageId); 23 | 24 | const lpMsgBuf = new Uint8Array(100); 25 | 26 | win32.FormatMessage( 27 | 0x00000100 | 0x00001000 | 0x00000200, 28 | new Deno.UnsafePointer(0n), 29 | dwMessageId, 30 | 0, 31 | Deno.UnsafePointer.of(lpMsgBuf), 32 | 0, 33 | new Deno.UnsafePointer(0n), 34 | ); 35 | 36 | console.log(lpMsgBuf); 37 | console.log(new TextDecoder().decode(lpMsgBuf)); 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) justjavac. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Windows represents Unicode characters using UTF-16 encoding, in which each 3 | * character is encoded as a 16-bit value. 4 | * UTF-16 characters are called **wide** characters, to distinguish them from 5 | * 8-bit ANSI characters. 6 | * 7 | * Windows providing two parallel sets of APIs, one for ANSI strings and the 8 | * other for Unicode strings. For example, there are two functions to displays 9 | * a modal dialog box: 10 | * 11 | * - `MessageBoxA` - takes an ANSI string. 12 | * - `MessageBoxW` - takes a Unicode string. 13 | * 14 | * Javascript already uses UTF-16 internally - use `charCodeAt()` to get the values. 15 | */ 16 | export function cstr2ptrW(cstr: string) { 17 | const buffer = new ArrayBuffer((cstr.length + 1) * 2); 18 | const u16 = new Uint16Array(buffer); 19 | for (let i = 0; i <= cstr.length; i++) { 20 | u16[i] = cstr.charCodeAt(i); 21 | } 22 | return Deno.UnsafePointer.of(u16); 23 | } 24 | 25 | export function ptr2cstrW(cstr: string) { 26 | const buffer = new ArrayBuffer((cstr.length + 1) * 2); 27 | const u16 = new Uint16Array(buffer); 28 | for (let i = 0; i <= cstr.length; i++) { 29 | u16[i] = cstr.charCodeAt(i); 30 | } 31 | return Deno.UnsafePointer.of(u16); 32 | } 33 | -------------------------------------------------------------------------------- /kernel32/FormatMessage.ts: -------------------------------------------------------------------------------- 1 | import { dll } from "./dll.ts"; 2 | 3 | /** 4 | * Formats a message string. The function requires a message definition as input. 5 | * The message definition can come from a buffer passed into the function. 6 | * It can come from a message table resource in an already-loaded module. 7 | * Or the caller can ask the function to search the system's message table 8 | * resource(s) for the message definition. The function finds the message 9 | * definition in a message table resource based on a message identifier and a 10 | * language identifier. The function copies the formatted message text to an 11 | * output buffer, processing any embedded insert sequences if requested. 12 | * 13 | * @see https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage 14 | * 15 | * @returns If the function succeeds, the return value is the number of TCHARs 16 | * stored in the output buffer, excluding the terminating null character. 17 | */ 18 | export function FormatMessage( 19 | dwFlags: number, 20 | lpSource: bigint | null, 21 | dwMessageId: number, 22 | dwLanguageId: number, 23 | lpBuffer: bigint | null, 24 | nSize: number, 25 | Arguments: bigint | null, 26 | ): bigint { 27 | return dll.symbols.FormatMessageW( 28 | dwFlags, 29 | lpSource, 30 | dwMessageId, 31 | dwLanguageId, 32 | lpBuffer, 33 | nSize, 34 | Arguments, 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /user32/MessageBox.ts: -------------------------------------------------------------------------------- 1 | import { cstr2ptrW } from "../util.ts"; 2 | import { dll } from "./dll.ts"; 3 | 4 | /** 5 | * Displays a modal dialog box that contains a system icon, a set of buttons, 6 | * and a brief application-specific message, such as status or error 7 | * information. 8 | * The message box returns an integer value that indicates which button the user clicked. 9 | * 10 | * @see https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox 11 | * 12 | * @param hWnd A handle to the owner window of the message box to be created. 13 | * If this parameter is `NULL`, the message box has no owner window. 14 | * @param lpText The message to be displayed. If the string consists of more than one line, 15 | * you can separate the lines using a carriage return and/or linefeed character between each line. 16 | * @param lpCaption The dialog box title. If this parameter is NULL, the default title is Error. 17 | * @param uType The contents and behavior of the dialog box. 18 | * This parameter can be a combination of flags from the following groups of flags. 19 | * @returns If a message box has a **Cancel** button, the function returns the **IDCANCEL** 20 | * value if either the ESC key is pressed or the **Cancel** button is selected. 21 | * 22 | * If the message box has no **Cancel** button, pressing ESC will no effect - unless 23 | * an **MB_OK** button is present. 24 | * 25 | * If an **MB_OK** button is displayed and the user presses ESC, the return value will be **IDOK**. 26 | * 27 | * If the function fails, the return value is zero. To get extended error information, call [GetLastError](). 28 | */ 29 | export function MessageBox( 30 | hWnd: bigint | null, 31 | lpText: string, 32 | lpCaption: string, 33 | uType: number, 34 | ): number { 35 | return dll.symbols.MessageBoxW( 36 | hWnd, 37 | cstr2ptrW(lpText), 38 | cstr2ptrW(lpCaption), 39 | uType, 40 | ) as number; 41 | } 42 | 43 | /// ================== 44 | /// To indicate the buttons displayed in the message box, specify one of the following values. 45 | ///=================== 46 | 47 | /** The message box contains three push buttons: **Abort**, **Retry**, and **Ignore**. */ 48 | export const MB_ABORTRETRYIGNORE = 0x00000002; 49 | 50 | /** 51 | * The message box contains three push buttons: **Cancel**, **Try Again**, 52 | * **Continue**. Use this message box type instead of MB_ABORTRETRYIGNORE. 53 | */ 54 | export const MB_CANCELTRYCONTINUE = 0x00000006; 55 | 56 | /** 57 | * Adds a **Help** button to the message box. When the user clicks the Help 58 | * button or presses F1, the system sends a [WM_HELP][] message to the owner. 59 | * 60 | * [WM_HELP]: https://docs.microsoft.com/en-us/windows/desktop/shell/wm-help 61 | */ 62 | export const MB_HELP = 0x00004000; 63 | 64 | /** The message box contains one push button: **OK**. This is the default. */ 65 | export const MB_OK = 0x00000000; 66 | 67 | /** The message box contains two push buttons: **OK** and **Cancel**. */ 68 | export const MB_OKCANCEL = 0x00000001; 69 | 70 | /** The message box contains two push buttons: **Retry** and **Cancel**. */ 71 | export const MB_RETRYCANCEL = 0x00000005; 72 | 73 | /** The message box contains two push buttons: **Yes** and **No**. */ 74 | export const MB_YESNO = 0x00000004; 75 | 76 | /** The message box contains three push buttons: **Yes**, **No**, and **Cancel**. */ 77 | export const MB_YESNOCANCEL = 0x00000003; 78 | 79 | /// ================== 80 | /// To display an icon in the message box, specify one of the following values. 81 | ///=================== 82 | 83 | /** An exclamation-point icon appears in the message box. */ 84 | export const MB_ICONEXCLAMATION = 0x00000030; 85 | 86 | /** An exclamation-point icon appears in the message box. */ 87 | export const MB_ICONWARNING = 0x00000030; 88 | 89 | /** An icon consisting of a lowercase letter i in a circle appears in the message box. */ 90 | export const MB_ICONINFORMATION = 0x00000040; 91 | 92 | /** An icon consisting of a lowercase letter i in a circle appears in the message box. */ 93 | export const MB_ICONASTERISK = 0x00000040; 94 | 95 | /** 96 | * A question-mark icon appears in the message box. The question-mark 97 | * message icon is no longer recommended because it does not clearly 98 | * represent a specific type of message and because the phrasing of a 99 | * message as a question could apply to any message type. In addition, 100 | * users can confuse the message symbol question mark with Help information. 101 | * Therefore, do not use this question mark message symbol in your message boxes. 102 | * The system continues to support its inclusion only for backward compatibility. 103 | */ 104 | export const MB_ICONQUESTION = 0x00000020; 105 | 106 | /** A stop-sign icon appears in the message box. */ 107 | export const MB_ICONSTOP = 0x00000010; 108 | 109 | /** A stop-sign icon appears in the message box. */ 110 | export const MB_ICONERROR = 0x00000010; 111 | 112 | /** A stop-sign icon appears in the message box. */ 113 | export const MB_ICONHAND = 0x00000010; 114 | 115 | /// ================== 116 | /// To indicate the default button, specify one of the following values. 117 | ///=================== 118 | 119 | /** 120 | * The first button is the default button. 121 | * **MB_DEFBUTTON1** is the default unless **MB_DEFBUTTON2**, **MB_DEFBUTTON3**, 122 | * or **MB_DEFBUTTON4** is specified. 123 | */ 124 | export const MB_DEFBUTTON1 = 0x00000000; 125 | 126 | /** The second button is the default button. */ 127 | export const MB_DEFBUTTON2 = 0x00000100; 128 | 129 | /** The third button is the default button. */ 130 | export const MB_DEFBUTTON3 = 0x00000200; 131 | 132 | /** The fourth button is the default button. */ 133 | export const MB_DEFBUTTON4 = 0x00000300; 134 | 135 | /// ================== 136 | /// To indicate the modality of the dialog box, specify one of the following values. 137 | ///=================== 138 | 139 | /** 140 | * The user must respond to the message box before continuing work in the window 141 | * identified by the hWnd parameter. However, the user can move to the windows of 142 | * other threads and work in those windows. 143 | * 144 | * Depending on the hierarchy of windows in the application, the user may be able 145 | * to move to other windows within the thread. All child windows of the parent of 146 | * the message box are automatically disabled, but pop-up windows are not. 147 | * 148 | * `MB_APPLMODAL` is the default if neither `MB_SYSTEMMODAL` nor `MB_TASKMODAL` is specified. 149 | */ 150 | export const MB_APPLMODAL = 0x00000000; 151 | 152 | /** 153 | * Same as **MB_APPLMODAL** except that the message box has the **WS_EX_TOPMOST** style. 154 | * Use system-modal message boxes to notify the user of serious, potentially damaging 155 | * errors that require immediate attention (for example, running out of memory). 156 | * This flag has no effect on the user's ability to interact with windows other than 157 | * those associated with `hWnd`. 158 | */ 159 | export const MB_SYSTEMMODAL = 0x00001000; 160 | 161 | /** 162 | * Same as `MB_APPLMODAL` except that all the top-level windows belonging to the 163 | * current thread are disabled if the hWnd parameter is `NULL`. 164 | * Use this flag when the calling application or library does not have a window 165 | * handle available but still needs to prevent input to other windows in the 166 | * calling thread without suspending other threads. 167 | */ 168 | export const MB_TASKMODAL = 0x00002000; 169 | 170 | /// ================== 171 | /// To specify other options, use one or more of the following values. 172 | ///=================== 173 | 174 | /** 175 | * Same as desktop of the interactive window station. For more information, 176 | * see [Window Stations][1]. 177 | * 178 | * [1]: https://docs.microsoft.com/en-us/windows/desktop/winstation/window-stations 179 | * 180 | * If the current input desktop is not the default desktop, **MessageBox** does 181 | * not return until the user switches to the default desktop. 182 | */ 183 | export const MB_DEFAULT_DESKTOP_ONLY = 0x00020000; 184 | 185 | /** The text is right-justified. */ 186 | export const MB_RIGHT = 0x00080000; 187 | 188 | /** 189 | * Displays message and caption text using right-to-left reading order on 190 | * Hebrew and Arabic systems. 191 | */ 192 | export const MB_RTLREADING = 0x00100000; 193 | 194 | /** 195 | * The message box becomes the foreground window. Internally, the system 196 | * calls the [SetForegroundWindow][1] function for the message box. 197 | * 198 | * [1]: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow 199 | */ 200 | export const MB_SETFOREGROUND = 0x00010000; 201 | 202 | /** The message box is created with the `WS_EX_TOPMOST` window style. */ 203 | export const MB_TOPMOST = 0x00040000; 204 | 205 | /** 206 | * The caller is a service notifying the user of an event. The function 207 | * displays a message box on the current active desktop, even if there is no 208 | * user logged on to the computer. 209 | * 210 | * **Terminal Services**: If the calling thread has an impersonation token, 211 | * the function directs the message box to the session specified in the 212 | * impersonation token. 213 | * 214 | * If this flag is set, the `hWnd` parameter must be `NULL`. This is so that 215 | * the message box can appear on a desktop other than the desktop corresponding 216 | * to the `hWnd`. 217 | * 218 | * For information on security considerations in regard to using this flag, see 219 | * [Interactive Services][1]. In particular, be aware that this flag can produce 220 | * interactive content on a locked desktop and should therefore be used for only 221 | * a very limited set of scenarios, such as resource exhaustion. 222 | * 223 | * [1]: https://docs.microsoft.com/en-us/windows/desktop/Services/interactive-services 224 | */ 225 | export const MB_SERVICE_NOTIFICATION = 0x00200000; 226 | 227 | /// ================== 228 | /// Return value 229 | ///=================== 230 | 231 | /** The **OK** button was selected. */ 232 | export const IDOK = 1; 233 | 234 | /** The **Cancel** button was selected. */ 235 | export const IDCANCEL = 2; 236 | 237 | /** The **Abort** button was selected. */ 238 | export const IDABORT = 3; 239 | 240 | /** The **Retry** button was selected. */ 241 | export const IDRETRY = 4; 242 | 243 | /** The **Ignore** button was selected. */ 244 | export const IDIGNORE = 5; 245 | 246 | /** The **Yes** button was selected. */ 247 | export const IDYES = 6; 248 | 249 | /** The **No** button was selected. */ 250 | export const IDNO = 7; 251 | 252 | /** The **Try Again** button was selected. */ 253 | export const IDTRYAGAIN = 10; 254 | 255 | /** The **Continue** button was selected. */ 256 | export const IDCONTINUE = 11; 257 | --------------------------------------------------------------------------------