4 * Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
5 * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
6 * Copyright 2002 Andriy Palamarchuk
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 LRESULT CALLBACK
EDIT_WndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
31 static const TCHAR helpfile
[] = _T("notepad.hlp");
32 static const TCHAR empty_str
[] = _T("");
33 static const TCHAR szDefaultExt
[] = _T("txt");
34 static const TCHAR txt_files
[] = _T("*.txt");
36 static UINT_PTR CALLBACK
DIALOG_PAGESETUP_Hook(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
38 VOID
ShowLastError(VOID
)
40 DWORD error
= GetLastError();
41 if (error
!= NO_ERROR
)
43 LPTSTR lpMsgBuf
= NULL
;
44 TCHAR szTitle
[MAX_STRING_LEN
];
46 LoadString(Globals
.hInstance
, STRING_ERROR
, szTitle
, ARRAY_SIZE(szTitle
));
48 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
56 MessageBox(NULL
, lpMsgBuf
, szTitle
, MB_OK
| MB_ICONERROR
);
62 * Sets the caption of the main window according to Globals.szFileTitle:
63 * (untitled) - Notepad if no file is open
64 * [filename] - Notepad if a file is given
66 static void UpdateWindowCaption(void)
68 TCHAR szCaption
[MAX_STRING_LEN
];
69 TCHAR szNotepad
[MAX_STRING_LEN
];
71 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szNotepad
, ARRAY_SIZE(szNotepad
));
73 if (Globals
.szFileTitle
[0] != 0)
75 StringCchCopy(szCaption
, ARRAY_SIZE(szCaption
), Globals
.szFileTitle
);
79 LoadString(Globals
.hInstance
, STRING_UNTITLED
, szCaption
, ARRAY_SIZE(szCaption
));
82 StringCchCat(szCaption
, ARRAY_SIZE(szCaption
), _T(" - "));
83 StringCchCat(szCaption
, ARRAY_SIZE(szCaption
), szNotepad
);
84 SetWindowText(Globals
.hMainWnd
, szCaption
);
87 int DIALOG_StringMsgBox(HWND hParent
, int formatId
, LPCTSTR szString
, DWORD dwFlags
)
89 TCHAR szMessage
[MAX_STRING_LEN
];
90 TCHAR szResource
[MAX_STRING_LEN
];
92 /* Load and format szMessage */
93 LoadString(Globals
.hInstance
, formatId
, szResource
, ARRAY_SIZE(szResource
));
94 _sntprintf(szMessage
, ARRAY_SIZE(szMessage
), szResource
, szString
);
97 if ((dwFlags
& MB_ICONMASK
) == MB_ICONEXCLAMATION
)
98 LoadString(Globals
.hInstance
, STRING_ERROR
, szResource
, ARRAY_SIZE(szResource
));
100 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szResource
, ARRAY_SIZE(szResource
));
102 /* Display Modal Dialog */
103 // if (hParent == NULL)
104 // hParent = Globals.hMainWnd;
105 return MessageBox(hParent
, szMessage
, szResource
, dwFlags
);
108 static void AlertFileNotFound(LPCTSTR szFileName
)
110 DIALOG_StringMsgBox(Globals
.hMainWnd
, STRING_NOTFOUND
, szFileName
, MB_ICONEXCLAMATION
| MB_OK
);
113 static int AlertFileNotSaved(LPCTSTR szFileName
)
115 TCHAR szUntitled
[MAX_STRING_LEN
];
117 LoadString(Globals
.hInstance
, STRING_UNTITLED
, szUntitled
, ARRAY_SIZE(szUntitled
));
119 return DIALOG_StringMsgBox(Globals
.hMainWnd
, STRING_NOTSAVED
,
120 szFileName
[0] ? szFileName
: szUntitled
,
121 MB_ICONQUESTION
| MB_YESNOCANCEL
);
124 static void AlertPrintError(void)
126 TCHAR szUntitled
[MAX_STRING_LEN
];
128 LoadString(Globals
.hInstance
, STRING_UNTITLED
, szUntitled
, ARRAY_SIZE(szUntitled
));
130 DIALOG_StringMsgBox(Globals
.hMainWnd
, STRING_PRINTERROR
,
131 Globals
.szFileName
[0] ? Globals
.szFileName
: szUntitled
,
132 MB_ICONEXCLAMATION
| MB_OK
);
137 * TRUE - if file exists
138 * FALSE - if file does not exist
140 BOOL
FileExists(LPCTSTR szFilename
)
142 WIN32_FIND_DATA entry
;
145 hFile
= FindFirstFile(szFilename
, &entry
);
148 return (hFile
!= INVALID_HANDLE_VALUE
);
151 BOOL
HasFileExtension(LPCTSTR szFilename
)
155 s
= _tcsrchr(szFilename
, _T('\\'));
158 return _tcsrchr(szFilename
, _T('.')) != NULL
;
161 int GetSelectionTextLength(HWND hWnd
)
166 SendMessage(hWnd
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
168 return dwEnd
- dwStart
;
171 int GetSelectionText(HWND hWnd
, LPTSTR lpString
, int nMaxCount
)
184 SendMessage(hWnd
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwEnd
);
186 if (dwStart
== dwEnd
)
191 dwSize
= GetWindowTextLength(hWnd
) + 1;
192 lpTemp
= HeapAlloc(GetProcessHeap(), 0, dwSize
* sizeof(TCHAR
));
198 dwSize
= GetWindowText(hWnd
, lpTemp
, dwSize
);
202 HeapFree(GetProcessHeap(), 0, lpTemp
);
206 hResult
= StringCchCopyN(lpString
, nMaxCount
, lpTemp
+ dwStart
, dwEnd
- dwStart
);
207 HeapFree(GetProcessHeap(), 0, lpTemp
);
213 return dwEnd
- dwStart
;
216 case STRSAFE_E_INSUFFICIENT_BUFFER
:
218 return nMaxCount
- 1;
228 static BOOL
DoSaveFile(VOID
)
235 hFile
= CreateFile(Globals
.szFileName
, GENERIC_WRITE
, FILE_SHARE_WRITE
,
236 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
237 if(hFile
== INVALID_HANDLE_VALUE
)
243 size
= GetWindowTextLength(Globals
.hEdit
) + 1;
244 pTemp
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(*pTemp
));
251 size
= GetWindowText(Globals
.hEdit
, pTemp
, size
);
255 if (!WriteText(hFile
, (LPWSTR
)pTemp
, size
, Globals
.encFile
, Globals
.iEoln
))
262 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, FALSE
, 0);
268 HeapFree(GetProcessHeap(), 0, pTemp
);
274 * TRUE - User agreed to close (both save/don't save)
275 * FALSE - User cancelled close by selecting "Cancel"
277 BOOL
DoCloseFile(VOID
)
281 if (SendMessage(Globals
.hEdit
, EM_GETMODIFY
, 0, 0))
283 /* prompt user to save changes */
284 nResult
= AlertFileNotSaved(Globals
.szFileName
);
288 if(!DIALOG_FileSave())
303 SetFileName(empty_str
);
304 UpdateWindowCaption();
309 VOID
DoOpenFile(LPCTSTR szFileName
)
311 static const TCHAR dotlog
[] = _T(".LOG");
313 LPTSTR pszText
= NULL
;
317 /* Close any files and prompt to save changes */
321 hFile
= CreateFile(szFileName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
322 OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
323 if (hFile
== INVALID_HANDLE_VALUE
)
329 if (!ReadText(hFile
, (LPWSTR
*)&pszText
, &dwTextLen
, &Globals
.encFile
, &Globals
.iEoln
))
334 SetWindowText(Globals
.hEdit
, pszText
);
336 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, FALSE
, 0);
337 SendMessage(Globals
.hEdit
, EM_EMPTYUNDOBUFFER
, 0, 0);
338 SetFocus(Globals
.hEdit
);
340 /* If the file starts with .LOG, add a time/date at the end and set cursor after
341 * See http://support.microsoft.com/?kbid=260563
343 if (GetWindowText(Globals
.hEdit
, log
, ARRAY_SIZE(log
)) && !_tcscmp(log
, dotlog
))
345 static const TCHAR lf
[] = _T("\r\n");
346 SendMessage(Globals
.hEdit
, EM_SETSEL
, GetWindowTextLength(Globals
.hEdit
), -1);
347 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)lf
);
348 DIALOG_EditTimeDate();
349 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)lf
);
352 SetFileName(szFileName
);
353 UpdateWindowCaption();
354 NOTEPAD_EnableSearchMenu();
356 if (hFile
!= INVALID_HANDLE_VALUE
)
359 HeapFree(GetProcessHeap(), 0, pszText
);
362 VOID
DIALOG_FileNew(VOID
)
364 /* Close any files and prompt to save changes */
366 SetWindowText(Globals
.hEdit
, empty_str
);
367 SendMessage(Globals
.hEdit
, EM_EMPTYUNDOBUFFER
, 0, 0);
368 SetFocus(Globals
.hEdit
);
369 NOTEPAD_EnableSearchMenu();
373 VOID
DIALOG_FileOpen(VOID
)
375 OPENFILENAME openfilename
;
376 TCHAR szDir
[MAX_PATH
];
377 TCHAR szPath
[MAX_PATH
];
379 ZeroMemory(&openfilename
, sizeof(openfilename
));
381 GetCurrentDirectory(ARRAY_SIZE(szDir
), szDir
);
382 if (Globals
.szFileName
[0] == 0)
383 _tcscpy(szPath
, txt_files
);
385 _tcscpy(szPath
, Globals
.szFileName
);
387 openfilename
.lStructSize
= sizeof(openfilename
);
388 openfilename
.hwndOwner
= Globals
.hMainWnd
;
389 openfilename
.hInstance
= Globals
.hInstance
;
390 openfilename
.lpstrFilter
= Globals
.szFilter
;
391 openfilename
.lpstrFile
= szPath
;
392 openfilename
.nMaxFile
= ARRAY_SIZE(szPath
);
393 openfilename
.lpstrInitialDir
= szDir
;
394 openfilename
.Flags
= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
;
395 openfilename
.lpstrDefExt
= szDefaultExt
;
397 if (GetOpenFileName(&openfilename
)) {
398 if (FileExists(openfilename
.lpstrFile
))
399 DoOpenFile(openfilename
.lpstrFile
);
401 AlertFileNotFound(openfilename
.lpstrFile
);
405 BOOL
DIALOG_FileSave(VOID
)
407 if (Globals
.szFileName
[0] == 0)
408 return DIALOG_FileSaveAs();
415 DIALOG_FileSaveAs_Hook(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
420 UNREFERENCED_PARAMETER(wParam
);
425 hCombo
= GetDlgItem(hDlg
, ID_ENCODING
);
427 LoadString(Globals
.hInstance
, STRING_ANSI
, szText
, ARRAY_SIZE(szText
));
428 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
430 LoadString(Globals
.hInstance
, STRING_UNICODE
, szText
, ARRAY_SIZE(szText
));
431 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
433 LoadString(Globals
.hInstance
, STRING_UNICODE_BE
, szText
, ARRAY_SIZE(szText
));
434 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
436 LoadString(Globals
.hInstance
, STRING_UTF8
, szText
, ARRAY_SIZE(szText
));
437 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
439 SendMessage(hCombo
, CB_SETCURSEL
, Globals
.encFile
, 0);
441 hCombo
= GetDlgItem(hDlg
, ID_EOLN
);
443 LoadString(Globals
.hInstance
, STRING_CRLF
, szText
, ARRAY_SIZE(szText
));
444 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
446 LoadString(Globals
.hInstance
, STRING_LF
, szText
, ARRAY_SIZE(szText
));
447 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
449 LoadString(Globals
.hInstance
, STRING_CR
, szText
, ARRAY_SIZE(szText
));
450 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
452 SendMessage(hCombo
, CB_SETCURSEL
, Globals
.iEoln
, 0);
456 if (((NMHDR
*) lParam
)->code
== CDN_FILEOK
)
458 hCombo
= GetDlgItem(hDlg
, ID_ENCODING
);
460 Globals
.encFile
= (int) SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
462 hCombo
= GetDlgItem(hDlg
, ID_EOLN
);
464 Globals
.iEoln
= (int) SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
471 BOOL
DIALOG_FileSaveAs(VOID
)
474 TCHAR szDir
[MAX_PATH
];
475 TCHAR szPath
[MAX_PATH
];
477 ZeroMemory(&saveas
, sizeof(saveas
));
479 GetCurrentDirectory(ARRAY_SIZE(szDir
), szDir
);
480 if (Globals
.szFileName
[0] == 0)
481 _tcscpy(szPath
, txt_files
);
483 _tcscpy(szPath
, Globals
.szFileName
);
485 saveas
.lStructSize
= sizeof(OPENFILENAME
);
486 saveas
.hwndOwner
= Globals
.hMainWnd
;
487 saveas
.hInstance
= Globals
.hInstance
;
488 saveas
.lpstrFilter
= Globals
.szFilter
;
489 saveas
.lpstrFile
= szPath
;
490 saveas
.nMaxFile
= ARRAY_SIZE(szPath
);
491 saveas
.lpstrInitialDir
= szDir
;
492 saveas
.Flags
= OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
| OFN_HIDEREADONLY
|
493 OFN_EXPLORER
| OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
;
494 saveas
.lpstrDefExt
= szDefaultExt
;
495 saveas
.lpTemplateName
= MAKEINTRESOURCE(DIALOG_ENCODING
);
496 saveas
.lpfnHook
= DIALOG_FileSaveAs_Hook
;
498 if (GetSaveFileName(&saveas
))
500 /* HACK: Because in ROS, Save-As boxes don't check the validity
501 * of file names and thus, here, szPath can be invalid !! We only
502 * see its validity when we call DoSaveFile()... */
506 UpdateWindowCaption();
521 VOID
DIALOG_FilePrint(VOID
)
526 int cWidthPels
, cHeightPels
, border
;
527 int xLeft
, yTop
, pagecount
, dopage
, copycount
;
530 HFONT font
, old_font
=0;
533 static const TCHAR times_new_roman
[] = _T("Times New Roman");
535 /* Get a small font and print some header info on each page */
536 ZeroMemory(&hdrFont
, sizeof(hdrFont
));
537 hdrFont
.lfHeight
= 100;
538 hdrFont
.lfWeight
= FW_BOLD
;
539 hdrFont
.lfCharSet
= ANSI_CHARSET
;
540 hdrFont
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
541 hdrFont
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
542 hdrFont
.lfQuality
= PROOF_QUALITY
;
543 hdrFont
.lfPitchAndFamily
= VARIABLE_PITCH
| FF_ROMAN
;
544 _tcscpy(hdrFont
.lfFaceName
, times_new_roman
);
546 font
= CreateFontIndirect(&hdrFont
);
548 /* Get Current Settings */
549 ZeroMemory(&printer
, sizeof(printer
));
550 printer
.lStructSize
= sizeof(printer
);
551 printer
.hwndOwner
= Globals
.hMainWnd
;
552 printer
.hInstance
= Globals
.hInstance
;
554 /* Set some default flags */
555 printer
.Flags
= PD_RETURNDC
| PD_SELECTION
;
557 /* Disable the selection radio button if there is no text selected */
558 if (!GetSelectionTextLength(Globals
.hEdit
))
560 printer
.Flags
= printer
.Flags
| PD_NOSELECTION
;
563 printer
.nFromPage
= 0;
564 printer
.nMinPage
= 1;
565 /* we really need to calculate number of pages to set nMaxPage and nToPage */
567 printer
.nMaxPage
= (WORD
)-1;
569 /* Let commdlg manage copy settings */
570 printer
.nCopies
= (WORD
)PD_USEDEVMODECOPIES
;
572 printer
.hDevMode
= Globals
.hDevMode
;
573 printer
.hDevNames
= Globals
.hDevNames
;
575 if (!PrintDlg(&printer
))
581 Globals
.hDevMode
= printer
.hDevMode
;
582 Globals
.hDevNames
= printer
.hDevNames
;
584 assert(printer
.hDC
!= 0);
586 /* initialize DOCINFO */
587 di
.cbSize
= sizeof(DOCINFO
);
588 di
.lpszDocName
= Globals
.szFileTitle
;
589 di
.lpszOutput
= NULL
;
590 di
.lpszDatatype
= NULL
;
593 if (StartDoc(printer
.hDC
, &di
) <= 0)
599 /* Get the page dimensions in pixels. */
600 cWidthPels
= GetDeviceCaps(printer
.hDC
, HORZRES
);
601 cHeightPels
= GetDeviceCaps(printer
.hDC
, VERTRES
);
603 /* Get the file text */
604 if (printer
.Flags
& PD_SELECTION
)
606 size
= GetSelectionTextLength(Globals
.hEdit
) + 1;
610 size
= GetWindowTextLength(Globals
.hEdit
) + 1;
613 pTemp
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(TCHAR
));
622 if (printer
.Flags
& PD_SELECTION
)
624 size
= GetSelectionText(Globals
.hEdit
, pTemp
, size
);
628 size
= GetWindowText(Globals
.hEdit
, pTemp
, size
);
632 for (copycount
=1; copycount
<= printer
.nCopies
; copycount
++) {
636 static const TCHAR letterM
[] = _T("M");
638 if (pagecount
>= printer
.nFromPage
&&
639 /* ((printer.Flags & PD_PAGENUMS) == 0 || pagecount <= printer.nToPage))*/
640 pagecount
<= printer
.nToPage
)
645 old_font
= SelectObject(printer
.hDC
, font
);
646 GetTextExtentPoint32(printer
.hDC
, letterM
, 1, &szMetric
);
649 if (StartPage(printer
.hDC
) <= 0) {
650 SelectObject(printer
.hDC
, old_font
);
652 DeleteDC(printer
.hDC
);
653 HeapFree(GetProcessHeap(), 0, pTemp
);
658 /* Write a rectangle and header at the top of each page */
659 Rectangle(printer
.hDC
, border
, border
, cWidthPels
-border
, border
+szMetric
.cy
*2);
660 /* I don't know what's up with this TextOut command. This comes out
665 border
+ szMetric
.cy
/ 2,
667 lstrlen(Globals
.szFileTitle
));
670 /* The starting point for the main text */
672 yTop
= border
+ szMetric
.cy
* 4;
674 SelectObject(printer
.hDC
, old_font
);
675 GetTextExtentPoint32(printer
.hDC
, letterM
, 1, &szMetric
);
677 /* Since outputting strings is giving me problems, output the main
678 * text one character at a time. */
680 if (pTemp
[i
] == '\n') {
684 else if (pTemp
[i
] != '\r') {
686 TextOut(printer
.hDC
, xLeft
, yTop
, &pTemp
[i
], 1);
687 xLeft
+= szMetric
.cx
;
689 } while (i
++ < size
&& yTop
< (cHeightPels
- border
* 2));
692 EndPage(printer
.hDC
);
698 SelectObject(printer
.hDC
, old_font
);
700 DeleteDC(printer
.hDC
);
701 HeapFree(GetProcessHeap(), 0, pTemp
);
705 VOID
DIALOG_FileExit(VOID
)
707 PostMessage(Globals
.hMainWnd
, WM_CLOSE
, 0, 0l);
710 VOID
DIALOG_EditUndo(VOID
)
712 SendMessage(Globals
.hEdit
, EM_UNDO
, 0, 0);
715 VOID
DIALOG_EditCut(VOID
)
717 SendMessage(Globals
.hEdit
, WM_CUT
, 0, 0);
720 VOID
DIALOG_EditCopy(VOID
)
722 SendMessage(Globals
.hEdit
, WM_COPY
, 0, 0);
725 VOID
DIALOG_EditPaste(VOID
)
727 SendMessage(Globals
.hEdit
, WM_PASTE
, 0, 0);
730 VOID
DIALOG_EditDelete(VOID
)
732 SendMessage(Globals
.hEdit
, WM_CLEAR
, 0, 0);
735 VOID
DIALOG_EditSelectAll(VOID
)
737 SendMessage(Globals
.hEdit
, EM_SETSEL
, 0, (LPARAM
)-1);
740 VOID
DIALOG_EditTimeDate(VOID
)
743 TCHAR szDate
[MAX_STRING_LEN
];
744 TCHAR szText
[MAX_STRING_LEN
* 2 + 2];
748 GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, szDate
, MAX_STRING_LEN
);
749 _tcscpy(szText
, szDate
);
750 _tcscat(szText
, _T(" "));
751 GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, szDate
, MAX_STRING_LEN
);
752 _tcscat(szText
, szDate
);
753 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)szText
);
756 VOID
DoCreateStatusBar(VOID
)
760 BOOL bStatusBarVisible
;
762 /* Check if status bar object already exists. */
763 if (Globals
.hStatusBar
== NULL
)
765 /* Try to create the status bar */
766 Globals
.hStatusBar
= CreateStatusWindow(WS_CHILD
| WS_VISIBLE
| WS_EX_STATICEDGE
,
769 CMD_STATUSBAR_WND_ID
);
771 if (Globals
.hStatusBar
== NULL
)
777 /* Load the string for formatting column/row text output */
778 LoadString(Globals
.hInstance
, STRING_LINE_COLUMN
, Globals
.szStatusBarLineCol
, MAX_PATH
- 1);
780 /* Set the status bar for single-text output */
781 SendMessage(Globals
.hStatusBar
, SB_SIMPLE
, (WPARAM
)TRUE
, (LPARAM
)0);
784 /* Set status bar visiblity according to the settings. */
785 if (Globals
.bWrapLongLines
== TRUE
|| Globals
.bShowStatusBar
== FALSE
)
787 bStatusBarVisible
= FALSE
;
788 ShowWindow(Globals
.hStatusBar
, SW_HIDE
);
792 bStatusBarVisible
= TRUE
;
793 ShowWindow(Globals
.hStatusBar
, SW_SHOW
);
794 SendMessage(Globals
.hStatusBar
, WM_SIZE
, 0, 0);
797 /* Set check state in show status bar item. */
798 if (bStatusBarVisible
)
800 CheckMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_CHECKED
);
804 CheckMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_UNCHECKED
);
807 /* Update menu mar with the previous changes */
808 DrawMenuBar(Globals
.hMainWnd
);
810 /* Sefety test is edit control exists */
811 if (Globals
.hEdit
!= NULL
)
813 /* Retrieve the sizes of the controls */
814 GetClientRect(Globals
.hMainWnd
, &rc
);
815 GetClientRect(Globals
.hStatusBar
, &rcstatus
);
817 /* If status bar is currently visible, update dimensions of edit control */
818 if (bStatusBarVisible
)
819 rc
.bottom
-= (rcstatus
.bottom
- rcstatus
.top
);
821 /* Resize edit control to right size. */
822 MoveWindow(Globals
.hEdit
,
830 /* Update content with current row/column text */
831 DIALOG_StatusBarUpdateCaretPos();
834 VOID
DoCreateEditWindow(VOID
)
839 BOOL bModified
= FALSE
;
843 /* If the edit control already exists, try to save its content */
844 if (Globals
.hEdit
!= NULL
)
846 /* number of chars currently written into the editor. */
847 iSize
= GetWindowTextLength(Globals
.hEdit
);
850 /* Allocates temporary buffer. */
851 pTemp
= HeapAlloc(GetProcessHeap(), 0, (iSize
+ 1) * sizeof(TCHAR
));
858 /* Recover the text into the control. */
859 GetWindowText(Globals
.hEdit
, pTemp
, iSize
+ 1);
861 if (SendMessage(Globals
.hEdit
, EM_GETMODIFY
, 0, 0))
865 /* Restore original window procedure */
866 SetWindowLongPtr(Globals
.hEdit
, GWLP_WNDPROC
, (LONG_PTR
)Globals
.EditProc
);
868 /* Destroy the edit control */
869 DestroyWindow(Globals
.hEdit
);
872 /* Update wrap status into the main menu and recover style flags */
873 if (Globals
.bWrapLongLines
)
875 dwStyle
= EDIT_STYLE_WRAP
;
876 EnableMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
878 dwStyle
= EDIT_STYLE
;
879 EnableMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_ENABLED
);
882 /* Update previous changes */
883 DrawMenuBar(Globals
.hMainWnd
);
885 /* Create the new edit control */
886 Globals
.hEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
,
899 if (Globals
.hEdit
== NULL
)
903 HeapFree(GetProcessHeap(), 0, pTemp
);
910 SendMessage(Globals
.hEdit
, WM_SETFONT
, (WPARAM
)Globals
.hFont
, FALSE
);
911 SendMessage(Globals
.hEdit
, EM_LIMITTEXT
, 0, 0);
913 /* If some text was previously saved, restore it. */
916 SetWindowText(Globals
.hEdit
, pTemp
);
917 HeapFree(GetProcessHeap(), 0, pTemp
);
920 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, TRUE
, 0);
923 /* Sub-class a new window callback for row/column detection. */
924 Globals
.EditProc
= (WNDPROC
)SetWindowLongPtr(Globals
.hEdit
,
926 (LONG_PTR
)EDIT_WndProc
);
928 /* Create/update status bar */
931 /* Finally shows new edit control and set focus into it. */
932 ShowWindow(Globals
.hEdit
, SW_SHOW
);
933 SetFocus(Globals
.hEdit
);
936 VOID
DIALOG_EditWrap(VOID
)
938 Globals
.bWrapLongLines
= !Globals
.bWrapLongLines
;
939 DoCreateEditWindow();
942 VOID
DIALOG_SelectFont(VOID
)
945 LOGFONT lf
= Globals
.lfFont
;
947 ZeroMemory( &cf
, sizeof(cf
) );
948 cf
.lStructSize
= sizeof(cf
);
949 cf
.hwndOwner
= Globals
.hMainWnd
;
951 cf
.Flags
= CF_SCREENFONTS
| CF_INITTOLOGFONTSTRUCT
;
955 HFONT currfont
= Globals
.hFont
;
957 Globals
.hFont
= CreateFontIndirect(&lf
);
959 SendMessage(Globals
.hEdit
, WM_SETFONT
, (WPARAM
)Globals
.hFont
, (LPARAM
)TRUE
);
960 if (currfont
!= NULL
)
961 DeleteObject(currfont
);
965 typedef HWND (WINAPI
*FINDPROC
)(LPFINDREPLACE lpfr
);
967 static VOID
DIALOG_SearchDialog(FINDPROC pfnProc
)
969 ZeroMemory(&Globals
.find
, sizeof(Globals
.find
));
970 Globals
.find
.lStructSize
= sizeof(Globals
.find
);
971 Globals
.find
.hwndOwner
= Globals
.hMainWnd
;
972 Globals
.find
.hInstance
= Globals
.hInstance
;
973 Globals
.find
.lpstrFindWhat
= Globals
.szFindText
;
974 Globals
.find
.wFindWhatLen
= ARRAY_SIZE(Globals
.szFindText
);
975 Globals
.find
.lpstrReplaceWith
= Globals
.szReplaceText
;
976 Globals
.find
.wReplaceWithLen
= ARRAY_SIZE(Globals
.szReplaceText
);
977 Globals
.find
.Flags
= FR_DOWN
;
979 /* We only need to create the modal FindReplace dialog which will */
980 /* notify us of incoming events using hMainWnd Window Messages */
982 Globals
.hFindReplaceDlg
= pfnProc(&Globals
.find
);
983 assert(Globals
.hFindReplaceDlg
!= 0);
986 VOID
DIALOG_Search(VOID
)
988 DIALOG_SearchDialog(FindText
);
991 VOID
DIALOG_SearchNext(VOID
)
993 if (Globals
.find
.lpstrFindWhat
!= NULL
)
994 NOTEPAD_FindNext(&Globals
.find
, FALSE
, TRUE
);
999 VOID
DIALOG_Replace(VOID
)
1001 DIALOG_SearchDialog(ReplaceText
);
1006 DIALOG_GoTo_DialogProc(HWND hwndDialog
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1008 BOOL bResult
= FALSE
;
1014 hTextBox
= GetDlgItem(hwndDialog
, ID_LINENUMBER
);
1015 _sntprintf(szText
, ARRAY_SIZE(szText
), _T("%ld"), lParam
);
1016 SetWindowText(hTextBox
, szText
);
1019 if (HIWORD(wParam
) == BN_CLICKED
)
1021 if (LOWORD(wParam
) == IDOK
)
1023 hTextBox
= GetDlgItem(hwndDialog
, ID_LINENUMBER
);
1024 GetWindowText(hTextBox
, szText
, ARRAY_SIZE(szText
));
1025 EndDialog(hwndDialog
, _ttoi(szText
));
1028 else if (LOWORD(wParam
) == IDCANCEL
)
1030 EndDialog(hwndDialog
, 0);
1040 VOID
DIALOG_GoTo(VOID
)
1045 DWORD dwStart
, dwEnd
;
1047 nLength
= GetWindowTextLength(Globals
.hEdit
);
1048 pszText
= (LPTSTR
) HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(*pszText
));
1052 /* Retrieve current text */
1053 GetWindowText(Globals
.hEdit
, pszText
, nLength
+ 1);
1054 SendMessage(Globals
.hEdit
, EM_GETSEL
, (WPARAM
) &dwStart
, (LPARAM
) &dwEnd
);
1057 for (i
= 0; pszText
[i
] && (i
< (int) dwStart
); i
++)
1059 if (pszText
[i
] == '\n')
1063 nLine
= DialogBoxParam(Globals
.hInstance
,
1064 MAKEINTRESOURCE(DIALOG_GOTO
),
1066 DIALOG_GoTo_DialogProc
,
1071 for (i
= 0; pszText
[i
] && (nLine
> 1) && (i
< nLength
- 1); i
++)
1073 if (pszText
[i
] == '\n')
1076 SendMessage(Globals
.hEdit
, EM_SETSEL
, i
, i
);
1077 SendMessage(Globals
.hEdit
, EM_SCROLLCARET
, 0, 0);
1079 HeapFree(GetProcessHeap(), 0, pszText
);
1082 VOID
DIALOG_StatusBarUpdateCaretPos(VOID
)
1085 TCHAR buff
[MAX_PATH
];
1086 DWORD dwStart
, dwSize
;
1088 SendMessage(Globals
.hEdit
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwSize
);
1089 line
= SendMessage(Globals
.hEdit
, EM_LINEFROMCHAR
, (WPARAM
)dwStart
, 0);
1090 col
= dwStart
- SendMessage(Globals
.hEdit
, EM_LINEINDEX
, (WPARAM
)line
, 0);
1092 _stprintf(buff
, Globals
.szStatusBarLineCol
, line
+ 1, col
+ 1);
1093 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, SB_SIMPLEID
, (LPARAM
)buff
);
1096 VOID
DIALOG_ViewStatusBar(VOID
)
1098 Globals
.bShowStatusBar
= !Globals
.bShowStatusBar
;
1100 DoCreateStatusBar();
1103 VOID
DIALOG_HelpContents(VOID
)
1105 WinHelp(Globals
.hMainWnd
, helpfile
, HELP_INDEX
, 0);
1108 VOID
DIALOG_HelpSearch(VOID
)
1113 VOID
DIALOG_HelpHelp(VOID
)
1115 WinHelp(Globals
.hMainWnd
, helpfile
, HELP_HELPONHELP
, 0);
1118 VOID
DIALOG_HelpAboutNotepad(VOID
)
1120 TCHAR szNotepad
[MAX_STRING_LEN
];
1121 HICON notepadIcon
= LoadIcon(Globals
.hInstance
, MAKEINTRESOURCE(IDI_NPICON
));
1123 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szNotepad
, ARRAY_SIZE(szNotepad
));
1124 ShellAbout(Globals
.hMainWnd
, szNotepad
, 0, notepadIcon
);
1125 DeleteObject(notepadIcon
);
1130 AboutDialogProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1132 HWND hLicenseEditWnd
;
1139 hLicenseEditWnd
= GetDlgItem(hDlg
, IDC_LICENSE
);
1141 /* 0x1000 should be enough */
1142 strLicense
= (TCHAR
*)_alloca(0x1000);
1143 LoadString(GetModuleHandle(NULL
), STRING_LICENSE
, strLicense
, 0x1000);
1145 SetWindowText(hLicenseEditWnd
, strLicense
);
1151 if ((LOWORD(wParam
) == IDOK
) || (LOWORD(wParam
) == IDCANCEL
))
1153 EndDialog(hDlg
, LOWORD(wParam
));
1163 /***********************************************************************
1165 * DIALOG_FilePageSetup
1167 VOID
DIALOG_FilePageSetup(void)
1171 ZeroMemory(&page
, sizeof(page
));
1172 page
.lStructSize
= sizeof(page
);
1173 page
.hwndOwner
= Globals
.hMainWnd
;
1174 page
.Flags
= PSD_ENABLEPAGESETUPTEMPLATE
| PSD_ENABLEPAGESETUPHOOK
| PSD_MARGINS
;
1175 page
.hInstance
= Globals
.hInstance
;
1176 page
.rtMargin
.left
= Globals
.lMarginLeft
;
1177 page
.rtMargin
.top
= Globals
.lMarginTop
;
1178 page
.rtMargin
.right
= Globals
.lMarginRight
;
1179 page
.rtMargin
.bottom
= Globals
.lMarginBottom
;
1180 page
.hDevMode
= Globals
.hDevMode
;
1181 page
.hDevNames
= Globals
.hDevNames
;
1182 page
.lpPageSetupTemplateName
= MAKEINTRESOURCE(DIALOG_PAGESETUP
);
1183 page
.lpfnPageSetupHook
= DIALOG_PAGESETUP_Hook
;
1185 PageSetupDlg(&page
);
1187 Globals
.hDevMode
= page
.hDevMode
;
1188 Globals
.hDevNames
= page
.hDevNames
;
1189 Globals
.lMarginLeft
= page
.rtMargin
.left
;
1190 Globals
.lMarginTop
= page
.rtMargin
.top
;
1191 Globals
.lMarginRight
= page
.rtMargin
.right
;
1192 Globals
.lMarginBottom
= page
.rtMargin
.bottom
;
1195 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1197 * DIALOG_PAGESETUP_Hook
1200 static UINT_PTR CALLBACK
DIALOG_PAGESETUP_Hook(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1205 if (HIWORD(wParam
) == BN_CLICKED
)
1207 switch (LOWORD(wParam
))
1210 /* save user input and close dialog */
1211 GetDlgItemText(hDlg
, 0x141, Globals
.szHeader
, ARRAY_SIZE(Globals
.szHeader
));
1212 GetDlgItemText(hDlg
, 0x143, Globals
.szFooter
, ARRAY_SIZE(Globals
.szFooter
));
1216 /* discard user input and close dialog */
1221 /* FIXME: Bring this to work */
1222 static const TCHAR sorry
[] = _T("Sorry, no help available");
1223 static const TCHAR help
[] = _T("Help");
1224 MessageBox(Globals
.hMainWnd
, sorry
, help
, MB_ICONEXCLAMATION
);
1235 /* fetch last user input prior to display dialog */
1236 SetDlgItemText(hDlg
, 0x141, Globals
.szHeader
);
1237 SetDlgItemText(hDlg
, 0x143, Globals
.szFooter
);