[NOTEPAD] Let the user know when an opened file is modified. By Lee Schroeder. CORE...
[reactos.git] / reactos / base / applications / notepad / main.c
index 9a4daed..c9a145f 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "notepad.h"
 
+#include <strsafe.h>
+
 NOTEPAD_GLOBALS Globals;
 static ATOM aFINDMSGSTRING;
 
@@ -43,9 +45,9 @@ VOID NOTEPAD_EnableSearchMenu()
  */
 VOID SetFileName(LPCTSTR szFileName)
 {
-    _tcscpy(Globals.szFileName, szFileName);
+    StringCchCopy(Globals.szFileName, ARRAY_SIZE(Globals.szFileName), szFileName);
     Globals.szFileTitle[0] = 0;
-    GetFileTitle(szFileName, Globals.szFileTitle, SIZEOF(Globals.szFileTitle));
+    GetFileTitle(szFileName, Globals.szFileTitle, ARRAY_SIZE(Globals.szFileTitle));
 }
 
 /***********************************************************************
@@ -58,47 +60,47 @@ static int NOTEPAD_MenuCommand(WPARAM wParam)
 {
     switch (wParam)
     {
-    case CMD_NEW:               DIALOG_FileNew(); break;
-    case CMD_OPEN:              DIALOG_FileOpen(); break;
-    case CMD_SAVE:              DIALOG_FileSave(); break;
-    case CMD_SAVE_AS:           DIALOG_FileSaveAs(); break;
-    case CMD_PRINT:             DIALOG_FilePrint(); break;
-    case CMD_PAGE_SETUP:        DIALOG_FilePageSetup(); break;
-    case CMD_PRINTER_SETUP:     DIALOG_FilePrinterSetup();break;
-    case CMD_EXIT:              DIALOG_FileExit(); break;
-
-    case CMD_UNDO:             DIALOG_EditUndo(); break;
-    case CMD_CUT:              DIALOG_EditCut(); break;
-    case CMD_COPY:             DIALOG_EditCopy(); break;
-    case CMD_PASTE:            DIALOG_EditPaste(); break;
-    case CMD_DELETE:           DIALOG_EditDelete(); break;
-    case CMD_SELECT_ALL:       DIALOG_EditSelectAll(); break;
-    case CMD_TIME_DATE:        DIALOG_EditTimeDate();break;
-
-    case CMD_SEARCH:           DIALOG_Search(); break;
-    case CMD_SEARCH_NEXT:      DIALOG_SearchNext(); break;
-    case CMD_REPLACE:          DIALOG_Replace(); break;
-    case CMD_GOTO:             DIALOG_GoTo(); break;
-
-    case CMD_WRAP:             DIALOG_EditWrap(); break;
-    case CMD_FONT:             DIALOG_SelectFont(); break;
-
-    case CMD_STATUSBAR:        DIALOG_ViewStatusBar(); break;
-
-    case CMD_HELP_CONTENTS:    DIALOG_HelpContents(); break;
-    case CMD_HELP_SEARCH:      DIALOG_HelpSearch(); break;
-    case CMD_HELP_ON_HELP:     DIALOG_HelpHelp(); break;
-    case CMD_ABOUT:            DialogBox(GetModuleHandle(NULL),
-                                         MAKEINTRESOURCE(IDD_ABOUTBOX),
-                                         Globals.hMainWnd,
-                                         AboutDialogProc);
-                               break;
-    case CMD_ABOUT_WINE:       DIALOG_HelpAboutWine(); break;
+    case CMD_NEW:        DIALOG_FileNew(); break;
+    case CMD_OPEN:       DIALOG_FileOpen(); break;
+    case CMD_SAVE:       DIALOG_FileSave(); break;
+    case CMD_SAVE_AS:    DIALOG_FileSaveAs(); break;
+    case CMD_PRINT:      DIALOG_FilePrint(); break;
+    case CMD_PAGE_SETUP: DIALOG_FilePageSetup(); break;
+    case CMD_EXIT:       DIALOG_FileExit(); break;
+
+    case CMD_UNDO:       DIALOG_EditUndo(); break;
+    case CMD_CUT:        DIALOG_EditCut(); break;
+    case CMD_COPY:       DIALOG_EditCopy(); break;
+    case CMD_PASTE:      DIALOG_EditPaste(); break;
+    case CMD_DELETE:     DIALOG_EditDelete(); break;
+    case CMD_SELECT_ALL: DIALOG_EditSelectAll(); break;
+    case CMD_TIME_DATE:  DIALOG_EditTimeDate(); break;
+
+    case CMD_SEARCH:      DIALOG_Search(); break;
+    case CMD_SEARCH_NEXT: DIALOG_SearchNext(); break;
+    case CMD_REPLACE:     DIALOG_Replace(); break;
+    case CMD_GOTO:        DIALOG_GoTo(); break;
+
+    case CMD_WRAP: DIALOG_EditWrap(); break;
+    case CMD_FONT: DIALOG_SelectFont(); break;
+
+    case CMD_STATUSBAR: DIALOG_ViewStatusBar(); break;
+
+    case CMD_HELP_CONTENTS: DIALOG_HelpContents(); break;
+
+    case CMD_ABOUT:
+        DialogBox(GetModuleHandle(NULL),
+                  MAKEINTRESOURCE(IDD_ABOUTBOX),
+                  Globals.hMainWnd,
+                  AboutDialogProc);
+        break;
+
+    case CMD_HELP_ABOUT_NOTEPAD: DIALOG_HelpAboutNotepad(); break;
 
     default:
-    break;
+        break;
     }
-   return 0;
+    return 0;
 }
 
 /***********************************************************************
@@ -106,11 +108,17 @@ static int NOTEPAD_MenuCommand(WPARAM wParam)
  *           NOTEPAD_FindTextAt
  */
 
-static BOOL NOTEPAD_FindTextAt(FINDREPLACE *pFindReplace, LPCTSTR pszText, int iTextLength, DWORD dwPosition)
+static BOOL
+NOTEPAD_FindTextAt(FINDREPLACE *pFindReplace, LPCTSTR pszText, int iTextLength, DWORD dwPosition)
 {
     BOOL bMatches;
     size_t iTargetLength;
 
+    if ((!pFindReplace) || (!pszText))
+    {
+        return FALSE;
+    }
+
     iTargetLength = _tcslen(pFindReplace->lpstrFindWhat);
 
     /* Make proper comparison */
@@ -207,9 +215,9 @@ BOOL NOTEPAD_FindNext(FINDREPLACE *pFindReplace, BOOL bReplace, BOOL bShowAlert)
         /* Can't find target */
         if (bShowAlert)
         {
-            LoadString(Globals.hInstance, STRING_CANNOTFIND, szResource, SIZEOF(szResource));
-            _sntprintf(szText, SIZEOF(szText), szResource, pFindReplace->lpstrFindWhat);
-            LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, SIZEOF(szResource));
+            LoadString(Globals.hInstance, STRING_CANNOTFIND, szResource, ARRAY_SIZE(szResource));
+            _sntprintf(szText, ARRAY_SIZE(szText), szResource, pFindReplace->lpstrFindWhat);
+            LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, ARRAY_SIZE(szResource));
             MessageBox(Globals.hFindReplaceDlg, szText, szResource, MB_OK);
         }
         bSuccess = FALSE;
@@ -256,15 +264,18 @@ static VOID NOTEPAD_InitData(VOID)
     static const TCHAR txt_files[] = _T("*.txt");
     static const TCHAR all_files[] = _T("*.*");
 
-    p += LoadString(Globals.hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN)+1;
+    p += LoadString(Globals.hInstance, STRING_TEXT_FILES_TXT, p, MAX_STRING_LEN) + 1;
     _tcscpy(p, txt_files);
-    p += SIZEOF(txt_files);
+    p += ARRAY_SIZE(txt_files);
 
-    p += LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN)+1;
+    p += LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN) + 1;
     _tcscpy(p, all_files);
-    p += SIZEOF(all_files);
+    p += ARRAY_SIZE(all_files);
     *p = '\0';
     Globals.find.lpstrFindWhat = NULL;
+
+    Globals.hDevMode = NULL;
+    Globals.hDevNames = NULL;
 }
 
 /***********************************************************************
@@ -278,7 +289,7 @@ static VOID NOTEPAD_InitMenuPopup(HMENU menu, LPARAM index)
 
     CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP,
         MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
-    if ( !Globals.bWrapLongLines )
+    if (!Globals.bWrapLongLines)
     {
         CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_STATUSBAR,
             MF_BYCOMMAND | (Globals.bShowStatusBar ? MF_CHECKED : MF_UNCHECKED));
@@ -313,6 +324,11 @@ LRESULT CALLBACK EDIT_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 case VK_RIGHT:
                     DIALOG_StatusBarUpdateCaretPos();
                     break;
+                default:
+                {
+                    UpdateWindowCaption(FALSE);
+                    break;
+                }
             }
         }
         case WM_LBUTTONUP:
@@ -321,17 +337,19 @@ LRESULT CALLBACK EDIT_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
             break;
         }
     }
-    return CallWindowProc( (WNDPROC)Globals.EditProc, hWnd, msg, wParam, lParam);
+    return CallWindowProc( Globals.EditProc, hWnd, msg, wParam, lParam);
 }
 
 /***********************************************************************
  *
  *           NOTEPAD_WndProc
  */
-static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
-                               LPARAM lParam)
+static LRESULT
+WINAPI
+NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-    switch (msg) {
+    switch (msg)
+    {
 
     case WM_CREATE:
         Globals.hMenu = GetMenu(hWnd);
@@ -353,6 +371,10 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
         if (DoCloseFile()) {
             if (Globals.hFont)
                 DeleteObject(Globals.hFont);
+            if (Globals.hDevMode)
+                GlobalFree(Globals.hDevMode);
+            if (Globals.hDevNames)
+                GlobalFree(Globals.hDevNames);
             DestroyWindow(hWnd);
         }
         break;
@@ -365,14 +387,13 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
 
     case WM_DESTROY:
         SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)Globals.EditProc);
-        SaveSettings();
+        NOTEPAD_SaveSettingsToRegistry();
         PostQuitMessage(0);
         break;
 
     case WM_SIZE:
     {
-        if (Globals.bShowStatusBar == TRUE &&
-            Globals.bWrapLongLines == FALSE)
+        if (Globals.bShowStatusBar == TRUE && Globals.bWrapLongLines == FALSE)
         {
             RECT rcStatusBar;
             HDWP hdwp;
@@ -384,24 +405,45 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
             if (hdwp == NULL)
                 break;
 
-            hdwp = DeferWindowPos(hdwp, Globals.hEdit, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam) - (rcStatusBar.bottom - rcStatusBar.top), SWP_NOZORDER | SWP_NOMOVE);
+            hdwp = DeferWindowPos(hdwp,
+                                  Globals.hEdit,
+                                  NULL,
+                                  0,
+                                  0,
+                                  LOWORD(lParam),
+                                  HIWORD(lParam) - (rcStatusBar.bottom - rcStatusBar.top),
+                                  SWP_NOZORDER | SWP_NOMOVE);
+
             if (hdwp == NULL)
                 break;
 
-            hdwp = DeferWindowPos(hdwp, Globals.hStatusBar, NULL, 0, 0, LOWORD(lParam), LOWORD(wParam), SWP_NOZORDER);
+            hdwp = DeferWindowPos(hdwp,
+                                  Globals.hStatusBar,
+                                  NULL,
+                                  0,
+                                  0,
+                                  LOWORD(lParam),
+                                  LOWORD(wParam),
+                                  SWP_NOZORDER);
 
             if (hdwp != NULL)
                 EndDeferWindowPos(hdwp);
         }
         else
-            SetWindowPos(Globals.hEdit, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER | SWP_NOMOVE);
+            SetWindowPos(Globals.hEdit,
+                         NULL,
+                         0,
+                         0,
+                         LOWORD(lParam),
+                         HIWORD(lParam),
+                         SWP_NOZORDER | SWP_NOMOVE);
 
         break;
     }
 
-    // The entire client area is covered by edit control and by
-    // the status bar. So there is no need to erase main background.
-    // This resolves the horrible fliker effect during windows resizes.
+    /* The entire client area is covered by edit control and by
+     * the status bar. So there is no need to erase main background.
+     * This resolves the horrible flicker effect during windows resizes. */
     case WM_ERASEBKGND:
         return 1;
 
@@ -414,7 +456,7 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
         TCHAR szFileName[MAX_PATH];
         HDROP hDrop = (HDROP) wParam;
 
-        DragQueryFile(hDrop, 0, szFileName, SIZEOF(szFileName));
+        DragQueryFile(hDrop, 0, szFileName, ARRAY_SIZE(szFileName));
         DragFinish(hDrop);
         DoOpenFile(szFileName);
         break;
@@ -447,24 +489,14 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam,
 
 static int AlertFileDoesNotExist(LPCTSTR szFileName)
 {
-   int nResult;
-   TCHAR szMessage[MAX_STRING_LEN];
-   TCHAR szResource[MAX_STRING_LEN];
-
-   LoadString(Globals.hInstance, STRING_DOESNOTEXIST, szResource, SIZEOF(szResource));
-   wsprintf(szMessage, szResource, szFileName);
-
-   LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, SIZEOF(szResource));
-
-   nResult = MessageBox(Globals.hMainWnd, szMessage, szResource,
-                        MB_ICONEXCLAMATION | MB_YESNO);
-
-   return(nResult);
+    return DIALOG_StringMsgBox(Globals.hMainWnd, STRING_DOESNOTEXIST,
+                               szFileName,
+                               MB_ICONEXCLAMATION | MB_YESNO);
 }
 
 static BOOL HandleCommandLine(LPTSTR cmdline)
 {
-    int opt_print = 0;
+    BOOL opt_print = FALSE;
 
     while (*cmdline == _T(' ') || *cmdline == _T('-') || *cmdline == _T('/'))
     {
@@ -480,7 +512,7 @@ static BOOL HandleCommandLine(LPTSTR cmdline)
         {
             case 'p':
             case 'P':
-                opt_print = 1;
+                opt_print = TRUE;
                 break;
         }
     }
@@ -553,53 +585,57 @@ static BOOL HandleCommandLine(LPTSTR cmdline)
  */
 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prev, LPTSTR cmdline, int show)
 {
-    MSG         msg;
-    HACCEL      hAccel;
-    WNDCLASSEX  wndclass;
-    HMONITOR    monitor;
+    MSG msg;
+    HACCEL hAccel;
+    WNDCLASSEX wndclass;
+    HMONITOR monitor;
     MONITORINFO info;
-    INT         x, y;
+    INT x, y;
 
-    static const TCHAR className[] = _T("NPClass");
-    static const TCHAR winName[]   = _T("Notepad");
+    static const TCHAR className[] = _T("Notepad");
+    static const TCHAR winName[] = _T("Notepad");
 
     switch (GetUserDefaultUILanguage())
-  {
+    {
     case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
-      SetProcessDefaultLayout(LAYOUT_RTL);
-      break;
+        SetProcessDefaultLayout(LAYOUT_RTL);
+        break;
 
     default:
-      break;
-  }
+        break;
+    }
 
     UNREFERENCED_PARAMETER(prev);
 
-    aFINDMSGSTRING = (ATOM) RegisterWindowMessage(FINDMSGSTRING);
+    aFINDMSGSTRING = (ATOM)RegisterWindowMessage(FINDMSGSTRING);
 
     ZeroMemory(&Globals, sizeof(Globals));
-    Globals.hInstance       = hInstance;
-    LoadSettings();
+    Globals.hInstance = hInstance;
+    NOTEPAD_LoadSettingsFromRegistry();
 
     ZeroMemory(&wndclass, sizeof(wndclass));
-    wndclass.cbSize        = sizeof(wndclass);
-    wndclass.lpfnWndProc   = NOTEPAD_WndProc;
-    wndclass.hInstance     = Globals.hInstance;
-    wndclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NPICON));
-    wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
+    wndclass.cbSize = sizeof(wndclass);
+    wndclass.lpfnWndProc = NOTEPAD_WndProc;
+    wndclass.hInstance = Globals.hInstance;
+    wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_NPICON));
+    wndclass.hCursor = LoadCursor(0, IDC_ARROW);
     wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    wndclass.lpszMenuName  = MAKEINTRESOURCE(MAIN_MENU);
+    wndclass.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU);
     wndclass.lpszClassName = className;
-    wndclass.hIconSm       = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_NPICON),
-                            IMAGE_ICON, 16, 16, 0);
+    wndclass.hIconSm = (HICON)LoadImage(hInstance,
+                                        MAKEINTRESOURCE(IDI_NPICON),
+                                        IMAGE_ICON,
+                                        16,
+                                        16,
+                                        0);
 
     if (!RegisterClassEx(&wndclass)) return FALSE;
 
     /* Setup windows */
 
-    monitor = MonitorFromRect( &Globals.main_rect, MONITOR_DEFAULTTOPRIMARY );
+    monitor = MonitorFromRect(&Globals.main_rect, MONITOR_DEFAULTTOPRIMARY);
     info.cbSize = sizeof(info);
-    GetMonitorInfoW( monitor, &info );
+    GetMonitorInfoW(monitor, &info);
 
     x = Globals.main_rect.left;
     y = Globals.main_rect.top;
@@ -609,11 +645,17 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prev, LPTSTR cmdline, int sh
         Globals.main_rect.bottom < info.rcWork.top)
         x = y = CW_USEDEFAULT;
 
-    Globals.hMainWnd =
-        CreateWindow(className, winName, WS_OVERLAPPEDWINDOW,
-                     x, y, Globals.main_rect.right - Globals.main_rect.left,
-                     Globals.main_rect.bottom - Globals.main_rect.top,
-                     NULL, NULL, Globals.hInstance, NULL);
+    Globals.hMainWnd = CreateWindow(className,
+                                    winName,
+                                    WS_OVERLAPPEDWINDOW,
+                                    x,
+                                    y,
+                                    Globals.main_rect.right - Globals.main_rect.left,
+                                    Globals.main_rect.bottom - Globals.main_rect.top,
+                                    NULL,
+                                    NULL,
+                                    Globals.hInstance,
+                                    NULL);
     if (!Globals.hMainWnd)
     {
         ShowLastError();
@@ -636,7 +678,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prev, LPTSTR cmdline, int sh
         return 0;
     }
 
-    hAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE(ID_ACCEL) );
+    hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(ID_ACCEL));
 
     while (GetMessage(&msg, 0, 0, 0))
     {