xref: /reactos/base/applications/notepad/main.c (revision 1734f297)
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  *  Copyright 2020 Katayama Hirofumi MZ
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25 
26 #include "notepad.h"
27 
28 #include <shlobj.h>
29 #include <strsafe.h>
30 
31 NOTEPAD_GLOBALS Globals;
32 static ATOM aFINDMSGSTRING;
33 
34 VOID NOTEPAD_EnableSearchMenu()
35 {
36     EnableMenuItem(Globals.hMenu, CMD_SEARCH,
37                    MF_BYCOMMAND | ((GetWindowTextLength(Globals.hEdit) == 0) ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
38     EnableMenuItem(Globals.hMenu, CMD_SEARCH_NEXT,
39                    MF_BYCOMMAND | ((GetWindowTextLength(Globals.hEdit) == 0) ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
40 }
41 
42 /***********************************************************************
43  *
44  *           SetFileName
45  *
46  *  Sets Global File Name.
47  */
48 VOID SetFileName(LPCTSTR szFileName)
49 {
50     StringCchCopy(Globals.szFileName, ARRAY_SIZE(Globals.szFileName), szFileName);
51     Globals.szFileTitle[0] = 0;
52     GetFileTitle(szFileName, Globals.szFileTitle, ARRAY_SIZE(Globals.szFileTitle));
53 
54     if (szFileName && szFileName[0])
55         SHAddToRecentDocs(SHARD_PATHW, szFileName);
56 }
57 
58 /***********************************************************************
59  *
60  *           NOTEPAD_MenuCommand
61  *
62  *  All handling of main menu events
63  */
64 static int NOTEPAD_MenuCommand(WPARAM wParam)
65 {
66     switch (wParam)
67     {
68     case CMD_NEW:        DIALOG_FileNew(); break;
69     case CMD_NEW_WINDOW: DIALOG_FileNewWindow(); break;
70     case CMD_OPEN:       DIALOG_FileOpen(); break;
71     case CMD_SAVE:       DIALOG_FileSave(); break;
72     case CMD_SAVE_AS:    DIALOG_FileSaveAs(); break;
73     case CMD_PRINT:      DIALOG_FilePrint(); break;
74     case CMD_PAGE_SETUP: DIALOG_FilePageSetup(); break;
75     case CMD_EXIT:       DIALOG_FileExit(); break;
76 
77     case CMD_UNDO:       DIALOG_EditUndo(); break;
78     case CMD_CUT:        DIALOG_EditCut(); break;
79     case CMD_COPY:       DIALOG_EditCopy(); break;
80     case CMD_PASTE:      DIALOG_EditPaste(); break;
81     case CMD_DELETE:     DIALOG_EditDelete(); break;
82     case CMD_SELECT_ALL: DIALOG_EditSelectAll(); break;
83     case CMD_TIME_DATE:  DIALOG_EditTimeDate(); break;
84 
85     case CMD_SEARCH:      DIALOG_Search(); break;
86     case CMD_SEARCH_NEXT: DIALOG_SearchNext(); break;
87     case CMD_REPLACE:     DIALOG_Replace(); break;
88     case CMD_GOTO:        DIALOG_GoTo(); break;
89 
90     case CMD_WRAP: DIALOG_EditWrap(); break;
91     case CMD_FONT: DIALOG_SelectFont(); break;
92 
93     case CMD_STATUSBAR: DIALOG_ViewStatusBar(); break;
94 
95     case CMD_HELP_CONTENTS: DIALOG_HelpContents(); break;
96     case CMD_HELP_ABOUT_NOTEPAD: DIALOG_HelpAboutNotepad(); break;
97 
98     default:
99         break;
100     }
101     return 0;
102 }
103 
104 /***********************************************************************
105  *
106  *           NOTEPAD_FindTextAt
107  */
108 
109 static BOOL
110 NOTEPAD_FindTextAt(FINDREPLACE *pFindReplace, LPCTSTR pszText, int iTextLength, DWORD dwPosition)
111 {
112     BOOL bMatches;
113     size_t iTargetLength;
114 
115     if ((!pFindReplace) || (!pszText))
116     {
117         return FALSE;
118     }
119 
120     iTargetLength = _tcslen(pFindReplace->lpstrFindWhat);
121 
122     /* Make proper comparison */
123     if (pFindReplace->Flags & FR_MATCHCASE)
124         bMatches = !_tcsncmp(&pszText[dwPosition], pFindReplace->lpstrFindWhat, iTargetLength);
125     else
126         bMatches = !_tcsnicmp(&pszText[dwPosition], pFindReplace->lpstrFindWhat, iTargetLength);
127 
128     if (bMatches && pFindReplace->Flags & FR_WHOLEWORD)
129     {
130         if ((dwPosition > 0) && !_istspace(pszText[dwPosition-1]))
131             bMatches = FALSE;
132         if ((dwPosition < (DWORD) iTextLength - 1) && !_istspace(pszText[dwPosition+1]))
133             bMatches = FALSE;
134     }
135 
136     return bMatches;
137 }
138 
139 /***********************************************************************
140  *
141  *           NOTEPAD_FindNext
142  */
143 
144 BOOL NOTEPAD_FindNext(FINDREPLACE *pFindReplace, BOOL bReplace, BOOL bShowAlert)
145 {
146     int iTextLength, iTargetLength;
147     size_t iAdjustment = 0;
148     LPTSTR pszText = NULL;
149     DWORD dwPosition, dwBegin, dwEnd;
150     BOOL bMatches = FALSE;
151     TCHAR szResource[128], szText[128];
152     BOOL bSuccess;
153 
154     iTargetLength = (int) _tcslen(pFindReplace->lpstrFindWhat);
155 
156     /* Retrieve the window text */
157     iTextLength = GetWindowTextLength(Globals.hEdit);
158     if (iTextLength > 0)
159     {
160         pszText = (LPTSTR) HeapAlloc(GetProcessHeap(), 0, (iTextLength + 1) * sizeof(TCHAR));
161         if (!pszText)
162             return FALSE;
163 
164         GetWindowText(Globals.hEdit, pszText, iTextLength + 1);
165     }
166 
167     SendMessage(Globals.hEdit, EM_GETSEL, (WPARAM) &dwBegin, (LPARAM) &dwEnd);
168     if (bReplace && ((dwEnd - dwBegin) == (DWORD) iTargetLength))
169     {
170         if (NOTEPAD_FindTextAt(pFindReplace, pszText, iTextLength, dwBegin))
171         {
172             SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM) pFindReplace->lpstrReplaceWith);
173             iAdjustment = _tcslen(pFindReplace->lpstrReplaceWith) - (dwEnd - dwBegin);
174         }
175     }
176 
177     if (pFindReplace->Flags & FR_DOWN)
178     {
179         /* Find Down */
180         dwPosition = dwEnd;
181         while(dwPosition < (DWORD) iTextLength)
182         {
183             bMatches = NOTEPAD_FindTextAt(pFindReplace, pszText, iTextLength, dwPosition);
184             if (bMatches)
185                 break;
186             dwPosition++;
187         }
188     }
189     else
190     {
191         /* Find Up */
192         dwPosition = dwBegin;
193         while(dwPosition > 0)
194         {
195             dwPosition--;
196             bMatches = NOTEPAD_FindTextAt(pFindReplace, pszText, iTextLength, dwPosition);
197             if (bMatches)
198                 break;
199         }
200     }
201 
202     if (bMatches)
203     {
204         /* Found target */
205         if (dwPosition > dwBegin)
206             dwPosition += (DWORD) iAdjustment;
207         SendMessage(Globals.hEdit, EM_SETSEL, dwPosition, dwPosition + iTargetLength);
208         SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0);
209         bSuccess = TRUE;
210     }
211     else
212     {
213         /* Can't find target */
214         if (bShowAlert)
215         {
216             LoadString(Globals.hInstance, STRING_CANNOTFIND, szResource, ARRAY_SIZE(szResource));
217             _sntprintf(szText, ARRAY_SIZE(szText), szResource, pFindReplace->lpstrFindWhat);
218             LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, ARRAY_SIZE(szResource));
219             MessageBox(Globals.hFindReplaceDlg, szText, szResource, MB_OK);
220         }
221         bSuccess = FALSE;
222     }
223 
224     if (pszText)
225         HeapFree(GetProcessHeap(), 0, pszText);
226     return bSuccess;
227 }
228 
229 /***********************************************************************
230  *
231  *           NOTEPAD_ReplaceAll
232  */
233 
234 static VOID NOTEPAD_ReplaceAll(FINDREPLACE *pFindReplace)
235 {
236     BOOL bShowAlert = TRUE;
237 
238     SendMessage(Globals.hEdit, EM_SETSEL, 0, 0);
239 
240     while (NOTEPAD_FindNext(pFindReplace, TRUE, bShowAlert))
241     {
242         bShowAlert = FALSE;
243     }
244 }
245 
246 /***********************************************************************
247  *
248  *           NOTEPAD_FindTerm
249  */
250 
251 static VOID NOTEPAD_FindTerm(VOID)
252 {
253     Globals.hFindReplaceDlg = NULL;
254 }
255 
256 /***********************************************************************
257  * Data Initialization
258  */
259 static VOID NOTEPAD_InitData(VOID)
260 {
261     LPTSTR p = Globals.szFilter;
262     static const TCHAR txt_files[] = _T("*.txt");
263     static const TCHAR all_files[] = _T("*.*");
264 
265     p += LoadString(Globals.hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN) + 1;
266     _tcscpy(p, txt_files);
267     p += ARRAY_SIZE(txt_files);
268 
269     p += LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN) + 1;
270     _tcscpy(p, all_files);
271     p += ARRAY_SIZE(all_files);
272     *p = '\0';
273     Globals.find.lpstrFindWhat = NULL;
274 
275     Globals.hDevMode = NULL;
276     Globals.hDevNames = NULL;
277 }
278 
279 /***********************************************************************
280  * Enable/disable items on the menu based on control state
281  */
282 static VOID NOTEPAD_InitMenuPopup(HMENU menu, LPARAM index)
283 {
284     int enable;
285 
286     UNREFERENCED_PARAMETER(index);
287 
288     CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP,
289         MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
290     if (!Globals.bWrapLongLines)
291     {
292         CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_STATUSBAR,
293             MF_BYCOMMAND | (Globals.bShowStatusBar ? MF_CHECKED : MF_UNCHECKED));
294     }
295     EnableMenuItem(menu, CMD_UNDO,
296         SendMessage(Globals.hEdit, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED);
297     EnableMenuItem(menu, CMD_PASTE,
298         IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED);
299     enable = (int) SendMessage(Globals.hEdit, EM_GETSEL, 0, 0);
300     enable = (HIWORD(enable) == LOWORD(enable)) ? MF_GRAYED : MF_ENABLED;
301     EnableMenuItem(menu, CMD_CUT, enable);
302     EnableMenuItem(menu, CMD_COPY, enable);
303     EnableMenuItem(menu, CMD_DELETE, enable);
304 
305     EnableMenuItem(menu, CMD_SELECT_ALL,
306         GetWindowTextLength(Globals.hEdit) ? MF_ENABLED : MF_GRAYED);
307     DrawMenuBar(Globals.hMainWnd);
308 }
309 
310 LRESULT CALLBACK EDIT_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
311 {
312     switch (msg)
313     {
314         case WM_KEYDOWN:
315         case WM_KEYUP:
316         {
317             switch (wParam)
318             {
319                 case VK_UP:
320                 case VK_DOWN:
321                 case VK_LEFT:
322                 case VK_RIGHT:
323                     DIALOG_StatusBarUpdateCaretPos();
324                     break;
325                 default:
326                 {
327                     UpdateWindowCaption(FALSE);
328                     break;
329                 }
330             }
331         }
332         case WM_LBUTTONUP:
333         {
334             DIALOG_StatusBarUpdateCaretPos();
335             break;
336         }
337     }
338     return CallWindowProc( Globals.EditProc, hWnd, msg, wParam, lParam);
339 }
340 
341 /***********************************************************************
342  *
343  *           NOTEPAD_WndProc
344  */
345 static LRESULT
346 WINAPI
347 NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
348 {
349     switch (msg)
350     {
351 
352     case WM_CREATE:
353         Globals.hMenu = GetMenu(hWnd);
354 
355         // For now, the "Help" dialog is disabled due to the lack of HTML Help support
356         EnableMenuItem(Globals.hMenu, CMD_HELP_CONTENTS, MF_BYCOMMAND | MF_GRAYED);
357         break;
358 
359     case WM_COMMAND:
360         if (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == EN_HSCROLL || HIWORD(wParam) == EN_VSCROLL)
361             DIALOG_StatusBarUpdateCaretPos();
362         if ((HIWORD(wParam) == EN_CHANGE))
363             NOTEPAD_EnableSearchMenu();
364         NOTEPAD_MenuCommand(LOWORD(wParam));
365         break;
366 
367     case WM_DESTROYCLIPBOARD:
368         /*MessageBox(Globals.hMainWnd, "Empty clipboard", "Debug", MB_ICONEXCLAMATION);*/
369         break;
370 
371     case WM_CLOSE:
372         if (DoCloseFile()) {
373             if (Globals.hFont)
374                 DeleteObject(Globals.hFont);
375             if (Globals.hDevMode)
376                 GlobalFree(Globals.hDevMode);
377             if (Globals.hDevNames)
378                 GlobalFree(Globals.hDevNames);
379             DestroyWindow(hWnd);
380         }
381         break;
382 
383     case WM_QUERYENDSESSION:
384         if (DoCloseFile()) {
385             return 1;
386         }
387         break;
388 
389     case WM_DESTROY:
390         SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)Globals.EditProc);
391         NOTEPAD_SaveSettingsToRegistry();
392         PostQuitMessage(0);
393         break;
394 
395     case WM_SIZE:
396     {
397         if ((Globals.bShowStatusBar != FALSE) && (Globals.bWrapLongLines == FALSE))
398         {
399             RECT rcStatusBar;
400             HDWP hdwp;
401 
402             if (!GetWindowRect(Globals.hStatusBar, &rcStatusBar))
403                 break;
404 
405             hdwp = BeginDeferWindowPos(2);
406             if (hdwp == NULL)
407                 break;
408 
409             hdwp = DeferWindowPos(hdwp,
410                                   Globals.hEdit,
411                                   NULL,
412                                   0,
413                                   0,
414                                   LOWORD(lParam),
415                                   HIWORD(lParam) - (rcStatusBar.bottom - rcStatusBar.top),
416                                   SWP_NOZORDER | SWP_NOMOVE);
417 
418             if (hdwp == NULL)
419                 break;
420 
421             hdwp = DeferWindowPos(hdwp,
422                                   Globals.hStatusBar,
423                                   NULL,
424                                   0,
425                                   0,
426                                   LOWORD(lParam),
427                                   LOWORD(wParam),
428                                   SWP_NOZORDER);
429 
430             if (hdwp == NULL)
431                 break;
432 
433             EndDeferWindowPos(hdwp);
434 
435             /* Align status bar parts, only if the status bar resize operation succeeds */
436             DIALOG_StatusBarAlignParts();
437         }
438         else
439             SetWindowPos(Globals.hEdit,
440                          NULL,
441                          0,
442                          0,
443                          LOWORD(lParam),
444                          HIWORD(lParam),
445                          SWP_NOZORDER | SWP_NOMOVE);
446 
447         break;
448     }
449 
450     /* The entire client area is covered by edit control and by
451      * the status bar. So there is no need to erase main background.
452      * This resolves the horrible flicker effect during windows resizes. */
453     case WM_ERASEBKGND:
454         return 1;
455 
456     case WM_SETFOCUS:
457         SetFocus(Globals.hEdit);
458         break;
459 
460     case WM_DROPFILES:
461     {
462         TCHAR szFileName[MAX_PATH];
463         HDROP hDrop = (HDROP) wParam;
464 
465         DragQueryFile(hDrop, 0, szFileName, ARRAY_SIZE(szFileName));
466         DragFinish(hDrop);
467         DoOpenFile(szFileName);
468         break;
469     }
470     case WM_CHAR:
471     case WM_INITMENUPOPUP:
472         NOTEPAD_InitMenuPopup((HMENU)wParam, lParam);
473         break;
474     default:
475         if (msg == aFINDMSGSTRING)
476         {
477             FINDREPLACE *pFindReplace = (FINDREPLACE *) lParam;
478             Globals.find = *(FINDREPLACE *) lParam;
479 
480             if (pFindReplace->Flags & FR_FINDNEXT)
481                 NOTEPAD_FindNext(pFindReplace, FALSE, TRUE);
482             else if (pFindReplace->Flags & FR_REPLACE)
483                 NOTEPAD_FindNext(pFindReplace, TRUE, TRUE);
484             else if (pFindReplace->Flags & FR_REPLACEALL)
485                 NOTEPAD_ReplaceAll(pFindReplace);
486             else if (pFindReplace->Flags & FR_DIALOGTERM)
487                 NOTEPAD_FindTerm();
488             break;
489         }
490 
491         return DefWindowProc(hWnd, msg, wParam, lParam);
492     }
493     return 0;
494 }
495 
496 static int AlertFileDoesNotExist(LPCTSTR szFileName)
497 {
498     return DIALOG_StringMsgBox(Globals.hMainWnd, STRING_DOESNOTEXIST,
499                                szFileName,
500                                MB_ICONEXCLAMATION | MB_YESNO);
501 }
502 
503 static BOOL HandleCommandLine(LPTSTR cmdline)
504 {
505     BOOL opt_print = FALSE;
506 
507     while (*cmdline == _T(' ') || *cmdline == _T('-') || *cmdline == _T('/'))
508     {
509         TCHAR option;
510 
511         if (*cmdline++ == _T(' ')) continue;
512 
513         option = *cmdline;
514         if (option) cmdline++;
515         while (*cmdline == _T(' ')) cmdline++;
516 
517         switch(option)
518         {
519             case 'p':
520             case 'P':
521                 opt_print = TRUE;
522                 break;
523         }
524     }
525 
526     if (*cmdline)
527     {
528         /* file name is passed in the command line */
529         LPCTSTR file_name = NULL;
530         BOOL file_exists = FALSE;
531         TCHAR buf[MAX_PATH];
532 
533         if (cmdline[0] == _T('"'))
534         {
535             cmdline++;
536             cmdline[lstrlen(cmdline) - 1] = 0;
537         }
538 
539         file_name = cmdline;
540         if (FileExists(file_name))
541         {
542             file_exists = TRUE;
543         }
544         else if (!HasFileExtension(cmdline))
545         {
546             static const TCHAR txt[] = _T(".txt");
547 
548             /* try to find file with ".txt" extension */
549             if (!_tcscmp(txt, cmdline + _tcslen(cmdline) - _tcslen(txt)))
550             {
551                 file_exists = FALSE;
552             }
553             else
554             {
555                 _tcsncpy(buf, cmdline, MAX_PATH - _tcslen(txt) - 1);
556                 _tcscat(buf, txt);
557                 file_name = buf;
558                 file_exists = FileExists(file_name);
559             }
560         }
561 
562         if (file_exists)
563         {
564             DoOpenFile(file_name);
565             InvalidateRect(Globals.hMainWnd, NULL, FALSE);
566             if (opt_print)
567             {
568                 DIALOG_FilePrint();
569                 return FALSE;
570             }
571         }
572         else
573         {
574             switch (AlertFileDoesNotExist(file_name)) {
575             case IDYES:
576                 DoOpenFile(file_name);
577                 break;
578 
579             case IDNO:
580                 break;
581             }
582         }
583     }
584 
585     return TRUE;
586 }
587 
588 /***********************************************************************
589  *
590  *           WinMain
591  */
592 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prev, LPTSTR cmdline, int show)
593 {
594     MSG msg;
595     HACCEL hAccel;
596     WNDCLASSEX wndclass;
597     HMONITOR monitor;
598     MONITORINFO info;
599     INT x, y;
600 
601     static const TCHAR className[] = _T("Notepad");
602     static const TCHAR winName[] = _T("Notepad");
603 
604     switch (GetUserDefaultUILanguage())
605     {
606     case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
607         SetProcessDefaultLayout(LAYOUT_RTL);
608         break;
609 
610     default:
611         break;
612     }
613 
614     UNREFERENCED_PARAMETER(prev);
615 
616     aFINDMSGSTRING = (ATOM)RegisterWindowMessage(FINDMSGSTRING);
617 
618     ZeroMemory(&Globals, sizeof(Globals));
619     Globals.hInstance = hInstance;
620     NOTEPAD_LoadSettingsFromRegistry();
621 
622     ZeroMemory(&wndclass, sizeof(wndclass));
623     wndclass.cbSize = sizeof(wndclass);
624     wndclass.lpfnWndProc = NOTEPAD_WndProc;
625     wndclass.hInstance = Globals.hInstance;
626     wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NPICON));
627     wndclass.hCursor = LoadCursor(0, IDC_ARROW);
628     wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
629     wndclass.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU);
630     wndclass.lpszClassName = className;
631     wndclass.hIconSm = (HICON)LoadImage(hInstance,
632                                         MAKEINTRESOURCE(IDI_NPICON),
633                                         IMAGE_ICON,
634                                         16,
635                                         16,
636                                         0);
637 
638     if (!RegisterClassEx(&wndclass)) return FALSE;
639 
640     /* Setup windows */
641 
642     monitor = MonitorFromRect(&Globals.main_rect, MONITOR_DEFAULTTOPRIMARY);
643     info.cbSize = sizeof(info);
644     GetMonitorInfoW(monitor, &info);
645 
646     x = Globals.main_rect.left;
647     y = Globals.main_rect.top;
648     if (Globals.main_rect.left >= info.rcWork.right ||
649         Globals.main_rect.top >= info.rcWork.bottom ||
650         Globals.main_rect.right < info.rcWork.left ||
651         Globals.main_rect.bottom < info.rcWork.top)
652         x = y = CW_USEDEFAULT;
653 
654     Globals.hMainWnd = CreateWindow(className,
655                                     winName,
656                                     WS_OVERLAPPEDWINDOW,
657                                     x,
658                                     y,
659                                     Globals.main_rect.right - Globals.main_rect.left,
660                                     Globals.main_rect.bottom - Globals.main_rect.top,
661                                     NULL,
662                                     NULL,
663                                     Globals.hInstance,
664                                     NULL);
665     if (!Globals.hMainWnd)
666     {
667         ShowLastError();
668         ExitProcess(1);
669     }
670 
671     DoCreateEditWindow();
672 
673     NOTEPAD_InitData();
674     DIALOG_FileNew();
675 
676     ShowWindow(Globals.hMainWnd, show);
677     UpdateWindow(Globals.hMainWnd);
678     DragAcceptFiles(Globals.hMainWnd, TRUE);
679 
680     DIALOG_ViewStatusBar();
681 
682     if (!HandleCommandLine(cmdline))
683     {
684         return 0;
685     }
686 
687     hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(ID_ACCEL));
688 
689     while (GetMessage(&msg, 0, 0, 0))
690     {
691         if (!IsDialogMessage(Globals.hFindReplaceDlg, &msg) &&
692             !TranslateAccelerator(Globals.hMainWnd, hAccel, &msg))
693         {
694             TranslateMessage(&msg);
695             DispatchMessage(&msg);
696         }
697     }
698     return (int) msg.wParam;
699 }
700