Index: dialog.c =================================================================== --- dialog.c (revision 48906) +++ dialog.c (working copy) @@ -687,55 +687,179 @@ SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate); } -VOID DIALOG_EditWrap(VOID) +VOID DoCreateStatusBar(VOID) { - static const TCHAR edit[] = _T("edit"); - DWORD dwStyle; - RECT rc, rcstatus; - DWORD size; + RECT rc; + RECT rcstatus; + BOOL bStatusBarVisible; + + // 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 DoCreateEditWindow(VOID) +{ + DWORD dwStyle; + int iSize; LPTSTR pTemp; - TCHAR buff[MAX_PATH]; - 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, 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); - Globals.EditProc = (WNDPROC) SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)EDIT_WndProc); - _stprintf(buff, Globals.szStatusBarLineCol, 1, 1); - SendMessage(Globals.hStatusBar, SB_SETTEXT, SB_SIMPLEID, (LPARAM)buff); - HeapFree(GetProcessHeap(), 0, pTemp); - DrawMenuBar(Globals.hMainWnd); } +VOID DIALOG_EditWrap(VOID) +{ + Globals.bWrapLongLines = !Globals.bWrapLongLines; + + DoCreateEditWindow(); +} + VOID DIALOG_SelectFont(VOID) { CHOOSEFONT cf; @@ -887,27 +1011,9 @@ VOID DIALOG_ViewStatusBar(VOID) { - RECT rc; - RECT rcstatus; + Globals.bShowStatusBar = !Globals.bShowStatusBar; - 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); - - 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) Index: dialog.h =================================================================== --- dialog.h (revision 48906) +++ dialog.h (working copy) @@ -63,3 +63,5 @@ BOOL HasFileExtension(LPCTSTR szFilename); BOOL DoCloseFile(void); void DoOpenFile(LPCTSTR szFileName); +VOID DoCreateStatusBar(VOID); +VOID DoCreateEditWindow(VOID); Index: main.c =================================================================== --- main.c (revision 48906) +++ main.c (working copy) @@ -29,9 +29,9 @@ VOID NOTEPAD_EnableSearchMenu() { - EnableMenuItem(GetMenu(Globals.hMainWnd), CMD_SEARCH, + EnableMenuItem(Globals.hMenu, CMD_SEARCH, MF_BYCOMMAND | ((GetWindowTextLength(Globals.hEdit) == 0) ? MF_DISABLED | MF_GRAYED : MF_ENABLED)); - EnableMenuItem(GetMenu(Globals.hMainWnd), CMD_SEARCH_NEXT, + EnableMenuItem(Globals.hMenu, CMD_SEARCH_NEXT, MF_BYCOMMAND | ((GetWindowTextLength(Globals.hEdit) == 0) ? MF_DISABLED | MF_GRAYED : MF_ENABLED)); } @@ -334,23 +334,8 @@ switch (msg) { case WM_CREATE: - { - static const TCHAR edit[] = _T("edit"); - RECT rc; - GetClientRect(hWnd, &rc); - Globals.hEdit = CreateWindowEx(EDIT_EXSTYLE, edit, NULL, Globals.bWrapLongLines ? EDIT_STYLE_WRAP : EDIT_STYLE, - 0, 0, rc.right, rc.bottom, hWnd, - NULL, Globals.hInstance, NULL); - if (!Globals.hEdit) - return -1; - SendMessage(Globals.hEdit, EM_LIMITTEXT, 0, 0); - if (Globals.hFont) - SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)TRUE); - - Globals.EditProc = (WNDPROC) SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)EDIT_WndProc); - + Globals.hMenu = GetMenu(hWnd); break; - } case WM_COMMAND: if (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == EN_HSCROLL || HIWORD(wParam) == EN_VSCROLL) @@ -386,7 +371,8 @@ case WM_SIZE: { - if (Globals.bShowStatusBar) + if (Globals.bShowStatusBar == TRUE && + Globals.bWrapLongLines == FALSE) { RECT rcStatusBar; HDWP hdwp; @@ -413,6 +399,12 @@ 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. + case WM_ERASEBKGND: + return 1; + case WM_SETFOCUS: SetFocus(Globals.hEdit); break; @@ -613,6 +605,8 @@ ExitProcess(1); } + DoCreateEditWindow(); + NOTEPAD_InitData(); DIALOG_FileNew(); Index: main.h =================================================================== --- main.h (revision 48906) +++ main.h (working copy) @@ -23,11 +23,12 @@ #include "notepad_res.h" -#define EDIT_STYLE_WRAP (WS_CHILD | WS_VISIBLE | WS_VSCROLL \ +#define EDIT_STYLE_WRAP (WS_CHILD | WS_VSCROLL \ | ES_AUTOVSCROLL | ES_MULTILINE | ES_NOHIDESEL) #define EDIT_STYLE (EDIT_STYLE_WRAP | WS_HSCROLL | ES_AUTOHSCROLL) -#define EDIT_EXSTYLE (WS_EX_CLIENTEDGE) +#define EDIT_CLASS _T("EDIT") + #define MAX_STRING_LEN 255 #define ENCODING_ANSI 0 @@ -47,6 +48,7 @@ HWND hEdit; HWND hStatusBar; HFONT hFont; /* Font used by the edit control */ + HMENU hMenu; LOGFONT lfFont; BOOL bWrapLongLines; BOOL bShowStatusBar;