Added a status bar to track line and column number Added a goto line dialog
-- v6: Track and display line number and column.
From: Jacob Czekalla jacobczekalla@gmail.com
--- programs/notepad/dialog.c | 1 + programs/notepad/main.c | 42 ++++++++++++++++++++++++++++++++-- programs/notepad/main.h | 3 +++ programs/notepad/notepad.rc | 4 ++++ programs/notepad/notepad_res.h | 1 + 5 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/programs/notepad/dialog.c b/programs/notepad/dialog.c index 94301b82bd3..cf83d29521f 100644 --- a/programs/notepad/dialog.c +++ b/programs/notepad/dialog.c @@ -1107,6 +1107,7 @@ VOID DIALOG_EditWrap(VOID) Globals.bWrapLongLines = !Globals.bWrapLongLines; CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP, MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED)); + updateWindowSize(MAKELPARAM(rc.right,rc.bottom)); }
VOID DIALOG_SelectFont(VOID) diff --git a/programs/notepad/main.c b/programs/notepad/main.c index b1cdad8156d..f243ac0c775 100644 --- a/programs/notepad/main.c +++ b/programs/notepad/main.c @@ -63,6 +63,7 @@ static const WCHAR value_iMarginLeft[] = {'i','M','a','r','g','i','n','L',' static const WCHAR value_iMarginRight[] = {'i','M','a','r','g','i','n','R','i','g','h','t','\0'}; static const WCHAR value_szHeader[] = {'s','z','H','e','a','d','e','r','\0'}; static const WCHAR value_szFooter[] = {'s','z','T','r','a','i','l','e','r','\0'}; +static const WCHAR value_bStatusBar[] = {'b','S','t','a','t','u','s','B','a','r','\0'};
/*********************************************************************** * @@ -107,6 +108,34 @@ DWORD get_dpi(void) return dpi; }
+static void ToggleStatusBar(void) +{ + RECT rc; + + Globals.bStatusBar = !Globals.bStatusBar; + CheckMenuItem(GetMenu(Globals.hMainWnd),CMD_SBAR, + MF_BYCOMMAND | (Globals.bStatusBar ? MF_CHECKED : MF_UNCHECKED)); + GetClientRect(Globals.hMainWnd, &rc); + ShowWindow(Globals.hStatusBar,Globals.bStatusBar); + updateWindowSize(MAKELPARAM(rc.right,rc.bottom)); +} + +void updateWindowSize(DWORD WidthHeight) +{ + int StatusBarHeight = 0; + + if(Globals.bStatusBar) + { + RECT SBarRect; + + SendMessageW(Globals.hStatusBar,WM_SIZE, 0, 0); + GetWindowRect(Globals.hStatusBar, &SBarRect); + StatusBarHeight = (SBarRect.bottom-SBarRect.top); + } + SetWindowPos(Globals.hEdit, NULL, 0, 0, LOWORD(WidthHeight), HIWORD(WidthHeight) - StatusBarHeight, + SWP_NOOWNERZORDER | SWP_NOZORDER); +} + /*********************************************************************** * * NOTEPAD_SaveSettingToRegistry @@ -149,6 +178,7 @@ static VOID NOTEPAD_SaveSettingToRegistry(void) SET_NOTEPAD_REG(hkey, value_iMarginBottom, Globals.iMarginBottom); SET_NOTEPAD_REG(hkey, value_iMarginLeft, Globals.iMarginLeft); SET_NOTEPAD_REG(hkey, value_iMarginRight, Globals.iMarginRight); + SET_NOTEPAD_REG(hkey, value_bStatusBar, Globals.bStatusBar); #undef SET_NOTEPAD_REG
/* Store the current value as 10 * twips */ @@ -192,6 +222,7 @@ static VOID NOTEPAD_LoadSettingFromRegistry(void) Globals.iMarginBottom = 2500; Globals.iMarginLeft = 2000; Globals.iMarginRight = 2000; + Globals.bStatusBar = TRUE;
Globals.lfFont.lfHeight = -12; Globals.lfFont.lfWidth = 0; @@ -240,6 +271,7 @@ static VOID NOTEPAD_LoadSettingFromRegistry(void) QUERY_NOTEPAD_REG(hkey, value_iMarginBottom, Globals.iMarginBottom); QUERY_NOTEPAD_REG(hkey, value_iMarginLeft, Globals.iMarginLeft); QUERY_NOTEPAD_REG(hkey, value_iMarginRight, Globals.iMarginRight); + QUERY_NOTEPAD_REG(hkey, value_bStatusBar, Globals.bStatusBar); #undef QUERY_NOTEPAD_REG
main_rect.right = main_rect.left + dx; @@ -302,6 +334,7 @@ static int NOTEPAD_MenuCommand(WPARAM wParam)
case CMD_WRAP: DIALOG_EditWrap(); break; case CMD_FONT: DIALOG_SelectFont(); break; + case CMD_SBAR: ToggleStatusBar(); break;
case CMD_HELP_CONTENTS: DIALOG_HelpContents(); break; case CMD_HELP_ABOUT_NOTEPAD: DIALOG_HelpAboutNotepad(); break; @@ -335,6 +368,9 @@ static VOID NOTEPAD_InitData(VOID)
CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP, MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(GetMenu(Globals.hMainWnd),CMD_SBAR, + MF_BYCOMMAND | (Globals.bStatusBar ? MF_CHECKED : MF_UNCHECKED)); + ShowWindow(Globals.hStatusBar,Globals.bStatusBar); }
/*********************************************************************** @@ -542,6 +578,9 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, Globals.hFont = CreateFontIndirectW(&Globals.lfFont); SendMessageW(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, FALSE); SendMessageW(Globals.hEdit, EM_LIMITTEXT, 0, 0); + Globals.hStatusBar = CreateWindowExW(0, STATUSCLASSNAMEW,NULL, + WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, hWnd, NULL, + Globals.hInstance, NULL); break; }
@@ -572,8 +611,7 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, break;
case WM_SIZE: - SetWindowPos(Globals.hEdit, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), - SWP_NOOWNERZORDER | SWP_NOZORDER); + updateWindowSize(lParam); break;
case WM_SETFOCUS: diff --git a/programs/notepad/main.h b/programs/notepad/main.h index e0efef0c080..330af03fb6e 100644 --- a/programs/notepad/main.h +++ b/programs/notepad/main.h @@ -43,6 +43,8 @@ typedef struct HWND hFindReplaceDlg; HWND hEdit; HFONT hFont; /* Font used by the edit control */ + HWND hStatusBar; + INT bStatusBar; LOGFONTW lfFont; BOOL bWrapLongLines; WCHAR szFindText[MAX_PATH]; @@ -71,3 +73,4 @@ extern NOTEPAD_GLOBALS Globals; VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc); void NOTEPAD_DoFind(FINDREPLACEW *fr); DWORD get_dpi(void); +void updateWindowSize(DWORD WidthHeight); diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc index 6fc12dcf5cd..60cd03d9c0e 100644 --- a/programs/notepad/notepad.rc +++ b/programs/notepad/notepad.rc @@ -56,6 +56,10 @@ POPUP "&Search" { MENUITEM "&Search next\tF3", CMD_SEARCH_NEXT MENUITEM "&Replace...\tCtrl+H", CMD_REPLACE } +POPUP "&View" +{ + MENUITEM "&Status Bar", CMD_SBAR +} POPUP "&Help" { MENUITEM "&Contents\tF1", CMD_HELP_CONTENTS MENUITEM "&About Notepad", CMD_HELP_ABOUT_NOTEPAD diff --git a/programs/notepad/notepad_res.h b/programs/notepad/notepad_res.h index 4fed2f8a3cf..bd994d9eede 100644 --- a/programs/notepad/notepad_res.h +++ b/programs/notepad/notepad_res.h @@ -52,6 +52,7 @@
#define CMD_WRAP 0x119 #define CMD_FONT 0x140 +#define CMD_SBAR 0x205
#define CMD_HELP_CONTENTS 0x130 #define CMD_HELP_ABOUT_NOTEPAD 0x134
From: Jacob Czekalla jacobczekalla@gmail.com
--- programs/notepad/main.c | 51 ++++++++++++++++++++++++++++++++++ programs/notepad/main.h | 3 ++ programs/notepad/notepad.rc | 2 ++ programs/notepad/notepad_res.h | 2 ++ 4 files changed, 58 insertions(+)
diff --git a/programs/notepad/main.c b/programs/notepad/main.c index f243ac0c775..3526f68b49e 100644 --- a/programs/notepad/main.c +++ b/programs/notepad/main.c @@ -108,6 +108,29 @@ DWORD get_dpi(void) return dpi; }
+void UpdateStatusBar(void) +{ + int currentLine; + int currentCol = -1; + wchar_t statusTxt[25]; + int lineIndex; + DWORD selStart; + DWORD selEnd; + + SendMessageW(Globals.hEdit,EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd); + if(selStart == selEnd) + Globals.trackedSel = selStart; + if(selStart < Globals.trackedSel) + currentCol = selStart; + else + currentCol = selEnd; + currentLine = SendMessageW(Globals.hEdit, EM_LINEFROMCHAR, currentCol,0); + lineIndex = SendMessageW(Globals.hEdit, EM_LINEINDEX, currentLine,0); + + swprintf(statusTxt, 25, Globals.szStatusString,currentLine+1, (currentCol+1) - lineIndex); + SendMessageW(Globals.hStatusBar, SB_SETTEXTW, 0, (LPARAM)statusTxt); +} + static void ToggleStatusBar(void) { RECT rc; @@ -118,6 +141,7 @@ static void ToggleStatusBar(void) GetClientRect(Globals.hMainWnd, &rc); ShowWindow(Globals.hStatusBar,Globals.bStatusBar); updateWindowSize(MAKELPARAM(rc.right,rc.bottom)); + UpdateStatusBar(); }
void updateWindowSize(DWORD WidthHeight) @@ -528,6 +552,29 @@ static void NOTEPAD_DoReplaceAll(FINDREPLACEW *fr) } }
+LRESULT CALLBACK EDIT_CallBackProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + UpdateStatusBar(); + break; + case WM_MOUSEMOVE: + if(wParam == MK_LBUTTON) + UpdateStatusBar(); + break; + + default: + break; + } + return DefSubclassProc(hWnd, msg, wParam, lParam); +} + /*********************************************************************** * * NOTEPAD_WndProc @@ -575,12 +622,16 @@ static LRESULT WINAPI NOTEPAD_WndProc(HWND hWnd, UINT msg, WPARAM wParam, dwStyle, 0, 0, rc.right, rc.bottom, hWnd, NULL, Globals.hInstance, NULL);
+ SetWindowSubclass(Globals.hEdit, (SUBCLASSPROC)&EDIT_CallBackProc, 0, 0); Globals.hFont = CreateFontIndirectW(&Globals.lfFont); SendMessageW(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, FALSE); SendMessageW(Globals.hEdit, EM_LIMITTEXT, 0, 0); Globals.hStatusBar = CreateWindowExW(0, STATUSCLASSNAMEW,NULL, WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, hWnd, NULL, Globals.hInstance, NULL); + + LoadStringW(Globals.hInstance, STRING_STATUSBAR, (LPWSTR)&Globals.szStatusString, 0); + UpdateStatusBar(); break; }
diff --git a/programs/notepad/main.h b/programs/notepad/main.h index 330af03fb6e..bd8980a9dcc 100644 --- a/programs/notepad/main.h +++ b/programs/notepad/main.h @@ -45,6 +45,7 @@ typedef struct HFONT hFont; /* Font used by the edit control */ HWND hStatusBar; INT bStatusBar; + WCHAR* szStatusString; LOGFONTW lfFont; BOOL bWrapLongLines; WCHAR szFindText[MAX_PATH]; @@ -61,6 +62,7 @@ typedef struct INT iMarginRight; WCHAR szHeader[MAX_PATH]; WCHAR szFooter[MAX_PATH]; + INT trackedSel;
FINDREPLACEW find; FINDREPLACEW lastFind; @@ -73,4 +75,5 @@ extern NOTEPAD_GLOBALS Globals; VOID SetFileNameAndEncoding(LPCWSTR szFileName, ENCODING enc); void NOTEPAD_DoFind(FINDREPLACEW *fr); DWORD get_dpi(void); +void UpdateStatusBar(void); void updateWindowSize(DWORD WidthHeight); diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc index 60cd03d9c0e..20257164e33 100644 --- a/programs/notepad/notepad.rc +++ b/programs/notepad/notepad.rc @@ -89,6 +89,8 @@ STRING_UNICODE_LE, "Unicode (UTF-16)" STRING_UNICODE_BE, "Unicode (UTF-16 big-endian)" STRING_UTF8, "Unicode (UTF-8)"
+STRING_STATUSBAR, "Ln %ld, Col %ld" + STRING_LOSS_OF_UNICODE_CHARACTERS, "%1\n\ This file contains Unicode characters which will be lost if\n\ you save this file in the %2 encoding.\n\ diff --git a/programs/notepad/notepad_res.h b/programs/notepad/notepad_res.h index bd994d9eede..e84224384ee 100644 --- a/programs/notepad/notepad_res.h +++ b/programs/notepad/notepad_res.h @@ -83,6 +83,8 @@ #define STRING_UNICODE_BE 0x181 #define STRING_UTF8 0x182
+#define STRING_STATUSBAR 0x206 + #define STRING_LOSS_OF_UNICODE_CHARACTERS 0x183
/* Open/Save As dialog template */
Huw Davies (@huw) commented about programs/notepad/dialog.c:
Globals.bWrapLongLines = !Globals.bWrapLongLines; CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP, MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
- updateWindowSize(MAKELPARAM(rc.right,rc.bottom));
I think it would make more sense to pass the width and height as separate paramaters.
Also, as mentioned last time, please add a space after the comma. There are more of these below as well, I won't point them all out.
Huw Davies (@huw) commented about programs/notepad/main.c:
return dpi;
}
+static void ToggleStatusBar(void) +{
- RECT rc;
- Globals.bStatusBar = !Globals.bStatusBar;
- CheckMenuItem(GetMenu(Globals.hMainWnd),CMD_SBAR,
MF_BYCOMMAND | (Globals.bStatusBar ? MF_CHECKED : MF_UNCHECKED));
- GetClientRect(Globals.hMainWnd, &rc);
- ShowWindow(Globals.hStatusBar,Globals.bStatusBar);
- updateWindowSize(MAKELPARAM(rc.right,rc.bottom));
+}
More spaces needed after commas throughout this function.
Huw Davies (@huw) commented about programs/notepad/main.c:
- GetClientRect(Globals.hMainWnd, &rc);
- ShowWindow(Globals.hStatusBar,Globals.bStatusBar);
- updateWindowSize(MAKELPARAM(rc.right,rc.bottom));
+}
+void updateWindowSize(DWORD WidthHeight) +{
- int StatusBarHeight = 0;
- if(Globals.bStatusBar)
- {
RECT SBarRect;
SendMessageW(Globals.hStatusBar,WM_SIZE, 0, 0);
GetWindowRect(Globals.hStatusBar, &SBarRect);
StatusBarHeight = (SBarRect.bottom-SBarRect.top);
Add a space either side of the '-'.
Huw Davies (@huw) commented about programs/notepad/main.c:
return dpi;
}
+void UpdateStatusBar(void) +{
- int currentLine;
- int currentCol = -1;
- wchar_t statusTxt[25];
This size is possibly going to be too small if the string is translated to a longer one - 256 would be a good choice. Also, let's use `WCHAR` rather than `wchar_t`.
Huw Davies (@huw) commented about programs/notepad/main.c:
return dpi;
}
+void UpdateStatusBar(void) +{
- int currentLine;
- int currentCol = -1;
- wchar_t statusTxt[25];
- int lineIndex;
- DWORD selStart;
- DWORD selEnd;
- SendMessageW(Globals.hEdit,EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
Again, add space after commas (more of which below which I won't point out).
Huw Davies (@huw) commented about programs/notepad/main.c:
- wchar_t statusTxt[25];
- int lineIndex;
- DWORD selStart;
- DWORD selEnd;
- SendMessageW(Globals.hEdit,EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
- if(selStart == selEnd)
Globals.trackedSel = selStart;
- if(selStart < Globals.trackedSel)
currentCol = selStart;
- else
currentCol = selEnd;
- currentLine = SendMessageW(Globals.hEdit, EM_LINEFROMCHAR, currentCol,0);
- lineIndex = SendMessageW(Globals.hEdit, EM_LINEINDEX, currentLine,0);
- swprintf(statusTxt, 25, Globals.szStatusString,currentLine+1, (currentCol+1) - lineIndex);
Use `ARRAY_SIZE(statusTxt)` instead of hardcoding the size here. Add spaces either side of the '+'s (and after the commas).
I think that the final arg would be clearer if written as `(currentCol - lineIndex) + 1` (basically compute the column index as zero-based first of all, then add the one to make it ones-based).
Huw Davies (@huw) commented about programs/notepad/main.c:
dwStyle, 0, 0, rc.right, rc.bottom, hWnd, NULL, Globals.hInstance, NULL);
SetWindowSubclass(Globals.hEdit, (SUBCLASSPROC)&EDIT_CallBackProc, 0, 0);
You shouldn't need the ampersand in front of `EDIT_CallBackProc` - the identifier on its own refers to the function's address.
Note that after this second commit, the executable fails to start on Windows. That's something which we'd want to fix.