notepad: Use HKCU\Software\Microsoft\Notepad for font and window-geometry.
[wine] / programs / notepad / main.c
1 /*
2  *  Notepad
3  *
4  *  Copyright 2000 Mike McCormack <Mike_McCormack@looksmart.com.au>
5  *  Copyright 1997,98 Marcel Baur <mbaur@g26.ethz.ch>
6  *  Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
7  *  Copyright 2002 Andriy Palamarchuk
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  *
23  */
24
25 #define UNICODE
26
27 #include <windows.h>
28 #include <stdio.h>
29
30 #include "main.h"
31 #include "dialog.h"
32 #include "notepad_res.h"
33
34 NOTEPAD_GLOBALS Globals;
35 static ATOM aFINDMSGSTRING;
36
37 static const WCHAR notepad_reg_key[] = {'S','o','f','t','w','a','r','e','\\',
38                                         'M','i','c','r','o','s','o','f','t','\\','N','o','t','e','p','a','d','\0'};
39 static const WCHAR value_fWrap[]            = {'f','W','r','a','p','\0'};
40 static const WCHAR value_iPointSize[]       = {'i','P','o','i','n','t','S','i','z','e','\0'};
41 static const WCHAR value_iWindowPosDX[]     = {'i','W','i','n','d','o','w','P','o','s','D','X','\0'};
42 static const WCHAR value_iWindowPosDY[]     = {'i','W','i','n','d','o','w','P','o','s','D','Y','\0'};
43 static const WCHAR value_iWindowPosX[]      = {'i','W','i','n','d','o','w','P','o','s','X','\0'};
44 static const WCHAR value_iWindowPosY[]      = {'i','W','i','n','d','o','w','P','o','s','Y','\0'};
45 static const WCHAR value_lfCharSet[]        = {'l','f','C','h','a','r','S','e','t','\0'};
46 static const WCHAR value_lfClipPrecision[]  = {'l','f','C','l','i','p','P','r','e','c','i','s','i','o','n','\0'};
47 static const WCHAR value_lfEscapement[]     = {'l','f','E','s','c','a','p','e','m','e','n','t','\0'};
48 static const WCHAR value_lfItalic[]         = {'l','f','I','t','a','l','i','c','\0'};
49 static const WCHAR value_lfOrientation[]    = {'l','f','O','r','i','e','n','t','a','t','i','o','n','\0'};
50 static const WCHAR value_lfOutPrecision[]   = {'l','f','O','u','t','P','r','e','c','i','s','i','o','n','\0'};
51 static const WCHAR value_lfPitchAndFamily[] = {'l','f','P','i','t','c','h','A','n','d','F','a','m','i','l','y','\0'};
52 static const WCHAR value_lfQuality[]        = {'l','f','Q','u','a','l','i','t','y','\0'};
53 static const WCHAR value_lfStrikeOut[]      = {'l','f','S','t','r','i','k','e','O','u','t','\0'};
54 static const WCHAR value_lfUnderline[]      = {'l','f','U','n','d','e','r','l','i','n','e','\0'};
55 static const WCHAR value_lfWeight[]         = {'l','f','W','e','i','g','h','t','\0'};
56 static const WCHAR value_lfFaceName[]       = {'l','f','F','a','c','e','N','a','m','e','\0'};
57
58 /***********************************************************************
59  *
60  *           SetFileName
61  *
62  *  Sets Global File Name.
63  */
64 VOID SetFileName(LPCWSTR szFileName)
65 {
66     lstrcpy(Globals.szFileName, szFileName);
67     Globals.szFileTitle[0] = 0;
68     GetFileTitle(szFileName, Globals.szFileTitle, sizeof(Globals.szFileTitle));
69 }
70
71 /******************************************************************************
72  *      get_dpi
73  *
74  * Get the dpi from registry HKCC\Software\Fonts\LogPixels.
75  */
76 static DWORD get_dpi(void)
77 {
78     static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
79     static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
80     DWORD dpi = 96;
81     HKEY hkey;
82
83     if (RegOpenKey(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
84     {
85         DWORD type, size, new_dpi;
86
87         size = sizeof(new_dpi);
88         if(RegQueryValueEx(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
89         {
90             if(type == REG_DWORD && new_dpi != 0)
91                 dpi = new_dpi;
92         }
93         RegCloseKey(hkey);
94     }
95     return dpi;
96 }
97
98 /***********************************************************************
99  *
100  *           NOTEPAD_SaveSettingToRegistry
101  *
102  *  Save settring to registry HKCU\Software\Microsoft\Notepad.
103  */
104 static VOID NOTEPAD_SaveSettingToRegistry(void)
105 {
106     HKEY hkey;
107     DWORD disp;
108
109     if(RegCreateKeyEx(HKEY_CURRENT_USER, notepad_reg_key, 0, NULL,
110                 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disp) == ERROR_SUCCESS)
111     {
112         DWORD data;
113         RECT rect;
114         
115         GetWindowRect(Globals.hMainWnd, &rect);
116         Globals.iWindowPosX  = rect.left;
117         Globals.iWindowPosY  = rect.top;
118         Globals.iWindowPosDX = rect.right - rect.left;
119         Globals.iWindowPosDY = rect.bottom - rect.top;
120
121 #define SET_NOTEPAD_REG(hkey, value_name, value_data) do { DWORD data = (DWORD)value_data; RegSetValueEx(hkey, value_name, 0, REG_DWORD, (LPBYTE)&data, sizeof(DWORD)); }while(0)
122         SET_NOTEPAD_REG(hkey, value_fWrap,            Globals.bWrapLongLines);
123         SET_NOTEPAD_REG(hkey, value_iWindowPosX,      Globals.iWindowPosX);
124         SET_NOTEPAD_REG(hkey, value_iWindowPosY,      Globals.iWindowPosY);
125         SET_NOTEPAD_REG(hkey, value_iWindowPosDX,     Globals.iWindowPosDX);
126         SET_NOTEPAD_REG(hkey, value_iWindowPosDY,     Globals.iWindowPosDY);
127         SET_NOTEPAD_REG(hkey, value_lfCharSet,        Globals.lfFont.lfCharSet);
128         SET_NOTEPAD_REG(hkey, value_lfClipPrecision,  Globals.lfFont.lfClipPrecision);
129         SET_NOTEPAD_REG(hkey, value_lfEscapement,     Globals.lfFont.lfEscapement);
130         SET_NOTEPAD_REG(hkey, value_lfItalic,         Globals.lfFont.lfItalic);
131         SET_NOTEPAD_REG(hkey, value_lfOrientation,    Globals.lfFont.lfOrientation);
132         SET_NOTEPAD_REG(hkey, value_lfOutPrecision,   Globals.lfFont.lfOutPrecision);
133         SET_NOTEPAD_REG(hkey, value_lfPitchAndFamily, Globals.lfFont.lfPitchAndFamily);
134         SET_NOTEPAD_REG(hkey, value_lfQuality,        Globals.lfFont.lfQuality);
135         SET_NOTEPAD_REG(hkey, value_lfStrikeOut,      Globals.lfFont.lfStrikeOut);
136         SET_NOTEPAD_REG(hkey, value_lfUnderline,      Globals.lfFont.lfUnderline);
137         SET_NOTEPAD_REG(hkey, value_lfWeight,         Globals.lfFont.lfWeight);
138 #undef SET_NOTEPAD_REG
139
140         data = (DWORD)(abs(Globals.lfFont.lfHeight) * 72 / get_dpi() * 10); /* method of native notepad.exe */
141         RegSetValueEx(hkey, value_iPointSize, 0, REG_DWORD, (LPBYTE)&data, sizeof(DWORD));
142
143         RegSetValueEx(hkey, value_lfFaceName, 0, REG_SZ, (LPBYTE)&Globals.lfFont.lfFaceName,
144                       lstrlen(Globals.lfFont.lfFaceName) * sizeof(Globals.lfFont.lfFaceName[0]));
145
146         RegCloseKey(hkey);
147     }
148 }
149
150 /***********************************************************************
151  *
152  *           NOTEPAD_LoadSettingFromRegistry
153  *
154  *  Load setting from registry HKCU\Software\Microsoft\Notepad.
155  */
156 static VOID NOTEPAD_LoadSettingFromRegistry(void)
157 {
158     static const WCHAR systemW[] = { 'S','y','s','t','e','m','\0' };
159     HKEY hkey;
160     INT base_length;
161
162     base_length = (GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN))?
163         GetSystemMetrics(SM_CYSCREEN) : GetSystemMetrics(SM_CXSCREEN);
164
165     Globals.iWindowPosX  = 0;
166     Globals.iWindowPosY  = 0;
167     Globals.iWindowPosDX = base_length * .95;
168     Globals.iWindowPosDY = Globals.iWindowPosDX * 3 / 4;
169
170     Globals.bWrapLongLines  = TRUE;
171     
172     Globals.lfFont.lfHeight         = -12;
173     Globals.lfFont.lfWidth          = 0;
174     Globals.lfFont.lfEscapement     = 0;
175     Globals.lfFont.lfOrientation    = 0;
176     Globals.lfFont.lfWeight         = FW_REGULAR;
177     Globals.lfFont.lfItalic         = FALSE;
178     Globals.lfFont.lfUnderline      = FALSE;
179     Globals.lfFont.lfStrikeOut      = FALSE;
180     Globals.lfFont.lfCharSet        = DEFAULT_CHARSET;
181     Globals.lfFont.lfOutPrecision   = OUT_DEFAULT_PRECIS;
182     Globals.lfFont.lfClipPrecision  = CLIP_DEFAULT_PRECIS;
183     Globals.lfFont.lfQuality        = DEFAULT_QUALITY;
184     Globals.lfFont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
185     lstrcpy(Globals.lfFont.lfFaceName, systemW);
186
187     if(RegOpenKey(HKEY_CURRENT_USER, notepad_reg_key, &hkey) == ERROR_SUCCESS)
188     {
189         WORD  data_lfFaceName[LF_FACESIZE];
190         DWORD type, data, size;
191
192 #define QUERY_NOTEPAD_REG(hkey, value_name, ret) do { DWORD type, data; DWORD size = sizeof(DWORD); if(RegQueryValueEx(hkey, value_name, 0, &type, (LPBYTE)&data, &size) == ERROR_SUCCESS) if(type == REG_DWORD) ret = (typeof(ret))data; } while(0)
193         QUERY_NOTEPAD_REG(hkey, value_fWrap,            Globals.bWrapLongLines);
194         QUERY_NOTEPAD_REG(hkey, value_iWindowPosX,      Globals.iWindowPosX);
195         QUERY_NOTEPAD_REG(hkey, value_iWindowPosY,      Globals.iWindowPosY);
196         QUERY_NOTEPAD_REG(hkey, value_iWindowPosDX,     Globals.iWindowPosDX);
197         QUERY_NOTEPAD_REG(hkey, value_iWindowPosDY,     Globals.iWindowPosDY);
198         QUERY_NOTEPAD_REG(hkey, value_lfCharSet,        Globals.lfFont.lfCharSet);
199         QUERY_NOTEPAD_REG(hkey, value_lfClipPrecision,  Globals.lfFont.lfClipPrecision);
200         QUERY_NOTEPAD_REG(hkey, value_lfEscapement,     Globals.lfFont.lfEscapement);
201         QUERY_NOTEPAD_REG(hkey, value_lfItalic,         Globals.lfFont.lfItalic);
202         QUERY_NOTEPAD_REG(hkey, value_lfOrientation,    Globals.lfFont.lfOrientation);
203         QUERY_NOTEPAD_REG(hkey, value_lfOutPrecision,   Globals.lfFont.lfOutPrecision);
204         QUERY_NOTEPAD_REG(hkey, value_lfPitchAndFamily, Globals.lfFont.lfPitchAndFamily);
205         QUERY_NOTEPAD_REG(hkey, value_lfQuality,        Globals.lfFont.lfQuality);
206         QUERY_NOTEPAD_REG(hkey, value_lfStrikeOut,      Globals.lfFont.lfStrikeOut);
207         QUERY_NOTEPAD_REG(hkey, value_lfUnderline,      Globals.lfFont.lfUnderline);
208         QUERY_NOTEPAD_REG(hkey, value_lfWeight,         Globals.lfFont.lfWeight);
209 #undef QUERY_NOTEPAD_REG
210
211         size = sizeof(DWORD);
212         if(RegQueryValueEx(hkey, value_iPointSize, 0, &type, (LPBYTE)&data, &size) == ERROR_SUCCESS)
213             if(type == REG_DWORD)
214                 Globals.lfFont.lfHeight = (LONG)(-abs(data / 10 * get_dpi() / 72)); /* method of native notepad.exe */
215
216         size = sizeof(Globals.lfFont.lfFaceName);
217         if(RegQueryValueEx(hkey, value_lfFaceName, 0, &type, (LPBYTE)&data_lfFaceName, &size) == ERROR_SUCCESS)
218             if(type == REG_SZ)
219                 lstrcpy(Globals.lfFont.lfFaceName, data_lfFaceName);
220         
221         RegCloseKey(hkey);
222     }
223 }
224
225 /***********************************************************************
226  *
227  *           NOTEPAD_MenuCommand
228  *
229  *  All handling of main menu events
230  */
231 static int NOTEPAD_MenuCommand(WPARAM wParam)
232 {
233     switch (wParam)
234     {
235     case CMD_NEW:               DIALOG_FileNew(); break;
236     case CMD_OPEN:              DIALOG_FileOpen(); break;
237     case CMD_SAVE:              DIALOG_FileSave(); break;
238     case CMD_SAVE_AS:           DIALOG_FileSaveAs(); break;
239     case CMD_PRINT:             DIALOG_FilePrint(); break;
240     case CMD_PAGE_SETUP:        DIALOG_FilePageSetup(); break;
241     case CMD_PRINTER_SETUP:     DIALOG_FilePrinterSetup();break;
242     case CMD_EXIT:              DIALOG_FileExit(); break;
243
244     case CMD_UNDO:             DIALOG_EditUndo(); break;
245     case CMD_CUT:              DIALOG_EditCut(); break;
246     case CMD_COPY:             DIALOG_EditCopy(); break;
247     case CMD_PASTE:            DIALOG_EditPaste(); break;
248     case CMD_DELETE:           DIALOG_EditDelete(); break;
249     case CMD_SELECT_ALL:       DIALOG_EditSelectAll(); break;
250     case CMD_TIME_DATE:        DIALOG_EditTimeDate();break;
251
252     case CMD_SEARCH:           DIALOG_Search(); break;
253     case CMD_SEARCH_NEXT:      DIALOG_SearchNext(); break;
254                                
255     case CMD_WRAP:             DIALOG_EditWrap(); break;
256     case CMD_FONT:             DIALOG_SelectFont(); break;
257
258     case CMD_HELP_CONTENTS:    DIALOG_HelpContents(); break;
259     case CMD_HELP_SEARCH:      DIALOG_HelpSearch(); break;
260     case CMD_HELP_ON_HELP:     DIALOG_HelpHelp(); break;
261     case CMD_LICENSE:          DIALOG_HelpLicense(); break;
262     case CMD_NO_WARRANTY:      DIALOG_HelpNoWarranty(); break;
263     case CMD_ABOUT_WINE:       DIALOG_HelpAboutWine(); break;
264
265     default:
266         break;
267     }
268    return 0;
269 }
270
271 /***********************************************************************
272  * Data Initialization
273  */
274 static VOID NOTEPAD_InitData(VOID)
275 {
276     LPWSTR p = Globals.szFilter;
277     static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
278     static const WCHAR all_files[] = { '*','.','*',0 };
279
280     LoadString(Globals.hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN);
281     p += lstrlen(p) + 1;
282     lstrcpy(p, txt_files);
283     p += lstrlen(p) + 1;
284     LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN);
285     p += lstrlen(p) + 1;
286     lstrcpy(p, all_files);
287     p += lstrlen(p) + 1;
288     *p = '\0';
289     Globals.hDevMode = NULL;
290     Globals.hDevNames = NULL;
291
292     CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP,
293             MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
294 }
295
296 /***********************************************************************
297  * Enable/disable items on the menu based on control state
298  */
299 static VOID NOTEPAD_InitMenuPopup(HMENU menu, int index)
300 {
301     int enable;
302
303     EnableMenuItem(menu, CMD_UNDO,
304         SendMessage(Globals.hEdit, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED);
305     EnableMenuItem(menu, CMD_PASTE,
306         IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED);
307     enable = SendMessage(Globals.hEdit, EM_GETSEL, 0, 0);
308     enable = (HIWORD(enable) == LOWORD(enable)) ? MF_GRAYED : MF_ENABLED;
309     EnableMenuItem(menu, CMD_CUT, enable);
310     EnableMenuItem(menu, CMD_COPY, enable);
311     EnableMenuItem(menu, CMD_DELETE, enable);
312     
313     EnableMenuItem(menu, CMD_SELECT_ALL,
314         GetWindowTextLength(Globals.hEdit) ? MF_ENABLED : MF_GRAYED);
315 }
316
317 /***********************************************************************
318  *
319  *           NOTEPAD_WndProc
320  */
321 static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
322                                LPARAM lParam)
323 {
324     switch (msg) {
325
326     case WM_CREATE:
327     {
328         static const WCHAR editW[] = { 'e','d','i','t',0 };
329         DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
330                         ES_AUTOVSCROLL | ES_MULTILINE;
331         RECT rc;
332         GetClientRect(hWnd, &rc);
333
334         if (!Globals.bWrapLongLines) dwStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
335
336         Globals.hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, editW, NULL,
337                              dwStyle,
338                              0, 0, rc.right, rc.bottom, hWnd,
339                              NULL, Globals.hInstance, NULL);
340
341         Globals.hFont = CreateFontIndirect(&Globals.lfFont);
342         SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)FALSE);
343         break;
344     }
345
346     case WM_COMMAND:
347         NOTEPAD_MenuCommand(LOWORD(wParam));
348         break;
349
350     case WM_DESTROYCLIPBOARD:
351         /*MessageBox(Globals.hMainWnd, "Empty clipboard", "Debug", MB_ICONEXCLAMATION);*/
352         break;
353
354     case WM_CLOSE:
355         if (DoCloseFile()) {
356             DestroyWindow(hWnd);
357         }
358         break;
359
360     case WM_QUERYENDSESSION:
361         if (DoCloseFile()) {
362             return 1;
363         }
364         break;
365
366     case WM_DESTROY:
367         NOTEPAD_SaveSettingToRegistry();
368
369         PostQuitMessage(0);
370         break;
371
372     case WM_SIZE:
373         SetWindowPos(Globals.hEdit, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
374                      SWP_NOOWNERZORDER | SWP_NOZORDER);
375         break;
376
377     case WM_SETFOCUS:
378         SetFocus(Globals.hEdit);
379         break;
380
381     case WM_DROPFILES:
382     {
383         WCHAR szFileName[MAX_PATH];
384         HANDLE hDrop = (HANDLE) wParam;
385
386         DragQueryFile(hDrop, 0, szFileName, SIZEOF(szFileName));
387         DragFinish(hDrop);
388         DoOpenFile(szFileName);
389         break;
390     }
391     
392     case WM_INITMENUPOPUP:
393         NOTEPAD_InitMenuPopup((HMENU)wParam, lParam);
394         break;
395
396     default:
397         return DefWindowProc(hWnd, msg, wParam, lParam);
398     }
399     return 0;
400 }
401
402 static int AlertFileDoesNotExist(LPCWSTR szFileName)
403 {
404    int nResult;
405    WCHAR szMessage[MAX_STRING_LEN];
406    WCHAR szResource[MAX_STRING_LEN];
407
408    LoadString(Globals.hInstance, STRING_DOESNOTEXIST, szResource, SIZEOF(szResource));
409    wsprintf(szMessage, szResource, szFileName);
410
411    LoadString(Globals.hInstance, STRING_ERROR, szResource, SIZEOF(szResource));
412
413    nResult = MessageBox(Globals.hMainWnd, szMessage, szResource,
414                         MB_ICONEXCLAMATION | MB_YESNO);
415
416    return(nResult);
417 }
418
419 static void HandleCommandLine(LPWSTR cmdline)
420 {
421     WCHAR delimiter;
422     int opt_print=0;
423     
424     /* skip white space */
425     while (*cmdline == ' ') cmdline++;
426
427     /* skip executable name */
428     delimiter = (*cmdline == '"' ? '"' : ' ');
429
430     if (*cmdline == delimiter) cmdline++;
431
432     while (*cmdline && *cmdline != delimiter) cmdline++;
433
434     if (*cmdline == delimiter) cmdline++;
435
436     while (*cmdline == ' ' || *cmdline == '-' || *cmdline == '/')
437     {
438         WCHAR option;
439
440         if (*cmdline++ == ' ') continue;
441
442         option = *cmdline;
443         if (option) cmdline++;
444         while (*cmdline == ' ') cmdline++;
445
446         switch(option)
447         {
448             case 'p':
449             case 'P':
450                 opt_print=1;
451                 break;
452         }
453     }
454
455     if (*cmdline)
456     {
457         /* file name is passed in the command line */
458         LPCWSTR file_name;
459         BOOL file_exists;
460         WCHAR buf[MAX_PATH];
461
462         if (cmdline[0] == '"')
463         {
464             cmdline++;
465             cmdline[lstrlen(cmdline) - 1] = 0;
466         }
467
468         if (FileExists(cmdline))
469         {
470             file_exists = TRUE;
471             file_name = cmdline;
472         }
473         else
474         {
475             static const WCHAR txtW[] = { '.','t','x','t',0 };
476
477             /* try to find file with ".txt" extension */
478             if (!lstrcmp(txtW, cmdline + lstrlen(cmdline) - lstrlen(txtW)))
479             {
480                 file_exists = FALSE;
481                 file_name = cmdline;
482             }
483             else
484             {
485                 lstrcpyn(buf, cmdline, MAX_PATH - lstrlen(txtW) - 1);
486                 lstrcat(buf, txtW);
487                 file_name = buf;
488                 file_exists = FileExists(buf);
489             }
490         }
491
492         if (file_exists)
493         {
494             DoOpenFile(file_name);
495             InvalidateRect(Globals.hMainWnd, NULL, FALSE);
496             if (opt_print)
497                 DIALOG_FilePrint();
498         }
499         else
500         {
501             switch (AlertFileDoesNotExist(file_name)) {
502             case IDYES:
503                 DoOpenFile(file_name);
504                 break;
505
506             case IDNO:
507                 break;
508             }
509         }
510      }
511 }
512
513 /***********************************************************************
514  *
515  *           WinMain
516  */
517 int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
518 {
519     MSG        msg;
520     HACCEL      hAccel;
521     WNDCLASSEX class;
522     static const WCHAR className[] = {'N','o','t','e','p','a','d',0};
523     static const WCHAR winName[]   = {'N','o','t','e','p','a','d',0};
524
525     aFINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
526
527     ZeroMemory(&Globals, sizeof(Globals));
528     Globals.hInstance       = hInstance;
529     NOTEPAD_LoadSettingFromRegistry();
530
531     ZeroMemory(&class, sizeof(class));
532     class.cbSize        = sizeof(class);
533     class.lpfnWndProc   = NOTEPAD_WndProc;
534     class.hInstance     = Globals.hInstance;
535     class.hIcon         = LoadIcon(0, IDI_APPLICATION);
536     class.hCursor       = LoadCursor(0, IDC_ARROW);
537     class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
538     class.lpszMenuName  = MAKEINTRESOURCE(MAIN_MENU);
539     class.lpszClassName = className;
540
541     if (!RegisterClassEx(&class)) return FALSE;
542
543     /* Setup windows */
544
545     Globals.hMainWnd =
546         CreateWindow(className, winName, WS_OVERLAPPEDWINDOW,
547                      Globals.iWindowPosX, Globals.iWindowPosY,
548                      Globals.iWindowPosDX, Globals.iWindowPosDY,
549                      NULL, NULL, Globals.hInstance, NULL);
550     if (!Globals.hMainWnd)
551     {
552         ShowLastError();
553         ExitProcess(1);
554     }
555
556     NOTEPAD_InitData();
557     DIALOG_FileNew();
558
559     ShowWindow(Globals.hMainWnd, show);
560     UpdateWindow(Globals.hMainWnd);
561     DragAcceptFiles(Globals.hMainWnd, TRUE);
562
563     HandleCommandLine(GetCommandLine());
564
565     hAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE(ID_ACCEL) );
566
567     while (GetMessage(&msg, 0, 0, 0))
568     {
569         if (!TranslateAccelerator(Globals.hMainWnd, hAccel, &msg) && !IsDialogMessage(Globals.hFindReplaceDlg, &msg))
570         {
571             TranslateMessage(&msg);
572             DispatchMessage(&msg);
573         }
574     }
575     return msg.wParam;
576 }