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);