[NOTEPAD]
[reactos.git] / reactos / base / applications / notepad / dialog.c
index 7dc02ce..1ac3019 100644 (file)
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <notepad.h>
 
+LRESULT CALLBACK EDIT_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
 static const TCHAR helpfile[]     = _T("notepad.hlp");
 static const TCHAR empty_str[]    = _T("");
 static const TCHAR szDefaultExt[] = _T("txt");
@@ -110,31 +112,27 @@ VOID ShowLastError(void)
 
 /**
  * Sets the caption of the main window according to Globals.szFileTitle:
- *    Notepad - (untitled)      if no file is open
- *    Notepad - [filename]      if a file is given
+ *    (untitled) - Notepad      if no file is open
+ *    [filename] - Notepad      if a file is given
  */
 static void UpdateWindowCaption(void)
 {
-  TCHAR szCaption[MAX_STRING_LEN];
-  TCHAR szUntitled[MAX_STRING_LEN];
+  TCHAR szCaption[MAX_STRING_LEN] = _T("");
+  TCHAR szNotepad[MAX_STRING_LEN];
 
-  LoadString(Globals.hInstance, STRING_NOTEPAD, szCaption, SIZEOF(szCaption));
+  LoadString(Globals.hInstance, STRING_NOTEPAD, szNotepad, SIZEOF(szNotepad));
 
-  if (Globals.szFileTitle[0] != '\0') {
-      static const TCHAR bracket_l[] = _T(" - [");
-      static const TCHAR bracket_r[] = _T("]");
-      _tcscat(szCaption, bracket_l);
-      _tcscat(szCaption, Globals.szFileTitle);
-      _tcscat(szCaption, bracket_r);
+  if (Globals.szFileTitle[0] != '\0')
+  {
+      StringCchCat(szCaption, MAX_STRING_LEN, Globals.szFileTitle);
   }
   else
   {
-      static const TCHAR hyphen[] = _T(" - ");
-      LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, SIZEOF(szUntitled));
-      _tcscat(szCaption, hyphen);
-      _tcscat(szCaption, szUntitled);
+      LoadString(Globals.hInstance, STRING_UNTITLED, szCaption, SIZEOF(szCaption));
   }
-
+  
+  StringCchCat(szCaption, MAX_STRING_LEN, _T(" - "));
+  StringCchCat(szCaption, MAX_STRING_LEN, szNotepad);
   SetWindowText(Globals.hMainWnd, szCaption);
 }
 
@@ -398,7 +396,6 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar
 {
     TCHAR szText[128];
     HWND hCombo;
-    OFNOTIFY *pNotify;
 
     UNREFERENCED_PARAMETER(wParam);
 
@@ -438,15 +435,13 @@ static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wPar
         case WM_NOTIFY:
             if (((NMHDR *) lParam)->code == CDN_FILEOK)
             {
-                pNotify = (OFNOTIFY *) lParam;
-
                 hCombo = GetDlgItem(hDlg, ID_ENCODING);
-                               if (hCombo)
-                       Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0);
+                if (hCombo)
+                    Globals.iEncoding = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0);
 
                 hCombo = GetDlgItem(hDlg, ID_EOLN);
-                               if (hCombo)
-                       Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0);
+                if (hCombo)
+                    Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0);
             }
             break;
     }
@@ -676,62 +671,189 @@ VOID DIALOG_EditTimeDate(VOID)
 {
     SYSTEMTIME   st;
     TCHAR        szDate[MAX_STRING_LEN];
-    static const TCHAR space[] = _T(" ");
+    TCHAR        szText[MAX_STRING_LEN * 2 + 2];
 
     GetLocalTime(&st);
 
     GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN);
-    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
+    _tcscpy(szText, szDate);
+    _tcscat(szText, _T(" "));
+    GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN);
+    _tcscat(szText, szDate);
+    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szText);
+}
 
-    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)space);
+VOID DoCreateStatusBar(VOID)
+{
+    RECT rc;
+    RECT rcstatus;
+    BOOL bStatusBarVisible;
 
-    GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN);
-    SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
+    // Check if status bar object already exists.
+    if (Globals.hStatusBar == NULL)
+    {
+        // Try to create the status bar
+        Globals.hStatusBar = CreateStatusWindow(
+                                WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE,
+                                NULL,
+                                Globals.hMainWnd,
+                                CMD_STATUSBAR_WND_ID);
+
+        if (Globals.hStatusBar == NULL)
+        {
+            ShowLastError();
+            return;
+        }
+
+        // Load the string for formatting column/row text output
+        LoadString(Globals.hInstance, STRING_LINE_COLUMN, Globals.szStatusBarLineCol, MAX_PATH-1);
+
+        // Set the status bar for single-text output
+        SendMessage(Globals.hStatusBar, SB_SIMPLE, (WPARAM)TRUE, (LPARAM)0);
+    }
+
+    // Set status bar visible or not accordind the the settings.
+    if (Globals.bWrapLongLines == TRUE ||
+        Globals.bShowStatusBar == FALSE)
+    {
+        bStatusBarVisible = FALSE;
+        ShowWindow(Globals.hStatusBar, SW_HIDE);
+    }
+    else
+    {
+        bStatusBarVisible = TRUE;
+        ShowWindow(Globals.hStatusBar, SW_SHOW);
+        SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0);
+    }
+
+    // Set check state in show status bar item.
+    if (Globals.bShowStatusBar == TRUE)
+    {
+        CheckMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_CHECKED);
+    }
+    else
+    {
+        CheckMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_UNCHECKED);
+    }
+
+    // Update menu mar with the previous changes
+    DrawMenuBar(Globals.hMainWnd);
+
+    // Sefety test is edit control exists
+    if (Globals.hEdit != NULL)
+    {
+        // Retrieve the sizes of the controls
+        GetClientRect(Globals.hMainWnd, &rc);
+        GetClientRect(Globals.hStatusBar, &rcstatus);
+
+        // If status bar is currently visible, update dimensions of edir control
+        if (bStatusBarVisible)
+            rc.bottom -= (rcstatus.bottom - rcstatus.top);
+
+        // Resize edit control to right size.
+        MoveWindow(Globals.hEdit, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
+    }
+
+    // Update content with current row/column text
+    DIALOG_StatusBarUpdateCaretPos();
 }
 
-VOID DIALOG_EditWrap(VOID)
+VOID DoCreateEditWindow(VOID)
 {
-    static const TCHAR edit[] = _T("edit");
-    DWORD dwStyle;
-    RECT rc, rcstatus;
-    DWORD size;
-    LPTSTR pTemp;
+    DWORD  dwStyle;
+    int    iSize;
+    LPTSTR pTemp = NULL;
 
-    Globals.bWrapLongLines = !Globals.bWrapLongLines;
+    iSize = 0;
 
-    size = GetWindowTextLength(Globals.hEdit) + 1;
-    pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
-    if (!pTemp)
+    // If the edit control already exists, try to save its content
+    if (Globals.hEdit != NULL)
+    {
+        // number of chars currently written into the editor.
+        iSize = GetWindowTextLength(Globals.hEdit);
+
+        if (iSize)
+        {
+            // Allocates temporary buffer.
+            pTemp = HeapAlloc(GetProcessHeap(), 0, (iSize + 1) * sizeof(TCHAR));
+
+            if (!pTemp)
+            {
+                ShowLastError();
+                return;
+            }
+
+            // Recover the text into the control.
+            GetWindowText(Globals.hEdit, pTemp, iSize + 1);
+        }
+
+        // Restore original window procedure
+        SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)Globals.EditProc);
+
+        // Destroy the edit control
+        DestroyWindow(Globals.hEdit);
+    }
+
+    // Update wrap status into the main menu and recover style flags
+    if (Globals.bWrapLongLines)
+    {
+        dwStyle = EDIT_STYLE_WRAP;
+        EnableMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
+    } else {
+        dwStyle = EDIT_STYLE;
+        EnableMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_ENABLED);
+    }
+
+    // Update previous changes
+    DrawMenuBar(Globals.hMainWnd);
+
+    // Create the new edit control
+    Globals.hEdit = CreateWindowEx(
+                        WS_EX_CLIENTEDGE,
+                        EDIT_CLASS,
+                        NULL,
+                        dwStyle,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        CW_USEDEFAULT,
+                        Globals.hMainWnd,
+                        NULL,
+                        Globals.hInstance,
+                        NULL);
+
+    if (Globals.hEdit == NULL)
     {
         ShowLastError();
         return;
     }
-    GetWindowText(Globals.hEdit, pTemp, size);
-    DestroyWindow(Globals.hEdit);
-    GetClientRect(Globals.hMainWnd, &rc);
-    dwStyle = Globals.bWrapLongLines ? EDIT_STYLE_WRAP : EDIT_STYLE;
-    EnableMenuItem(GetMenu(Globals.hMainWnd), CMD_STATUSBAR,
-        MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
-    if ( Globals.hStatusBar )
+
+    SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, FALSE);
+    SendMessage(Globals.hEdit, EM_LIMITTEXT, 0, 0);
+
+    // If some text was previously saved, restore it.
+    if (iSize != 0)
     {
-       if ( Globals.bWrapLongLines )
-          ShowWindow(Globals.hStatusBar, SW_HIDE);
-       else if ( Globals.bShowStatusBar )
-       {
-          GetClientRect(Globals.hStatusBar, &rcstatus);
-          rc.bottom -= (rcstatus.bottom - rcstatus.top);
-          ShowWindow(Globals.hStatusBar, SW_SHOW);
-       }
+        SetWindowText(Globals.hEdit, pTemp);
+        HeapFree(GetProcessHeap(), 0, pTemp);
     }
-    Globals.hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, edit, NULL, dwStyle,
-                         0, 0, rc.right, rc.bottom, Globals.hMainWnd,
-                         NULL, Globals.hInstance, NULL);
-    SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)FALSE);
-    SendMessage(Globals.hEdit, EM_LIMITTEXT, 0, 0);
-    SetWindowText(Globals.hEdit, pTemp);
+
+    // Sub-class a new window callback for row/column detection.
+    Globals.EditProc = (WNDPROC) SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)EDIT_WndProc);
+
+    // Create/update status bar
+    DoCreateStatusBar();
+
+    // Finally shows new edit control and set focus into it.
+    ShowWindow(Globals.hEdit, SW_SHOW);
     SetFocus(Globals.hEdit);
-    HeapFree(GetProcessHeap(), 0, pTemp);
-    DrawMenuBar(Globals.hMainWnd);
+}
+
+VOID DIALOG_EditWrap(VOID)
+{
+    Globals.bWrapLongLines = !Globals.bWrapLongLines;
+
+    DoCreateEditWindow();
 }
 
 VOID DIALOG_SelectFont(VOID)
@@ -803,11 +925,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA
     TCHAR szText[32];
 
     switch(uMsg) {
-       case WM_INITDIALOG:
+    case WM_INITDIALOG:
         hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER);
-               _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam);
+        _sntprintf(szText, SIZEOF(szText), _T("%d"), lParam);
         SetWindowText(hTextBox, szText);
-               break;
+        break;
     case WM_COMMAND:
         if (HIWORD(wParam) == BN_CLICKED)
         {
@@ -818,11 +940,11 @@ static INT_PTR CALLBACK DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARA
                 EndDialog(hwndDialog, _ttoi(szText));
                 bResult = TRUE;
             }
-                       else if (LOWORD(wParam) == IDCANCEL)
-                       {
+            else if (LOWORD(wParam) == IDCANCEL)
+            {
                 EndDialog(hwndDialog, 0);
                 bResult = TRUE;
-                       }
+            }
         }
         break;
     }
@@ -857,7 +979,7 @@ VOID DIALOG_GoTo(VOID)
         Globals.hMainWnd, DIALOG_GoTo_DialogProc, nLine);
 
     if (nLine >= 1)
-       {
+    {
         for (i = 0; pszText[i] && (nLine > 1) && (i < nLength - 1); i++)
         {
             if (pszText[i] == '\n')
@@ -865,8 +987,8 @@ VOID DIALOG_GoTo(VOID)
         }
         SendMessage(Globals.hEdit, EM_SETSEL, i, i);
         SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0);
-       }
-       HeapFree(GetProcessHeap(), 0, pszText);
+    }
+    HeapFree(GetProcessHeap(), 0, pszText);
 }
 
 VOID DIALOG_StatusBarUpdateCaretPos(VOID)
@@ -880,32 +1002,14 @@ VOID DIALOG_StatusBarUpdateCaretPos(VOID)
     col  = dwStart - SendMessage(Globals.hEdit, EM_LINEINDEX, (WPARAM)line, 0);
 
     _stprintf(buff, Globals.szStatusBarLineCol, line+1, col+1);
-    SendMessage(Globals.hStatusBar, SB_SETTEXT, (WPARAM) SB_SIMPLEID, (LPARAM)buff);
+    SendMessage(Globals.hStatusBar, SB_SETTEXT, SB_SIMPLEID, (LPARAM)buff);
 }
 
 VOID DIALOG_ViewStatusBar(VOID)
 {
-   RECT rc;
-   RECT rcstatus;
-
-   Globals.bShowStatusBar = !Globals.bShowStatusBar;
-   if ( !Globals.hStatusBar )
-   {
-       Globals.hStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE, TEXT("test"), Globals.hMainWnd, CMD_STATUSBAR_WND_ID );
-       LoadString(Globals.hInstance, STRING_LINE_COLUMN, Globals.szStatusBarLineCol, MAX_PATH-1);
-       SendMessage(Globals.hStatusBar, SB_SIMPLE, (WPARAM)TRUE, (LPARAM)0);
-   }
-    CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_STATUSBAR,
-        MF_BYCOMMAND | (Globals.bShowStatusBar ? MF_CHECKED : MF_UNCHECKED));
-    DrawMenuBar(Globals.hMainWnd);
-    GetClientRect(Globals.hMainWnd, &rc);
-    GetClientRect(Globals.hStatusBar, &rcstatus);
-    if ( Globals.bShowStatusBar )
-        rc.bottom -= (rcstatus.bottom - rcstatus.top);
+    Globals.bShowStatusBar = !Globals.bShowStatusBar;
 
-    MoveWindow(Globals.hEdit, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
-    ShowWindow(Globals.hStatusBar, Globals.bShowStatusBar);
-    DIALOG_StatusBarUpdateCaretPos();
+    DoCreateStatusBar();
 }
 
 VOID DIALOG_HelpContents(VOID)
@@ -964,11 +1068,12 @@ AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
 VOID DIALOG_HelpAboutWine(VOID)
 {
-    static const TCHAR notepad[] = _T("Notepad\n");
     TCHAR szNotepad[MAX_STRING_LEN];
+    HICON notepadIcon = LoadIcon(Globals.hInstance, MAKEINTRESOURCE(IDI_NPICON));
 
     LoadString(Globals.hInstance, STRING_NOTEPAD, szNotepad, SIZEOF(szNotepad));
-    ShellAbout(Globals.hMainWnd, szNotepad, notepad, 0);
+    ShellAbout(Globals.hMainWnd, szNotepad, 0, notepadIcon);
+    DeleteObject(notepadIcon);
 }