comparison src/gui.c @ 81:c06dcab17923 v2.1

*: change license to BSD, update README for Unicode src/gui: use tchar.h for unicode instead of our own macros
author Paper <paper@paper.us.eu.org>
date Fri, 22 Mar 2024 22:04:16 -0400
parents 8f90d5addda9
children
comparison
equal deleted inserted replaced
80:719570851563 81:c06dcab17923
1 /** 1 /* mingw hack */
2 * msvpvf GUI for Windows
3 * Copyright (c) Paper 2022-2024
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 **/
23
24 /* change these macros to configure the window size */
25 #define WINDOW_WIDTH 225
26 #define WINDOW_HEIGHT 200
27
28 /* mingw */
29 #ifdef UNICODE 2 #ifdef UNICODE
30 #define NTDDI_VERSION 0x06000000 3 #define NTDDI_VERSION 0x06000000
31 #define _WIN32_WINNT 0x0600 4 #define _WIN32_WINNT 0x0600
32 #else 5 #else
33 #define _WIN32_WINNT 0x0400 6 #define _WIN32_WINNT 0x0400
34 #endif 7 #endif
35 8
36 #include <windef.h> 9 #include <windef.h>
37 #include <winbase.h> 10 #include <winbase.h>
38 #include <shlwapi.h> 11 #include <shlwapi.h>
39 #include <shobjidl.h>
40 12
41 #include <stdint.h> 13 #include <stdint.h>
42 #include <stdio.h> 14 #include <stdio.h>
43 15
16 #include <tchar.h> /* tchar versions of string.h functions */
17
44 #include "common.h" 18 #include "common.h"
45 19
46 /* we use COM when `UNICODE=1` to avoid file paths being cut off */ 20 /* make sure this is defined... */
47 #define COM_INITFLAGS (COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) 21 #ifndef _MAX_ULTOSTR_BASE10_COUNT
48 22 #define _MAX_ULTOSTR_BASE10_COUNT (10 + 1)
49 #define OPEN_FILE_BUTTON 0 23 #endif
50 #define COMBOBOX 1 24
51 #define LISTBOX 2 25 /* put all of our types in an array */
52 #define SAVE_FILE_BUTTON 3 26 static const enum types types[] = { TYPES_VF, TYPES_VEG };
53 #define VERSION 4 27
54 28 /* HWND ids */
55 /* adjust for these functions for Unicode */ 29 enum {
56 #if UNICODE 30 OPEN_FILE_BUTTON = 0,
57 #define _tstrncpy wcsncpy 31 COMBOBOX,
58 #define _tstrdup _wcsdup 32 LISTBOX,
59 #define _tfopen _wfopen 33 SAVE_FILE_BUTTON,
60 #define _sntprintf _snwprintf 34 VERSION
61 #else 35 };
62 #define _tstrncpy strncpy 36
63 #define _tstrdup _strdup 37 #if UNICODE
64 #define _tfopen fopen 38 /* use COM when `UNICODE=1` to avoid file paths being cut off */
65 #define _sntprintf _snprintf 39 #include <shobjidl.h>
66 #endif 40
67 41 static const DWORD COM_INITFLAGS = (COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
68 /* enumerate over this */ 42 #endif
69 static const enum types types[] = {TYPES_VF, TYPES_VEG}; 43
44 /* user-adjustable. set these values to whatever you want, the GUI will scale */
45 #define WINDOW_WIDTH 225U
46 #define WINDOW_HEIGHT 200U
70 47
71 static LPTSTR file_path = NULL; 48 static LPTSTR file_path = NULL;
72 static uint8_t version = 13; 49
50 /* these values are loaded by AddControls() if they're valid */
51 static uint8_t version = 11;
73 static enum types type = TYPES_VEG; 52 static enum types type = TYPES_VEG;
74 53
75 /* we edit this from display_file() */ 54 /* we edit this from display_file() */
76 static HWND hwnd_version = NULL; 55 static HWND hwnd_version = NULL;
77 56
241 free(output_template); 220 free(output_template);
242 } else { 221 } else {
243 #endif 222 #endif
244 /* fallback to OPENFILENAME if COM fucks up for whatever reason (or we're on ANSI)... */ 223 /* fallback to OPENFILENAME if COM fucks up for whatever reason (or we're on ANSI)... */
245 output = calloc(MAX_PATH + 1, sizeof(TCHAR)); 224 output = calloc(MAX_PATH + 1, sizeof(TCHAR));
246 _tstrncpy(output, output_template, MAX_PATH); 225 _tcsncpy(output, output_template, MAX_PATH);
247 free(output_template); 226 free(output_template);
248 227
249 OPENFILENAME ofn = {0}; 228 OPENFILENAME ofn = {0};
250 229
251 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; 230 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
296 HWND combobox = CreateWindow(TEXT("ComboBox"), NULL, 275 HWND combobox = CreateWindow(TEXT("ComboBox"), NULL,
297 CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_VSCROLL, 276 CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_VSCROLL,
298 WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT * 3 / 20, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT, 277 WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT * 3 / 20, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT,
299 hWnd, (HMENU)COMBOBOX, NULL, NULL); 278 hWnd, (HMENU)COMBOBOX, NULL, NULL);
300 279
301 static LPCTSTR versions[] = {TEXT("8"), TEXT("9"), TEXT("10"), 280 for (size_t v = 8; v <= 21; v++) {
302 TEXT("11"), TEXT("12"), TEXT("13"), 281 TCHAR v_str[_MAX_ULTOSTR_BASE10_COUNT] = {'\0'};
303 TEXT("14"), TEXT("15"), TEXT("16"), 282
304 TEXT("17"), TEXT("18"), TEXT("19"), 283 _ultot(v, v_str, 10);
305 TEXT("20"), TEXT("21")}; /* wuss 9+10 */ 284
306 285 LRESULT pos = SendMessage(combobox, CB_ADDSTRING, 0, (LPARAM)v_str);
307 for (size_t i = 0; i < ARRAYSIZE(versions); i++) 286 SendMessage(combobox, CB_SETITEMDATA, pos, v);
308 SendMessage(combobox, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)versions[i]); 287 if (v == version)
309 288 SendMessage(combobox, CB_SETCURSEL, pos, 0);
310 SendMessage(combobox, CB_SETCURSEL, (WPARAM)3, (LPARAM)0); 289 }
311 290
312 /* Type */ 291 /* Type */
313 HWND listbox = CreateWindow(TEXT("Listbox"), NULL, WS_VISIBLE | WS_CHILD | LBS_STANDARD | LBS_NOTIFY, WINDOW_WIDTH * 5 / 18, WINDOW_HEIGHT * 11 / 40, WINDOW_WIDTH * 4 / 9, WINDOW_HEIGHT / 5, hWnd, (HMENU)LISTBOX, NULL, NULL); 292 HWND listbox = CreateWindow(TEXT("Listbox"), NULL, WS_VISIBLE | WS_CHILD | LBS_STANDARD | LBS_NOTIFY, WINDOW_WIDTH * 5 / 18, WINDOW_HEIGHT * 11 / 40, WINDOW_WIDTH * 4 / 9, WINDOW_HEIGHT / 5, hWnd, (HMENU)LISTBOX, NULL, NULL);
314 293
315 for (size_t i = 0; i < ARRAYSIZE(types); i++) { 294 for (size_t i = 0; i < ARRAYSIZE(types); i++) {
316 LRESULT pos = SendMessage(listbox, LB_ADDSTRING, i, (LPARAM)type_to_string(types[i])); 295 LRESULT pos = SendMessage(listbox, LB_ADDSTRING, i, (LPARAM)type_to_string(types[i]));
317 SendMessage(listbox, LB_SETITEMDATA, pos, (LPARAM)types[i]); 296 SendMessage(listbox, LB_SETITEMDATA, pos, types[i]);
318 if (types[i] == type) 297 if (types[i] == type)
319 SendMessage(listbox, LB_SETCURSEL, (WPARAM)pos, (LPARAM)0); 298 SendMessage(listbox, LB_SETCURSEL, pos, 0);
320 } 299 }
321 300
322 /* Save File */ 301 /* Save File */
323 HWND save_button = CreateWindow(TEXT("Button"), TEXT("Save"), WS_VISIBLE | WS_CHILD, WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT * 9 / 20, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT / 10, hWnd, (HMENU)SAVE_FILE_BUTTON, NULL, NULL); 302 HWND save_button = CreateWindow(TEXT("Button"), TEXT("Save"), WS_VISIBLE | WS_CHILD, WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT * 9 / 20, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT / 10, hWnd, (HMENU)SAVE_FILE_BUTTON, NULL, NULL);
324 303
325 /* Version and Type display */ 304 /* Version and Type display */
326 hwnd_version = CreateWindow(TEXT("Edit"), TEXT(""), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY | ES_CENTER | ES_MULTILINE | SS_CENTER, WINDOW_WIDTH / 6, WINDOW_HEIGHT * 3 / 5, WINDOW_WIDTH * 2 / 3, WINDOW_HEIGHT / 5, hWnd, (HMENU)VERSION, NULL, NULL); 305 hwnd_version = CreateWindow(TEXT("Edit"), TEXT("No file opened!"), WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY | ES_CENTER | ES_MULTILINE | SS_CENTER, WINDOW_WIDTH / 6, WINDOW_HEIGHT * 3 / 5, WINDOW_WIDTH * 2 / 3, WINDOW_HEIGHT / 5, hWnd, (HMENU)VERSION, NULL, NULL);
327 if (!open_button || !save_button || !listbox || !combobox || !hwnd_version) 306 if (!open_button || !save_button || !listbox || !combobox || !hwnd_version)
328 MessageBox(hWnd, TEXT("how did you even trigger this"), TEXT("GUI could not be initialized!"), MB_ICONEXCLAMATION); 307 MessageBox(hWnd, TEXT("how did you even trigger this"), TEXT("GUI could not be initialized!"), MB_ICONEXCLAMATION);
329 } 308 }
330 309
331 int CALLBACK SetFont(HWND child, LPARAM font) { 310 /* Make the fonts not as ugly */
311 BOOL CALLBACK SetFont(HWND child, LPARAM font) {
332 SendMessage(child, WM_SETFONT, font, 1); 312 SendMessage(child, WM_SETFONT, font, 1);
333 return 1; 313 return 1;
334 } 314 }
335 315
336 LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { 316 LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
337 switch(msg) { 317 switch(msg) {
338 case WM_COMMAND: 318 case WM_COMMAND:
339 if (HIWORD(wParam) == CBN_SELCHANGE) { 319 if (HIWORD(wParam) == CBN_SELCHANGE) {
340 switch (LOWORD(wParam)) { 320 switch (LOWORD(wParam)) {
341 case COMBOBOX: 321 case COMBOBOX: {
342 version = (uint8_t)(8+SendMessage((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0)); 322 LRESULT i = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
323 version = (uint8_t)SendMessage((HWND)lParam, CB_GETITEMDATA, i, 0);
343 break; 324 break;
325 }
344 case LISTBOX: { 326 case LISTBOX: {
345 LRESULT i = SendMessage((HWND)lParam, (UINT)LB_GETCURSEL, (WPARAM)0, (LPARAM)0); 327 LRESULT i = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
346 type = (enum types)SendMessage((HWND)lParam, (UINT)LB_GETITEMDATA, (WPARAM)i, (LPARAM)0); 328 type = (enum types)SendMessage((HWND)lParam, LB_GETITEMDATA, i, 0);
347 break; 329 break;
348 } 330 }
349 default: 331 default:
350 break; 332 break;
351 } 333 }
364 break; 346 break;
365 } 347 }
366 break; 348 break;
367 case WM_CREATE: 349 case WM_CREATE:
368 AddControls(hWnd); 350 AddControls(hWnd);
369 EnumChildWindows(hWnd, (WNDENUMPROC)SetFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT)); 351 EnumChildWindows(hWnd, SetFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
370 break; 352 break;
371 case WM_DESTROY: 353 case WM_DESTROY:
372 PostQuitMessage(0); 354 PostQuitMessage(0);
373 break; 355 break;
374 case WM_DROPFILES: { 356 case WM_DROPFILES: {