Mercurial > msvpvf
comparison src/gui.c @ 79:8f90d5addda9 v2.0
*: refactor... basically everything!
The Win32 GUI version is now unicode-friendly. HOWEVER, ANSI still very
much works. you can configure which version to use through `-DUNICODE=0/1`
in CFLAGS.
the CLI is also friendlier and uses a more sane interface as well.
note: the command line flags (which were optional before) are now required.
Unicode filenames will not work on Windows because Windows sucks.
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 20 Mar 2024 17:06:26 -0400 |
parents | 79a35af2cb56 |
children | c06dcab17923 |
comparison
equal
deleted
inserted
replaced
78:fae1d67d8cfd | 79:8f90d5addda9 |
---|---|
1 /** | 1 /** |
2 * msvpvf GUI for Windows | 2 * msvpvf GUI for Windows |
3 * Copyright (c) Paper 2022 | 3 * Copyright (c) Paper 2022-2024 |
4 * | |
5 * View this file with 4-tab spacing; if you don't it will be a formatting nightmare. | |
6 * | 4 * |
7 * Permission is hereby granted, free of charge, to any person obtaining a copy | 5 * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 * of this software and associated documentation files (the "Software"), to deal | 6 * of this software and associated documentation files (the "Software"), to deal |
9 * in the Software without restriction, including without limitation the rights | 7 * in the Software without restriction, including without limitation the rights |
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 * SOFTWARE. | 21 * SOFTWARE. |
24 **/ | 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 | |
30 #define NTDDI_VERSION 0x06000000 | |
31 #define _WIN32_WINNT 0x0600 | |
32 #else | |
33 #define _WIN32_WINNT 0x0400 | |
34 #endif | |
35 | |
36 #include <windef.h> | |
37 #include <winbase.h> | |
38 #include <shlwapi.h> | |
39 #include <shobjidl.h> | |
40 | |
41 #include <stdint.h> | |
25 #include <stdio.h> | 42 #include <stdio.h> |
26 #include <windows.h> | 43 |
27 #include <shellapi.h> | 44 #include "common.h" |
28 #include <shlwapi.h> | 45 |
29 #include <stdint.h> | 46 /* we use COM when `UNICODE=1` to avoid file paths being cut off */ |
30 #include <stdbool.h> | 47 #define COM_INITFLAGS (COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) |
31 #include <commdlg.h> | 48 |
32 #include "../include/common.h" | |
33 #define _WIN32_WINNT 0x0400 | |
34 #define ARRAYSIZE(a) \ | |
35 sizeof(a)/sizeof(a[0]) | |
36 #define OPEN_FILE_BUTTON 0 | 49 #define OPEN_FILE_BUTTON 0 |
37 #define COMBOBOX 1 | 50 #define COMBOBOX 1 |
38 #define LISTBOX 2 | 51 #define LISTBOX 2 |
39 #define SAVE_FILE_BUTTON 3 | 52 #define SAVE_FILE_BUTTON 3 |
40 #define VERSION 4 | 53 #define VERSION 4 |
41 #ifdef _MSC_VER | 54 |
42 #define strdup(p) _strdup(p) | 55 /* adjust for these functions for Unicode */ |
43 #endif | 56 #if UNICODE |
44 | 57 #define _tstrncpy wcsncpy |
45 HWND hWndListBox, hWndComboBox, hWndVersion; | 58 #define _tstrdup _wcsdup |
46 int16_t version = 13; | 59 #define _tfopen _wfopen |
47 enum types { | 60 #define _sntprintf _snwprintf |
48 vf, | 61 #else |
49 veg | 62 #define _tstrncpy strncpy |
50 } type; | 63 #define _tstrdup _strdup |
51 char file_name[257] = {'\0'}; | 64 #define _tfopen fopen |
52 | 65 #define _sntprintf _snprintf |
53 void display_file(char* path) { | 66 #endif |
67 | |
68 /* enumerate over this */ | |
69 static const enum types types[] = {TYPES_VF, TYPES_VEG}; | |
70 | |
71 static LPTSTR file_path = NULL; | |
72 static uint8_t version = 13; | |
73 static enum types type = TYPES_VEG; | |
74 | |
75 /* we edit this from display_file() */ | |
76 static HWND hwnd_version = NULL; | |
77 | |
78 static inline LPCTSTR type_to_prefix(enum types type) { | |
79 switch (type) { | |
80 case TYPES_VF: return TEXT("MS"); | |
81 case TYPES_VEG: return TEXT("PRO"); | |
82 case TYPES_UNKNOWN: | |
83 default: return TEXT("UNK"); | |
84 } | |
85 } | |
86 | |
87 static inline LPCTSTR type_to_string(enum types type) { | |
88 switch (type) { | |
89 case TYPES_VF: return TEXT("Movie Studio"); | |
90 case TYPES_VEG: return TEXT("Vegas Pro"); | |
91 case TYPES_UNKNOWN: | |
92 default: return TEXT("Unknown"); | |
93 } | |
94 } | |
95 | |
96 static inline LPCTSTR type_to_extension(enum types type) { | |
97 switch (type) { | |
98 case TYPES_VF: return TEXT("vf"); | |
99 case TYPES_VEG: | |
100 case TYPES_UNKNOWN: | |
101 default: return TEXT("veg"); | |
102 } | |
103 } | |
104 | |
105 /* these functions are designed to *not* use global variables, | |
106 * to make everything a bit more simple... */ | |
107 static int display_file(LPCTSTR path) { | |
54 /* Read the file to memory */ | 108 /* Read the file to memory */ |
55 FILE* file; | 109 FILE* file = _tfopen(path, TEXT("rb")); |
56 file = fopen(path, "rb"); | 110 |
57 fseek(file, 0x46, SEEK_SET); | 111 uint8_t file_version = 0; |
58 int f_version = fgetc(file)+1; | 112 enum types file_type = TYPES_UNKNOWN; |
59 fseek(file, 0x18, SEEK_SET); | 113 |
60 TCHAR p[32]; | 114 get_file_information(file, &file_version, &file_type); |
61 switch (fgetc(file)) { | 115 |
62 case 0xEF: | 116 int needed = _sntprintf(NULL, 0, TEXT("File version: %s %u"), type_to_string(file_type), file_version); |
63 snprintf(p, 32, "File version: %s %d", "VEGAS Pro", f_version); | 117 LPTSTR text = calloc(needed + 1, sizeof(TCHAR)); |
64 break; | 118 if (!text) /* out of memory... lol */ |
65 case 0xF6: | 119 exit(1); |
66 snprintf(p, 32, "File version: %s %d", "Movie Studio", f_version); | 120 _sntprintf(text, needed + 1, TEXT("File version: %s %u"), type_to_string(file_type), file_version); |
67 break; | 121 |
68 default: | 122 if (!SendMessage(hwnd_version, WM_SETTEXT, (WPARAM)0, (LPARAM)text)) { |
69 snprintf(p, 32, "File version: %s %d", "Unknown", f_version); | 123 free(text); |
70 break; | 124 return -1; |
71 } | 125 } |
72 SendMessage(hWndVersion, WM_SETTEXT, (WPARAM)0, (LPARAM)p); | 126 |
127 free(text); | |
73 fclose(file); | 128 fclose(file); |
74 } | 129 |
75 | 130 return 0; |
76 char* open_file(HWND hWnd) { | 131 } |
77 OPENFILENAME ofn; | 132 |
78 char* filename = calloc(256, sizeof(char)); | 133 static int open_file(HWND hWnd, LPTSTR* filepath) { |
79 | 134 #if UNICODE |
80 ZeroMemory(&ofn, OPENFILENAME_SIZE_VERSION_400); | 135 if (CoInitializeEx(NULL, COM_INITFLAGS) != S_OK) |
81 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; | 136 return -1; /* what */ |
82 ofn.hwndOwner = hWnd; | 137 |
83 ofn.lpstrFile = filename; | 138 COMDLG_FILTERSPEC filters[] = {{L"Project files", L"*.veg;*.vf"}, {L"All files", L"*.*"}}; |
84 ofn.lpstrFile[0] = '\0'; | 139 |
85 ofn.nMaxFile = 256; | 140 IFileDialog* pfd = NULL; |
86 ofn.lpstrFilter = "Project files\0*.veg;*.vf\0All files\0*.*\0"; | 141 IShellItem* result = NULL; |
87 ofn.nFilterIndex = 1; | 142 |
88 | 143 if (SUCCEEDED(CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, &IID_IFileOpenDialog, (LPVOID*)&pfd))) { |
89 if (GetOpenFileName(&ofn) == 0) { | 144 pfd->lpVtbl->SetFileTypes(pfd, ARRAYSIZE(filters), filters); |
90 return " "; | 145 pfd->lpVtbl->SetFileTypeIndex(pfd, 1); |
91 } | 146 pfd->lpVtbl->Show(pfd, hWnd); |
92 | 147 |
93 display_file(filename); | 148 if (!SUCCEEDED(pfd->lpVtbl->GetResult(pfd, &result)) || !result) { |
94 | 149 pfd->lpVtbl->Release(pfd); |
95 return filename; | 150 return -1; |
96 } | 151 } |
97 | 152 |
98 void save_file(HWND hWnd, char* input_file) { | 153 if (!SUCCEEDED(result->lpVtbl->GetDisplayName(result, SIGDN_FILESYSPATH, filepath))) { |
99 if (strcmp(input_file, " ") == 0) { | 154 pfd->lpVtbl->Release(pfd); |
155 result->lpVtbl->Release(result); | |
156 *filepath = NULL; /* might memleak? */ | |
157 return -1; | |
158 } | |
159 | |
160 result->lpVtbl->Release(result); | |
161 pfd->lpVtbl->Release(pfd); | |
162 } else { | |
163 #endif | |
164 /* initialize our buffer */ | |
165 *filepath = calloc(MAX_PATH + 1, sizeof(TCHAR)); | |
166 | |
167 OPENFILENAME ofn = {0}; | |
168 | |
169 /* NT 4.0 compat */ | |
170 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; | |
171 ofn.hwndOwner = hWnd; | |
172 ofn.lpstrFile = *filepath; | |
173 ofn.nMaxFile = MAX_PATH; | |
174 ofn.lpstrFilter = TEXT("Project files\0*.veg;*.vf\0All files\0*.*\0"); | |
175 | |
176 if (!GetOpenFileName(&ofn)) | |
177 return -1; | |
178 #if UNICODE | |
179 } | |
180 | |
181 CoUninitialize(); | |
182 #endif | |
183 | |
184 return display_file(*filepath);; | |
185 } | |
186 | |
187 static int save_file(HWND hWnd, LPCTSTR input, uint8_t version, enum types type) { | |
188 if (!input) { | |
100 MessageBox(hWnd, | 189 MessageBox(hWnd, |
101 TEXT("Please open a file first!"), | 190 TEXT("Please open a file first!"), |
102 TEXT("Invalid input file!"), | 191 TEXT("Invalid input file!"), |
103 MB_ICONEXCLAMATION); | 192 MB_ICONEXCLAMATION); |
104 return; | 193 return -1; |
105 } | 194 } |
106 OPENFILENAME ofn; | 195 |
107 char output_file[256] = {'\0'}, *input_basename = strdup(input_file); | 196 LPTSTR output_template = NULL; |
108 PathStripPath(input_basename); | 197 LPTSTR output = NULL; |
109 int amt_of_ch = snprintf(output_file, 256, "PRO_V%d_", version); | 198 |
110 if (256-amt_of_ch > 0) | 199 { |
111 strncat(output_file, input_basename, 256-amt_of_ch); | 200 LPTSTR input_basename = PathFindFileName(input); |
112 | 201 int input_basename_len = PathFindExtension(input_basename) - input_basename; |
113 ZeroMemory(&ofn, OPENFILENAME_SIZE_VERSION_400); | 202 |
114 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; | 203 int needed = _sntprintf(NULL, 0, TEXT("%s_V%u_%.*s.%s"), type_to_prefix(type), version, input_basename_len, input_basename, type_to_extension(type)); |
115 ofn.hwndOwner = hWnd; | 204 output_template = calloc(needed + 1, sizeof(TCHAR)); |
116 ofn.lpstrFile = output_file; | 205 _sntprintf(output_template, needed + 1, TEXT("%s_V%u_%.*s.%s"), type_to_prefix(type), version, input_basename_len, input_basename, type_to_extension(type)); |
117 ofn.nMaxFile = 256; | 206 |
118 ofn.lpstrFilter = "Movie Studio project files\0*.vf\0VEGAS Pro project files\0*.veg\0All files\0*.*\0"; | 207 free(input_basename); |
119 ofn.nFilterIndex = (int)type+1; | 208 } |
120 | 209 |
121 if (GetSaveFileName(&ofn) == 0) { | 210 { |
122 return; | 211 /* File dialog */ |
123 } | 212 #if UNICODE |
124 | 213 int com_initialized = SUCCEEDED(CoInitializeEx(NULL, COM_INITFLAGS)); |
125 if (CopyFile((TCHAR*)input_file, (TCHAR*)output_file, 0) == 0) { | 214 |
126 MessageBox(hWnd, TEXT("Failed to copy original project file! Does the destination file already exist?"), TEXT("Saving project failed!"), MB_ICONEXCLAMATION); | 215 COMDLG_FILTERSPEC filters[] = {{L"Movie Studio project files", L"*.vf"}, {L"Vegas Pro project files", L"*.veg"}, {L"All files", L"*.*"}}; |
127 return; | 216 |
128 } | 217 IFileDialog* pfd = NULL; |
129 FILE* output = fopen(output_file, "r+b"); | 218 IShellItem* result = NULL; |
130 if (output == NULL) { | 219 if (com_initialized && SUCCEEDED(CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, &IID_IFileSaveDialog, (LPVOID*)&pfd))) { |
131 MessageBox(hWnd, TEXT("Failed to save project file!"), TEXT("Saving project failed!"), MB_ICONEXCLAMATION); | 220 pfd->lpVtbl->SetFileTypes(pfd, ARRAYSIZE(filters), filters); |
132 return; | 221 pfd->lpVtbl->SetFileTypeIndex(pfd, (type == TYPES_UNKNOWN) ? ARRAYSIZE(filters) : type - TYPES_UNKNOWN); |
133 } | 222 pfd->lpVtbl->SetFileName(pfd, output_template); |
134 | 223 pfd->lpVtbl->Show(pfd, hWnd); |
135 unsigned char magic_veg[] = {0xEF, 0x29, 0xC4, 0x46, 0x4A, 0x90, 0xD2, 0x11, 0x87, 0x22, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A}; | 224 |
136 unsigned char magic_vf[] = {0xF6, 0x1B, 0x3C, 0x53, 0x35, 0xD6, 0xF3, 0x43, 0x8A, 0x90, 0x64, 0xB8, 0x87, 0x23, 0x1F, 0x7F}; | 225 if (!SUCCEEDED(pfd->lpVtbl->GetResult(pfd, &result))) { |
137 | 226 pfd->lpVtbl->Release(pfd); |
138 set_data(type == veg ? magic_veg : magic_vf, version-1, output); | 227 free(output_template); |
139 | 228 return -1; |
140 fclose(output); | 229 } |
141 } | 230 |
142 | 231 if (!SUCCEEDED(result->lpVtbl->GetDisplayName(result, SIGDN_FILESYSPATH, &output))) { |
232 pfd->lpVtbl->Release(pfd); | |
233 result->lpVtbl->Release(result); | |
234 free(output_template); | |
235 output = NULL; /* might memleak ? */ | |
236 return -1; | |
237 } | |
238 | |
239 result->lpVtbl->Release(result); | |
240 pfd->lpVtbl->Release(pfd); | |
241 free(output_template); | |
242 } else { | |
243 #endif | |
244 /* fallback to OPENFILENAME if COM fucks up for whatever reason (or we're on ANSI)... */ | |
245 output = calloc(MAX_PATH + 1, sizeof(TCHAR)); | |
246 _tstrncpy(output, output_template, MAX_PATH); | |
247 free(output_template); | |
248 | |
249 OPENFILENAME ofn = {0}; | |
250 | |
251 ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; | |
252 ofn.hwndOwner = hWnd; | |
253 ofn.lpstrFile = output; | |
254 ofn.nMaxFile = MAX_PATH; | |
255 ofn.lpstrFilter = TEXT("Movie Studio project files\0*.vf\0Vegas Pro project files\0*.veg\0All files\0*.*\0"); | |
256 ofn.nFilterIndex = (type == TYPES_UNKNOWN) ? 3 : type - TYPES_UNKNOWN; | |
257 | |
258 if (!GetSaveFileName(&ofn)) | |
259 return -1; | |
260 #if UNICODE | |
261 } | |
262 | |
263 if (com_initialized) | |
264 CoUninitialize(); | |
265 #endif | |
266 } | |
267 | |
268 if (!CopyFile(input, output, 0)) { | |
269 MessageBox(hWnd, TEXT("Failed to copy original project file! Does the destination file already exist?"), TEXT("Saving project failed!"), MB_ICONEXCLAMATION | MB_OK); | |
270 free(output); | |
271 return -1; | |
272 } | |
273 | |
274 FILE* output_file = _tfopen(output, TEXT("ab")); | |
275 if (!output_file) { | |
276 MessageBox(hWnd, TEXT("Failed to save project file!"), TEXT("Saving project failed!"), MB_ICONEXCLAMATION | MB_OK); | |
277 free(output); | |
278 return -1; | |
279 } | |
280 | |
281 free(output); | |
282 | |
283 set_file_information(output_file, version, type); | |
284 | |
285 fclose(output_file); | |
286 | |
287 return 0; | |
288 } | |
289 | |
290 /* TODO: use a resource file instead... */ | |
143 void AddControls(HWND hWnd) { | 291 void AddControls(HWND hWnd) { |
292 /* Open File */ | |
293 HWND open_button = CreateWindow(TEXT("Button"), TEXT("Open"), WS_VISIBLE | WS_CHILD, WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT / 40, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT / 10, hWnd, (HMENU)OPEN_FILE_BUTTON, NULL, NULL); | |
294 | |
144 /* Versions */ | 295 /* Versions */ |
145 hWndComboBox = CreateWindow("ComboBox", NULL, | 296 HWND combobox = CreateWindow(TEXT("ComboBox"), NULL, |
146 CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_VSCROLL, | 297 CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | WS_VSCROLL, |
147 (int)((225 - 50)/2), 30, 50, 200, | 298 WINDOW_WIDTH * 7 / 18, WINDOW_HEIGHT * 3 / 20, WINDOW_WIDTH * 2 / 9, WINDOW_HEIGHT, |
148 hWnd, (HMENU)COMBOBOX, NULL, NULL); | 299 hWnd, (HMENU)COMBOBOX, NULL, NULL); |
149 | 300 |
150 TCHAR versions[][10] = {TEXT("8"), TEXT("9"), TEXT("10"), | 301 static LPCTSTR versions[] = {TEXT("8"), TEXT("9"), TEXT("10"), |
151 TEXT("11"), TEXT("12"), TEXT("13"), | 302 TEXT("11"), TEXT("12"), TEXT("13"), |
152 TEXT("14"), TEXT("15"), TEXT("16"), | 303 TEXT("14"), TEXT("15"), TEXT("16"), |
153 TEXT("17"), TEXT("18"), TEXT("19")}; | 304 TEXT("17"), TEXT("18"), TEXT("19"), |
154 | 305 TEXT("20"), TEXT("21")}; /* wuss 9+10 */ |
155 int i = 0; | 306 |
156 for (i = 0; i < ARRAYSIZE(versions); i++) { | 307 for (size_t i = 0; i < ARRAYSIZE(versions); i++) |
157 SendMessage(hWndComboBox, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)versions[i]); | 308 SendMessage(combobox, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)versions[i]); |
158 } | 309 |
159 SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)3, (LPARAM)0); | 310 SendMessage(combobox, CB_SETCURSEL, (WPARAM)3, (LPARAM)0); |
160 /* Open File */ | 311 |
161 HWND open_button = CreateWindow("Button", "Open", WS_VISIBLE | WS_CHILD, (int)((225 - 50)/2), 5, 50, 20, hWnd, (HMENU)OPEN_FILE_BUTTON, NULL, NULL); | |
162 /* Type */ | 312 /* Type */ |
163 TCHAR listbox_items[][13] = {TEXT("VEGAS Pro"), TEXT("Movie Studio")}; | 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); |
164 hWndListBox = CreateWindow("Listbox", NULL, WS_VISIBLE | WS_CHILD | LBS_STANDARD | LBS_NOTIFY, (int)((225 - 100)/2), 55, 100, 40, hWnd, (HMENU)LISTBOX, NULL, NULL); | 314 |
165 for (i = 0; i < ARRAYSIZE(listbox_items); i++) { | 315 for (size_t i = 0; i < ARRAYSIZE(types); i++) { |
166 int pos = (int)SendMessage(hWndListBox, LB_ADDSTRING, i, (LPARAM) listbox_items[i]); | 316 LRESULT pos = SendMessage(listbox, LB_ADDSTRING, i, (LPARAM)type_to_string(types[i])); |
167 SendMessage(hWndListBox, LB_SETITEMDATA, pos, (LPARAM) i); | 317 SendMessage(listbox, LB_SETITEMDATA, pos, (LPARAM)types[i]); |
168 } | 318 if (types[i] == type) |
169 SendMessage(hWndListBox, LB_SETCURSEL, (WPARAM)0, (LPARAM)0); | 319 SendMessage(listbox, LB_SETCURSEL, (WPARAM)pos, (LPARAM)0); |
320 } | |
321 | |
170 /* Save File */ | 322 /* Save File */ |
171 HWND save_button = CreateWindow("Button", "Save", WS_VISIBLE | WS_CHILD, (int)((225 - 50)/2), 90, 50, 20, hWnd, (HMENU)SAVE_FILE_BUTTON, NULL, NULL); | 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); |
324 | |
172 /* Version and Type display */ | 325 /* Version and Type display */ |
173 hWndVersion = CreateWindow("Edit", "", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY | ES_CENTER | ES_MULTILINE | SS_CENTER, (int)((225 - 150)/2), 120, 150, 40, hWnd, (HMENU)VERSION, NULL, NULL); | 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); |
174 if (open_button == NULL || save_button == NULL || hWndListBox == NULL || hWndComboBox == NULL) | 327 if (!open_button || !save_button || !listbox || !combobox || !hwnd_version) |
175 MessageBox(hWnd, TEXT("how did you even trigger this"), TEXT("GUI could not be initialized!"), MB_ICONEXCLAMATION); | 328 MessageBox(hWnd, TEXT("how did you even trigger this"), TEXT("GUI could not be initialized!"), MB_ICONEXCLAMATION); |
176 } | 329 } |
177 | 330 |
178 bool CALLBACK SetFont(HWND child, LPARAM font) { | 331 int CALLBACK SetFont(HWND child, LPARAM font) { |
179 SendMessage(child, WM_SETFONT, font, true); | 332 SendMessage(child, WM_SETFONT, font, 1); |
180 return true; | 333 return 1; |
181 } | 334 } |
182 | 335 |
183 LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { | 336 LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { |
184 switch(msg) { | 337 switch(msg) { |
185 case WM_COMMAND: | 338 case WM_COMMAND: |
186 if(HIWORD(wParam) == CBN_SELCHANGE) { | 339 if (HIWORD(wParam) == CBN_SELCHANGE) { |
187 if (LOWORD(wParam) == COMBOBOX) | 340 switch (LOWORD(wParam)) { |
188 version = (int16_t)(8+SendMessage((HWND) lParam, (UINT) CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0)); | 341 case COMBOBOX: |
189 if (LOWORD(wParam) == LISTBOX) | 342 version = (uint8_t)(8+SendMessage((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0)); |
190 type = SendMessage((HWND) lParam, (UINT) LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0); | 343 break; |
344 case LISTBOX: { | |
345 LRESULT i = SendMessage((HWND)lParam, (UINT)LB_GETCURSEL, (WPARAM)0, (LPARAM)0); | |
346 type = (enum types)SendMessage((HWND)lParam, (UINT)LB_GETITEMDATA, (WPARAM)i, (LPARAM)0); | |
347 break; | |
348 } | |
349 default: | |
350 break; | |
351 } | |
191 } | 352 } |
192 switch(wParam) { | 353 |
354 switch (wParam) { | |
193 case OPEN_FILE_BUTTON: | 355 case OPEN_FILE_BUTTON: |
194 strncpy(file_name, open_file(hWnd), 256); | 356 /* free(NULL) == no-op */ |
195 case COMBOBOX: | 357 free(file_path); |
196 case LISTBOX: | 358 open_file(hWnd, &file_path); |
197 case VERSION: | |
198 break; | 359 break; |
199 case SAVE_FILE_BUTTON: | 360 case SAVE_FILE_BUTTON: |
200 save_file(hWnd, file_name); | 361 save_file(hWnd, file_path, version, type); |
362 break; | |
363 default: | |
364 break; | |
201 } | 365 } |
202 break; | 366 break; |
203 case WM_CREATE: { | 367 case WM_CREATE: |
204 AddControls(hWnd); | 368 AddControls(hWnd); |
205 EnumChildWindows(hWnd, (WNDENUMPROC)SetFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT)); | 369 EnumChildWindows(hWnd, (WNDENUMPROC)SetFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT)); |
206 break; | 370 break; |
207 } | |
208 case WM_DESTROY: | 371 case WM_DESTROY: |
209 PostQuitMessage(0); | 372 PostQuitMessage(0); |
210 break; | 373 break; |
211 case WM_DROPFILES: { | 374 case WM_DROPFILES: { |
212 /* Drag and drop support */ | 375 /* Drag and drop support */ |
213 HDROP hDrop = (HDROP)wParam; | 376 free(file_path); |
214 DragQueryFile(hDrop, 0, file_name, 256); | 377 |
215 display_file(file_name); | 378 HDROP drop = (HDROP)wParam; |
379 | |
380 int needed = DragQueryFile(drop, 0, NULL, 0); | |
381 file_path = malloc((needed + 1) * sizeof(TCHAR)); | |
382 DragQueryFile(drop, 0, file_path, needed + 1); | |
383 file_path[needed] = L'\0'; | |
384 | |
385 display_file(file_path); | |
216 break; | 386 break; |
217 } | 387 } |
218 default: | 388 default: |
219 return DefWindowProc(hWnd, msg, wParam, lParam); | 389 return DefWindowProc(hWnd, msg, wParam, lParam); |
220 } | 390 } |
221 return false; | 391 return 0; |
222 } | 392 } |
223 | 393 |
224 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int ncmdshow) { | 394 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int ncmdshow) { |
225 WNDCLASS wc = {0}; | 395 WNDCLASS wc = {0}; |
226 | 396 |
227 wc.hbrBackground = (HBRUSH)COLOR_WINDOW; | 397 wc.hbrBackground = (HBRUSH)COLOR_WINDOW; |
228 wc.hCursor = LoadCursor(NULL, IDC_ARROW); | 398 wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
229 wc.hInstance = hInstance; | 399 wc.hInstance = hInstance; |
230 wc.lpszClassName = "msvpvf"; | 400 wc.lpszClassName = TEXT("msvpvf"); |
231 wc.lpfnWndProc = WindowProcedure; | 401 wc.lpfnWndProc = WindowProcedure; |
232 | 402 |
233 if (!RegisterClass(&wc)) return -1; | 403 if (!RegisterClass(&wc)) return -1; |
234 | 404 |
235 CreateWindowEx(WS_EX_ACCEPTFILES, TEXT("msvpvf"), TEXT("Movie Studio / Vegas Pro version spoofer"), WS_OVERLAPPED | WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU, 100, 100, 225, 200, NULL, NULL, hInstance, NULL); | 405 CreateWindowEx(WS_EX_ACCEPTFILES, TEXT("msvpvf"), TEXT("Movie Studio / Vegas Pro version spoofer"), WS_OVERLAPPED | WS_VISIBLE | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL); |
236 | 406 |
237 MSG msg = {0}; | 407 MSG msg = {0}; |
238 | 408 |
239 while (GetMessage(&msg, NULL, 0, 0)) { | 409 while (GetMessage(&msg, NULL, 0, 0)) { |
240 TranslateMessage(&msg); | 410 TranslateMessage(&msg); |