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 INT_PTR WINAPI
DIALOG_PAGESETUP_DlgProc(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
39 static LPSTR
ConvertToASCII(LPSTR pszText
)
42 LPWSTR pszTextW
= (LPWSTR
)pszText
;
44 /* default return value */
47 /* query about requested size for conversion */
48 sz
= WideCharToMultiByte(CP_ACP
, 0, pszTextW
, -1, NULL
, 0, NULL
, NULL
);
52 /* get space for ASCII buffer */
53 pszText
= (LPSTR
)HeapAlloc(GetProcessHeap(), 0, sz
);
57 /* if previous diagnostic call worked fine,
58 * then this one will work too,
59 * so no need to test return value here
61 WideCharToMultiByte(CP_ACP
, 0, pszTextW
, -1, pszText
, sz
, NULL
, NULL
);
64 HeapFree(GetProcessHeap(), 0, pszTextW
);
68 static LPWSTR
ConvertToUNICODE(LPSTR pszText
, DWORD
*pdwSize
)
71 LPWSTR pszTextW
= NULL
;
74 /* query about requested size for conversion */
75 sz
= MultiByteToWideChar(CP_ACP
, 0, pszText
, -1, NULL
, 0);
79 /* get space for UNICODE buffer */
80 pszTextW
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
));
84 /* if previous diagnostic call worked fine,
85 * then this one will work too,
86 * so no need to test return value here
88 MultiByteToWideChar(CP_ACP
, 0, pszText
, -1, pszTextW
, sz
);
90 /* report the new size of the text to the caller */
94 HeapFree(GetProcessHeap(), 0, pszText
);
99 VOID
ShowLastError(VOID
)
101 DWORD error
= GetLastError();
102 if (error
!= NO_ERROR
)
104 LPTSTR lpMsgBuf
= NULL
;
105 TCHAR szTitle
[MAX_STRING_LEN
];
107 LoadString(Globals
.hInstance
, STRING_ERROR
, szTitle
, SIZEOF(szTitle
));
109 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
117 MessageBox(NULL
, lpMsgBuf
, szTitle
, MB_OK
| MB_ICONERROR
);
123 * Sets the caption of the main window according to Globals.szFileTitle:
124 * (untitled) - Notepad if no file is open
125 * [filename] - Notepad if a file is given
127 static void UpdateWindowCaption(void)
129 TCHAR szCaption
[MAX_STRING_LEN
];
130 TCHAR szNotepad
[MAX_STRING_LEN
];
132 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szNotepad
, SIZEOF(szNotepad
));
134 if (Globals
.szFileTitle
[0] != 0)
136 StringCchCopy(szCaption
, SIZEOF(szCaption
), Globals
.szFileTitle
);
140 LoadString(Globals
.hInstance
, STRING_UNTITLED
, szCaption
, SIZEOF(szCaption
));
143 StringCchCat(szCaption
, SIZEOF(szCaption
), _T(" - "));
144 StringCchCat(szCaption
, SIZEOF(szCaption
), szNotepad
);
145 SetWindowText(Globals
.hMainWnd
, szCaption
);
148 static void AlertFileNotFound(LPCTSTR szFileName
)
150 TCHAR szMessage
[MAX_STRING_LEN
];
151 TCHAR szResource
[MAX_STRING_LEN
];
153 /* Load and format szMessage */
154 LoadString(Globals
.hInstance
, STRING_NOTFOUND
, szResource
, SIZEOF(szResource
));
155 wsprintf(szMessage
, szResource
, szFileName
);
158 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szResource
, SIZEOF(szResource
));
160 /* Display Modal Dialog */
161 MessageBox(Globals
.hMainWnd
, szMessage
, szResource
, MB_ICONEXCLAMATION
);
164 static int AlertFileNotSaved(LPCTSTR szFileName
)
166 TCHAR szMessage
[MAX_STRING_LEN
];
167 TCHAR szResource
[MAX_STRING_LEN
];
168 TCHAR szUntitled
[MAX_STRING_LEN
];
170 LoadString(Globals
.hInstance
, STRING_UNTITLED
, szUntitled
, SIZEOF(szUntitled
));
172 /* Load and format Message */
173 LoadString(Globals
.hInstance
, STRING_NOTSAVED
, szResource
, SIZEOF(szResource
));
174 wsprintf(szMessage
, szResource
, szFileName
[0] ? szFileName
: szUntitled
);
177 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szResource
, SIZEOF(szResource
));
180 return MessageBox(Globals
.hMainWnd
, szMessage
, szResource
, MB_ICONEXCLAMATION
|MB_YESNOCANCEL
);
185 * TRUE - if file exists
186 * FALSE - if file does not exist
188 BOOL
FileExists(LPCTSTR szFilename
)
190 WIN32_FIND_DATA entry
;
193 hFile
= FindFirstFile(szFilename
, &entry
);
196 return (hFile
!= INVALID_HANDLE_VALUE
);
199 BOOL
HasFileExtension(LPCTSTR szFilename
)
203 s
= _tcsrchr(szFilename
, _T('\\'));
206 return _tcsrchr(szFilename
, _T('.')) != NULL
;
209 static BOOL
DoSaveFile(VOID
)
216 hFile
= CreateFile(Globals
.szFileName
, GENERIC_WRITE
, FILE_SHARE_WRITE
,
217 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
218 if(hFile
== INVALID_HANDLE_VALUE
)
224 size
= GetWindowTextLength(Globals
.hEdit
) + 1;
225 pTemp
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(*pTemp
));
232 size
= GetWindowText(Globals
.hEdit
, pTemp
, size
);
235 pTemp
= (LPTSTR
)ConvertToUNICODE(pTemp
, &size
);
238 /* original "pTemp" already freed */
247 if (!WriteText(hFile
, (LPWSTR
)pTemp
, size
, Globals
.iEncoding
, Globals
.iEoln
))
254 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, FALSE
, 0);
260 HeapFree(GetProcessHeap(), 0, pTemp
);
266 * TRUE - User agreed to close (both save/don't save)
267 * FALSE - User cancelled close by selecting "Cancel"
269 BOOL
DoCloseFile(VOID
)
273 if (SendMessage(Globals
.hEdit
, EM_GETMODIFY
, 0, 0))
275 /* prompt user to save changes */
276 nResult
= AlertFileNotSaved(Globals
.szFileName
);
280 if(!DIALOG_FileSave())
295 SetFileName(empty_str
);
296 UpdateWindowCaption();
301 VOID
DoOpenFile(LPCTSTR szFileName
)
303 static const TCHAR dotlog
[] = _T(".LOG");
305 LPTSTR pszText
= NULL
;
309 /* Close any files and prompt to save changes */
313 hFile
= CreateFile(szFileName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
314 OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
315 if (hFile
== INVALID_HANDLE_VALUE
)
321 if (!ReadText(hFile
, (LPWSTR
*)&pszText
, &dwTextLen
, &Globals
.iEncoding
, &Globals
.iEoln
))
327 pszText
= ConvertToASCII(pszText
);
328 if (pszText
== NULL
) {
333 SetWindowText(Globals
.hEdit
, pszText
);
335 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, FALSE
, 0);
336 SendMessage(Globals
.hEdit
, EM_EMPTYUNDOBUFFER
, 0, 0);
337 SetFocus(Globals
.hEdit
);
339 /* If the file starts with .LOG, add a time/date at the end and set cursor after
340 * See http://support.microsoft.com/?kbid=260563
342 if (GetWindowText(Globals
.hEdit
, log
, SIZEOF(log
)) && !_tcscmp(log
, dotlog
))
344 static const TCHAR lf
[] = _T("\r\n");
345 SendMessage(Globals
.hEdit
, EM_SETSEL
, GetWindowTextLength(Globals
.hEdit
), -1);
346 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)lf
);
347 DIALOG_EditTimeDate();
348 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)lf
);
351 SetFileName(szFileName
);
352 UpdateWindowCaption();
353 NOTEPAD_EnableSearchMenu();
355 if (hFile
!= INVALID_HANDLE_VALUE
)
358 HeapFree(GetProcessHeap(), 0, pszText
);
361 VOID
DIALOG_FileNew(VOID
)
363 /* Close any files and prompt to save changes */
365 SetWindowText(Globals
.hEdit
, empty_str
);
366 SendMessage(Globals
.hEdit
, EM_EMPTYUNDOBUFFER
, 0, 0);
367 SetFocus(Globals
.hEdit
);
368 NOTEPAD_EnableSearchMenu();
372 VOID
DIALOG_FileOpen(VOID
)
374 OPENFILENAME openfilename
;
375 TCHAR szDir
[MAX_PATH
];
376 TCHAR szPath
[MAX_PATH
];
378 ZeroMemory(&openfilename
, sizeof(openfilename
));
380 GetCurrentDirectory(SIZEOF(szDir
), szDir
);
381 if (Globals
.szFileName
[0] == 0)
382 _tcscpy(szPath
, txt_files
);
384 _tcscpy(szPath
, Globals
.szFileName
);
386 openfilename
.lStructSize
= sizeof(openfilename
);
387 openfilename
.hwndOwner
= Globals
.hMainWnd
;
388 openfilename
.hInstance
= Globals
.hInstance
;
389 openfilename
.lpstrFilter
= Globals
.szFilter
;
390 openfilename
.lpstrFile
= szPath
;
391 openfilename
.nMaxFile
= SIZEOF(szPath
);
392 openfilename
.lpstrInitialDir
= szDir
;
393 openfilename
.Flags
= OFN_FILEMUSTEXIST
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
;
394 openfilename
.lpstrDefExt
= szDefaultExt
;
396 if (GetOpenFileName(&openfilename
)) {
397 if (FileExists(openfilename
.lpstrFile
))
398 DoOpenFile(openfilename
.lpstrFile
);
400 AlertFileNotFound(openfilename
.lpstrFile
);
404 BOOL
DIALOG_FileSave(VOID
)
406 if (Globals
.szFileName
[0] == 0)
407 return DIALOG_FileSaveAs();
414 DIALOG_FileSaveAs_Hook(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
419 UNREFERENCED_PARAMETER(wParam
);
424 hCombo
= GetDlgItem(hDlg
, ID_ENCODING
);
426 LoadString(Globals
.hInstance
, STRING_ANSI
, szText
, SIZEOF(szText
));
427 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
429 LoadString(Globals
.hInstance
, STRING_UNICODE
, szText
, SIZEOF(szText
));
430 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
432 LoadString(Globals
.hInstance
, STRING_UNICODE_BE
, szText
, SIZEOF(szText
));
433 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
435 LoadString(Globals
.hInstance
, STRING_UTF8
, szText
, SIZEOF(szText
));
436 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
438 SendMessage(hCombo
, CB_SETCURSEL
, Globals
.iEncoding
, 0);
440 hCombo
= GetDlgItem(hDlg
, ID_EOLN
);
442 LoadString(Globals
.hInstance
, STRING_CRLF
, szText
, SIZEOF(szText
));
443 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
445 LoadString(Globals
.hInstance
, STRING_LF
, szText
, SIZEOF(szText
));
446 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
448 LoadString(Globals
.hInstance
, STRING_CR
, szText
, SIZEOF(szText
));
449 SendMessage(hCombo
, CB_ADDSTRING
, 0, (LPARAM
) szText
);
451 SendMessage(hCombo
, CB_SETCURSEL
, Globals
.iEoln
, 0);
455 if (((NMHDR
*) lParam
)->code
== CDN_FILEOK
)
457 hCombo
= GetDlgItem(hDlg
, ID_ENCODING
);
459 Globals
.iEncoding
= (int) SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
461 hCombo
= GetDlgItem(hDlg
, ID_EOLN
);
463 Globals
.iEoln
= (int) SendMessage(hCombo
, CB_GETCURSEL
, 0, 0);
470 BOOL
DIALOG_FileSaveAs(VOID
)
473 TCHAR szDir
[MAX_PATH
];
474 TCHAR szPath
[MAX_PATH
];
476 ZeroMemory(&saveas
, sizeof(saveas
));
478 GetCurrentDirectory(SIZEOF(szDir
), szDir
);
479 if (Globals
.szFileName
[0] == 0)
480 _tcscpy(szPath
, txt_files
);
482 _tcscpy(szPath
, Globals
.szFileName
);
484 saveas
.lStructSize
= sizeof(OPENFILENAME
);
485 saveas
.hwndOwner
= Globals
.hMainWnd
;
486 saveas
.hInstance
= Globals
.hInstance
;
487 saveas
.lpstrFilter
= Globals
.szFilter
;
488 saveas
.lpstrFile
= szPath
;
489 saveas
.nMaxFile
= SIZEOF(szPath
);
490 saveas
.lpstrInitialDir
= szDir
;
491 saveas
.Flags
= OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
| OFN_HIDEREADONLY
|
492 OFN_EXPLORER
| OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
;
493 saveas
.lpstrDefExt
= szDefaultExt
;
494 saveas
.lpTemplateName
= MAKEINTRESOURCE(DIALOG_ENCODING
);
495 saveas
.lpfnHook
= DIALOG_FileSaveAs_Hook
;
497 if (GetSaveFileName(&saveas
))
499 /* HACK: Because in ROS, Save-As boxes don't check the validity
500 * of file names and thus, here, szPath can be invalid !! We only
501 * see its validity when we call DoSaveFile()... */
505 UpdateWindowCaption();
520 VOID
DIALOG_FilePrint(VOID
)
525 int cWidthPels
, cHeightPels
, border
;
526 int xLeft
, yTop
, pagecount
, dopage
, copycount
;
529 HFONT font
, old_font
=0;
532 static const TCHAR times_new_roman
[] = _T("Times New Roman");
534 /* Get a small font and print some header info on each page */
535 ZeroMemory(&hdrFont
, sizeof(hdrFont
));
536 hdrFont
.lfHeight
= 100;
537 hdrFont
.lfWeight
= FW_BOLD
;
538 hdrFont
.lfCharSet
= ANSI_CHARSET
;
539 hdrFont
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
540 hdrFont
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
541 hdrFont
.lfQuality
= PROOF_QUALITY
;
542 hdrFont
.lfPitchAndFamily
= VARIABLE_PITCH
| FF_ROMAN
;
543 _tcscpy(hdrFont
.lfFaceName
, times_new_roman
);
545 font
= CreateFontIndirect(&hdrFont
);
547 /* Get Current Settings */
548 ZeroMemory(&printer
, sizeof(printer
));
549 printer
.lStructSize
= sizeof(printer
);
550 printer
.hwndOwner
= Globals
.hMainWnd
;
551 printer
.hInstance
= Globals
.hInstance
;
553 /* Set some default flags */
554 printer
.Flags
= PD_RETURNDC
;
555 printer
.nFromPage
= 0;
556 printer
.nMinPage
= 1;
557 /* we really need to calculate number of pages to set nMaxPage and nToPage */
559 printer
.nMaxPage
= (WORD
)-1;
561 /* Let commdlg manage copy settings */
562 printer
.nCopies
= (WORD
)PD_USEDEVMODECOPIES
;
564 if (!PrintDlg(&printer
))
570 assert(printer
.hDC
!= 0);
572 /* initialize DOCINFO */
573 di
.cbSize
= sizeof(DOCINFO
);
574 di
.lpszDocName
= Globals
.szFileTitle
;
575 di
.lpszOutput
= NULL
;
576 di
.lpszDatatype
= NULL
;
579 if (StartDoc(printer
.hDC
, &di
) <= 0)
585 /* Get the page dimensions in pixels. */
586 cWidthPels
= GetDeviceCaps(printer
.hDC
, HORZRES
);
587 cHeightPels
= GetDeviceCaps(printer
.hDC
, VERTRES
);
589 /* Get the file text */
590 size
= GetWindowTextLength(Globals
.hEdit
) + 1;
591 pTemp
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(TCHAR
));
599 size
= GetWindowText(Globals
.hEdit
, pTemp
, size
);
602 for (copycount
=1; copycount
<= printer
.nCopies
; copycount
++) {
606 static const TCHAR letterM
[] = _T("M");
608 if (pagecount
>= printer
.nFromPage
&&
609 /* ((printer.Flags & PD_PAGENUMS) == 0 || pagecount <= printer.nToPage))*/
610 pagecount
<= printer
.nToPage
)
615 old_font
= SelectObject(printer
.hDC
, font
);
616 GetTextExtentPoint32(printer
.hDC
, letterM
, 1, &szMetric
);
619 if (StartPage(printer
.hDC
) <= 0) {
620 static const TCHAR failed
[] = _T("StartPage failed");
621 static const TCHAR error
[] = _T("Print Error");
622 SelectObject(printer
.hDC
, old_font
);
624 DeleteDC(printer
.hDC
);
625 HeapFree(GetProcessHeap(), 0, pTemp
);
627 MessageBox(Globals
.hMainWnd
, failed
, error
, MB_ICONEXCLAMATION
);
630 /* Write a rectangle and header at the top of each page */
631 Rectangle(printer
.hDC
, border
, border
, cWidthPels
-border
, border
+szMetric
.cy
*2);
632 /* I don't know what's up with this TextOut command. This comes out
637 border
+ szMetric
.cy
/ 2,
639 lstrlen(Globals
.szFileTitle
));
642 /* The starting point for the main text */
644 yTop
= border
+ szMetric
.cy
* 4;
646 SelectObject(printer
.hDC
, old_font
);
647 GetTextExtentPoint32(printer
.hDC
, letterM
, 1, &szMetric
);
649 /* Since outputting strings is giving me problems, output the main
650 * text one character at a time. */
652 if (pTemp
[i
] == '\n') {
656 else if (pTemp
[i
] != '\r') {
658 TextOut(printer
.hDC
, xLeft
, yTop
, &pTemp
[i
], 1);
659 xLeft
+= szMetric
.cx
;
661 } while (i
++ < size
&& yTop
< (cHeightPels
- border
* 2));
664 EndPage(printer
.hDC
);
670 SelectObject(printer
.hDC
, old_font
);
672 DeleteDC(printer
.hDC
);
673 HeapFree(GetProcessHeap(), 0, pTemp
);
677 VOID
DIALOG_FilePrinterSetup(VOID
)
681 ZeroMemory(&printer
, sizeof(printer
));
682 printer
.lStructSize
= sizeof(printer
);
683 printer
.hwndOwner
= Globals
.hMainWnd
;
684 printer
.hInstance
= Globals
.hInstance
;
685 printer
.Flags
= PD_PRINTSETUP
;
691 VOID
DIALOG_FileExit(VOID
)
693 PostMessage(Globals
.hMainWnd
, WM_CLOSE
, 0, 0l);
696 VOID
DIALOG_EditUndo(VOID
)
698 SendMessage(Globals
.hEdit
, EM_UNDO
, 0, 0);
701 VOID
DIALOG_EditCut(VOID
)
703 SendMessage(Globals
.hEdit
, WM_CUT
, 0, 0);
706 VOID
DIALOG_EditCopy(VOID
)
708 SendMessage(Globals
.hEdit
, WM_COPY
, 0, 0);
711 VOID
DIALOG_EditPaste(VOID
)
713 SendMessage(Globals
.hEdit
, WM_PASTE
, 0, 0);
716 VOID
DIALOG_EditDelete(VOID
)
718 SendMessage(Globals
.hEdit
, WM_CLEAR
, 0, 0);
721 VOID
DIALOG_EditSelectAll(VOID
)
723 SendMessage(Globals
.hEdit
, EM_SETSEL
, 0, (LPARAM
)-1);
726 VOID
DIALOG_EditTimeDate(VOID
)
729 TCHAR szDate
[MAX_STRING_LEN
];
730 TCHAR szText
[MAX_STRING_LEN
* 2 + 2];
734 GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &st
, NULL
, szDate
, MAX_STRING_LEN
);
735 _tcscpy(szText
, szDate
);
736 _tcscat(szText
, _T(" "));
737 GetDateFormat(LOCALE_USER_DEFAULT
, DATE_LONGDATE
, &st
, NULL
, szDate
, MAX_STRING_LEN
);
738 _tcscat(szText
, szDate
);
739 SendMessage(Globals
.hEdit
, EM_REPLACESEL
, TRUE
, (LPARAM
)szText
);
742 VOID
DoCreateStatusBar(VOID
)
746 BOOL bStatusBarVisible
;
748 /* Check if status bar object already exists. */
749 if (Globals
.hStatusBar
== NULL
)
751 /* Try to create the status bar */
752 Globals
.hStatusBar
= CreateStatusWindow(WS_CHILD
| WS_VISIBLE
| WS_EX_STATICEDGE
,
755 CMD_STATUSBAR_WND_ID
);
757 if (Globals
.hStatusBar
== NULL
)
763 /* Load the string for formatting column/row text output */
764 LoadString(Globals
.hInstance
, STRING_LINE_COLUMN
, Globals
.szStatusBarLineCol
, MAX_PATH
- 1);
766 /* Set the status bar for single-text output */
767 SendMessage(Globals
.hStatusBar
, SB_SIMPLE
, (WPARAM
)TRUE
, (LPARAM
)0);
770 /* Set status bar visiblity according to the settings. */
771 if (Globals
.bWrapLongLines
== TRUE
|| Globals
.bShowStatusBar
== FALSE
)
773 bStatusBarVisible
= FALSE
;
774 ShowWindow(Globals
.hStatusBar
, SW_HIDE
);
778 bStatusBarVisible
= TRUE
;
779 ShowWindow(Globals
.hStatusBar
, SW_SHOW
);
780 SendMessage(Globals
.hStatusBar
, WM_SIZE
, 0, 0);
783 /* Set check state in show status bar item. */
784 if (bStatusBarVisible
)
786 CheckMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_CHECKED
);
790 CheckMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_UNCHECKED
);
793 /* Update menu mar with the previous changes */
794 DrawMenuBar(Globals
.hMainWnd
);
796 /* Sefety test is edit control exists */
797 if (Globals
.hEdit
!= NULL
)
799 /* Retrieve the sizes of the controls */
800 GetClientRect(Globals
.hMainWnd
, &rc
);
801 GetClientRect(Globals
.hStatusBar
, &rcstatus
);
803 /* If status bar is currently visible, update dimensions of edit control */
804 if (bStatusBarVisible
)
805 rc
.bottom
-= (rcstatus
.bottom
- rcstatus
.top
);
807 /* Resize edit control to right size. */
808 MoveWindow(Globals
.hEdit
,
816 /* Update content with current row/column text */
817 DIALOG_StatusBarUpdateCaretPos();
820 VOID
DoCreateEditWindow(VOID
)
825 BOOL bModified
= FALSE
;
829 /* If the edit control already exists, try to save its content */
830 if (Globals
.hEdit
!= NULL
)
832 /* number of chars currently written into the editor. */
833 iSize
= GetWindowTextLength(Globals
.hEdit
);
836 /* Allocates temporary buffer. */
837 pTemp
= HeapAlloc(GetProcessHeap(), 0, (iSize
+ 1) * sizeof(TCHAR
));
844 /* Recover the text into the control. */
845 GetWindowText(Globals
.hEdit
, pTemp
, iSize
+ 1);
847 if (SendMessage(Globals
.hEdit
, EM_GETMODIFY
, 0, 0))
851 /* Restore original window procedure */
852 SetWindowLongPtr(Globals
.hEdit
, GWLP_WNDPROC
, (LONG_PTR
)Globals
.EditProc
);
854 /* Destroy the edit control */
855 DestroyWindow(Globals
.hEdit
);
858 /* Update wrap status into the main menu and recover style flags */
859 if (Globals
.bWrapLongLines
)
861 dwStyle
= EDIT_STYLE_WRAP
;
862 EnableMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
864 dwStyle
= EDIT_STYLE
;
865 EnableMenuItem(Globals
.hMenu
, CMD_STATUSBAR
, MF_BYCOMMAND
| MF_ENABLED
);
868 /* Update previous changes */
869 DrawMenuBar(Globals
.hMainWnd
);
871 /* Create the new edit control */
872 Globals
.hEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
,
885 if (Globals
.hEdit
== NULL
)
891 SendMessage(Globals
.hEdit
, WM_SETFONT
, (WPARAM
)Globals
.hFont
, FALSE
);
892 SendMessage(Globals
.hEdit
, EM_LIMITTEXT
, 0, 0);
894 /* If some text was previously saved, restore it. */
897 SetWindowText(Globals
.hEdit
, pTemp
);
898 HeapFree(GetProcessHeap(), 0, pTemp
);
901 SendMessage(Globals
.hEdit
, EM_SETMODIFY
, TRUE
, 0);
904 /* Sub-class a new window callback for row/column detection. */
905 Globals
.EditProc
= (WNDPROC
)SetWindowLongPtr(Globals
.hEdit
,
907 (LONG_PTR
)EDIT_WndProc
);
909 /* Create/update status bar */
912 /* Finally shows new edit control and set focus into it. */
913 ShowWindow(Globals
.hEdit
, SW_SHOW
);
914 SetFocus(Globals
.hEdit
);
917 VOID
DIALOG_EditWrap(VOID
)
919 Globals
.bWrapLongLines
= !Globals
.bWrapLongLines
;
920 DoCreateEditWindow();
923 VOID
DIALOG_SelectFont(VOID
)
926 LOGFONT lf
= Globals
.lfFont
;
928 ZeroMemory( &cf
, sizeof(cf
) );
929 cf
.lStructSize
= sizeof(cf
);
930 cf
.hwndOwner
= Globals
.hMainWnd
;
932 cf
.Flags
= CF_SCREENFONTS
| CF_INITTOLOGFONTSTRUCT
;
936 HFONT currfont
= Globals
.hFont
;
938 Globals
.hFont
= CreateFontIndirect(&lf
);
940 SendMessage(Globals
.hEdit
, WM_SETFONT
, (WPARAM
)Globals
.hFont
, (LPARAM
)TRUE
);
941 if (currfont
!= NULL
)
942 DeleteObject(currfont
);
946 typedef HWND (WINAPI
*FINDPROC
)(LPFINDREPLACE lpfr
);
948 static VOID
DIALOG_SearchDialog(FINDPROC pfnProc
)
950 ZeroMemory(&Globals
.find
, sizeof(Globals
.find
));
951 Globals
.find
.lStructSize
= sizeof(Globals
.find
);
952 Globals
.find
.hwndOwner
= Globals
.hMainWnd
;
953 Globals
.find
.hInstance
= Globals
.hInstance
;
954 Globals
.find
.lpstrFindWhat
= Globals
.szFindText
;
955 Globals
.find
.wFindWhatLen
= SIZEOF(Globals
.szFindText
);
956 Globals
.find
.lpstrReplaceWith
= Globals
.szReplaceText
;
957 Globals
.find
.wReplaceWithLen
= SIZEOF(Globals
.szReplaceText
);
958 Globals
.find
.Flags
= FR_DOWN
;
960 /* We only need to create the modal FindReplace dialog which will */
961 /* notify us of incoming events using hMainWnd Window Messages */
963 Globals
.hFindReplaceDlg
= pfnProc(&Globals
.find
);
964 assert(Globals
.hFindReplaceDlg
!= 0);
967 VOID
DIALOG_Search(VOID
)
969 DIALOG_SearchDialog(FindText
);
972 VOID
DIALOG_SearchNext(VOID
)
974 if (Globals
.find
.lpstrFindWhat
!= NULL
)
975 NOTEPAD_FindNext(&Globals
.find
, FALSE
, TRUE
);
980 VOID
DIALOG_Replace(VOID
)
982 DIALOG_SearchDialog(ReplaceText
);
987 DIALOG_GoTo_DialogProc(HWND hwndDialog
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
989 BOOL bResult
= FALSE
;
995 hTextBox
= GetDlgItem(hwndDialog
, ID_LINENUMBER
);
996 _sntprintf(szText
, SIZEOF(szText
), _T("%ld"), lParam
);
997 SetWindowText(hTextBox
, szText
);
1000 if (HIWORD(wParam
) == BN_CLICKED
)
1002 if (LOWORD(wParam
) == IDOK
)
1004 hTextBox
= GetDlgItem(hwndDialog
, ID_LINENUMBER
);
1005 GetWindowText(hTextBox
, szText
, SIZEOF(szText
));
1006 EndDialog(hwndDialog
, _ttoi(szText
));
1009 else if (LOWORD(wParam
) == IDCANCEL
)
1011 EndDialog(hwndDialog
, 0);
1021 VOID
DIALOG_GoTo(VOID
)
1026 DWORD dwStart
, dwEnd
;
1028 nLength
= GetWindowTextLength(Globals
.hEdit
);
1029 pszText
= (LPTSTR
) HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(*pszText
));
1033 /* Retrieve current text */
1034 GetWindowText(Globals
.hEdit
, pszText
, nLength
+ 1);
1035 SendMessage(Globals
.hEdit
, EM_GETSEL
, (WPARAM
) &dwStart
, (LPARAM
) &dwEnd
);
1038 for (i
= 0; pszText
[i
] && (i
< (int) dwStart
); i
++)
1040 if (pszText
[i
] == '\n')
1044 nLine
= DialogBoxParam(Globals
.hInstance
,
1045 MAKEINTRESOURCE(DIALOG_GOTO
),
1047 DIALOG_GoTo_DialogProc
,
1052 for (i
= 0; pszText
[i
] && (nLine
> 1) && (i
< nLength
- 1); i
++)
1054 if (pszText
[i
] == '\n')
1057 SendMessage(Globals
.hEdit
, EM_SETSEL
, i
, i
);
1058 SendMessage(Globals
.hEdit
, EM_SCROLLCARET
, 0, 0);
1060 HeapFree(GetProcessHeap(), 0, pszText
);
1063 VOID
DIALOG_StatusBarUpdateCaretPos(VOID
)
1066 TCHAR buff
[MAX_PATH
];
1067 DWORD dwStart
, dwSize
;
1069 SendMessage(Globals
.hEdit
, EM_GETSEL
, (WPARAM
)&dwStart
, (LPARAM
)&dwSize
);
1070 line
= SendMessage(Globals
.hEdit
, EM_LINEFROMCHAR
, (WPARAM
)dwStart
, 0);
1071 col
= dwStart
- SendMessage(Globals
.hEdit
, EM_LINEINDEX
, (WPARAM
)line
, 0);
1073 _stprintf(buff
, Globals
.szStatusBarLineCol
, line
+ 1, col
+ 1);
1074 SendMessage(Globals
.hStatusBar
, SB_SETTEXT
, SB_SIMPLEID
, (LPARAM
)buff
);
1077 VOID
DIALOG_ViewStatusBar(VOID
)
1079 Globals
.bShowStatusBar
= !Globals
.bShowStatusBar
;
1081 DoCreateStatusBar();
1084 VOID
DIALOG_HelpContents(VOID
)
1086 WinHelp(Globals
.hMainWnd
, helpfile
, HELP_INDEX
, 0);
1089 VOID
DIALOG_HelpSearch(VOID
)
1094 VOID
DIALOG_HelpHelp(VOID
)
1096 WinHelp(Globals
.hMainWnd
, helpfile
, HELP_HELPONHELP
, 0);
1100 #pragma warning(disable : 4100)
1104 AboutDialogProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1106 HWND hLicenseEditWnd
;
1113 hLicenseEditWnd
= GetDlgItem(hDlg
, IDC_LICENSE
);
1115 /* 0x1000 should be enough */
1116 strLicense
= (TCHAR
*)_alloca(0x1000);
1117 LoadString(GetModuleHandle(NULL
), STRING_LICENSE
, strLicense
, 0x1000);
1119 SetWindowText(hLicenseEditWnd
, strLicense
);
1125 if ((LOWORD(wParam
) == IDOK
) || (LOWORD(wParam
) == IDCANCEL
))
1127 EndDialog(hDlg
, LOWORD(wParam
));
1137 VOID
DIALOG_HelpAboutWine(VOID
)
1139 TCHAR szNotepad
[MAX_STRING_LEN
];
1140 HICON notepadIcon
= LoadIcon(Globals
.hInstance
, MAKEINTRESOURCE(IDI_NPICON
));
1142 LoadString(Globals
.hInstance
, STRING_NOTEPAD
, szNotepad
, SIZEOF(szNotepad
));
1143 ShellAbout(Globals
.hMainWnd
, szNotepad
, 0, notepadIcon
);
1144 DeleteObject(notepadIcon
);
1147 /***********************************************************************
1149 * DIALOG_FilePageSetup
1151 VOID
DIALOG_FilePageSetup(void)
1153 DialogBox(Globals
.hInstance
,
1154 MAKEINTRESOURCE(DIALOG_PAGESETUP
),
1156 DIALOG_PAGESETUP_DlgProc
);
1159 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1161 * DIALOG_PAGESETUP_DlgProc
1166 DIALOG_PAGESETUP_DlgProc(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
1171 if (HIWORD(wParam
) == BN_CLICKED
)
1173 switch (LOWORD(wParam
))
1176 /* save user input and close dialog */
1177 GetDlgItemText(hDlg
, 0x141, Globals
.szHeader
, SIZEOF(Globals
.szHeader
));
1178 GetDlgItemText(hDlg
, 0x143, Globals
.szFooter
, SIZEOF(Globals
.szFooter
));
1179 GetDlgItemText(hDlg
, 0x14A, Globals
.szMarginTop
, SIZEOF(Globals
.szMarginTop
));
1180 GetDlgItemText(hDlg
, 0x150, Globals
.szMarginBottom
, SIZEOF(Globals
.szMarginBottom
));
1181 GetDlgItemText(hDlg
, 0x147, Globals
.szMarginLeft
, SIZEOF(Globals
.szMarginLeft
));
1182 GetDlgItemText(hDlg
, 0x14D, Globals
.szMarginRight
, SIZEOF(Globals
.szMarginRight
));
1183 EndDialog(hDlg
, IDOK
);
1187 /* discard user input and close dialog */
1188 EndDialog(hDlg
, IDCANCEL
);
1193 /* FIXME: Bring this to work */
1194 static const TCHAR sorry
[] = _T("Sorry, no help available");
1195 static const TCHAR help
[] = _T("Help");
1196 MessageBox(Globals
.hMainWnd
, sorry
, help
, MB_ICONEXCLAMATION
);
1207 /* fetch last user input prior to display dialog */
1208 SetDlgItemText(hDlg
, 0x141, Globals
.szHeader
);
1209 SetDlgItemText(hDlg
, 0x143, Globals
.szFooter
);
1210 SetDlgItemText(hDlg
, 0x14A, Globals
.szMarginTop
);
1211 SetDlgItemText(hDlg
, 0x150, Globals
.szMarginBottom
);
1212 SetDlgItemText(hDlg
, 0x147, Globals
.szMarginLeft
);
1213 SetDlgItemText(hDlg
, 0x14D, Globals
.szMarginRight
);