├── CNAME ├── README.md ├── makefile ├── mkuni ├── makefile ├── mkuni.c ├── mkuni.h ├── mkuni.rc ├── names2.txt └── sources ├── notepad.c ├── notepad.def ├── notepad.dlg ├── notepad.h ├── notepad.ico ├── notepad.rc ├── notepad.rcv ├── npapp.ico ├── npdate.c ├── npfile.c ├── npinit.c ├── npmisc.c ├── npprint.c ├── nputf.c ├── precomp.h ├── sources ├── texttxt └── utf-8.txt └── windowsshell.manifest /CNAME: -------------------------------------------------------------------------------- 1 | notepadleak.com -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NotePad-Source-Code-Leak 2 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # 2 | # DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 3 | # file to this component. This file merely indirects to the real make file 4 | # that is shared by all the components of NT OS/2 5 | # 6 | !INCLUDE $(NTMAKEENV)\makefile.def 7 | -------------------------------------------------------------------------------- /mkuni/makefile: -------------------------------------------------------------------------------- 1 | # 2 | # DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source 3 | # file to this component. This file merely indirects to the real make file 4 | # that is shared by all the components of NT OS/2 5 | # 6 | !INCLUDE $(NTMAKEENV)\makefile.def 7 | -------------------------------------------------------------------------------- /mkuni/mkuni.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | 3 | PROGRAM: MkUni.c 4 | 5 | PURPOSE: Creates a text file with unicode characters 6 | 7 | FUNCTIONS: 8 | 9 | ****************************************************************************/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "mkuni.h" 16 | 17 | 18 | #define REVERSE 0 19 | #define LINE_SIZE 1000 20 | 21 | #define ASCIIEOL TEXT("\r\n") 22 | #define UNILINESEP 0x2028 23 | #define UNIPARASEP 0x2029 24 | 25 | struct __range { 26 | int low; 27 | int high; 28 | LPTSTR pDes; 29 | } range[] = { 30 | {0x20, 0x7f, TEXT("ANSI") }, 31 | {0xa0, 0xff, TEXT("Latin") }, 32 | {0x100, 0x17f, TEXT("European Latin") }, 33 | {0x180, 0x1f0, TEXT("Extended Latin") }, 34 | {0x250, 0x2a8, TEXT("Standard Phonetic") }, 35 | {0x2b0, 0x2e9, TEXT("Modifier Letters") }, 36 | {0x300, 0x341, TEXT("Generic Diacritical") }, 37 | {0x370, 0x3f5, TEXT("Greek") }, 38 | {0x400, 0x486, TEXT("Cyrillic") }, 39 | {0x490, 0x4cc, TEXT("Extended Cyrillic") }, 40 | {0x5b0, 0x5f5, TEXT("Hebrew") }, 41 | {0x0600,0x06F9, TEXT("Arabic") }, 42 | {0x0900,0x0970, TEXT("Devanagari") }, 43 | {0x0E00,0x0E5B, TEXT("Thai") }, 44 | {0x1000,0x104C, TEXT("Tibetan") }, 45 | {0x10A0,0x10FB, TEXT("Georgian") }, 46 | {0x20a0,0x20aa, TEXT("Currency Symbols") }, 47 | {0x2100,0x2138, TEXT("Letterlike Symbols") }, 48 | {0x2153,0x2182, TEXT("Number Forms") }, 49 | {0x2190,0x21ea, TEXT("Arrows") }, 50 | {0x2200,0x22f1, TEXT("Math Operators") }, 51 | {0x2500,0x257F, TEXT("Form and Chart Components") }, 52 | {0x25A0,0x25EE, TEXT("Geometric Shapes") }, 53 | {0x2600,0x266F, TEXT("Miscellaneous Dingbats") }, 54 | {0x3000,0x303F, TEXT("CJK Symbols and Punctuations") }, 55 | {0x3040,0x309E, TEXT("Hiragana") }, 56 | {0x3100,0x312C, TEXT("Bopomofo") }, 57 | {0x3131,0x318E, TEXT("Hangul Elements") }, 58 | {0, 0, TEXT("terminating entry") }, 59 | }; 60 | 61 | /**************************************************************************** 62 | 63 | FUNCTION: putu(FILE*pf, TCHAR c) 64 | 65 | PURPOSE: writes a character to the file. 66 | (Reverses the order of leadbytes if the flag is set) 67 | 68 | ****************************************************************************/ 69 | 70 | void 71 | putu(FILE*pf, TCHAR c) 72 | { 73 | TCHAR chr=c; 74 | 75 | if( REVERSE ) 76 | chr= ( c<<8 ) + ( ( c>>8 ) &0xFF); 77 | 78 | 79 | fwrite((void*)&chr, 1, sizeof(TCHAR), pf); 80 | } 81 | 82 | 83 | /**************************************************************************** 84 | 85 | FUNCTION: putust(FILE*pf, LPTSTR pc) 86 | 87 | PURPOSE: writes a string to the file. 88 | 89 | ****************************************************************************/ 90 | 91 | void 92 | putust(FILE*pf, LPTSTR pc) 93 | { 94 | while (*pc) 95 | putu(pf, *pc++); 96 | } 97 | 98 | 99 | /**************************************************************************** 100 | 101 | FUNCTION: main(int, char**) 102 | 103 | PURPOSE: write sample unicode file 104 | 105 | ****************************************************************************/ 106 | 107 | int _cdecl main(int argc, char**argv) 108 | { 109 | struct __range*pr = range; 110 | int i; 111 | FILE *pf; 112 | FILE *pfo; 113 | char lpstrLine[LINE_SIZE]; 114 | 115 | if(!(pf = fopen("unicode.txt", "wb"))) 116 | return FALSE; 117 | 118 | // Task1: Write all the unicode ranges and all the characters 119 | // in those ranges to the output file. 120 | putu(pf, (TCHAR)0xfeff); 121 | while (pr->low != 0) { 122 | putust(pf, TEXT("<<< ")); 123 | putust(pf, pr->pDes); 124 | putust(pf, TEXT(" >>>")); 125 | putust(pf, ASCIIEOL ); 126 | for (i=pr->low ; i<=pr->high ; i++) 127 | putu(pf, (TCHAR)i); 128 | putust(pf, ASCIIEOL); 129 | pr++; 130 | } 131 | 132 | putust(pf, TEXT("Unicode Line separator here ->")); 133 | putu(pf, UNILINESEP ); 134 | putust(pf, TEXT("<- Unicode line separator")); 135 | putust( pf, ASCIIEOL ); 136 | 137 | putust(pf, TEXT("Unicode Paragraph separator here ->")); 138 | putu(pf, UNIPARASEP ); 139 | putust(pf, TEXT("<- Unicode paragraph separator")); 140 | putust( pf, ASCIIEOL ); 141 | 142 | fclose( pf ); 143 | 144 | // Task2: Write all the characters codes and information 145 | // on each character code to an output file. 146 | if (!(pf = fopen( "names2.txt", "r" ))) 147 | return FALSE; 148 | 149 | if (!(pfo = fopen("unicodes.txt", "wb"))) 150 | return FALSE; 151 | 152 | // The first character should be 0xFEFF in the file, 153 | // indicating that it's an unicode file. 154 | putu( pfo, (TCHAR)0xfeff); 155 | 156 | // Read the input file (names2.txt) which has information 157 | // on every unicode character. 158 | do 159 | { 160 | WCHAR wLineBuffer[LINE_SIZE]; 161 | int i, num; 162 | 163 | if (!memset(lpstrLine, 0, LINE_SIZE)) 164 | { 165 | _tprintf(TEXT("Something wrong - failed in Memset!!\n") ); 166 | break; 167 | } 168 | 169 | // fgets returns NULL on eof or on an error condition 170 | if( fgets( lpstrLine, LINE_SIZE, pf) == NULL ) 171 | { 172 | if (!feof(pf)) 173 | _tprintf(TEXT("Error occured while reading names2.txt.\n") ); 174 | 175 | break; 176 | } 177 | 178 | i = 0; 179 | 180 | // Find the first newline (if there is any) and replace it by \0. 181 | while((lpstrLine[i]!= '\n') && (lpstrLine[i]!='\r') && (lpstrLine[i]!='\0')) 182 | { 183 | i++; 184 | } 185 | 186 | lpstrLine[i]= '\0'; 187 | 188 | // If the line has the character code (for which info is given) 189 | // grab and "display" that. 190 | num= -1; 191 | sscanf( lpstrLine, "%x", &num); 192 | 193 | if( num != -1 ) 194 | { 195 | putu( pfo, (TCHAR) num ); 196 | putust( pfo, TEXT(": ") ); 197 | } 198 | else 199 | { 200 | putust( pfo,TEXT(" ") ); 201 | } 202 | // Convert it to the world of unicodes. 203 | if (MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, lpstrLine, -1, 204 | wLineBuffer, LINE_SIZE )) 205 | putust(pfo, wLineBuffer); 206 | 207 | putust( pfo, ASCIIEOL ); 208 | 209 | } 210 | while( TRUE ); 211 | 212 | fclose( pfo ); 213 | fclose( pf ); 214 | 215 | return 1; 216 | } 217 | -------------------------------------------------------------------------------- /mkuni/mkuni.h: -------------------------------------------------------------------------------- 1 | #define ID_ASCII 105 2 | #define ID_LATIN 106 3 | #define ID_LATIN_E 107 4 | #define ID_LATIN_X 108 5 | #define ID_PHONETIC 109 6 | #define ID_MODIFIER 110 7 | #define ID_DIACRITICAL 111 8 | #define ID_GREEK 112 9 | #define ID_CYRILLIC 113 10 | #define ID_CYRILLIC_X 114 11 | #define ID_HEBREW 115 12 | #define ID_CURRENCY 116 13 | #define ID_LETTERS 117 14 | #define ID_ARROWS 118 15 | #define ID_MATH 119 16 | -------------------------------------------------------------------------------- /mkuni/mkuni.rc: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Version 4 | // 5 | #include 6 | #include 7 | 8 | #define VER_FILETYPE VFT_DLL 9 | #define VER_FILESUBTYPE VFT2_UNKNOWN 10 | #define VER_FILEDESCRIPTION_STR "MicrosoftUnicode String Utility" 11 | #define VER_INTERNALNAME_STR "mkuni.exe" 12 | #define VER_ORIGINALFILENAME_STR "mkuni.exe" 13 | 14 | #include 15 | 16 | -------------------------------------------------------------------------------- /mkuni/sources: -------------------------------------------------------------------------------- 1 | MAJORCOMP=sdk 2 | MINORCOMP=samples 3 | 4 | TARGETNAME=mkuni 5 | TARGETPATH=obj 6 | TARGETTYPE=PROGRAM 7 | TARGETLIBS= 8 | 9 | INCLUDES=. 10 | 11 | C_DEFINES= -DWIN32 -DUNICODE -D_UNICODE 12 | 13 | SOURCES=mkuni.c \ 14 | mkuni.rc 15 | 16 | UMTYPE=console 17 | UMAPPL=mkuni 18 | UMENTRY=main 19 | UMLIBS= $(SDK_LIB_PATH)\user32.lib 20 | -------------------------------------------------------------------------------- /notepad.def: -------------------------------------------------------------------------------- 1 | NAME Notepad 2 | 3 | EXETYPE WINDOWS 4 | STUB 'WINSTUB.EXE' 5 | 6 | CODE MOVEABLE DISCARDABLE 7 | DATA MOVEABLE MULTIPLE 8 | 9 | HEAPSIZE 8192 10 | STACKSIZE 16384 11 | 12 | SEGMENTS 13 | _TEXT PRELOAD MOVABLE DISCARDABLE 14 | _NPINIT PRELOAD MOVABLE DISCARDABLE 15 | _NPFILE MOVABLE DISCARDABLE 16 | _NPDATE MOVABLE DISCARDABLE 17 | _NPMISC MOVABLE DISCARDABLE 18 | _DLGOPEN MOVABLE DISCARDABLE 19 | 20 | EXPORTS 21 | NPWndProc @1 22 | AbortProc @2 23 | AboutDlgProc @3 24 | AbortDlgProc @4 25 | PageSetupDlgProc @5 26 | -------------------------------------------------------------------------------- /notepad.dlg: -------------------------------------------------------------------------------- 1 | #define WS_TABONLY (WS_TABSTOP | WS_GROUP) 2 | #define ID_NULL -1 3 | 4 | #define WIDTHPRINTDLG 200 5 | 6 | IDD_ABORTPRINT DIALOG 20,20,WIDTHPRINTDLG, 64 7 | STYLE WS_POPUPWINDOW | DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 8 | CAPTION "Notepad" 9 | FONT 8 "MS Shell Dlg" 10 | BEGIN 11 | defpushbutton "Cancel" IDCANCEL, 84, 44, 32, 14, GRP 12 | ctext "Now Printing", -1, 0, 8, WIDTHPRINTDLG, 8 13 | ctext "", ID_FILENAME, 0, 18, WIDTHPRINTDLG, 8, SS_PATHELLIPSIS | SS_CENTER 14 | ctext "", ID_PAGENUMBER, 0, 28, WIDTHPRINTDLG, 8, SS_CENTER 15 | END 16 | 17 | NpEncodingDialog DIALOG 30, 17, 300, 22 18 | STYLE WS_CHILD | DS_3DLOOK | WS_CLIPSIBLINGS | DS_CONTEXTHELP | DS_CONTROL 19 | FONT 8, "MS Shell Dlg" 20 | BEGIN 21 | CONTROL "&Encoding:", IDC_ENCODING, "static" SS_LEFT , 68,1, 40,40 22 | COMBOBOX IDC_FILETYPE, 130,0, 164,100, CBS_DROPDOWNLIST | WS_VSCROLL | WS_GROUP | WS_TABSTOP 23 | END 24 | 25 | IDD_PAGESETUP DIALOG DISCARDABLE 0, 0, 356, 196 26 | STYLE DS_MODALFRAME | 4L | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP 27 | CAPTION "Page Setup" 28 | FONT 8, "MS Shell Dlg" 29 | BEGIN 30 | GROUPBOX "Paper",1073,8,8,224,56,WS_GROUP 31 | LTEXT "Si&ze:",1089,16,24,36,8 32 | COMBOBOX 1137,64,23,160,160,CBS_DROPDOWNLIST | CBS_SORT | 33 | WS_VSCROLL | WS_GROUP | WS_TABSTOP 34 | LTEXT "&Source:",1090,16,45,36,8 35 | COMBOBOX 1138,64,42,160,160,CBS_DROPDOWNLIST | CBS_SORT | 36 | WS_VSCROLL | WS_GROUP | WS_TABSTOP 37 | GROUPBOX "Orientation",1072,8,69,64,56,WS_GROUP 38 | CONTROL "P&ortrait",1056,"Button",BS_AUTORADIOBUTTON | WS_GROUP | 39 | WS_TABSTOP,16,82,52,12 40 | CONTROL "L&andscape",1057,"Button",BS_AUTORADIOBUTTON,16,103,52, 41 | 12 42 | GROUPBOX "Margins",1075,80,69,152,56,WS_GROUP 43 | LTEXT "&Left:",1102,88,85,32,8 44 | EDITTEXT 1155,120,82,28,12,WS_GROUP 45 | LTEXT "&Right:",1103,164,85,32,8 46 | EDITTEXT 1157,196,82,28,12,WS_GROUP 47 | LTEXT "&Top:",1104,88,104,32,8 48 | EDITTEXT 1156,120,103,28,12,WS_GROUP 49 | LTEXT "&Bottom:",1105,164,104,32,8 50 | EDITTEXT 1158,196,103,28,12,WS_GROUP 51 | LTEXT "&Header:",ID_HEADER_LABEL,8,135,29,8 52 | EDITTEXT ID_HEADER,56,134,174,12,ES_AUTOHSCROLL 53 | LTEXT "&Footer:",ID_FOOTER_LABEL,8,154,29,8 54 | EDITTEXT ID_FOOTER,56,153,174,12,ES_AUTOHSCROLL 55 | DEFPUSHBUTTON "OK",IDOK,190,174,50,14,WS_GROUP 56 | PUSHBUTTON "Cancel",IDCANCEL,244,174,50,14 57 | PUSHBUTTON "&Printer...",1026,298,174,50,14 58 | GROUPBOX "Preview",-1,240,8,108,158 59 | CONTROL "",1080,"Static",SS_WHITERECT,254,46,80,80 60 | CONTROL "",1081,"Static",SS_GRAYRECT,334,50,4,80 61 | CONTROL "",1082,"Static",SS_GRAYRECT,262,122,80,4 62 | END 63 | 64 | IDD_GOTODIALOG DIALOG DISCARDABLE 0, 0, 180, 57 65 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP 66 | CAPTION "Goto line" 67 | FONT 8, "MS Shell Dlg" 68 | BEGIN 69 | LTEXT "&Line Number:", 1200, 7, 9, 50, 10 70 | EDITTEXT IDC_GOTO,55,7,57,12,ES_AUTOHSCROLL 71 | DEFPUSHBUTTON "OK",IDOK,7,34,50,14 72 | PUSHBUTTON "Cancel",IDCANCEL,78,34,50,14 73 | END 74 | -------------------------------------------------------------------------------- /notepad.h: -------------------------------------------------------------------------------- 1 | /* Notepad.h */ 2 | 3 | #define NOCOMM 4 | #define NOSOUND 5 | #include 6 | #include 7 | #include 8 | #include 9 | // we need this for CharSizeOf(), ByteCountOf(), 10 | #include "uniconv.h" 11 | 12 | /* handy debug macro */ 13 | #define ODS OutputDebugString 14 | 15 | typedef enum _NP_FILETYPE { 16 | FT_UNKNOWN=-1, 17 | FT_ANSI=0, 18 | FT_UNICODE=1, 19 | FT_UNICODEBE=2, 20 | FT_UTF8=3, 21 | } NP_FILETYPE; 22 | 23 | 24 | #define BOM_UTF8_HALF 0xBBEF 25 | #define BOM_UTF8_2HALF 0xBF 26 | 27 | 28 | /* openfile filter for all text files */ 29 | #define FILE_TEXT 1 30 | 31 | 32 | /* ID for the status window */ 33 | #define ID_STATUS_WINDOW WM_USER+1 34 | 35 | 36 | #define PT_LEN 40 /* max length of page setup strings */ 37 | #define CCHFILTERMAX 80 /* max. length of filter name buffers */ 38 | 39 | // Menu IDs 40 | #define ID_APPICON 1 /* must be one for explorer to find this */ 41 | #define ID_ICON 2 42 | #define ID_MENUBAR 1 43 | 44 | // Dialog IDs 45 | 46 | #define IDD_ABORTPRINT 11 47 | #define IDD_PAGESETUP 12 48 | #define IDD_SAVEDIALOG 13 // template for save dialog 49 | #define IDD_GOTODIALOG 14 // goto line number dialog 50 | 51 | // Control IDs 52 | 53 | #define IDC_FILETYPE 257 // listbox in save dialog 54 | #define IDC_GOTO 258 // line number to goto 55 | #define IDC_ENCODING 259 // static text in save dialog 56 | 57 | // Menu IDs 58 | 59 | // File 60 | #define M_NEW 1 61 | #define M_OPEN 2 62 | #define M_SAVE 3 63 | #define M_SAVEAS 4 64 | #define M_PAGESETUP 5 65 | #define M_PRINT 6 66 | #define M_EXIT 7 67 | 68 | // Edit 69 | #define M_UNDO 16 70 | #define M_CUT WM_CUT /* These just get passed down to the edit control */ 71 | #define M_COPY WM_COPY 72 | #define M_PASTE WM_PASTE 73 | #define M_CLEAR WM_CLEAR 74 | #define M_FIND 21 75 | #define M_FINDNEXT 22 76 | #define M_REPLACE 23 77 | #define M_GOTO 24 78 | #define M_SELECTALL 25 79 | #define M_DATETIME 26 80 | #define M_STATUSBAR 27 81 | 82 | // Format 83 | #define M_WW 32 84 | #define M_SETFONT 33 85 | 86 | // Help 87 | #define M_HELP 64 88 | #define M_ABOUT 65 89 | 90 | // Control IDs 91 | 92 | #define ID_EDIT 15 93 | #define ID_FILENAME 20 94 | #define ID_PAGENUMBER 21 95 | 96 | 97 | #define ID_HEADER 30 98 | #define ID_FOOTER 31 99 | #define ID_HEADER_LABEL 32 100 | #define ID_FOOTER_LABEL 33 101 | 102 | #define ID_ASCII 50 103 | #define ID_UNICODE 51 104 | 105 | 106 | // IDs used to load RC strings 107 | // 108 | // Note: The international team doesn't like wholesale changes 109 | // to these IDs. Apparently, if the ID changes they have to 110 | // translate the string again. It's best to just add new IDs 111 | // to the end. 112 | 113 | #define IDS_DISKERROR 1 114 | #define IDS_FNF 2 115 | #define IDS_SCBC 3 116 | #define IDS_UNTITLED 4 117 | #define IDS_NOTEPAD 5 118 | #define IDS_CFS 6 119 | #define IDS_ERRSPACE 7 120 | #define IDS_FTL 8 121 | #define IDS_NN 9 122 | #define IDS_COMMDLGINIT 10 123 | #define IDS_PRINTDLGINIT 11 124 | #define IDS_CANTPRINT 12 125 | #define IDS_NVF 13 126 | #define IDS_CREATEERR 14 127 | #define IDS_NOWW 15 128 | #define IDS_MERGE1 16 129 | #define IDS_HELPFILE 17 130 | #define IDS_HEADER 18 131 | #define IDS_FOOTER 19 132 | 133 | #define IDS_ANSITEXT 20 134 | #define IDS_ALLFILES 21 135 | #define IDS_OPENCAPTION 22 136 | #define IDS_SAVECAPTION 23 137 | #define IDS_CANNOTQUIT 24 138 | #define IDS_LOADDRVFAIL 25 139 | #define IDS_ACCESSDENY 26 140 | #define IDS_ERRUNICODE 27 141 | 142 | 143 | #define IDS_FONTTOOBIG 28 144 | #define IDS_COMMDLGERR 29 145 | 146 | 147 | #define IDS_LINEERROR 30 /* line number error */ 148 | #define IDS_LINETOOLARGE 31 /* line number too large */ 149 | 150 | #define IDS_FT_ANSI 32 /* ascii */ 151 | #define IDS_FT_UNICODE 33 /* unicode */ 152 | #define IDS_FT_UNICODEBE 34 /* unicode big endian */ 153 | #define IDS_FT_UTF8 35 /* UTF-8 format */ 154 | 155 | #define IDS_CURRENT_PAGE 36 /* currently printing page on abort dlg */ 156 | 157 | // constants for the status bar 158 | #define IDS_LINECOL 37 159 | #define IDS_COMPRESSED_FILE 38 160 | #define IDS_ENCRYPTED_FILE 39 161 | #define IDS_HIDDEN_FILE 40 162 | #define IDS_OFFLINE_FILE 41 163 | #define IDS_READONLY_FILE 42 164 | #define IDS_SYSTEM_FILE 43 165 | #define IDS_FILE 44 166 | 167 | 168 | #define IDS_LETTERS 45 /* formatting letters used in page setup */ 169 | 170 | #define CSTRINGS 45 /* cnt of stringtable strings from .rc file */ 171 | 172 | // This string is used by MUI for the "FriendlyTypeName". 173 | // See reference to it in hivecls.inx 174 | // We don't load it so the number is out of sequence with those we do load. 175 | 176 | #define IDS_TEXT_FRIENDLY_NAME 469 177 | 178 | #define CCHKEYMAX 128 /* max characters in search string */ 179 | 180 | #define BUFFER_TEST_SIZE 1024 /* number of characters to read from a file to determine the file encoding */ 181 | 182 | #define CCHNPMAX 0 /* no limit on file size */ 183 | 184 | #define SETHANDLEINPROGRESS 0x0001 /* EM_SETHANDLE has been sent */ 185 | #define SETHANDLEFAILED 0x0002 /* EM_SETHANDLE caused EN_ERRSPACE */ 186 | 187 | /* Standard edit control style: 188 | * ES_NOHIDESEL set so that find/replace dialog doesn't undo selection 189 | * of text while it has the focus away from the edit control. Makes finding 190 | * your text easier. 191 | */ 192 | #define ES_STD (WS_CHILD|WS_VSCROLL|WS_VISIBLE|ES_MULTILINE|ES_NOHIDESEL) 193 | 194 | /* EXTERN decls for data */ 195 | extern NP_FILETYPE fFileType; /* Flag indicating the type of text file */ 196 | 197 | extern BOOL fCase; /* Flag specifying case sensitive search */ 198 | extern BOOL fReverse; /* Flag for direction of search */ 199 | extern TCHAR szSearch[]; 200 | extern HWND hDlgFind; /* handle to modeless FindText window */ 201 | 202 | extern HANDLE hEdit; 203 | extern HANDLE hFont; 204 | extern HANDLE hAccel; 205 | extern HANDLE hInstanceNP; 206 | extern HANDLE hStdCursor, hWaitCursor; 207 | extern HWND hwndNP, hwndEdit, hwndStatus; 208 | 209 | extern LOGFONT FontStruct; 210 | extern INT iPointSize; 211 | 212 | extern BOOL fRunBySetup; 213 | 214 | extern DWORD dwEmSetHandle; 215 | 216 | extern TCHAR chMerge; 217 | 218 | extern BOOL fUntitled; 219 | extern BOOL fWrap; 220 | extern TCHAR szFileName[]; 221 | extern HANDLE fp; 222 | 223 | extern BOOL fMLE_is_broken; 224 | 225 | // 226 | // Holds header and footer strings to be used in printing. 227 | // use HEADER and FOOTER to index. 228 | // 229 | extern TCHAR chPageText[2][PT_LEN]; // header and footer strings 230 | #define HEADER 0 231 | #define FOOTER 1 232 | // 233 | // Holds header and footer from pagesetupdlg during destroy. 234 | // if the user hit ok, then keep. Otherwise ignore. 235 | // 236 | extern TCHAR chPageTextTemp[2][PT_LEN]; 237 | 238 | extern TCHAR szNotepad[]; 239 | extern TCHAR *szMerge; 240 | extern TCHAR *szUntitled, *szNpTitle, *szNN, *szErrSpace; 241 | extern TCHAR *szErrUnicode; 242 | extern TCHAR **rgsz[]; /* More strings. */ 243 | extern TCHAR *szNVF; 244 | extern TCHAR *szPDIE; 245 | extern TCHAR *szDiskError; 246 | extern TCHAR *szCREATEERR; 247 | extern TCHAR *szWE; 248 | extern TCHAR *szFTL; 249 | extern TCHAR *szINF; 250 | extern TCHAR *szFNF; 251 | extern TCHAR *szNEDSTP; 252 | extern TCHAR *szNEMTP; 253 | extern TCHAR *szCFS; 254 | extern TCHAR *szPE; 255 | extern TCHAR *szCP; 256 | extern TCHAR *szACCESSDENY; 257 | extern TCHAR *szFontTooBig; 258 | extern TCHAR *szLoadDrvFail; 259 | extern TCHAR *szCommDlgErr; 260 | extern TCHAR *szCommDlgInitErr; 261 | extern TCHAR *szHelpFile; 262 | 263 | extern TCHAR *szFtAnsi; 264 | extern TCHAR *szFtUnicode; 265 | extern TCHAR *szFtUnicodeBe; 266 | extern TCHAR *szFtUtf8; 267 | extern TCHAR *szCurrentPage; 268 | extern TCHAR *szHeader; 269 | extern TCHAR *szFooter; 270 | extern TCHAR *szLetters; 271 | 272 | /* variables for the new File/Open and File/Saveas dialogs */ 273 | extern OPENFILENAME OFN; /* passed to the File Open/save APIs */ 274 | extern TCHAR szOpenFilterSpec[]; /* default open filter spec */ 275 | extern TCHAR szSaveFilterSpec[]; /* default save filter spec */ 276 | extern TCHAR *szAnsiText; /* part of the text for the above */ 277 | extern TCHAR *szAllFiles; /* part of the text for the above */ 278 | extern FINDREPLACE FR; /* Passed to FindText() */ 279 | extern PAGESETUPDLG g_PageSetupDlg; 280 | extern TCHAR szPrinterName []; /* name of the printer passed to PrintTo */ 281 | 282 | extern NP_FILETYPE g_ftOpenedAs; /* file was opened */ 283 | extern NP_FILETYPE g_ftSaveAs; /* file was saved as type */ 284 | 285 | extern UINT wFRMsg; /* message used in communicating */ 286 | /* with Find/Replace dialog */ 287 | extern UINT wHlpMsg; /* message used in invoking help */ 288 | 289 | extern HMENU hSysMenuSetup; /* Save Away for disabled Minimize */ 290 | extern BOOL fStatus; 291 | extern INT dyStatus; 292 | 293 | 294 | /* Macro for setting status bar - x is the text to set and n is the part number 295 | in the statusbar */ 296 | #define SetStatusBarText(x, n) if(hwndStatus)SendMessage(hwndStatus, SB_SETTEXT, n, (LPARAM)(LPTSTR)(x)); 297 | VOID UpdateStatusBar( BOOL fForceUpdate ); 298 | 299 | 300 | 301 | /* EXTERN procs */ 302 | /* procs in notepad.c */ 303 | VOID 304 | PASCAL 305 | SetPageSetupDefaults( 306 | VOID 307 | ); 308 | 309 | BOOL far PASCAL SaveAsDlgHookProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); 310 | 311 | LPTSTR PASCAL far PFileInPath (LPTSTR sz); 312 | 313 | BOOL FAR CheckSave (BOOL fSysModal); 314 | LRESULT FAR NPWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 315 | void FAR SetTitle (TCHAR *sz); 316 | INT FAR AlertBox (HWND hwndParent, TCHAR *szCaption, TCHAR *szText1, 317 | TCHAR *szText2, UINT style); 318 | void FAR NpWinIniChange (VOID); 319 | void FAR FreeGlobalPD (void); 320 | INT_PTR CALLBACK GotoDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam); 321 | VOID CALLBACK WinEventFunc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, 322 | LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime); 323 | 324 | 325 | NP_FILETYPE fDetermineFileType(LPBYTE lpFileContents, UINT iSize); 326 | VOID GotoAndScrollInView( INT OneBasedLineNumber ); 327 | void NPSize (int cxNew, int cyNew); 328 | 329 | 330 | /* procs in npdate.c */ 331 | VOID FAR InsertDateTime (BOOL fCrlf); 332 | 333 | /* procs in npfile.c */ 334 | BOOL FAR SaveFile (HWND hwndParent, TCHAR *szFileSave, BOOL fSaveAs); 335 | BOOL FAR LoadFile (TCHAR *sz, INT type ); 336 | VOID FAR New (BOOL fCheck); 337 | void FAR AddExt (TCHAR *sz); 338 | INT FAR Remove (LPTSTR szFileName); 339 | VOID FAR AlertUser_FileFail( LPTSTR szFileName ); 340 | 341 | /* procs in npinit.c */ 342 | INT FAR NPInit (HANDLE hInstance, HANDLE hPrevInstance, 343 | LPTSTR lpCmdLine, INT cmdShow); 344 | void FAR InitLocale (VOID); 345 | void SaveGlobals( VOID ); 346 | 347 | /* procs in npmisc.c */ 348 | INT FAR FindDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 349 | BOOL Search (TCHAR *szSearch); 350 | INT FAR AboutDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); 351 | BOOL FAR NpReCreate (LONG style); 352 | LPTSTR ForwardScan (LPTSTR lpSource, LPTSTR lpSearch, BOOL fCaseSensitive); 353 | 354 | 355 | /* procs in npprint.c */ 356 | typedef enum _PRINT_DIALOG_TYPE { 357 | UseDialog, 358 | DoNotUseDialog, 359 | NoDialogNonDefault 360 | } PRINT_DIALOG_TYPE; 361 | 362 | INT AbortProc( HDC hPrintDC, INT reserved ); 363 | INT_PTR AbortDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); 364 | INT NpPrint( PRINT_DIALOG_TYPE type ); 365 | INT NpPrintGivenDC( HDC hPrintDC ); 366 | 367 | UINT_PTR 368 | CALLBACK 369 | PageSetupHookProc( 370 | HWND hWnd, 371 | UINT Message, 372 | WPARAM wParam, 373 | LPARAM lParam 374 | ); 375 | 376 | HANDLE GetPrinterDC (VOID); 377 | HANDLE GetNonDefPrinterDC (VOID); 378 | VOID PrintIt(PRINT_DIALOG_TYPE type); 379 | 380 | 381 | /* procs in nputf.c */ 382 | 383 | INT IsTextUTF8 (LPSTR lpstrInputStream, INT iLen); 384 | INT IsInputTextUnicode(LPSTR lpstrInputStream, INT iLen); 385 | 386 | 387 | 388 | // Help IDs for Notepad 389 | 390 | #define NO_HELP ((DWORD) -1) // Disables Help for a control 391 | 392 | #define IDH_PAGE_FOOTER 1000 393 | #define IDH_PAGE_HEADER 1001 394 | #define IDH_FILETYPE 1002 395 | #define IDH_GOTO 1003 396 | 397 | // Private message to track the HKL switch 398 | 399 | #define PWM_CHECK_HKL (WM_APP + 1) 400 | 401 | -------------------------------------------------------------------------------- /notepad.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windows-source/MS-Notepad/093fcdec1210bb0e3e115f33a50633242bde4e04/notepad.ico -------------------------------------------------------------------------------- /notepad.rc: -------------------------------------------------------------------------------- 1 | /* */ 2 | /* Notepad application */ 3 | /* */ 4 | /* Copyright (C) 1984-2001 Microsoft Inc. */ 5 | /* */ 6 | 7 | #include "notepad.h" 8 | #define GRP WS_GROUP 9 | #define TAB WS_TABSTOP 10 | #define TABGRP WS_TABSTOP | WS_GROUP 11 | #define DLGMODAL WS_POPUP | WS_DLGFRAME 12 | 13 | /* Version Stamping */ 14 | #include "notepad.rcv" 15 | 16 | ID_ICON ICON PRELOAD DISCARDABLE notepad.ico 17 | 18 | ID_MENUBAR MENU PRELOAD DISCARDABLE 19 | BEGIN 20 | POPUP "&File" 21 | BEGIN 22 | MENUITEM "&New\tCtrl+N", M_NEW 23 | MENUITEM "&Open...\tCtrl+O", M_OPEN 24 | MENUITEM "&Save\tCtrl+S", M_SAVE 25 | MENUITEM "Save &As...", M_SAVEAS 26 | MENUITEM SEPARATOR 27 | MENUITEM "Page Set&up...", M_PAGESETUP 28 | MENUITEM "&Print...\tCtrl+P", M_PRINT 29 | MENUITEM SEPARATOR 30 | MENUITEM "E&xit", M_EXIT 31 | END 32 | 33 | POPUP "&Edit" 34 | BEGIN 35 | MENUITEM "&Undo\tCtrl+Z", M_UNDO 36 | MENUITEM SEPARATOR 37 | MENUITEM "Cu&t\tCtrl+X", M_CUT , GRAYED 38 | MENUITEM "&Copy\tCtrl+C", M_COPY, GRAYED 39 | MENUITEM "&Paste\tCtrl+V", M_PASTE, GRAYED 40 | MENUITEM "De&lete\tDel", M_CLEAR, GRAYED 41 | MENUITEM SEPARATOR 42 | MENUITEM "&Find...\tCtrl+F", M_FIND 43 | MENUITEM "Find &Next\tF3", M_FINDNEXT 44 | MENUITEM "&Replace...\tCtrl+H", M_REPLACE 45 | /* 46 | The hotkey used for replace is CTRL-H in most of the editors, and hence though 47 | this key may conflict with backspace key in IMEs, this key is used here to be compatible 48 | with all the editors. Please contact ChrisW/RajeshM for more details. 49 | */ 50 | MENUITEM "&Go To...\tCtrl+G", M_GOTO 51 | MENUITEM SEPARATOR 52 | MENUITEM "Select &All\tCtrl+A", M_SELECTALL 53 | MENUITEM "Time/&Date\tF5", M_DATETIME 54 | END 55 | 56 | POPUP "F&ormat" 57 | BEGIN 58 | MENUITEM "&Word Wrap" M_WW 59 | MENUITEM "&Font...", M_SETFONT 60 | END 61 | 62 | POPUP "&View" 63 | BEGIN 64 | MENUITEM "&Status Bar", M_STATUSBAR 65 | END 66 | 67 | POPUP "&Help" 68 | BEGIN 69 | MENUITEM "&Help Topics", M_HELP 70 | MENUITEM SEPARATOR 71 | MENUITEM "&About Notepad",M_ABOUT 72 | END 73 | 74 | END 75 | 76 | MainAcc ACCELERATORS PRELOAD DISCARDABLE 77 | BEGIN 78 | "N", M_NEW, VIRTKEY, CONTROL 79 | "O", M_OPEN, VIRTKEY, CONTROL 80 | "S", M_SAVE, VIRTKEY, CONTROL 81 | "P", M_PRINT, VIRTKEY, CONTROL 82 | VK_INSERT, M_COPY, VIRTKEY, CONTROL 83 | VK_F1, M_HELP, VIRTKEY 84 | VK_F3, M_FINDNEXT, VIRTKEY 85 | VK_F5, M_DATETIME, VIRTKEY 86 | "G", M_GOTO, VIRTKEY, CONTROL 87 | "F", M_FIND , VIRTKEY, CONTROL, NOINVERT 88 | "H", M_REPLACE, VIRTKEY, CONTROL, NOINVERT 89 | VK_BACK, M_UNDO, VIRTKEY, ALT 90 | "Z", M_UNDO, VIRTKEY, CONTROL 91 | "X", M_CUT, VIRTKEY, CONTROL 92 | "C", M_COPY, VIRTKEY, CONTROL 93 | "V", M_PASTE, VIRTKEY, CONTROL 94 | "A", M_SELECTALL,VIRTKEY, CONTROL 95 | END 96 | 97 | /* Allow exit using ^C, ^D or ^Z during Setup */ 98 | SlipUpAcc ACCELERATORS PRELOAD DISCARDABLE 99 | BEGIN 100 | "N", M_NEW, VIRTKEY, CONTROL 101 | "O", M_OPEN, VIRTKEY, CONTROL 102 | "S", M_SAVE, VIRTKEY, CONTROL 103 | "P", M_PRINT, VIRTKEY, CONTROL 104 | VK_INSERT, M_COPY, VIRTKEY, CONTROL 105 | VK_F1, M_HELP, VIRTKEY 106 | VK_F3, M_FINDNEXT, VIRTKEY 107 | VK_F5, M_DATETIME, VIRTKEY 108 | "G", M_GOTO, VIRTKEY, CONTROL 109 | "F", M_FIND, VIRTKEY, CONTROL, NOINVERT 110 | "H", M_REPLACE, VIRTKEY, CONTROL, NOINVERT 111 | VK_BACK, M_UNDO, VIRTKEY, ALT 112 | "Z", M_UNDO, VIRTKEY, CONTROL 113 | "X", M_CUT, VIRTKEY, CONTROL 114 | "C", M_COPY, VIRTKEY, CONTROL 115 | "V", M_PASTE, VIRTKEY, CONTROL 116 | "A", M_SELECTALL,VIRTKEY, CONTROL 117 | VK_ESCAPE, M_EXIT, VIRTKEY 118 | 0x43, M_EXIT, VIRTKEY, CONTROL 119 | 0x44, M_EXIT, VIRTKEY, CONTROL 120 | 0x5A, M_EXIT, VIRTKEY, CONTROL 121 | END 122 | 123 | STRINGTABLE PRELOAD DISCARDABLE 124 | BEGIN 125 | IDS_MERGE1 "%%" 126 | IDS_DISKERROR "Cannot open the %% file.\n\nMake sure a disk is in the drive you specified." 127 | IDS_FNF "Cannot find the %% file.\n\nDo you want to create a new file?" 128 | IDS_SCBC "The text in the %% file has changed.\n\nDo you want to save the changes?" 129 | IDS_UNTITLED "Untitled" 130 | IDS_NOTEPAD " - Notepad" 131 | IDS_CFS "Cannot find ""%%""" 132 | /* The following is a generic out of memory message which can also be 133 | system modal so no /n can appear in it. */ 134 | IDS_ERRSPACE "Not enough memory available to complete this operation. Quit one or more applications to increase available memory, and then try again." 135 | IDS_FTL "The %% file is too large for Notepad.\n\nUse another editor to edit the file." 136 | IDS_NN "Notepad" 137 | IDS_COMMDLGINIT "Failed to Initialize File Dialogs. Change the Filename and try again." 138 | IDS_PRINTDLGINIT "Failed to Initialize Print Dialogs. Make sure that your printer is connected properly and use Control Panel to verify that the printer is configured properly." 139 | IDS_CANTPRINT "Cannot print the %% file. Be sure that your printer is connected properly and use Control Panel to verify that the printer is configured properly." 140 | IDS_NVF "Not a valid file name." 141 | IDS_CREATEERR "Cannot create the %% file.\n\nMake sure that the path and filename are correct." 142 | IDS_NOWW "Cannot carry out the Word Wrap command because there is too much text in the file." 143 | IDS_HELPFILE "notepad.hlp" 144 | IDS_HEADER "&f" 145 | IDS_FOOTER "Page &p" 146 | 147 | IDS_ACCESSDENY "%%\nYou do not have permission to open this file. See the owner of the file or an administrator to obtain permission." 148 | 149 | 150 | IDS_ANSITEXT "Text Documents (*.txt)" /* filter text for File/Open */ 151 | IDS_ALLFILES "All Files " /* filter text for File/Open */ 152 | IDS_OPENCAPTION "Open" /* title for file/open dialog */ 153 | IDS_SAVECAPTION "Save As" /* title for file/save dialog */ 154 | IDS_CANNOTQUIT "You cannot quit Windows because the Save As dialog\nbox in Notepad is open. Switch to Notepad, close this\ndialog box, and then try quitting Windows again." 155 | IDS_LOADDRVFAIL "Cannot access your printer.\nBe sure that your printer is connected properly and use Control Panel to verify that the printer is configured properly." 156 | IDS_ERRUNICODE "%%\n This file contains characters in Unicode format which will be lost if you save this file as an ANSI encoded text file. To keep the Unicode information, click Cancel below and then select one of the Unicode options from the Encoding drop down list. Continue?" 157 | IDS_FONTTOOBIG "Page too small to print one line.\nTry printing using smaller font." 158 | IDS_COMMDLGERR "Common Dialog error (0x%04x)" 159 | 160 | IDS_LINEERROR "Notepad - Goto Line" 161 | IDS_LINETOOLARGE "Line number out of range" 162 | 163 | IDS_FT_ANSI "ANSI" 164 | IDS_FT_UNICODE "Unicode" 165 | IDS_FT_UNICODEBE "Unicode big endian" 166 | IDS_FT_UTF8 "UTF-8" 167 | 168 | IDS_CURRENT_PAGE "Page %d" /* don't change %d; used for printf formatting */ 169 | 170 | IDS_LINECOL " Ln %d, Col %d " 171 | IDS_COMPRESSED_FILE " Compressed," 172 | IDS_ENCRYPTED_FILE " Encrypted," 173 | IDS_HIDDEN_FILE " Hidden," 174 | IDS_OFFLINE_FILE " Offline," 175 | IDS_READONLY_FILE " ReadOnly," 176 | IDS_SYSTEM_FILE " System," 177 | IDS_FILE " File" 178 | 179 | /* Use by MUI, not notepad. See hivecls.inx for reference */ 180 | 181 | IDS_TEXT_FRIENDLY_NAME "Text Document" 182 | 183 | /* IDS_LETTERS "fFpPtTdDcCrRlL" Original US values. This does get translated! */ 184 | /* The order is: File, Page, Time, Date, Center, Right, Left */ 185 | 186 | IDS_LETTERS "fFpPtTdDcCrRlL" 187 | 188 | END 189 | 190 | /* Include other dialogs. */ 191 | rcinclude notepad.dlg 192 | 193 | #include 194 | 195 | #include "common.ver" 196 | -------------------------------------------------------------------------------- /notepad.rcv: -------------------------------------------------------------------------------- 1 | /********************************************************************/ 2 | /* NOTEPAD.RCV */ 3 | /* Version control data generated from layouts.dat */ 4 | /********************************************************************/ 5 | 6 | #define VER_FILETYPE VFT_APP 7 | #define VER_FILESUBTYPE VFT_UNKNOWN 8 | #define VER_FILEDESCRIPTION_STR "Notepad" 9 | #define VER_INTERNALNAME_STR "Notepad" 10 | #define VER_ORIGINALFILENAME_STR "NOTEPAD.EXE" 11 | -------------------------------------------------------------------------------- /npapp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windows-source/MS-Notepad/093fcdec1210bb0e3e115f33a50633242bde4e04/npapp.ico -------------------------------------------------------------------------------- /npdate.c: -------------------------------------------------------------------------------- 1 | /* npdate - Code for getting and inserting current date and time. 2 | * Copyright (C) 1984-1995 Microsoft Inc. 3 | */ 4 | 5 | #include "precomp.h" 6 | 7 | /* ** Replace current selection with date/time string. 8 | * if fCrlf is true, date/time string should begin 9 | * and end with crlf 10 | */ 11 | VOID FAR InsertDateTime (BOOL fCrlf) 12 | { 13 | SYSTEMTIME time ; 14 | TCHAR szDate[80] ; 15 | TCHAR szTime[80] ; 16 | TCHAR szDateTime[sizeof(szDate) + sizeof(szTime) + 10] = TEXT(""); 17 | DWORD locale; 18 | BOOL bMELocale; 19 | DWORD dwFlags = DATE_SHORTDATE; 20 | 21 | // See if the user locale id is Arabic or Hebrew. 22 | locale = GetUserDefaultLCID(); 23 | bMELocale = ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) || 24 | (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW)); 25 | 26 | locale = MAKELCID( MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT) ; 27 | 28 | // Get the time 29 | GetLocalTime( &time ) ; 30 | 31 | if (bMELocale) 32 | { 33 | //Get the date format that matches the edit control reading direction. 34 | if (GetWindowLong(hwndEdit, GWL_EXSTYLE) & WS_EX_RTLREADING) { 35 | dwFlags |= DATE_RTLREADING; 36 | lstrcat(szDateTime, TEXT("\x200F")); // RLM 37 | } else { 38 | dwFlags |= DATE_LTRREADING; 39 | lstrcat(szDateTime, TEXT("\x200E")); // LRM 40 | } 41 | } 42 | 43 | // Format date and time 44 | GetDateFormat(locale,dwFlags, &time,NULL,szDate,CharSizeOf(szDate)); 45 | GetTimeFormat(locale,TIME_NOSECONDS,&time,NULL,szTime,CharSizeOf(szTime)); 46 | 47 | if( fCrlf ) 48 | lstrcat(szDateTime, TEXT("\r\n")); 49 | 50 | 51 | lstrcat(szDateTime, szTime); 52 | lstrcat(szDateTime, TEXT(" ")); 53 | lstrcat(szDateTime, szDate); 54 | 55 | if( fCrlf ) 56 | lstrcat(szDateTime, TEXT("\r\n")); 57 | 58 | // send it in one shot; this is also useful for undo command 59 | // so that user can undo the date-time. 60 | SendMessage(hwndEdit, EM_REPLACESEL, TRUE, (LPARAM)szDateTime); 61 | 62 | } 63 | -------------------------------------------------------------------------------- /npfile.c: -------------------------------------------------------------------------------- 1 | /* 2 | * npfile.c - Routines for file i/o for notepad 3 | * Copyright (C) 1984-2001 Microsoft Inc. 4 | */ 5 | 6 | #include "precomp.h" 7 | 8 | 9 | HANDLE hFirstMem; 10 | CHAR BOM_UTF8[3]= {(BYTE) 0xEF, (BYTE) 0xBB, (BYTE)0xBF}; 11 | 12 | 13 | 14 | //**************************************************************** 15 | // 16 | // ReverseEndian 17 | // 18 | // Purpose: copies unicode character from one endian source 19 | // to another. 20 | // 21 | // may work on lpDst == lpSrc 22 | // 23 | 24 | VOID ReverseEndian( PTCHAR lpDst, PTCHAR lpSrc, DWORD nChars ) 25 | { 26 | DWORD cnt; 27 | 28 | for( cnt=0; cnt < nChars; cnt++,lpDst++,lpSrc++ ) 29 | { 30 | *lpDst= (TCHAR) (((*lpSrc<<8) & 0xFF00) + ((*lpSrc>>8)&0xFF)); 31 | } 32 | } 33 | 34 | //***************************************************************** 35 | // 36 | // AnsiWriteFile() 37 | // 38 | // Purpose : To simulate the effects of _lwrite() in a Unicode 39 | // environment by converting to ANSI buffer and 40 | // writing out the ANSI text. 41 | // Returns : TRUE is successful, FALSE if not 42 | // GetLastError() will have the error code. 43 | // 44 | //***************************************************************** 45 | 46 | BOOL AnsiWriteFile(HANDLE hFile, // file to write to 47 | UINT uCodePage, // code page to convert unicode to 48 | DWORD dwFlags, // flags for WideCharToMultiByte conversion 49 | LPVOID lpBuffer, // unicode buffer 50 | DWORD nChars) // number of unicode chars 51 | { 52 | LPSTR lpAnsi; // pointer to allocate buffer 53 | BOOL fDefCharUsed; // flag that conversion wasn't perfect 54 | BOOL* pfDefCharUsed; // pointer to flag 55 | DWORD nBytesWritten; // number of bytes written 56 | BOOL bStatus; // status from conversion and writefile 57 | DWORD nBytes; // number of ascii character to produce 58 | 59 | // 60 | // WideCharToMultiByte fails to convert zero characters. 61 | // If we get a request to write 0 chars, just return. We are done. 62 | // 63 | 64 | if( nChars == 0 ) 65 | { 66 | return( TRUE ); 67 | } 68 | 69 | pfDefCharUsed= NULL; 70 | if( uCodePage != CP_UTF8 ) 71 | { 72 | pfDefCharUsed= &fDefCharUsed; 73 | } 74 | 75 | // 76 | // Calculate number of bytes to write 77 | // The caller calculated the number of bytes to write 78 | // but it might be wrong because the user approved data loss. 79 | // Do the calculation here (again) in case the dwFlags are different. 80 | // FEATURE: We could optimize this in the case where the dwFlags did not 81 | // change. 82 | // 83 | 84 | nBytes= 85 | WideCharToMultiByte( uCodePage, // code page 86 | dwFlags, // performance and mapping flags 87 | (LPWSTR) lpBuffer, // wide char buffer 88 | nChars, // chars in wide char buffer 89 | NULL, // output buffer 90 | 0, // size of output buffer 91 | NULL, // char to sub. for unmapped chars (use default) 92 | pfDefCharUsed); // flag to set if default char used 93 | 94 | if( nBytes == 0 ) 95 | { 96 | return( FALSE ); 97 | } 98 | 99 | // 100 | // Allocate buffer to convert to 101 | // 102 | 103 | lpAnsi= (LPSTR) LocalAlloc( LPTR, nBytes + 1 ); 104 | 105 | if( !lpAnsi ) 106 | { 107 | SetLastError( ERROR_NOT_ENOUGH_MEMORY ); 108 | return (FALSE); 109 | } 110 | 111 | bStatus= 112 | WideCharToMultiByte( uCodePage, // code page 113 | dwFlags, // performance and mapping flags 114 | (LPWSTR) lpBuffer, // wide char buffer 115 | nChars, // chars in wide char buffer 116 | lpAnsi, // resultant ascii string 117 | nBytes, // size of ascii string buffer 118 | NULL, // char to sub. for unmapped chars (use default) 119 | pfDefCharUsed); // flag to set if default char used 120 | 121 | if( bStatus ) 122 | { 123 | bStatus= WriteFile( hFile, lpAnsi, nBytes, &nBytesWritten, NULL ); 124 | } 125 | 126 | LocalFree( lpAnsi ); 127 | 128 | return( bStatus ); 129 | 130 | } // end of AnsiWriteFile() 131 | 132 | 133 | // Routines to deal with the soft EOL formatting. 134 | // 135 | // MLE Actually inserts characters into the text being under edit, so they 136 | // have to be removed before saving the file. 137 | // 138 | // It turns out that MLE will get confused if the current line is bigger than 139 | // the current file, so we will reset the cursor to 0,0 to keep it from looking stupid. 140 | // Should be fixed in MLE, but... 141 | // 142 | 143 | 144 | static DWORD dwStartSel; // saved start of selection 145 | static DWORD dwEndSel; // saved end of selection 146 | 147 | VOID ClearFmt(VOID) 148 | { 149 | 150 | if( fWrap ) 151 | { 152 | if( fMLE_is_broken ) 153 | { 154 | GotoAndScrollInView( 1 ); 155 | } 156 | else 157 | { 158 | SendMessage( hwndEdit, EM_GETSEL, (WPARAM) &dwStartSel, (LPARAM) &dwEndSel ); 159 | SendMessage( hwndEdit, EM_SETSEL, (WPARAM) 0, (LPARAM) 0 ); 160 | } 161 | 162 | SendMessage( hwndEdit, EM_FMTLINES, (WPARAM)FALSE, 0 ); // remove soft EOLs 163 | } 164 | 165 | } 166 | 167 | VOID RestoreFmt(VOID) 168 | { 169 | UINT CharIndex; 170 | 171 | if( fWrap ) 172 | { 173 | if( fMLE_is_broken ) 174 | { 175 | NpReCreate( ES_STD ); // slow but it works 176 | } 177 | else 178 | { 179 | SendMessage( hwndEdit, EM_FMTLINES, (WPARAM)TRUE, 0 ); // add soft EOLs 180 | SendMessage( hwndEdit, EM_SETSEL, (WPARAM) dwStartSel, (LPARAM) dwEndSel); 181 | } 182 | } 183 | 184 | 185 | } 186 | 187 | /* Save notepad file to disk. szFileSave points to filename. fSaveAs 188 | is TRUE iff we are being called from SaveAsDlgProc. This implies we must 189 | open file on current directory, whether or not it already exists there 190 | or somewhere else in our search path. 191 | Assumes that text exists within hwndEdit. 30 July 1991 Clark Cyr 192 | */ 193 | 194 | BOOL FAR SaveFile (HWND hwndParent, TCHAR *szFileSave, BOOL fSaveAs ) 195 | { 196 | LPTSTR lpch; 197 | UINT nChars; 198 | BOOL flag; 199 | BOOL fNew = FALSE; 200 | BOOL fDefCharUsed = FALSE; 201 | BOOL* pfDefCharUsed; 202 | static WCHAR wchBOM = BYTE_ORDER_MARK; 203 | static WCHAR wchRBOM= REVERSE_BYTE_ORDER_MARK; 204 | HLOCAL hEText; // handle to MLE text 205 | DWORD nBytesWritten; // number of bytes written 206 | DWORD nAsciiLength; // length of equivalent ascii file 207 | UINT cpTemp= CP_ACP; // code page to convert to 208 | DWORD dwFlags; // flags for WideCharToMultiByte 209 | 210 | 211 | /* If saving to an existing file, make sure correct disk is in drive */ 212 | if (!fSaveAs) 213 | { 214 | fp= CreateFile( szFileSave, // name of file 215 | GENERIC_READ|GENERIC_WRITE, // access mode 216 | FILE_SHARE_READ, // share mode 217 | NULL, // security descriptor 218 | OPEN_EXISTING, // how to create 219 | FILE_ATTRIBUTE_NORMAL, // file attributes 220 | NULL); // hnd of file with attrs 221 | } 222 | else 223 | { 224 | 225 | // Carefully open the file. Do not truncate it if it exists. 226 | // set the fNew flag if it had to be created. 227 | // We do all this in case of failures later in the process. 228 | 229 | fp= CreateFile( szFileSave, // name of file 230 | GENERIC_READ|GENERIC_WRITE, // access mode 231 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode 232 | NULL, // security descriptor 233 | OPEN_ALWAYS, // how to create 234 | FILE_ATTRIBUTE_NORMAL, // file attributes 235 | NULL); // hnd of file with attrs 236 | 237 | if( fp != INVALID_HANDLE_VALUE ) 238 | { 239 | fNew= (GetLastError() != ERROR_ALREADY_EXISTS ); 240 | } 241 | } 242 | 243 | if( fp == INVALID_HANDLE_VALUE ) 244 | { 245 | AlertBox( hwndParent, szNN, szCREATEERR, szFileSave, 246 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 247 | return FALSE; 248 | } 249 | 250 | 251 | // if wordwrap, remove soft carriage returns 252 | // Also move the cursor to a safe place to get around MLE bugs 253 | 254 | if( fWrap ) 255 | { 256 | ClearFmt(); 257 | } 258 | 259 | /* Must get text length after formatting */ 260 | nChars = (UINT)SendMessage (hwndEdit, WM_GETTEXTLENGTH, 0, (LPARAM)0); 261 | 262 | hEText= (HANDLE) SendMessage( hwndEdit, EM_GETHANDLE, 0,0 ); 263 | if( !hEText || !(lpch= (LPTSTR) LocalLock(hEText) )) 264 | { 265 | AlertUser_FileFail( szFileSave ); 266 | goto CleanUp; 267 | } 268 | 269 | 270 | 271 | 272 | // Determine the SaveAs file type, and write the appropriate BOM. 273 | // If the filetype is UTF-8 or Ansi, do the conversion. 274 | switch(g_ftSaveAs) 275 | { 276 | case FT_UNICODE: 277 | WriteFile( fp, &wchBOM, ByteCountOf(1), &nBytesWritten, NULL ); 278 | flag= WriteFile(fp, lpch, ByteCountOf(nChars), &nBytesWritten, NULL); 279 | break; 280 | 281 | case FT_UNICODEBE: 282 | WriteFile( fp, &wchRBOM, ByteCountOf(1), &nBytesWritten, NULL ); 283 | ReverseEndian( lpch, lpch,nChars ); 284 | flag= WriteFile(fp, lpch, ByteCountOf(nChars), &nBytesWritten, NULL); 285 | ReverseEndian( lpch, lpch, nChars ); 286 | break; 287 | 288 | // If it UTF-8, write the BOM (3 bytes), set the code page and fall 289 | // through to the default case. 290 | case FT_UTF8: 291 | WriteFile( fp, &BOM_UTF8, 3, &nBytesWritten, NULL ); 292 | // fall through to convert and write the file 293 | 294 | default: 295 | 296 | if (g_ftSaveAs != FT_UTF8) 297 | { 298 | // 299 | // Always use the current locale code page to do the translation 300 | // If the user changes locales, they will need to know what locale 301 | // this version of the file was saved with. Since we don't save that 302 | // information, the user may be in trouble. Unicode would save his bacon. 303 | // 304 | 305 | cpTemp= GetACP(); 306 | 307 | pfDefCharUsed= &fDefCharUsed; 308 | dwFlags= WC_NO_BEST_FIT_CHARS; 309 | } 310 | else 311 | { 312 | cpTemp= CP_UTF8; 313 | pfDefCharUsed= NULL; // these must be NULL and 0 for this code page 314 | dwFlags= 0; 315 | } 316 | 317 | 318 | nAsciiLength= WideCharToMultiByte( cpTemp, 319 | dwFlags, 320 | (LPWSTR)lpch, 321 | nChars, 322 | NULL, 323 | 0, 324 | NULL, // if no conversion, use default char 325 | pfDefCharUsed); 326 | 327 | // If we can't round-trip the character, warn the user. 328 | // If we don't use WC_NO_BEST_FIT_CHARS, WCTMB() will convert some characters 329 | // without setting the fDefCharUsed (for example alt-233) 330 | // This fixes ntbug9:367586 331 | 332 | if( fDefCharUsed || (nChars && (nAsciiLength==0) ) ) 333 | { 334 | if ( AlertBox( hwndParent, szNN, szErrUnicode, szFileSave, 335 | MB_APPLMODAL|MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) 336 | goto CleanUp; 337 | 338 | // User has approved loss of data, so try conversion with flags 339 | // that allow loss. ntbug9: 435042 340 | 341 | dwFlags= 0; 342 | } 343 | flag= AnsiWriteFile( fp, cpTemp, dwFlags, lpch, nChars ); 344 | break; 345 | } 346 | 347 | 348 | if (!flag) 349 | { 350 | SetCursor(hStdCursor); /* display normal cursor */ 351 | 352 | AlertUser_FileFail( szFileSave ); 353 | CleanUp: 354 | SetCursor( hStdCursor ); 355 | CloseHandle (fp); fp=INVALID_HANDLE_VALUE; 356 | if( hEText ) 357 | LocalUnlock( hEText ); 358 | if (fNew) 359 | DeleteFile (szFileSave); 360 | /* if wordwrap, insert soft carriage returns */ 361 | if (fWrap) 362 | { 363 | RestoreFmt(); 364 | } 365 | return FALSE; 366 | } 367 | else 368 | { 369 | SetEndOfFile (fp); 370 | g_ftOpenedAs = g_ftSaveAs; 371 | SendMessage (hwndEdit, EM_SETMODIFY, FALSE, 0L); 372 | SetTitle (szFileSave); 373 | fUntitled = FALSE; 374 | } 375 | 376 | CloseHandle (fp); fp=INVALID_HANDLE_VALUE; 377 | 378 | if( hEText ) 379 | LocalUnlock( hEText ); 380 | 381 | /* if wordwrap, insert soft carriage returns */ 382 | if (fWrap) 383 | { 384 | RestoreFmt(); 385 | } 386 | 387 | /* Display the hour glass cursor */ 388 | SetCursor(hStdCursor); 389 | 390 | return TRUE; 391 | 392 | } // end of SaveFile() 393 | 394 | /* Read contents of file from disk. 395 | * Do any conversions required. 396 | * File is already open, referenced by handle fp 397 | * Close the file when done. 398 | * If typeFlag>=0, then use it as filetype, otherwise do automagic guessing. 399 | */ 400 | 401 | BOOL FAR LoadFile (TCHAR * sz, INT typeFlag ) 402 | { 403 | UINT len, i, nChars; 404 | LPTSTR lpch=NULL; 405 | LPTSTR lpBuf; 406 | LPSTR lpBufAfterBOM; 407 | BOOL fLog=FALSE; 408 | TCHAR* p; 409 | TCHAR szSave[MAX_PATH]; /* Private copy of current filename */ 410 | BOOL bUnicode=FALSE; /* true if file detected as unicode */ 411 | BOOL bUTF8=FALSE; /* true if file detected as UTF-8 */ 412 | DWORD nBytesRead; // number of bytes read 413 | BY_HANDLE_FILE_INFORMATION fiFileInfo; 414 | BOOL bStatus; // boolean status 415 | HLOCAL hNewEdit=NULL; // new handle for edit buffer 416 | HANDLE hMap; // file mapping handle 417 | TCHAR szNullFile[2]; // fake null mapped file 418 | INT cpTemp = CP_ACP; 419 | NP_FILETYPE ftOpenedAs=FT_UNKNOWN; 420 | 421 | 422 | if( fp == INVALID_HANDLE_VALUE ) 423 | { 424 | AlertUser_FileFail( sz ); 425 | return (FALSE); 426 | } 427 | 428 | // 429 | // Get size of file 430 | // We use this heavy duty GetFileInformationByHandle API 431 | // because it finds bugs. It takes longer, but it only is 432 | // called at user interaction time. 433 | // 434 | 435 | bStatus= GetFileInformationByHandle( fp, &fiFileInfo ); 436 | len= (UINT) fiFileInfo.nFileSizeLow; 437 | 438 | // NT may delay giving this status until the file is accessed. 439 | // i.e. the open succeeds, but operations may fail on damaged files. 440 | 441 | if( !bStatus ) 442 | { 443 | AlertUser_FileFail( sz ); 444 | CloseHandle( fp ); fp=INVALID_HANDLE_VALUE; 445 | return( FALSE ); 446 | } 447 | 448 | // If the file is too big, fail now. 449 | // -1 not valid because we need a zero on the end. 450 | 451 | 452 | // If the file is too big, fail now. 453 | // -1 not valid because we need a zero on the end. 454 | // 455 | // bug# 168148: silently fails to open 2.4 gig text file on win64 456 | // Caused by trying to convert ascii file to unicode which overflowed 457 | // the dword length handled by multibytetowidechar conversion. 458 | // Since no one will be happy with the performance of the MLE with 459 | // a file this big, we will just refuse to open it now. 460 | // 461 | // For example, on a Pentium 173 MHz with 192 Megs o'RAM (Tecra 8000) 462 | // I got these results: 463 | // 464 | // size CPU-time 465 | // 0 .12 466 | // 1 .46 467 | // 2 .77 468 | // 3 1.041 469 | // 4 1.662 470 | // 5 2.092 471 | // 6 2.543 472 | // 7 3.023 473 | // 8 3.534 474 | // 9 4.084 475 | // 10 4.576 476 | // 16 8.371 477 | // 32 23.142 478 | // 64 74.426 479 | // 480 | // Curve fitting these numbers to cpu-time=a+b*size+c*size*size 481 | // we get a really good fit with cpu= .24+.28*size+.013*size*size 482 | // 483 | // For 1 gig, this works out to be 3.68 hours. 2 gigs=14.6 hours 484 | // 485 | // And the user isn't going to be happy with adding or deleting characters 486 | // with the MLE control. It wants to keep the memory stuctures uptodate 487 | // at all times. 488 | // 489 | // Going to richedit isn't a near term solution either: 490 | // 491 | // size CPU-time 492 | // 2 3.8 493 | // 4 9.0 494 | // 6 21.9 495 | // 8 30.4 496 | // 10 65.3 497 | // 16 1721 or >3.5 hours (it was still running when I killed it) 498 | // 499 | // 500 | // feature: should we only bail if not unicode? 501 | // 502 | 503 | if( len >=0x40000000 || fiFileInfo.nFileSizeHigh != 0 ) 504 | { 505 | AlertBox( hwndNP, szNN, szFTL, sz, 506 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 507 | CloseHandle (fp); fp=INVALID_HANDLE_VALUE; 508 | return (FALSE); 509 | } 510 | 511 | SetCursor(hWaitCursor); // physical I/O takes time 512 | 513 | // 514 | // Create a file mapping so we don't page the file to 515 | // the pagefile. This is a big win on small ram machines. 516 | // 517 | 518 | if( len != 0 ) 519 | { 520 | lpBuf= NULL; 521 | 522 | hMap= CreateFileMapping( fp, NULL, PAGE_READONLY, 0, len, NULL ); 523 | 524 | if( hMap ) 525 | { 526 | lpBuf= MapViewOfFile( hMap, FILE_MAP_READ, 0,0,len); 527 | CloseHandle( hMap ); 528 | } 529 | } 530 | else // file mapping doesn't work on zero length files 531 | { 532 | lpBuf= (LPTSTR) &szNullFile; 533 | *lpBuf= 0; // null terminate 534 | } 535 | 536 | CloseHandle( fp ); fp=INVALID_HANDLE_VALUE; 537 | 538 | if( lpBuf == NULL ) 539 | { 540 | SetCursor( hStdCursor ); 541 | AlertUser_FileFail( sz ); 542 | return( FALSE ); 543 | } 544 | 545 | 546 | // 547 | // protect access to the mapped file with a try/except so we 548 | // can detect I/O errors. 549 | // 550 | 551 | // 552 | // WARNING: be very very careful. This code is pretty fragile. 553 | // Files across the network, or RSM files (tape) may throw excepts 554 | // at random points in this code. Anywhere the code touches the 555 | // memory mapped file can cause an AV. Make sure variables are 556 | // in consistent state if an exception is thrown. Be very careful 557 | // with globals. 558 | 559 | __try 560 | { 561 | /* Determine the file type and number of characters 562 | * If the user overrides, use what is specified. 563 | * Otherwise, we depend on 'IsTextUnicode' getting it right. 564 | * If it doesn't, bug IsTextUnicode. 565 | */ 566 | 567 | lpBufAfterBOM= (LPSTR) lpBuf; 568 | if( typeFlag == FT_UNKNOWN ) 569 | { 570 | switch(*lpBuf) 571 | { 572 | case BYTE_ORDER_MARK: 573 | bUnicode= TRUE; 574 | ftOpenedAs= FT_UNICODE; 575 | 576 | // don't count the BOM. 577 | nChars= len / sizeof(TCHAR) -1; 578 | break; 579 | 580 | case REVERSE_BYTE_ORDER_MARK: 581 | bUnicode= TRUE; 582 | ftOpenedAs= FT_UNICODEBE; 583 | 584 | // don't count the BOM. 585 | nChars= len / sizeof(TCHAR) -1; 586 | break; 587 | 588 | // UTF bom has 3 bytes; if it doesn't have UTF BOM just fall through .. 589 | case BOM_UTF8_HALF: 590 | if (len > 2 && ((BYTE) *(((LPSTR)lpBuf)+2) == BOM_UTF8_2HALF) ) 591 | { 592 | bUTF8= TRUE; 593 | cpTemp= CP_UTF8; 594 | ftOpenedAs= FT_UTF8; 595 | // Ignore the first three bytes. 596 | lpBufAfterBOM= (LPSTR)lpBuf + 3; 597 | len -= 3; 598 | break; 599 | } 600 | 601 | default: 602 | 603 | // Is the file unicode without BOM ? 604 | if ((bUnicode= IsInputTextUnicode((LPSTR) lpBuf, len))) 605 | { 606 | ftOpenedAs= FT_UNICODE; 607 | nChars= len / sizeof(TCHAR); 608 | } 609 | else 610 | { 611 | // Is the file UTF-8 even though it doesn't have UTF-8 BOM. 612 | if ((bUTF8= IsTextUTF8((LPSTR) lpBuf, len))) 613 | { 614 | ftOpenedAs= FT_UTF8; 615 | cpTemp= CP_UTF8; 616 | } 617 | // well, not it must be an ansi file! 618 | else 619 | { 620 | ftOpenedAs= FT_ANSI; 621 | cpTemp= CP_ACP; 622 | } 623 | } 624 | break; 625 | } 626 | } 627 | else 628 | { 629 | switch(typeFlag) 630 | { 631 | case FT_UNICODE: 632 | 633 | bUnicode= TRUE; 634 | ftOpenedAs= FT_UNICODE; 635 | 636 | nChars= len / sizeof(TCHAR); 637 | 638 | // don't count the BOM. 639 | if (*lpBuf == BYTE_ORDER_MARK) 640 | nChars--; 641 | break; 642 | 643 | case FT_UNICODEBE: 644 | 645 | bUnicode= TRUE; 646 | ftOpenedAs= FT_UNICODE; 647 | 648 | nChars= len / sizeof(TCHAR); 649 | 650 | // don't count the BOM. 651 | if (*lpBuf == REVERSE_BYTE_ORDER_MARK) 652 | nChars--; 653 | break; 654 | 655 | 656 | case FT_UTF8: 657 | 658 | bUTF8= TRUE; 659 | cpTemp= CP_UTF8; 660 | ftOpenedAs= FT_UTF8; 661 | 662 | if (len > 2 && ((*lpBuf == BOM_UTF8_HALF) && ((BYTE) *(((LPSTR)lpBuf)+2) == BOM_UTF8_2HALF)) ) 663 | { 664 | // Ignore the first three bytes. 665 | lpBufAfterBOM= (LPSTR)lpBuf + 3; 666 | len -= 3; 667 | break; 668 | } 669 | break; 670 | 671 | 672 | case FT_ANSI: 673 | default: 674 | 675 | ftOpenedAs= FT_ANSI; 676 | cpTemp= CP_ACP; 677 | break; 678 | } 679 | } 680 | 681 | 682 | // find out no. of chars present in the string. 683 | if (!bUnicode) 684 | { 685 | nChars = MultiByteToWideChar (cpTemp, 686 | 0, 687 | (LPSTR)lpBufAfterBOM, 688 | len, 689 | NULL, 690 | 0); 691 | } 692 | 693 | // 694 | // Don't display text until all done. 695 | // 696 | 697 | SendMessage (hwndEdit, WM_SETREDRAW, (WPARAM)FALSE, (LPARAM)0); 698 | 699 | // Reset selection to 0 700 | 701 | SendMessage(hwndEdit, EM_SETSEL, 0, 0L); 702 | SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0); 703 | 704 | // resize the edit buffer 705 | // if we can't resize the memory, inform the user 706 | 707 | if (!(hNewEdit= LocalReAlloc(hEdit,ByteCountOf(nChars + 1),LMEM_MOVEABLE))) 708 | { 709 | /* Bug 7441: New() causes szFileName to be set to "Untitled". Save a 710 | * copy of the filename to pass to AlertBox. 711 | * 17 November 1991 Clark R. Cyr 712 | */ 713 | lstrcpy(szSave, sz); 714 | New(FALSE); 715 | 716 | /* Display the hour glass cursor */ 717 | SetCursor(hStdCursor); 718 | 719 | AlertBox( hwndNP, szNN, szFTL, szSave, 720 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 721 | if( lpBuf != (LPTSTR) &szNullFile ) 722 | { 723 | UnmapViewOfFile( lpBuf ); 724 | } 725 | 726 | // let user see old text 727 | 728 | SendMessage (hwndEdit, WM_SETREDRAW, (WPARAM)FALSE, (LPARAM)0); 729 | return FALSE; 730 | } 731 | 732 | /* Transfer file from temporary buffer to the edit buffer */ 733 | lpch= (LPTSTR) LocalLock(hNewEdit); 734 | 735 | if( bUnicode ) 736 | { 737 | /* skip the Byte Order Mark */ 738 | if (*lpBuf == BYTE_ORDER_MARK) 739 | { 740 | CopyMemory (lpch, lpBuf + 1, ByteCountOf(nChars)); 741 | } 742 | else if( *lpBuf == REVERSE_BYTE_ORDER_MARK ) 743 | { 744 | ReverseEndian( lpch, lpBuf+1, nChars ); 745 | } 746 | else 747 | { 748 | CopyMemory (lpch, lpBuf, ByteCountOf(nChars)); 749 | } 750 | } 751 | else 752 | { 753 | nChars = MultiByteToWideChar (cpTemp, 754 | 0, 755 | (LPSTR)lpBufAfterBOM, 756 | len, 757 | (LPWSTR)lpch, 758 | nChars); 759 | 760 | } 761 | 762 | g_ftOpenedAs= ftOpenedAs; // got everything; update global safe now 763 | 764 | } 765 | __except(EXCEPTION_EXECUTE_HANDLER) 766 | { 767 | AlertBox( hwndNP, szNN, szDiskError, sz, 768 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION ); 769 | nChars= 0; // don't deal with it. 770 | } 771 | 772 | /* Free file mapping */ 773 | if( lpBuf != (LPTSTR) &szNullFile ) 774 | { 775 | UnmapViewOfFile( lpBuf ); 776 | } 777 | 778 | 779 | if( lpch ) 780 | { 781 | 782 | // Fix any NUL character that came in from the file to be spaces. 783 | 784 | for (i = 0, p = lpch; i < nChars; i++, p++) 785 | { 786 | if( *p == (TCHAR) 0 ) 787 | *p= TEXT(' '); 788 | } 789 | 790 | // null terminate it. Safe even if nChars==0 because it is 1 TCHAR bigger 791 | 792 | *(lpch+nChars)= (TCHAR) 0; /* zero terminate the thing */ 793 | 794 | // Set 'fLog' if first characters in file are ".LOG" 795 | 796 | fLog= *lpch++ == TEXT('.') && *lpch++ == TEXT('L') && 797 | *lpch++ == TEXT('O') && *lpch == TEXT('G'); 798 | } 799 | 800 | if( hNewEdit ) 801 | { 802 | LocalUnlock( hNewEdit ); 803 | 804 | // now it is safe to set the global edit handle 805 | 806 | hEdit= hNewEdit; 807 | } 808 | 809 | lstrcpy( szFileName, sz ); 810 | SetTitle( sz ); 811 | fUntitled= FALSE; 812 | 813 | /* Pass handle to edit control. This is more efficient than WM_SETTEXT 814 | * which would require twice the buffer space. 815 | */ 816 | 817 | /* Bug 7443: If EM_SETHANDLE doesn't have enough memory to complete things, 818 | * it will send the EN_ERRSPACE message. If this happens, don't put up the 819 | * out of memory notification, put up the file to large message instead. 820 | * 17 November 1991 Clark R. Cyr 821 | */ 822 | dwEmSetHandle = SETHANDLEINPROGRESS; 823 | SendMessage (hwndEdit, EM_SETHANDLE, (WPARAM)hEdit, (LPARAM)0); 824 | if (dwEmSetHandle == SETHANDLEFAILED) 825 | { 826 | SetCursor(hStdCursor); 827 | 828 | dwEmSetHandle = 0; 829 | AlertBox( hwndNP, szNN, szFTL, sz,MB_APPLMODAL|MB_OK|MB_ICONEXCLAMATION); 830 | New (FALSE); 831 | SendMessage (hwndEdit, WM_SETREDRAW, (WPARAM)TRUE, (LPARAM)0); 832 | return (FALSE); 833 | } 834 | dwEmSetHandle = 0; 835 | 836 | PostMessage (hwndEdit, EM_LIMITTEXT, (WPARAM)CCHNPMAX, 0L); 837 | 838 | /* If file starts with ".LOG" go to end and stamp date time */ 839 | if (fLog) 840 | { 841 | SendMessage( hwndEdit, EM_SETSEL, (WPARAM)nChars, (LPARAM)nChars); 842 | SendMessage( hwndEdit, EM_SCROLLCARET, 0, 0); 843 | InsertDateTime(TRUE); 844 | } 845 | 846 | /* Move vertical thumb to correct position */ 847 | SetScrollPos (hwndNP, 848 | SB_VERT, 849 | (int) SendMessage (hwndEdit, WM_VSCROLL, EM_GETTHUMB, 0L), 850 | TRUE); 851 | 852 | /* Now display text */ 853 | SendMessage( hwndEdit, WM_SETREDRAW, (WPARAM)TRUE, (LPARAM)0 ); 854 | InvalidateRect( hwndEdit, (LPRECT)NULL, TRUE ); 855 | UpdateWindow( hwndEdit ); 856 | 857 | SetCursor(hStdCursor); 858 | 859 | return( TRUE ); 860 | 861 | } // end of LoadFile() 862 | 863 | /* New Command - reset everything 864 | */ 865 | 866 | void FAR New (BOOL fCheck) 867 | { 868 | HANDLE hTemp; 869 | TCHAR* pSz; 870 | 871 | if (!fCheck || CheckSave (FALSE)) 872 | { 873 | SendMessage( hwndEdit, WM_SETTEXT, (WPARAM)0, (LPARAM)TEXT("") ); 874 | fUntitled= TRUE; 875 | lstrcpy( szFileName, szUntitled ); 876 | SetTitle(szFileName ); 877 | SendMessage( hwndEdit, EM_SETSEL, 0, 0L ); 878 | SendMessage( hwndEdit, EM_SCROLLCARET, 0, 0 ); 879 | 880 | // resize of 1 NULL character i.e. zero length 881 | 882 | hTemp= LocalReAlloc( hEdit, sizeof(TCHAR), LMEM_MOVEABLE ); 883 | if( hTemp ) 884 | { 885 | hEdit= hTemp; 886 | } 887 | 888 | // null terminate the buffer. LocalReAlloc won't do it 889 | // because in all cases it is not growing which is the 890 | // only time it would zero out anything. 891 | 892 | pSz= LocalLock( hEdit ); 893 | *pSz= TEXT('\0'); 894 | LocalUnlock( hEdit ); 895 | 896 | SendMessage (hwndEdit, EM_SETHANDLE, (WPARAM)hEdit, 0L); 897 | szSearch[0] = (TCHAR) 0; 898 | } 899 | 900 | } // end of New() 901 | 902 | /* If sz does not have extension, append ".txt" 903 | * This function is useful for getting to undecorated filenames 904 | * that setup apps use. DO NOT CHANGE the extension. Too many setup 905 | * apps depend on this functionality. 906 | */ 907 | 908 | void FAR AddExt( TCHAR* sz ) 909 | { 910 | TCHAR* pch1; 911 | int ch; 912 | DWORD dwSize; 913 | 914 | dwSize= lstrlen(sz); 915 | 916 | pch1= sz + dwSize; // point to end 917 | 918 | ch= *pch1; 919 | while( ch != TEXT('.') && ch != TEXT('\\') && ch != TEXT(':') && pch1 > sz) 920 | { 921 | // 922 | // backup one character. Do NOT use CharPrev because 923 | // it sometimes doesn't actually backup. Some Thai 924 | // tone marks fit this category but there seems to be others. 925 | // This is safe since it will stop at the beginning of the 926 | // string or on delimiters listed above. bug# 139374 2/13/98 927 | // 928 | // pch1= (TCHAR*)CharPrev (sz, pch1); 929 | pch1--; // back up 930 | ch= *pch1; 931 | } 932 | 933 | if( *pch1 != TEXT('.') ) 934 | { 935 | if( dwSize + sizeof(".txt") <= MAX_PATH ) { // avoid buffer overruns 936 | lstrcat( sz, TEXT(".txt") ); 937 | } 938 | } 939 | 940 | } 941 | 942 | 943 | /* AlertUser_FileFail( LPTSTR szFileName ) 944 | * 945 | * szFileName is the name of file that was attempted to open. 946 | * Some sort of failure on file open. Alert the user 947 | * with some monologue box. At least give him decent 948 | * error messages. 949 | */ 950 | 951 | VOID FAR AlertUser_FileFail( LPTSTR szFileName ) 952 | { 953 | TCHAR msg[256]; // buffer to format message into 954 | DWORD dwStatus; // status from FormatMessage 955 | UINT style= MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION; 956 | 957 | // Check GetLastError to see why we failed 958 | dwStatus= 959 | FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | 960 | FORMAT_MESSAGE_FROM_SYSTEM, 961 | NULL, 962 | GetLastError(), 963 | GetUserDefaultLangID(), 964 | msg, // where message will end up 965 | CharSizeOf(msg), NULL ); 966 | if( dwStatus ) 967 | { 968 | MessageBox( hwndNP, msg, szNN, style ); 969 | } 970 | else 971 | { 972 | AlertBox( hwndNP, szNN, szDiskError, szFileName, style ); 973 | } 974 | } 975 | -------------------------------------------------------------------------------- /npinit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Notepad application 3 | * 4 | * Copyright (C) 1984-1995 Microsoft Inc. 5 | * 6 | * NPInit - One time init for notepad. 7 | * Routines are in a separate segment. 8 | */ 9 | 10 | #include "precomp.h" 11 | 12 | 13 | TCHAR chPageText[2][PT_LEN]; /* Strings to hold PageSetup items. */ 14 | TCHAR chPageTextTemp[2][PT_LEN]; 15 | TCHAR szPrinterName[256]; /* String to hold printername for PrintTo verb */ 16 | 17 | static NP_FILETYPE fInitFileType; /* file type override */ 18 | static INT fSaveWindowPositions=0; /* true if we are to save window position */ 19 | 20 | static INT g_WPtop,g_WPleft,g_WPDX,g_WPDY; /* initial window positions */ 21 | 22 | /* routines to handle saving and restoring information in the registry. 23 | * 24 | * SaveGlobals - saves interesting globals to the registry 25 | * 26 | * GetGlobals - gets interesting globals from the registry 27 | * 28 | * Interesting Globals: 29 | * 30 | * FontStruct information include calculated pointsize 31 | * Codepage 32 | * 33 | * If we want to save PageSetup info, save the margins in some 34 | * units (cm for example) and convert on input and output. 35 | */ 36 | 37 | /* name of section to save into -- never internationalize */ 38 | #define OURKEYNAME TEXT("Software\\Microsoft\\Notepad") 39 | 40 | // RegWriteInt - write an integer to the registry 41 | 42 | VOID RegWriteInt( HKEY hKey, PTCHAR pszKey, INT iValue ) 43 | { 44 | RegSetValueEx( hKey, pszKey, 0, REG_DWORD, (BYTE*)&iValue, sizeof(INT) ); 45 | } 46 | 47 | // RegWriteString - write a string to the registry 48 | 49 | VOID RegWriteString( HKEY hKey, PTCHAR pszKey, PTCHAR pszValue ) 50 | { 51 | INT len; // length of string with null in bytes 52 | 53 | len= (lstrlen( pszValue )+1) * sizeof(TCHAR); 54 | RegSetValueEx( hKey, pszKey, 0, REG_SZ, (BYTE*)pszValue, len ); 55 | } 56 | 57 | // RegGetInt - Get integer from registry 58 | 59 | DWORD RegGetInt( HKEY hKey, PTCHAR pszKey, DWORD dwDefault ) 60 | { 61 | DWORD dwResult= !ERROR_SUCCESS; 62 | LONG lStatus= ERROR_SUCCESS; 63 | DWORD dwSize= sizeof(DWORD); 64 | DWORD dwType= 0; 65 | 66 | if( hKey ) 67 | { 68 | lStatus= RegQueryValueEx( hKey, 69 | pszKey, 70 | NULL, 71 | &dwType, 72 | (BYTE*) &dwResult, 73 | &dwSize ); 74 | } 75 | 76 | if( lStatus != ERROR_SUCCESS || dwType != REG_DWORD ) 77 | { 78 | dwResult= dwDefault; 79 | } 80 | return( dwResult ); 81 | } 82 | 83 | // RegGetString - get string from registry 84 | 85 | VOID RegGetString( HKEY hKey, PTCHAR pszKey, PTCHAR pszDefault, PTCHAR pszResult, INT iCharLen ) 86 | { 87 | LONG lStatus= !ERROR_SUCCESS; 88 | DWORD dwSize; // size of buffer 89 | DWORD dwType; 90 | 91 | dwSize= iCharLen * sizeof(TCHAR); 92 | 93 | if( hKey ) 94 | { 95 | lStatus= RegQueryValueEx( hKey, 96 | pszKey, 97 | NULL, 98 | &dwType, 99 | (BYTE*) pszResult, 100 | &dwSize ); 101 | } 102 | 103 | if( lStatus != ERROR_SUCCESS || dwType != REG_SZ ) 104 | { 105 | CopyMemory( pszResult, pszDefault, iCharLen*sizeof(TCHAR) ); 106 | } 107 | } 108 | 109 | 110 | // lfHeight is calculated using PointSize 111 | // lfWidth set by font mapper 112 | 113 | 114 | VOID SaveGlobals(VOID) 115 | { 116 | HKEY hKey; // key to our registry root 117 | LONG lStatus; // status from RegCreateKey 118 | WINDOWPLACEMENT wp; 119 | 120 | lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey ); 121 | if( lStatus != ERROR_SUCCESS ) 122 | { 123 | return; // just return quietly 124 | } 125 | 126 | RegWriteInt( hKey, TEXT("lfEscapement"), FontStruct.lfEscapement); 127 | RegWriteInt( hKey, TEXT("lfOrientation"), FontStruct.lfOrientation); 128 | RegWriteInt( hKey, TEXT("lfWeight"), FontStruct.lfWeight); 129 | RegWriteInt( hKey, TEXT("lfItalic"), FontStruct.lfItalic); 130 | RegWriteInt( hKey, TEXT("lfUnderline"), FontStruct.lfUnderline); 131 | RegWriteInt( hKey, TEXT("lfStrikeOut"), FontStruct.lfStrikeOut); 132 | RegWriteInt( hKey, TEXT("lfCharSet"), FontStruct.lfCharSet); 133 | RegWriteInt( hKey, TEXT("lfOutPrecision"), FontStruct.lfOutPrecision); 134 | RegWriteInt( hKey, TEXT("lfClipPrecision"), FontStruct.lfClipPrecision); 135 | RegWriteInt( hKey, TEXT("lfQuality"), FontStruct.lfQuality); 136 | RegWriteInt( hKey, TEXT("lfPitchAndFamily"), FontStruct.lfPitchAndFamily); 137 | RegWriteInt( hKey, TEXT("iPointSize"), iPointSize); 138 | RegWriteInt( hKey, TEXT("fWrap"), fWrap); 139 | RegWriteInt( hKey, TEXT("StatusBar"), fStatus); 140 | RegWriteInt( hKey, TEXT("fSaveWindowPositions"),fSaveWindowPositions ); 141 | 142 | RegWriteString( hKey, TEXT("lfFaceName"), FontStruct.lfFaceName); 143 | 144 | RegWriteString( hKey, TEXT("szHeader"), chPageText[HEADER] ); 145 | RegWriteString( hKey, TEXT("szTrailer"), chPageText[FOOTER] ); 146 | RegWriteInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top ); 147 | RegWriteInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom ); 148 | RegWriteInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left ); 149 | RegWriteInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right ); 150 | 151 | RegWriteInt( hKey, TEXT("fMLE_is_broken"), fMLE_is_broken ); 152 | 153 | wp.length= sizeof(wp); 154 | 155 | if( GetWindowPlacement( hwndNP, &wp ) ) 156 | { 157 | RegWriteInt( hKey, TEXT("iWindowPosX"), wp.rcNormalPosition.left); 158 | RegWriteInt( hKey, TEXT("iWindowPosY"), wp.rcNormalPosition.top); 159 | RegWriteInt( hKey, TEXT("iWindowPosDX"), wp.rcNormalPosition.right - wp.rcNormalPosition.left); 160 | RegWriteInt( hKey, TEXT("iWindowPosDY"), wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); 161 | } 162 | 163 | RegCloseKey( hKey ); 164 | } 165 | 166 | 167 | // GetGlobals 168 | // 169 | // Pick up font information etc that may be saved in the registry. 170 | // 171 | // We are called pretty early in setup and don't have things like hwndNP valid yet. 172 | // 173 | 174 | VOID GetGlobals( VOID ) 175 | { 176 | LOGFONT lfDef; // default logical font 177 | HFONT hFont; // standard font to use 178 | LONG lStatus; // status from RegCreateKey 179 | HKEY hKey; // key into registry 180 | 181 | // 182 | // quickly get a reasonable set of default parameters 183 | // for the default font if we need it. 184 | // 185 | 186 | hFont= GetStockObject( SYSTEM_FIXED_FONT ); 187 | 188 | if ( hFont ) 189 | { 190 | GetObject( hFont, sizeof(LOGFONT), &lfDef ); 191 | } 192 | 193 | lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey ); 194 | if( lStatus != ERROR_SUCCESS ) 195 | { 196 | hKey= NULL; // later calls to RegGet... will return defaults 197 | } 198 | FontStruct.lfWidth= 0; 199 | 200 | 201 | 202 | FontStruct.lfEscapement= (LONG)RegGetInt( hKey, TEXT("lfEscapement"), lfDef.lfEscapement); 203 | FontStruct.lfOrientation= (LONG)RegGetInt( hKey, TEXT("lfOrientation"), lfDef.lfOrientation); 204 | FontStruct.lfWeight= (LONG)RegGetInt( hKey, TEXT("lfWeight"), lfDef.lfWeight); 205 | FontStruct.lfItalic= (BYTE)RegGetInt( hKey, TEXT("lfItalic"), lfDef.lfItalic); 206 | FontStruct.lfUnderline= (BYTE)RegGetInt( hKey, TEXT("lfUnderline"), lfDef.lfUnderline); 207 | FontStruct.lfStrikeOut= (BYTE)RegGetInt( hKey, TEXT("lfStrikeOut"), lfDef.lfStrikeOut); 208 | 209 | // 210 | // We have to preserve lfCharSet because some fonts (symbol, marlett) don't handle 211 | // 0 (ANSI_CHARSET) or 1 (DEFAULT_CHARSET), and the font mapper will map to a 212 | // different facename. Later we will see if the CreateFont has the same FaceName 213 | // and get a more appropriate lfCharSet if need be. 214 | // 215 | 216 | FontStruct.lfCharSet= (BYTE)RegGetInt( hKey, TEXT("lfCharSet"), lfDef.lfCharSet); 217 | 218 | FontStruct.lfOutPrecision= (BYTE)RegGetInt( hKey, TEXT("lfOutPrecision"), lfDef.lfOutPrecision); 219 | FontStruct.lfClipPrecision= (BYTE)RegGetInt( hKey, TEXT("lfClipPrecision"), lfDef.lfClipPrecision); 220 | FontStruct.lfQuality= (BYTE)RegGetInt( hKey, TEXT("lfQuality"), lfDef.lfQuality); 221 | FontStruct.lfPitchAndFamily= (BYTE)RegGetInt( hKey, TEXT("lfPitchAndFamily"), lfDef.lfPitchAndFamily); 222 | 223 | // 224 | // If there is no FaceName in the registry, use the default "Lucida Console" 225 | // This will show off most of the glyphs except in the FE locales. 226 | // For FE, we can't font link fonts with the glyphs because they would have to have 227 | // the exact width as lucida console, or the console/csrss will AV (July 9, 1999) 228 | // 229 | 230 | RegGetString( hKey, TEXT("lfFaceName"), TEXT("Lucida Console"), FontStruct.lfFaceName, LF_FACESIZE); 231 | 232 | iPointSize= RegGetInt( hKey, TEXT("iPointSize"), 100); 233 | fWrap= RegGetInt( hKey, TEXT("fWrap"), 0); 234 | fStatus= RegGetInt( hKey, TEXT("StatusBar"), 0); 235 | fSaveWindowPositions= RegGetInt( hKey, TEXT("fSaveWindowPositions"), 0 ); 236 | 237 | // if page settings not in registry, we will use defaults 238 | 239 | RegGetString( hKey, TEXT("szHeader"), chPageText[HEADER], chPageText[HEADER], PT_LEN ); 240 | RegGetString( hKey, TEXT("szTrailer"), chPageText[FOOTER], chPageText[FOOTER], PT_LEN ); 241 | 242 | g_PageSetupDlg.rtMargin.top= (LONG)RegGetInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top ); 243 | g_PageSetupDlg.rtMargin.bottom= (LONG)RegGetInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom ); 244 | g_PageSetupDlg.rtMargin.left= (LONG)RegGetInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left ); 245 | g_PageSetupDlg.rtMargin.right= (LONG)RegGetInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right ); 246 | 247 | // if window positions in registry use them, otherwise us defaults 248 | 249 | g_WPtop= RegGetInt( hKey, TEXT("iWindowPosY"), CW_USEDEFAULT ); 250 | g_WPleft= RegGetInt( hKey, TEXT("iWindowPosX"), CW_USEDEFAULT ); 251 | g_WPDX= RegGetInt( hKey, TEXT("iWindowPosDX"), CW_USEDEFAULT ); 252 | g_WPDY= RegGetInt( hKey, TEXT("iWindowPosDY"), CW_USEDEFAULT ); 253 | 254 | 255 | fMLE_is_broken= RegGetInt( hKey, TEXT("fMLE_is_broken"), FALSE ); // assume edit control works 256 | 257 | if( hKey ) 258 | { 259 | RegCloseKey( hKey ); 260 | } 261 | 262 | } 263 | 264 | /* 265 | * lstrncmpi( str1, str2, len ) 266 | * compares two strings, str1 and str2, up 267 | * to length 'len' ignoring case. If they 268 | * are equal, we will return 0. Otherwise not 0. 269 | */ 270 | 271 | static 272 | INT lstrncmpi( PTCHAR sz1, PTCHAR sz2 ) 273 | { 274 | TCHAR ch1, ch2; 275 | while( *sz1 ) 276 | { 277 | ch1= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz1++ ); 278 | ch2= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz2++ ); 279 | if( ch1 != ch2 ) 280 | return 1; 281 | } 282 | return 0; // they are equal 283 | } 284 | 285 | static int NPRegister (HANDLE hInstance); 286 | 287 | /* GetFileName 288 | * 289 | * Parse off filename from command line and put 290 | * into lpFileName 291 | */ 292 | 293 | LPTSTR GetFileName( LPTSTR lpFileName, LPTSTR lpCmdLine ) 294 | { 295 | LPTSTR lpTemp = lpFileName; 296 | HANDLE hFindFile; 297 | WIN32_FIND_DATA info; 298 | 299 | /* 300 | ** Allow for filenames surrounded by double and single quotes 301 | ** like in longfilenames. 302 | */ 303 | if( *lpCmdLine == TEXT('\"') || *lpCmdLine == TEXT('\'') ) 304 | { 305 | TCHAR chMatch = *lpCmdLine; 306 | DWORD dwSize=0; 307 | 308 | // Copy over filename 309 | while( *(++lpCmdLine) && (*lpCmdLine != chMatch) && (dwSize= iElementSize-1 ) 379 | { 380 | #if DBG 381 | ODS(TEXT("notepad: resource string too long!\n")); 382 | #endif 383 | break; 384 | } 385 | total += len+1; // account for null terminator 386 | } 387 | LocalFree( Buf ); 388 | if( ids >= CSTRINGS ) 389 | break; 390 | iElementSize= iElementSize*2; 391 | } 392 | return( total ); 393 | } 394 | 395 | 396 | /* InitStrings - Get all text strings from resource file */ 397 | BOOL InitStrings (HANDLE hInstance) 398 | { 399 | TCHAR* pch; 400 | INT cchRemaining; 401 | INT ids, cch; 402 | 403 | // allocate memory and lock it down forever. we have pointers into it. 404 | // the localrealloc() function will not work well for freeing 405 | // unused memory because it may (and did) move memory. 406 | 407 | cchRemaining= SizeStrings( hInstance ); 408 | if( !cchRemaining ) 409 | return( FALSE ); // fail because we are out of memory 410 | 411 | pch= LocalAlloc( LPTR, ByteCountOf(cchRemaining) ); 412 | if( !pch ) 413 | return( FALSE ); 414 | 415 | cchRemaining= (INT)LocalSize( pch ) / sizeof(TCHAR); 416 | if( cchRemaining == 0 ) // can't alloc memory - failure 417 | return( FALSE ); 418 | 419 | for( ids = 0; ids < CSTRINGS; ids++ ) 420 | { 421 | cch= 1 + LoadString( hInstance, (UINT) (UINT_PTR) (*rgsz[ids]), pch, cchRemaining ); 422 | *rgsz[ids]= pch; 423 | pch += cch; 424 | 425 | if( cch > cchRemaining ) // should never happen 426 | { 427 | MessageBox( NULL, TEXT("Out of RC string space!!"), 428 | TEXT("DEV Error!"), MB_OK); 429 | return( FALSE ); 430 | } 431 | 432 | cchRemaining -= cch; 433 | } 434 | 435 | /* Get header and footer strings */ 436 | 437 | lstrcpyn( chPageText[HEADER], szHeader, PT_LEN ); 438 | lstrcpyn( chPageText[FOOTER], szFooter, PT_LEN ); 439 | 440 | chMerge= *szMerge; 441 | return (TRUE); 442 | } 443 | 444 | /* 445 | * SkipBlanks( pszText ) 446 | * skips blanks or tabs to either next character or EOL 447 | * returns pointer to same. 448 | */ 449 | PTCHAR SkipBlanks( PTCHAR pszText ) 450 | { 451 | while( *pszText == TEXT(' ') || *pszText == TEXT('\t') ) 452 | pszText++; 453 | 454 | return pszText; 455 | } 456 | 457 | 458 | // if /.SETUP option exists in the command line process it. 459 | BOOL ProcessSetupOption (LPTSTR lpszCmdLine) 460 | { 461 | INT iSta= 0; 462 | /* Search for /.SETUP in the command line */ 463 | if( !lstrncmpi( TEXT("/.SETUP"), lpszCmdLine ) ) 464 | { 465 | fRunBySetup = TRUE; 466 | /* Save system menu handle for INITMENUPOPUP message */ 467 | hSysMenuSetup =GetSystemMenu(hwndNP, FALSE); 468 | /* Allow exit on ^C, ^D and ^Z */ 469 | /* Note that LoadAccelerators must be called before */ 470 | /* TranslateAccelerator is called, true here */ 471 | hAccel = LoadAccelerators(hInstanceNP, TEXT("SlipUpAcc")); 472 | lpszCmdLine += 7; 473 | } 474 | else 475 | return FALSE; 476 | 477 | /* Don't offer a minimize button */ 478 | SetWindowLong( hwndNP, GWL_STYLE, 479 | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | 480 | WS_THICKFRAME | WS_MAXIMIZEBOX | 481 | WS_VSCROLL | WS_HSCROLL); 482 | 483 | /* skip blanks again to get to filename */ 484 | lpszCmdLine= SkipBlanks( lpszCmdLine ); 485 | 486 | if (*lpszCmdLine) 487 | { 488 | /* Get the filename. */ 489 | GetFileName(szFileName, lpszCmdLine); 490 | 491 | fp= CreateFile( szFileName, // filename 492 | GENERIC_READ, // access mode 493 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode 494 | NULL, // security descriptor 495 | OPEN_EXISTING, // how to create 496 | FILE_ATTRIBUTE_NORMAL, //file attributes 497 | NULL); // hnd of file attrs 498 | 499 | if( fp == INVALID_HANDLE_VALUE ) 500 | { 501 | DWORD dwErr; 502 | 503 | // Check GetLastError to see why we failed 504 | dwErr = GetLastError (); 505 | switch (dwErr) 506 | { 507 | case ERROR_ACCESS_DENIED: 508 | iSta= AlertBox( hwndNP, szNN, szACCESSDENY, szFileName, 509 | MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); 510 | break; 511 | 512 | case ERROR_FILE_NOT_FOUND: 513 | iSta= AlertBox(hwndNP, szNN, szFNF, szFileName, 514 | MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION); 515 | if( iSta == IDYES ) 516 | { 517 | fp= CreateFile( szFileName, // filename 518 | GENERIC_READ|GENERIC_WRITE, // access 519 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share 520 | NULL, // security descrp 521 | OPEN_ALWAYS, // how to create 522 | FILE_ATTRIBUTE_NORMAL, // file attributes 523 | NULL); // hnd of file attrs 524 | } 525 | break; 526 | 527 | case ERROR_INVALID_NAME: 528 | iSta= AlertBox( hwndNP, szNN, szNVF, szFileName, 529 | MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); 530 | break; 531 | 532 | default: 533 | iSta= AlertBox(hwndNP, szNN, szDiskError, szFileName, 534 | MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); 535 | break; 536 | } 537 | } 538 | 539 | if (fp == INVALID_HANDLE_VALUE) 540 | return (FALSE); 541 | LoadFile(szFileName, fInitFileType ); // load setup file 542 | } 543 | 544 | if( iSta == IDCANCEL ) 545 | return( IDCANCEL ); 546 | else 547 | return( IDYES ); 548 | } 549 | 550 | /* 551 | * ProcessShellOptions(lpszCmdLine) 552 | * 553 | * If the command line has any options specified by the shell 554 | * process them. 555 | * Currently /P - prints the given file 556 | * /PT "filename" "printer name" "Driver dll" "port" 557 | */ 558 | BOOL ProcessShellOptions (LPTSTR lpszCmdLine, int cmdShow) 559 | { 560 | BOOL bDefPrinter = TRUE; 561 | LPTSTR lpszAfterFileName; 562 | 563 | 564 | // Is it PrintTo ? 565 | if( lstrncmpi( TEXT("/PT"), lpszCmdLine ) == 0) 566 | { 567 | lpszCmdLine= SkipBlanks( lpszCmdLine+3 ); 568 | bDefPrinter = FALSE; 569 | } 570 | // Or is it Print ? 571 | else if ( lstrncmpi( TEXT("/P"), lpszCmdLine ) == 0) 572 | { 573 | lpszCmdLine= SkipBlanks( lpszCmdLine+2 ); 574 | } 575 | else 576 | return FALSE; 577 | 578 | if (!*lpszCmdLine) 579 | return FALSE; 580 | 581 | /* Added as per Bug #10923 declaring that the window should show up 582 | * and then the printing should begin. 29 July 1991 Clark Cyr 583 | */ 584 | 585 | ShowWindow(hwndNP, cmdShow); 586 | 587 | /* Get the filename; have the pointer to the end of the filename */ 588 | lpszAfterFileName= GetFileName (szFileName, lpszCmdLine) + 1; 589 | 590 | if (!bDefPrinter) 591 | { 592 | UINT index; 593 | 594 | /* extract the printer name from the command line. */ 595 | if (!*lpszAfterFileName) 596 | return FALSE; 597 | 598 | lpszAfterFileName = SkipBlanks( lpszAfterFileName ); 599 | 600 | /* (since we are passing multiple arguments here, the filename, */ 601 | /* the printername have to be in quotes. */ 602 | if( *lpszAfterFileName != TEXT('\"') ) 603 | return FALSE; 604 | 605 | // Copy over printername 606 | lpszAfterFileName++; // skip over quote 607 | index= 0; 608 | while( *(lpszAfterFileName) && 609 | *lpszAfterFileName != TEXT('\"' ) && 610 | (index+1 < sizeof(szPrinterName)/sizeof(szPrinterName[0]) ) ) 611 | { 612 | szPrinterName[index++] = *lpszAfterFileName++; 613 | } 614 | 615 | // NULL terminate the printername (no embedded quotes allowed in printernames) 616 | szPrinterName[index] = TEXT('\0'); 617 | } 618 | 619 | 620 | fp= CreateFile( szFileName, // filename 621 | GENERIC_READ, // access mode 622 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode 623 | NULL, // security descriptor 624 | OPEN_EXISTING, // how to create 625 | FILE_ATTRIBUTE_NORMAL, // file attributes 626 | NULL); // hnd of file attrs to copy 627 | 628 | if( fp == INVALID_HANDLE_VALUE ) 629 | { 630 | TCHAR* pszMsg; 631 | 632 | // select reasonable error message based on GetLastError 633 | 634 | switch( GetLastError() ) 635 | { 636 | case ERROR_ACCESS_DENIED: 637 | case ERROR_NETWORK_ACCESS_DENIED: 638 | pszMsg= szACCESSDENY; 639 | break; 640 | 641 | case ERROR_FILE_NOT_FOUND: 642 | pszMsg= szFNF; 643 | break; 644 | 645 | case ERROR_INVALID_NAME: 646 | pszMsg= szNVF; 647 | break; 648 | 649 | default: 650 | pszMsg= szDiskError; 651 | break; 652 | } 653 | 654 | AlertBox(hwndNP, szNN, pszMsg, szFileName, 655 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 656 | return (TRUE); 657 | } 658 | 659 | /* load the file into the edit control */ 660 | LoadFile( szFileName, fInitFileType ); // get print file 661 | 662 | 663 | /* print the file */ 664 | 665 | if (bDefPrinter) 666 | { 667 | PrintIt( DoNotUseDialog ); 668 | } 669 | else 670 | { 671 | PrintIt( NoDialogNonDefault ); 672 | } 673 | 674 | 675 | return (TRUE); 676 | } 677 | 678 | /* CreateFilter 679 | * 680 | * Creates filters for GetOpenFileName. 681 | * 682 | */ 683 | 684 | VOID CreateFilter(PTCHAR szFilterSpec ) 685 | { 686 | PTCHAR pszFilterSpec; 687 | 688 | /* construct default filter string in the required format for 689 | * the new FileOpen and FileSaveAs dialogs 690 | * if you add to this, make sure CCHFILTERMAX is large enough. 691 | */ 692 | 693 | // .txt first for compatibility 694 | pszFilterSpec= szFilterSpec; 695 | lstrcpy( pszFilterSpec, szAnsiText ); 696 | pszFilterSpec += lstrlen( pszFilterSpec ) + 1; 697 | 698 | lstrcpy( pszFilterSpec, TEXT("*.txt")); 699 | pszFilterSpec += lstrlen( pszFilterSpec ) + 1; 700 | 701 | // and last, all files 702 | lstrcpy( pszFilterSpec, szAllFiles ); 703 | pszFilterSpec += lstrlen( pszFilterSpec ) + 1; 704 | 705 | lstrcpy(pszFilterSpec, TEXT("*.*") ); 706 | pszFilterSpec += lstrlen( pszFilterSpec ) + 1; 707 | 708 | *pszFilterSpec = TEXT('\0'); 709 | 710 | } 711 | 712 | // EnumProc 713 | // 714 | // Callback function for EnumFonts 715 | // 716 | // Purpose: sets lfCharSet in passed logfont to a valid lfCharSet 717 | // and terminates enumeration. 718 | // 719 | 720 | int CALLBACK EnumProc( 721 | LOGFONT* pLf, 722 | TEXTMETRIC* pTm, 723 | DWORD dwType, 724 | LPARAM lpData ) 725 | { 726 | 727 | ((LOGFONT*) lpData)-> lfCharSet= pLf->lfCharSet; 728 | 729 | return( 0 ); // stop enumeration 730 | } 731 | 732 | 733 | /* One time initialization */ 734 | INT FAR NPInit (HANDLE hInstance, HANDLE hPrevInstance, 735 | LPTSTR lpCmdLine, INT cmdShow) 736 | { 737 | HDC hDisplayDC; /* screen DC */ 738 | RECT rcT1; /* for sizing edit window */ 739 | RECT rcStatus; /* rect for the status window */ 740 | INT iSta; 741 | WINDOWPLACEMENT wp; /* structure to place window at the correct position */ 742 | INT iParts[2]; 743 | HMENU hMenu; // handle to the menu. 744 | 745 | 746 | /* determine the message number to be used for communication with 747 | * Find dialog 748 | */ 749 | if (!(wFRMsg = RegisterWindowMessage ((LPTSTR)FINDMSGSTRING))) 750 | return FALSE; 751 | if (!(wHlpMsg = RegisterWindowMessage ((LPTSTR)HELPMSGSTRING))) 752 | return FALSE; 753 | 754 | /* open a global DC to the display */ 755 | 756 | hDisplayDC= GetDC(NULL); 757 | if( !hDisplayDC ) 758 | return FALSE; 759 | 760 | /* Go load strings */ 761 | if (!InitStrings (hInstance)) 762 | return FALSE; 763 | 764 | InitLocale(); // localize strings etc. 765 | 766 | /* Load the arrow and hourglass cursors. */ 767 | hStdCursor= LoadCursor( NULL, 768 | (LPTSTR) (INT_PTR) (GetSystemMetrics(SM_PENWINDOWS) ? IDC_ARROW : IDC_IBEAM )); 769 | hWaitCursor= LoadCursor( NULL, IDC_WAIT ); 770 | 771 | /* Load accelerators. */ 772 | hAccel= LoadAccelerators(hInstance, TEXT("MainAcc")); 773 | if( !hWaitCursor || !hAccel ) 774 | return FALSE; 775 | 776 | if( !hPrevInstance ) 777 | { 778 | if( !NPRegister( hInstance ) ) 779 | return (FALSE); 780 | } 781 | 782 | hInstanceNP= hInstance; 783 | 784 | /* init. fields of PRINTDLG struct.. */ 785 | /* Inserted here since command line print statements are valid. */ 786 | g_PageSetupDlg.lStructSize = sizeof(PAGESETUPDLG); 787 | g_PageSetupDlg.hDevMode = NULL; 788 | g_PageSetupDlg.hDevNames = NULL; 789 | g_PageSetupDlg.hInstance = hInstance; 790 | SetPageSetupDefaults(); 791 | 792 | // 793 | // Pick up information saved in registry 794 | // 795 | 796 | GetGlobals(); 797 | 798 | 799 | hwndNP= CreateWindow( szNotepad, 800 | TEXT(""), 801 | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | 802 | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | 0, 803 | g_WPleft, // x 804 | g_WPtop, // y 805 | g_WPDX, // width 806 | g_WPDY, // height 807 | (HWND)NULL, // parent or owner 808 | (HMENU)NULL, // menu or child window 809 | hInstance, // application instance 810 | NULL); // window creation data 811 | 812 | g_PageSetupDlg.hwndOwner = hwndNP; 813 | 814 | if( !hwndNP ) 815 | return FALSE; 816 | 817 | // On multimon machines, the previous position stored of notepad may 818 | // not be in the display area. call SetWindowPlacement to fix this. 819 | 820 | // If the information specified in WINDOWPLACEMENT would result in a window 821 | // that is completely off the screen, the system will automatically adjust 822 | // the coordinates so that the window is visible, taking into account 823 | // changes in screen resolution and multiple monitor configuration. 824 | 825 | // g_WPDX and g_WPDY are CW_USEDEFAULT when notepad is started for the 826 | // first time on the user machine. 827 | if (g_WPDX != CW_USEDEFAULT && g_WPDY != CW_USEDEFAULT) 828 | { 829 | memset(&wp, 0, sizeof(wp)); 830 | wp.length = sizeof(wp); 831 | wp.rcNormalPosition.left = g_WPleft; 832 | wp.rcNormalPosition.right = g_WPleft + g_WPDX; 833 | wp.rcNormalPosition.top = g_WPtop; 834 | wp.rcNormalPosition.bottom = g_WPtop + g_WPDY; 835 | 836 | // don't check the return value; if this call fails for any reason, 837 | // just go on with the position of the notepad in the above CreateWindow() call. 838 | SetWindowPlacement(hwndNP, &wp); 839 | } 840 | 841 | /* File Drag Drop support added 03/26/91 - prototype only. w-dougw */ 842 | /* All processing of drag/drop files is done the under WM_DROPFILES */ 843 | /* message. */ 844 | DragAcceptFiles( hwndNP,TRUE ); /* Process dragged and dropped files. */ 845 | 846 | GetClientRect( hwndNP, (LPRECT) &rcT1 ); 847 | 848 | if (!(hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, 849 | TEXT("Edit"), TEXT(""), 850 | (fWrap) ? ES_STD : (ES_STD | WS_HSCROLL), 851 | 0, 0, rcT1.right, rcT1.bottom - 100, 852 | hwndNP, (HMENU)ID_EDIT, hInstance, (LPVOID)NULL))) 853 | return FALSE; 854 | 855 | 856 | // create a status window. 857 | hwndStatus = CreateStatusWindow ((fStatus?WS_VISIBLE:0)|WS_BORDER|WS_CHILD|WS_CLIPSIBLINGS, TEXT(""), hwndNP, ID_STATUS_WINDOW); 858 | if ( !hwndStatus ) 859 | return FALSE; 860 | UpdateStatusBar( TRUE ); 861 | 862 | GetClientRect( hwndStatus, (LPRECT) &rcStatus ); 863 | 864 | // determine height of statusbar window and save... 865 | dyStatus = rcStatus.bottom - rcStatus.top; 866 | 867 | iParts[0] = 3 * (rcStatus.right-rcStatus.left)/4; 868 | iParts[1] = -1; 869 | 870 | // Divide the status window into two parts 871 | SendMessage(hwndStatus, SB_SETPARTS, (WPARAM) sizeof(iParts)/sizeof(INT), (LPARAM) &iParts); 872 | 873 | 874 | // handle word wrap now if set in registry 875 | 876 | SendMessage( hwndEdit, EM_FMTLINES, fWrap, 0L ); // tell MLE 877 | 878 | // if wordwrap, disable the statusbar 879 | if (fWrap) 880 | { 881 | hMenu = GetMenu(hwndNP); 882 | EnableMenuItem(GetSubMenu(hMenu, 3), M_STATUSBAR, MF_GRAYED); 883 | } 884 | 885 | FontStruct.lfHeight= -MulDiv(iPointSize, 886 | GetDeviceCaps(hDisplayDC,LOGPIXELSY), 887 | 720); 888 | hFont= CreateFontIndirect( &FontStruct ); 889 | 890 | // 891 | // Make sure the font mapper gives us the same face name. 892 | // 893 | // If the locale changes, a font that use to work just fine gets mapped to 894 | // a different facename because of support for the charset does not exist 895 | // in the new locale. 896 | // 897 | // In this case, we will find one lfCharSet that does exist for this FaceName 898 | // and use that for the CreateFontIndirect. 899 | // 900 | 901 | { 902 | HFONT hPrev; 903 | TCHAR szTextFace[LF_FACESIZE]; 904 | 905 | // Get the facename that was really used. 906 | 907 | hPrev= SelectObject( hDisplayDC, hFont ); 908 | GetTextFace( hDisplayDC, sizeof(szTextFace)/sizeof(TCHAR), (LPTSTR) &szTextFace ); 909 | SelectObject( hDisplayDC, hPrev ); 910 | 911 | // if not the same, get a lfCharSet that does exist in this font 912 | 913 | if( lstrcmpi( szTextFace, FontStruct.lfFaceName ) != 0 ) 914 | { 915 | EnumFonts( hDisplayDC, FontStruct.lfFaceName, (FONTENUMPROC) EnumProc, (LPARAM) &FontStruct ); 916 | DeleteObject( hFont ); 917 | 918 | hFont= CreateFontIndirect( &FontStruct ); 919 | } 920 | } 921 | 922 | SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(FALSE, 0)); 923 | ReleaseDC( NULL, hDisplayDC ); 924 | 925 | /* we will not verify that a unicode font is available until 926 | ** we actually need it. Perhaps we'll get lucky, and only deal 927 | ** with ascii files. 928 | */ 929 | 930 | szSearch[0] = (TCHAR) 0; 931 | /* 932 | * Win32s does not allow local memory handles to be passed to Win3.1. 933 | * So, hEdit is used for transferring text to and from the edit control. 934 | * Before reading text into it, it must be reallocated to a proper size. 935 | */ 936 | hEdit = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, ByteCountOf(1)); 937 | 938 | /* limit text for safety's sake. */ 939 | PostMessage( hwndEdit, EM_LIMITTEXT, (WPARAM)CCHNPMAX, 0L ); 940 | 941 | /* get visible window on desktop; helps taskman find it */ 942 | SetTitle( szUntitled ); 943 | ShowWindow( hwndNP, cmdShow ); 944 | SetCursor( hStdCursor ); 945 | 946 | /* Scan for initial /A or /W to override automatic file typing for 947 | * 'notepad /p file' or 'notepad file' 948 | */ 949 | lpCmdLine= SkipBlanks( lpCmdLine ); 950 | fInitFileType= FT_UNKNOWN; 951 | if( !lstrncmpi( TEXT("/A"), lpCmdLine ) ) 952 | fInitFileType= FT_ANSI; 953 | else if( !lstrncmpi( TEXT("/W"), lpCmdLine ) ) 954 | fInitFileType= FT_UNICODE; 955 | 956 | if( fInitFileType != FT_UNKNOWN ) // skip over option 957 | lpCmdLine= SkipBlanks( lpCmdLine+2 ); 958 | 959 | /* check for /.SETUP option first. 960 | if /.SETUP absent, check for SHELL options /P 961 | Whenever a SHELL option is processed, post a WM_CLOSE msg. 962 | */ 963 | if( iSta= ProcessSetupOption( lpCmdLine ) ) 964 | { 965 | if( iSta == IDCANCEL ) 966 | { 967 | return( FALSE ); 968 | } 969 | } 970 | else if( ProcessShellOptions( lpCmdLine, cmdShow ) ) 971 | { 972 | PostMessage( hwndNP, WM_CLOSE, 0, 0L ); 973 | return TRUE; 974 | } 975 | else if( *lpCmdLine ) 976 | { 977 | /* Get the filename. */ 978 | GetFileName( szFileName, lpCmdLine ); 979 | fp= CreateFile( szFileName, // filename 980 | GENERIC_READ, // access mode 981 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode 982 | NULL, // security descriptor 983 | OPEN_EXISTING, // how to create 984 | FILE_ATTRIBUTE_NORMAL, // file attributes 985 | NULL); // hnd of file attrs to copy 986 | 987 | if( fp == INVALID_HANDLE_VALUE ) 988 | { 989 | // If the file can't be opened, maybe the user wants a new 990 | // one created. 991 | 992 | if( GetLastError() == ERROR_FILE_NOT_FOUND ) 993 | { 994 | INT iSta; 995 | 996 | iSta= AlertBox( hwndNP, szNN, szFNF, szFileName, 997 | MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION); 998 | if( iSta == IDCANCEL ) 999 | { 1000 | return( FALSE ); 1001 | } 1002 | 1003 | if( iSta == IDYES ) 1004 | { 1005 | fp= CreateFile( szFileName, // filename 1006 | GENERIC_READ|GENERIC_WRITE, // access 1007 | FILE_SHARE_READ|FILE_SHARE_WRITE, // share 1008 | NULL, // security descrp 1009 | OPEN_ALWAYS, // how to create 1010 | FILE_ATTRIBUTE_NORMAL, // file attributes 1011 | NULL); // hnd of file attrs 1012 | } 1013 | 1014 | } 1015 | else 1016 | { 1017 | AlertUser_FileFail(szFileName); 1018 | // now open an untitled file instead of the file that we failed 1019 | // to read. 1020 | SetTitle( szUntitled ); 1021 | lstrcpy(szFileName, szUntitled); 1022 | } 1023 | } 1024 | 1025 | if( fp != INVALID_HANDLE_VALUE ) 1026 | { 1027 | LoadFile( szFileName, fInitFileType ); // get file specified on command line 1028 | } 1029 | } 1030 | 1031 | CreateFilter( szOpenFilterSpec ); 1032 | CreateFilter( szSaveFilterSpec ); 1033 | 1034 | /* init. some fields of the OPENFILENAME struct used by fileopen and 1035 | * filesaveas, but NEVER changed. 1036 | */ 1037 | memset( &OFN, 0, sizeof(OFN) ); 1038 | OFN.lStructSize = sizeof(OPENFILENAME); 1039 | OFN.hwndOwner = hwndNP; 1040 | OFN.nMaxFile = MAX_PATH; 1041 | OFN.hInstance = hInstance; 1042 | 1043 | /* init.fields of the FINDREPLACE struct used by FindText() */ 1044 | memset( &FR, 0, sizeof(FR) ); 1045 | FR.lStructSize = sizeof(FINDREPLACE); /* Don't hard code it */ 1046 | FR.hwndOwner = hwndNP; 1047 | 1048 | 1049 | /* Force a scroll to current selection (which could be at eof if 1050 | we loaded a log file.) */ 1051 | { 1052 | DWORD dwStart, dwEnd; 1053 | 1054 | SendMessage( hwndEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd ); 1055 | SendMessage( hwndEdit, EM_SETSEL, dwStart, dwEnd ); 1056 | SendMessage( hwndEdit, EM_SCROLLCARET, 0, 0 ); 1057 | } 1058 | 1059 | 1060 | 1061 | if (PRIMARYLANGID(LOWORD((DWORD) (INT_PTR) GetKeyboardLayout(0))) == LANG_JAPANESE) { 1062 | /* 1063 | * If current HKL is Japanese, handle the result string at once. 1064 | */ 1065 | SendMessage(hwndEdit, EM_SETIMESTATUS, 1066 | EMSIS_COMPOSITIONSTRING, EIMES_GETCOMPSTRATONCE); 1067 | } 1068 | 1069 | return TRUE; 1070 | } 1071 | 1072 | /* ** Notepad class registration proc */ 1073 | BOOL NPRegister (HANDLE hInstance) 1074 | { 1075 | WNDCLASSEX NPClass; 1076 | PWNDCLASSEX pNPClass = &NPClass; 1077 | 1078 | /* Bug 12191: If Pen Windows is running, make the background cursor an 1079 | * arrow instead of the edit control ibeam. This way the user will know 1080 | * where they can use the pen for writing vs. what will be considered a 1081 | * mouse action. 18 October 1991 Clark Cyr 1082 | */ 1083 | pNPClass->cbSize = sizeof(NPClass); 1084 | pNPClass->hCursor = LoadCursor(NULL, GetSystemMetrics(SM_PENWINDOWS) 1085 | ? IDC_ARROW : IDC_IBEAM); 1086 | pNPClass->hIcon = LoadIcon(hInstance, 1087 | (LPTSTR) MAKEINTRESOURCE(ID_ICON)); 1088 | 1089 | pNPClass->hIconSm = LoadImage(hInstance, 1090 | MAKEINTRESOURCE(ID_ICON), 1091 | IMAGE_ICON, 16, 16, 1092 | LR_DEFAULTCOLOR); 1093 | pNPClass->lpszMenuName = (LPTSTR) MAKEINTRESOURCE(ID_MENUBAR); 1094 | pNPClass->hInstance = hInstance; 1095 | pNPClass->lpszClassName = szNotepad; 1096 | pNPClass->lpfnWndProc = NPWndProc; 1097 | pNPClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 1098 | pNPClass->style = 0; // was CS_BYTEALIGNCLIENT (obsolete) 1099 | pNPClass->cbClsExtra = 0; 1100 | pNPClass->cbWndExtra = 0; 1101 | 1102 | if (!RegisterClassEx((LPWNDCLASSEX)pNPClass)) 1103 | return (FALSE); 1104 | 1105 | return (TRUE); 1106 | } 1107 | 1108 | 1109 | /* Get Locale info from the Registry, and initialize global vars */ 1110 | 1111 | void FAR InitLocale (void) 1112 | { 1113 | 1114 | } 1115 | -------------------------------------------------------------------------------- /npmisc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * misc notepad functions 3 | * Copyright (C) 1984-2000 Microsoft Corporation 4 | */ 5 | 6 | #include "precomp.h" 7 | 8 | BOOL fCase = FALSE; // Flag specifying case sensitive search 9 | BOOL fReverse = FALSE; // Flag for direction of search 10 | 11 | extern HWND hDlgFind; // handle to modeless FindText window 12 | 13 | LPTSTR ReverseScan( 14 | LPTSTR lpSource, 15 | LPTSTR lpLast, 16 | LPTSTR lpSearch, 17 | BOOL fCaseSensitive ) 18 | { 19 | TCHAR cLastCharU; 20 | TCHAR cLastCharL; 21 | INT iLen; 22 | 23 | cLastCharU= (TCHAR) (INT_PTR) CharUpper( (LPTSTR)(INT_PTR)(*lpSearch) ); 24 | cLastCharL= (TCHAR) (INT_PTR) CharLower( (LPTSTR)(INT_PTR)(*lpSearch) ); 25 | 26 | iLen = lstrlen(lpSearch); 27 | 28 | if (!lpLast) 29 | lpLast = lpSource + lstrlen(lpSource); 30 | 31 | do 32 | { 33 | if (lpLast == lpSource) 34 | return NULL; 35 | 36 | --lpLast; 37 | 38 | if (fCaseSensitive) 39 | { 40 | if (*lpLast != *lpSearch) 41 | continue; 42 | } 43 | else 44 | { 45 | if( !( *lpLast == cLastCharU || *lpLast == cLastCharL ) ) 46 | continue; 47 | } 48 | 49 | if (fCaseSensitive) 50 | { 51 | if (!_tcsncmp( lpLast, lpSearch, iLen)) 52 | break; 53 | } 54 | else 55 | { 56 | // 57 | // compare whole string using locale specific comparison. 58 | // do not use C runtime version since it may be wrong. 59 | // 60 | 61 | if( 2 == CompareString( LOCALE_USER_DEFAULT, 62 | NORM_IGNORECASE | SORT_STRINGSORT | NORM_STOP_ON_NULL, 63 | lpLast, iLen, 64 | lpSearch, iLen) ) 65 | break; 66 | } 67 | } while (TRUE); 68 | 69 | return lpLast; 70 | } 71 | 72 | LPTSTR ForwardScan(LPTSTR lpSource, LPTSTR lpSearch, BOOL fCaseSensitive ) 73 | { 74 | TCHAR cFirstCharU; 75 | TCHAR cFirstCharL; 76 | int iLen = lstrlen(lpSearch); 77 | 78 | cFirstCharU= (TCHAR) (INT_PTR) CharUpper( (LPTSTR)(INT_PTR)(*lpSearch) ); 79 | cFirstCharL= (TCHAR) (INT_PTR) CharLower( (LPTSTR)(INT_PTR)(*lpSearch) ); 80 | 81 | while (*lpSource) 82 | { 83 | if (fCaseSensitive) 84 | { 85 | if (*lpSource != *lpSearch) 86 | { 87 | lpSource++; 88 | continue; 89 | } 90 | } 91 | else 92 | { 93 | if( !( *lpSource == cFirstCharU || *lpSource == cFirstCharL ) ) 94 | { 95 | lpSource++; 96 | continue; 97 | } 98 | } 99 | 100 | if (fCaseSensitive) 101 | { 102 | if (!_tcsncmp( lpSource, lpSearch, iLen)) 103 | break; 104 | } 105 | else 106 | { 107 | if( 2 == CompareString( LOCALE_USER_DEFAULT, 108 | NORM_IGNORECASE | SORT_STRINGSORT | NORM_STOP_ON_NULL, 109 | lpSource, iLen, 110 | lpSearch, iLen) ) 111 | break; 112 | } 113 | 114 | lpSource++; 115 | } 116 | 117 | return *lpSource ? lpSource : NULL; 118 | } 119 | 120 | 121 | // search forward or backward in the edit control text for the given pattern 122 | // It is the responsibility of the caller to set the cursor 123 | 124 | BOOL Search (TCHAR * szKey) 125 | { 126 | BOOL bStatus= FALSE; 127 | TCHAR * pStart, *pMatch; 128 | DWORD StartIndex, LineNum, EndIndex; 129 | DWORD SelStart, SelEnd, i; 130 | HANDLE hEText; // handle to edit text 131 | UINT uSelState; 132 | HMENU hMenu; 133 | BOOL bSelectAll = FALSE; 134 | 135 | 136 | if (!*szKey) 137 | return( bStatus ); 138 | 139 | SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&SelStart, (LPARAM)&SelEnd); 140 | 141 | 142 | // when we finish the search, we highlight the text found, and continue 143 | // the search after the end of the highlighted position (in forward 144 | // case) or from the begining of the highlighted position in the reverse 145 | // direction (in reverse case). this would break if the user has 146 | // selected all text. this hack would take care of it. (this is consistent 147 | // with VC editors' search too. 148 | 149 | hMenu = GetMenu(hwndNP); 150 | uSelState = GetMenuState(GetSubMenu(hMenu, 1), M_SELECTALL, MF_BYCOMMAND); 151 | if (uSelState == MF_GRAYED) 152 | { 153 | bSelectAll = TRUE; 154 | SelStart = SelEnd =0; 155 | } 156 | 157 | 158 | // 159 | // get pointer to edit control text to search 160 | // 161 | 162 | hEText= (HANDLE) SendMessage( hwndEdit, EM_GETHANDLE, 0, 0 ); 163 | if( !hEText ) // silently return if we can't get it 164 | { 165 | return( bStatus ); 166 | } 167 | pStart= LocalLock( hEText ); 168 | if( !pStart ) 169 | { 170 | return( bStatus ); 171 | } 172 | 173 | if (fReverse) 174 | { 175 | // Get current line number 176 | LineNum= (DWORD)SendMessage(hwndEdit, EM_LINEFROMCHAR, SelStart, 0); 177 | // Get index to start of the line 178 | StartIndex= (DWORD)SendMessage(hwndEdit, EM_LINEINDEX, LineNum, 0); 179 | // Set upper limit for search text 180 | EndIndex= SelStart; 181 | pMatch= NULL; 182 | 183 | // Search line by line, from LineNum to 0 184 | i = LineNum; 185 | while (TRUE) 186 | { 187 | pMatch= ReverseScan(pStart+StartIndex,pStart+EndIndex,szKey,fCase); 188 | if (pMatch) 189 | break; 190 | // current StartIndex is the upper limit for the next search 191 | EndIndex= StartIndex; 192 | 193 | if (i) 194 | { 195 | // Get start of the next line 196 | i-- ; 197 | StartIndex = (DWORD)SendMessage(hwndEdit, EM_LINEINDEX, i, 0); 198 | } 199 | else 200 | break ; 201 | } 202 | } 203 | else 204 | { 205 | pMatch= ForwardScan(pStart+SelEnd, szKey, fCase); 206 | } 207 | 208 | LocalUnlock(hEText); 209 | 210 | if (pMatch == NULL) 211 | { 212 | // 213 | // alert user on not finding any text unless it is replace all 214 | // 215 | if( !(FR.Flags & FR_REPLACEALL) ) 216 | { 217 | HANDLE hPrevCursor= SetCursor( hStdCursor ); 218 | AlertBox( hDlgFind ? hDlgFind : hwndNP, 219 | szNN, 220 | szCFS, 221 | szSearch, 222 | MB_APPLMODAL | MB_OK | MB_ICONINFORMATION); 223 | SetCursor( hPrevCursor ); 224 | } 225 | } 226 | else 227 | { 228 | SelStart = (DWORD)(pMatch - pStart); 229 | SendMessage( hwndEdit, EM_SETSEL, SelStart, SelStart+lstrlen(szKey)); 230 | 231 | // since we are selecting the found text, enable SelectAll again. 232 | if (bSelectAll) 233 | { 234 | EnableMenuItem(GetSubMenu(hMenu, 1), M_SELECTALL, MF_ENABLED); 235 | } 236 | 237 | // 238 | // show the selected text unless it is replace all 239 | // 240 | 241 | if( !(FR.Flags & FR_REPLACEALL) ) 242 | { 243 | SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0); 244 | UpdateStatusBar( TRUE ); 245 | } 246 | bStatus= TRUE; // found 247 | } 248 | 249 | return( bStatus ); 250 | } 251 | 252 | // Recreate notepad edit window, get text from old window and put in new window. 253 | // Called when user changes style from wrap on/off 254 | // 255 | // Called with the style of the new window 256 | // 257 | 258 | BOOL NpReCreate( long style ) 259 | { 260 | RECT rcT1; 261 | HWND hwndT1; 262 | HANDLE hT1; 263 | int cchTextNew; 264 | TCHAR* pchText; 265 | BOOL fWrapIsOn = ((style & WS_HSCROLL) != 0); 266 | HCURSOR hPrevCursor; 267 | BOOL bModified; // modify flag from old edit buffer 268 | 269 | // if wordwrap, remove soft carriage returns 270 | 271 | hPrevCursor= SetCursor( hWaitCursor ); // this may take some time... 272 | if( fWrapIsOn ) 273 | { 274 | GotoAndScrollInView(1); // get around MLE bug 275 | 276 | SendMessage(hwndEdit, EM_FMTLINES, FALSE, 0L); 277 | } 278 | 279 | bModified= (SendMessage( hwndEdit, EM_GETMODIFY, 0,0 ) != 0); 280 | 281 | cchTextNew= (int)SendMessage( hwndEdit, WM_GETTEXTLENGTH, 0, 0L ); 282 | hT1= LocalAlloc( LMEM_MOVEABLE, ByteCountOf(cchTextNew + 1) ); 283 | if( !hT1 ) 284 | { 285 | // failed, restore wordwrap; insert soft carriage returns 286 | if( fWrapIsOn ) 287 | { 288 | SendMessage(hwndEdit, EM_FMTLINES, TRUE, 0L); 289 | } 290 | SetCursor( hPrevCursor ); 291 | return FALSE; 292 | } 293 | 294 | GetClientRect( hwndNP, (LPRECT)&rcT1 ); 295 | 296 | // 297 | // save the current edit control text. 298 | // 299 | 300 | pchText= LocalLock (hT1); 301 | SendMessage( hwndEdit, WM_GETTEXT, cchTextNew+1, (LPARAM)pchText ); 302 | hwndT1= CreateWindowEx( WS_EX_CLIENTEDGE, 303 | TEXT("Edit"), 304 | TEXT(""), // pchText 305 | style, 306 | 0, 307 | 0, 308 | rcT1.right, 309 | rcT1.bottom, 310 | hwndNP, 311 | (HMENU)ID_EDIT, 312 | hInstanceNP, NULL ); 313 | if( !hwndT1 ) 314 | { 315 | SetCursor( hPrevCursor ); 316 | if( fWrapIsOn ) // restore wordwrap 317 | { 318 | SendMessage( hwndEdit, EM_FMTLINES, TRUE, 0L ); 319 | } 320 | LocalUnlock(hT1); 321 | LocalFree(hT1); 322 | return FALSE; 323 | } 324 | 325 | // 326 | // The user can "add" styles to the edit window after it is 327 | // created (like WS_EX_RTLREADING) when language packs are installed. 328 | // Preserve these styles when changing the word wrap. 329 | // 330 | 331 | SetWindowLong( hwndT1 , 332 | GWL_EXSTYLE , 333 | GetWindowLong( hwndEdit , GWL_EXSTYLE )|WS_EX_CLIENTEDGE ) ; 334 | 335 | // Set font before set text to save time calculating 336 | SendMessage( hwndT1, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0) ); 337 | 338 | if (!SendMessage (hwndT1, WM_SETTEXT, 0, (LPARAM) pchText)) 339 | { 340 | SetCursor( hPrevCursor ); 341 | if( fWrapIsOn ) // restore wordwrap 342 | { 343 | SendMessage( hwndEdit, EM_FMTLINES, TRUE, 0L ); 344 | } 345 | DestroyWindow( hwndT1 ); 346 | LocalUnlock( hT1 ); 347 | LocalFree( hT1 ); 348 | return FALSE; 349 | } 350 | LocalUnlock(hT1); 351 | 352 | 353 | DestroyWindow( hwndEdit ); // out with the old 354 | hwndEdit = hwndT1; // in with the new 355 | 356 | // free the earlier allocated memory in hEdit 357 | 358 | if (hEdit) 359 | LocalFree(hEdit); 360 | 361 | hEdit = hT1; 362 | 363 | // limit text for safety's sake. 364 | 365 | PostMessage( hwndEdit, EM_LIMITTEXT, (WPARAM)CCHNPMAX, 0L ); 366 | 367 | ShowWindow(hwndNP, SW_SHOW); 368 | SendMessage( hwndEdit, EM_SETMODIFY, bModified, 0L ); 369 | SetFocus(hwndEdit); 370 | 371 | SetCursor( hPrevCursor ); // restore cursor 372 | 373 | // redraw the status bar 374 | 375 | if( fStatus ) 376 | { 377 | RECT rcClient; 378 | GetClientRect(hwndNP, &rcClient); 379 | NPSize(rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); 380 | UpdateStatusBar( TRUE ); 381 | ShowWindow( hwndStatus, SW_SHOW ); 382 | } 383 | 384 | return TRUE; 385 | } 386 | -------------------------------------------------------------------------------- /npprint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * npprint.c -- Code for printing from notepad. 3 | * Copyright (C) 1984-1995 Microsoft Inc. 4 | */ 5 | 6 | #define NOMINMAX 7 | #include "precomp.h" 8 | 9 | //#define DBGPRINT 10 | 11 | /* indices into chBuff */ 12 | #define LEFT 0 13 | #define CENTER 1 14 | #define RIGHT 2 15 | 16 | INT tabSize; /* Size of a tab for print device in device units*/ 17 | HWND hAbortDlgWnd; 18 | INT fAbort; /* true if abort in progress */ 19 | INT yPrintChar; /* height of a character */ 20 | 21 | 22 | RECT rtMargin; 23 | 24 | /* left,center and right string for header or trailer */ 25 | #define MAXTITLE MAX_PATH 26 | TCHAR chBuff[RIGHT+1][MAXTITLE]; 27 | 28 | /* date and time stuff for headers */ 29 | #define MAXDATE MAX_PATH 30 | #define MAXTIME MAX_PATH 31 | TCHAR szFormattedDate[MAXDATE]=TEXT("Y"); // formatted date (may be internationalized) 32 | TCHAR szFormattedTime[MAXTIME]=TEXT("Y"); // formatted time (may be internaltionalized) 33 | SYSTEMTIME PrintTime; // time we started printing 34 | 35 | 36 | INT xPrintRes; // printer resolution in x direction 37 | INT yPrintRes; // printer resolution in y direction 38 | INT yPixInch; // pixels/inch 39 | INT xPhysRes; // physical resolution x of paper 40 | INT yPhysRes; // physical resolution y of paper 41 | 42 | INT xPhysOff; // physical offset x 43 | INT yPhysOff; // physical offset y 44 | 45 | INT dyTop; // width of top border (pixels) 46 | INT dyBottom; // width of bottom border 47 | INT dxLeft; // width of left border 48 | INT dxRight; // width of right border 49 | 50 | INT iPageNum; // global page number currently being printed 51 | 52 | /* define a type for NUM and the base */ 53 | typedef long NUM; 54 | #define BASE 100L 55 | 56 | /* converting in/out of fixed point */ 57 | #define NumToShort(x,s) (LOWORD(((x) + (s)) / BASE)) 58 | #define NumRemToShort(x) (LOWORD((x) % BASE)) 59 | 60 | /* rounding options for NumToShort */ 61 | #define NUMFLOOR 0 62 | #define NUMROUND (BASE/2) 63 | #define NUMCEILING (BASE-1) 64 | 65 | #define ROUND(x) NumToShort(x,NUMROUND) 66 | #define FLOOR(x) NumToShort(x,NUMFLOOR) 67 | 68 | /* Unit conversion */ 69 | #define InchesToCM(x) (((x) * 254L + 50) / 100) 70 | #define CMToInches(x) (((x) * 100L + 127) / 254) 71 | 72 | void DestroyAbortWnd(void) ; 73 | VOID TranslateString(TCHAR *); 74 | 75 | BOOL CALLBACK AbortProc(HDC hPrintDC, INT reserved) 76 | { 77 | MSG msg; 78 | 79 | while( !fAbort && PeekMessage((LPMSG)&msg, NULL, 0, 0, TRUE) ) 80 | { 81 | if( !hAbortDlgWnd || !IsDialogMessage( hAbortDlgWnd, (LPMSG)&msg ) ) 82 | { 83 | TranslateMessage( (LPMSG)&msg ); 84 | DispatchMessage( (LPMSG)&msg ); 85 | } 86 | } 87 | return( !fAbort ); 88 | 89 | UNREFERENCED_PARAMETER(hPrintDC); 90 | UNREFERENCED_PARAMETER(reserved); 91 | } 92 | 93 | 94 | INT_PTR CALLBACK AbortDlgProc( 95 | HWND hwnd, 96 | UINT msg, 97 | WPARAM wParam, 98 | LPARAM lParam) 99 | { 100 | static HMENU hSysMenu; 101 | 102 | switch( msg ) 103 | { 104 | case WM_COMMAND: 105 | fAbort= TRUE; 106 | DestroyAbortWnd(); 107 | return( TRUE ); 108 | 109 | case WM_INITDIALOG: 110 | hSysMenu= GetSystemMenu( hwnd, FALSE ); 111 | SetDlgItemText( hwnd, ID_FILENAME, 112 | fUntitled ? szUntitled : PFileInPath(szFileName) ); 113 | SetFocus( hwnd ); 114 | return( TRUE ); 115 | 116 | case WM_INITMENU: 117 | EnableMenuItem( hSysMenu, (WORD)SC_CLOSE, (DWORD)MF_GRAYED ); 118 | return( TRUE ); 119 | } 120 | return( FALSE ); 121 | 122 | UNREFERENCED_PARAMETER(wParam); 123 | UNREFERENCED_PARAMETER(lParam); 124 | } 125 | 126 | 127 | /* 128 | * print out the translated header/footer string in proper position. 129 | * uses globals xPrintWidth, ... 130 | * 131 | * returns 1 if line was printed, otherwise 0. 132 | */ 133 | 134 | INT PrintHeaderFooter (HDC hDC, INT nHF) 135 | { 136 | SIZE Size; // to compute the width of each string 137 | INT yPos; // y position to print 138 | INT xPos; // x position to print 139 | 140 | if( *chPageText[nHF] == 0 ) // see if anything to do 141 | return 0; // we didn't print 142 | 143 | TranslateString( chPageText[nHF] ); 144 | 145 | // figure out the y position we are printing 146 | 147 | if( nHF == HEADER ) 148 | yPos= dyTop; 149 | else 150 | yPos= yPrintRes - dyBottom - yPrintChar; 151 | 152 | // print out the various strings 153 | // N.B. could overprint which seems ok for now 154 | 155 | if( *chBuff[LEFT] ) // left string 156 | { 157 | TextOut( hDC, dxLeft, yPos, chBuff[LEFT], lstrlen(chBuff[LEFT]) ); 158 | } 159 | 160 | if( *chBuff[CENTER] ) // center string 161 | { 162 | GetTextExtentPoint32( hDC, chBuff[CENTER], lstrlen(chBuff[CENTER]), &Size ); 163 | xPos= (xPrintRes-dxRight+dxLeft)/2 - Size.cx/2; 164 | TextOut( hDC, xPos, yPos, chBuff[CENTER], lstrlen(chBuff[CENTER]) ); 165 | } 166 | 167 | if( *chBuff[RIGHT] ) // right string 168 | { 169 | GetTextExtentPoint32( hDC, chBuff[RIGHT], lstrlen(chBuff[RIGHT]), &Size ); 170 | xPos= xPrintRes - dxRight - Size.cx; 171 | TextOut( hDC, xPos, yPos, chBuff[RIGHT], lstrlen(chBuff[RIGHT]) ); 172 | } 173 | return 1; // we did print something 174 | } 175 | /* 176 | * GetResolutions 177 | * 178 | * Gets printer resolutions. 179 | * sets globals: xPrintRes, yPrintRes, yPixInch 180 | * 181 | */ 182 | 183 | VOID GetResolutions(HDC hPrintDC) 184 | { 185 | xPrintRes = GetDeviceCaps( hPrintDC, HORZRES ); 186 | yPrintRes = GetDeviceCaps( hPrintDC, VERTRES ); 187 | yPixInch = GetDeviceCaps( hPrintDC, LOGPIXELSY ); 188 | 189 | xPhysRes = GetDeviceCaps( hPrintDC, PHYSICALWIDTH ); 190 | yPhysRes = GetDeviceCaps( hPrintDC, PHYSICALHEIGHT ); 191 | 192 | xPhysOff = GetDeviceCaps( hPrintDC, PHYSICALOFFSETX ); 193 | yPhysOff = GetDeviceCaps( hPrintDC, PHYSICALOFFSETY ); 194 | } 195 | 196 | /* GetMoreText 197 | * 198 | * Gets the next line of text from the MLE, returning a pointer 199 | * to the beginning and just past the end. 200 | * 201 | * linenum - index into MLE (IN) 202 | * pStartText - start of MLE (IN) 203 | * ppsStr - pointer to where to put pointer to start of text (OUT) 204 | * ppEOL - pointer to where to put pointer to just past EOL (OUT) 205 | * 206 | */ 207 | 208 | VOID GetMoreText( INT linenum, PTCHAR pStartText, PTCHAR* ppsStr, PTCHAR* ppEOL ) 209 | { 210 | INT Offset; // offset in 'chars' into edit buffer 211 | INT nChars; // number of chars in line 212 | 213 | Offset= (INT)SendMessage( hwndEdit, EM_LINEINDEX, linenum, 0 ); 214 | 215 | nChars= (INT)SendMessage( hwndEdit, EM_LINELENGTH, Offset, 0 ); 216 | 217 | *ppsStr= pStartText + Offset; 218 | 219 | *ppEOL= (pStartText+Offset) + nChars; 220 | } 221 | 222 | #ifdef DBGPRINT 223 | TCHAR dbuf[100]; 224 | VOID ShowMargins( HDC hPrintDC ) 225 | { 226 | INT xPrintRes, yPrintRes; 227 | RECT rct; 228 | HBRUSH hBrush; 229 | 230 | xPrintRes= GetDeviceCaps( hPrintDC, HORZRES ); 231 | yPrintRes= GetDeviceCaps( hPrintDC, VERTRES ); 232 | hBrush= GetStockObject( BLACK_BRUSH ); 233 | 234 | if ( hBrush ) 235 | { 236 | SetRect( &rct, 0,0,xPrintRes-1, yPrintRes-1 ); 237 | FrameRect( hPrintDC, &rct, hBrush ); 238 | SetRect( &rct, dxLeft, dyTop, xPrintRes-dxRight, yPrintRes-dyBottom ); 239 | FrameRect( hPrintDC, &rct, hBrush ); 240 | } 241 | } 242 | 243 | VOID PrintLogFont( LOGFONT lf ) 244 | { 245 | wsprintf(dbuf,TEXT("lfHeight %d\n"), lf.lfHeight ); ODS(dbuf); 246 | wsprintf(dbuf,TEXT("lfWidth %d\n"), lf.lfWidth ); ODS(dbuf); 247 | wsprintf(dbuf,TEXT("lfEscapement %d\n"), lf. lfEscapement ); ODS(dbuf); 248 | wsprintf(dbuf,TEXT("lfOrientation %d\n"), lf.lfOrientation ); ODS(dbuf); 249 | wsprintf(dbuf,TEXT("lfWeight %d\n"), lf.lfWeight ); ODS(dbuf); 250 | wsprintf(dbuf,TEXT("lfItalic %d\n"), lf.lfItalic ); ODS(dbuf); 251 | wsprintf(dbuf,TEXT("lfUnderline %d\n"), lf.lfUnderline ); ODS(dbuf); 252 | wsprintf(dbuf,TEXT("lfStrikeOut %d\n"), lf.lfStrikeOut ); ODS(dbuf); 253 | wsprintf(dbuf,TEXT("lfCharSet %d\n"), lf.lfCharSet ); ODS(dbuf); 254 | wsprintf(dbuf,TEXT("lfOutPrecision %d\n"), lf.lfOutPrecision ); ODS(dbuf); 255 | wsprintf(dbuf,TEXT("lfClipPrecison %d\n"), lf.lfClipPrecision ); ODS(dbuf); 256 | wsprintf(dbuf,TEXT("lfQuality %d\n"), lf.lfQuality ); ODS(dbuf); 257 | wsprintf(dbuf,TEXT("lfPitchAndFamily %d\n"), lf.lfPitchAndFamily); ODS(dbuf); 258 | wsprintf(dbuf,TEXT("lfFaceName %s\n"), lf.lfFaceName ); ODS(dbuf); 259 | } 260 | #endif 261 | 262 | // GetPrinterDCviaDialog 263 | // 264 | // Use the common dialog PrintDlgEx() function to get a printer DC to print to. 265 | // 266 | // Returns: valid HDC or INVALID_HANDLE_VALUE if error. 267 | // 268 | 269 | HDC GetPrinterDCviaDialog( VOID ) 270 | { 271 | PRINTDLGEX pdTemp; 272 | HDC hDC; 273 | HRESULT hRes; 274 | 275 | // 276 | // Get the page setup information 277 | // 278 | 279 | if( !g_PageSetupDlg.hDevNames ) /* Retrieve default printer if none selected. */ 280 | { 281 | g_PageSetupDlg.Flags |= (PSD_RETURNDEFAULT|PSD_NOWARNING ); 282 | PageSetupDlg(&g_PageSetupDlg); 283 | g_PageSetupDlg.Flags &= ~(PSD_RETURNDEFAULT|PSD_NOWARNING); 284 | } 285 | 286 | // 287 | // Initialize the dialog structure 288 | // 289 | 290 | ZeroMemory( &pdTemp, sizeof(pdTemp) ); 291 | 292 | pdTemp.lStructSize= sizeof(pdTemp); 293 | 294 | pdTemp.hwndOwner= hwndNP; 295 | pdTemp.nStartPage= START_PAGE_GENERAL; 296 | 297 | // FEATURE: We turn off multiple copies seen 'notepad' doesn't do it. 298 | // But this will work on many print drivers esp. if using EMF printing. 299 | // We may want to add our own code to do the multiple copies 300 | 301 | pdTemp.Flags= PD_NOPAGENUMS | PD_RETURNDC | PD_NOCURRENTPAGE | 302 | PD_USEDEVMODECOPIESANDCOLLATE | 303 | PD_NOSELECTION | 0; 304 | 305 | // if use set printer in PageSetup, use it here too. 306 | 307 | if( g_PageSetupDlg.hDevMode ) 308 | { 309 | pdTemp.hDevMode= g_PageSetupDlg.hDevMode; 310 | } 311 | 312 | if( g_PageSetupDlg.hDevNames ) 313 | { 314 | pdTemp.hDevNames= g_PageSetupDlg.hDevNames; 315 | } 316 | 317 | 318 | // 319 | // let user select printer 320 | // 321 | 322 | hRes= PrintDlgEx( &pdTemp ); 323 | 324 | // 325 | // get DC if valid return 326 | // 327 | 328 | hDC= INVALID_HANDLE_VALUE; 329 | 330 | if( hRes == S_OK ) 331 | { 332 | if( (pdTemp.dwResultAction == PD_RESULT_PRINT) || (pdTemp.dwResultAction == PD_RESULT_APPLY) ) 333 | { 334 | if( pdTemp.dwResultAction == PD_RESULT_PRINT ) 335 | { 336 | hDC= pdTemp.hDC; 337 | } 338 | 339 | // 340 | // Get the page setup information for the printer selected in case it was 341 | // the first printer added by the user through notepad. 342 | // 343 | if( !g_PageSetupDlg.hDevMode ) 344 | { 345 | g_PageSetupDlg.Flags |= (PSD_RETURNDEFAULT|PSD_NOWARNING ); 346 | PageSetupDlg(&g_PageSetupDlg); 347 | g_PageSetupDlg.Flags &= ~(PSD_RETURNDEFAULT|PSD_NOWARNING); 348 | } 349 | 350 | // change devmode if user pressed print or apply 351 | g_PageSetupDlg.hDevMode= pdTemp.hDevMode; 352 | g_PageSetupDlg.hDevNames= pdTemp.hDevNames; 353 | } 354 | } 355 | 356 | // FEATURE: free hDevNames 357 | 358 | return( hDC ); 359 | } 360 | 361 | INT NpPrint( PRINT_DIALOG_TYPE type) 362 | { 363 | HDC hPrintDC; 364 | 365 | SetCursor( hWaitCursor ); 366 | 367 | switch( type ) 368 | { 369 | case UseDialog: 370 | hPrintDC= GetPrinterDCviaDialog(); 371 | break; 372 | case NoDialogNonDefault: 373 | hPrintDC= GetNonDefPrinterDC(); 374 | break; 375 | case DoNotUseDialog: 376 | default: 377 | hPrintDC= GetPrinterDC(); 378 | break; 379 | } 380 | 381 | if( hPrintDC == INVALID_HANDLE_VALUE ) 382 | { 383 | SetCursor( hStdCursor ); 384 | return( 0 ); // message already given 385 | } 386 | 387 | return( NpPrintGivenDC( hPrintDC ) ); 388 | 389 | } 390 | 391 | INT NpPrintGivenDC( HDC hPrintDC ) 392 | { 393 | HANDLE hText= NULL; // handle to MLE text 394 | HFONT hPrintFont= NULL; // font to print with 395 | HANDLE hPrevFont= NULL; // previous font in hPrintDC 396 | 397 | BOOL fPageStarted= FALSE; // true if StartPage called for this page 398 | BOOL fDocStarted= FALSE; // true if StartDoc called 399 | PTCHAR pStartText= NULL; // start of edit text (locked hText) 400 | TEXTMETRIC Metrics; 401 | TCHAR msgbuf[MAX_PATH]; // Document name for tracking print job 402 | INT nLinesPerPage; // not inc. header and footer 403 | // iErr will contain the first error discovered ie it is sticky 404 | // This will be the value returned by this function. 405 | // It does not need to translate SP_* errors except for SP_ERROR which should be 406 | // GetLastError() right after it is first detected. 407 | INT iErr=0; // error return 408 | DOCINFO DocInfo; 409 | LOGFONT lfPrintFont; // local version of FontStruct 410 | LCID lcid; // locale id 411 | 412 | fAbort = FALSE; 413 | hAbortDlgWnd= NULL; 414 | 415 | SetCursor( hWaitCursor ); 416 | 417 | GetResolutions( hPrintDC ); 418 | 419 | // Get the time and date for use in the header or trailer. 420 | // We use the GetDateFormat and GetTimeFormat to get the 421 | // internationalized versions. 422 | 423 | GetLocalTime( &PrintTime ); // use local, not gmt 424 | 425 | lcid= GetUserDefaultLCID(); 426 | 427 | GetDateFormat( lcid, DATE_LONGDATE, &PrintTime, NULL, szFormattedDate, MAXDATE ); 428 | 429 | GetTimeFormat( lcid, 0, &PrintTime, NULL, szFormattedTime, MAXTIME ); 430 | 431 | 432 | /* 433 | * This part is to select the current font to the printer device. 434 | * We have to change the height because FontStruct was created 435 | * assuming the display. Using the remembered pointsize, calculate 436 | * the new height. 437 | */ 438 | 439 | lfPrintFont= FontStruct; // make local copy 440 | lfPrintFont.lfHeight= -(iPointSize*yPixInch)/(72*10); 441 | lfPrintFont.lfWidth= 0; 442 | 443 | // 444 | // convert margins to pixels 445 | // ptPaperSize is the physical paper size, not the printable area. 446 | // do the mapping in physical units 447 | // 448 | 449 | SetMapMode( hPrintDC, MM_ANISOTROPIC ); 450 | 451 | SetViewportExtEx( hPrintDC, 452 | xPhysRes, 453 | yPhysRes, 454 | NULL ); 455 | 456 | SetWindowExtEx( hPrintDC, 457 | g_PageSetupDlg.ptPaperSize.x, 458 | g_PageSetupDlg.ptPaperSize.y, 459 | NULL ); 460 | 461 | rtMargin = g_PageSetupDlg.rtMargin; 462 | 463 | LPtoDP( hPrintDC, (LPPOINT) &rtMargin, 2 ); 464 | 465 | SetMapMode( hPrintDC,MM_TEXT ); // restore to mm_text mode 466 | 467 | hPrintFont= CreateFontIndirect(&lfPrintFont); 468 | 469 | if( !hPrintFont ) 470 | { 471 | goto ErrorExit; 472 | } 473 | 474 | hPrevFont= SelectObject( hPrintDC, hPrintFont ); 475 | if( !hPrevFont ) 476 | { 477 | goto ErrorExit; 478 | } 479 | 480 | SetBkMode( hPrintDC, TRANSPARENT ); 481 | if( !GetTextMetrics( hPrintDC, (LPTEXTMETRIC) &Metrics ) ) 482 | { 483 | goto ErrorExit; 484 | } 485 | 486 | // The font may not a scalable (say on a bubblejet printer) 487 | // In this case, just pick some font 488 | // For example, FixedSys 9 pt would be non-scalable 489 | 490 | if( !(Metrics.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE )) ) 491 | { 492 | // remove just created font 493 | 494 | hPrintFont= SelectObject( hPrintDC, hPrevFont ); // get old font 495 | DeleteObject( hPrintFont ); 496 | 497 | memset( lfPrintFont.lfFaceName, 0, LF_FACESIZE*sizeof(TCHAR) ); 498 | 499 | hPrintFont= CreateFontIndirect( &lfPrintFont ); 500 | if( !hPrintFont ) 501 | { 502 | goto ErrorExit; 503 | } 504 | 505 | hPrevFont= SelectObject( hPrintDC, hPrintFont ); 506 | if( !hPrevFont ) 507 | { 508 | goto ErrorExit; 509 | } 510 | 511 | if( !GetTextMetrics( hPrintDC, (LPTEXTMETRIC) &Metrics ) ) 512 | { 513 | goto ErrorExit; 514 | } 515 | } 516 | yPrintChar= Metrics.tmHeight+Metrics.tmExternalLeading; /* the height */ 517 | 518 | tabSize = Metrics.tmAveCharWidth * 8; /* 8 ave char width pixels for tabs */ 519 | 520 | // compute margins in pixels 521 | 522 | dxLeft= max(rtMargin.left - xPhysOff,0); 523 | dxRight= max(rtMargin.right - (xPhysRes - xPrintRes - xPhysOff), 0 ); 524 | dyTop= max(rtMargin.top - yPhysOff,0); 525 | dyBottom= max(rtMargin.bottom - (yPhysRes - yPrintRes - yPhysOff), 0 ); 526 | 527 | #ifdef DBGPRINT 528 | { 529 | TCHAR dbuf[100]; 530 | RECT rt= g_PageSetupDlg.rtMargin; 531 | POINT pt; 532 | 533 | wsprintf(dbuf,TEXT("Print pOffx %d pOffy %d\n"), 534 | GetDeviceCaps(hPrintDC, PHYSICALOFFSETX), 535 | GetDeviceCaps(hPrintDC, PHYSICALOFFSETY)); 536 | ODS(dbuf); 537 | wsprintf(dbuf,TEXT("PHYSICALWIDTH: %d\n"), xPhysRes); 538 | ODS(dbuf); 539 | wsprintf(dbuf,TEXT("HORZRES: %d\n"),xPrintRes); 540 | ODS(dbuf); 541 | wsprintf(dbuf,TEXT("PHYSICALOFFSETX: %d\n"),xPhysOff); 542 | ODS(dbuf); 543 | wsprintf(dbuf,TEXT("LOGPIXELSX: %d\n"), 544 | GetDeviceCaps(hPrintDC,LOGPIXELSX)); 545 | ODS(dbuf); 546 | 547 | GetViewportOrgEx( hPrintDC, (LPPOINT) &pt ); 548 | wsprintf(dbuf,TEXT("Viewport org: %d %d\n"), pt.x, pt.y ); 549 | ODS(dbuf); 550 | GetWindowOrgEx( hPrintDC, (LPPOINT) &pt ); 551 | wsprintf(dbuf,TEXT("Window org: %d %d\n"), pt.x, pt.y ); 552 | ODS(dbuf); 553 | wsprintf(dbuf,TEXT("PrintRes x: %d y: %d\n"),xPrintRes, yPrintRes); 554 | ODS(dbuf); 555 | wsprintf(dbuf,TEXT("PaperSize x: %d y: %d\n"), 556 | g_PageSetupDlg.ptPaperSize.x, 557 | g_PageSetupDlg.ptPaperSize.y ); 558 | ODS(dbuf); 559 | wsprintf(dbuf,TEXT("unit margins: l: %d r: %d t: %d b: %d\n"), 560 | rt.left, rt.right, rt.top, rt.bottom); 561 | ODS(dbuf); 562 | wsprintf(dbuf,TEXT("pixel margins: l: %d r: %d t: %d b: %d\n"), 563 | rtMargin.left, rtMargin.right, rtMargin.top, rtMargin.bottom); 564 | ODS(dbuf); 565 | 566 | wsprintf(dbuf,TEXT("dxLeft %d dxRight %d\n"),dxLeft,dxRight); 567 | ODS(dbuf); 568 | wsprintf(dbuf,TEXT("dyTop %d dyBot %d\n"),dyTop,dyBottom); 569 | ODS(dbuf); 570 | } 571 | #endif 572 | 573 | 574 | /* Number of lines on a page with margins */ 575 | /* two lines are used by header and footer */ 576 | nLinesPerPage = ((yPrintRes - dyTop - dyBottom) / yPrintChar); 577 | 578 | if( *chPageText[HEADER] ) 579 | nLinesPerPage--; 580 | if( *chPageText[FOOTER] ) 581 | nLinesPerPage--; 582 | 583 | 584 | /* 585 | ** There was a bug in NT once where a printer driver would 586 | ** return a font that was larger than the page size which 587 | ** would then cause Notepad to constantly print blank pages 588 | ** To keep from doing this we check to see if we can fit ANYTHING 589 | ** on a page, if not then there is a problem so quit. MarkRi 8/92 590 | */ 591 | if( nLinesPerPage <= 0 ) 592 | { 593 | FontTooBig: 594 | MessageBox( hwndNP, szFontTooBig, szNN, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION ); 595 | 596 | SetLastError(0); // no error 597 | 598 | ErrorExit: 599 | iErr= GetLastError(); // remember the first error 600 | 601 | ExitWithThisError: // preserve iErr (return SP_* errors) 602 | 603 | if( hPrevFont ) 604 | { 605 | SelectObject( hPrintDC, hPrevFont ); 606 | DeleteObject( hPrintFont ); 607 | } 608 | 609 | if( pStartText ) // were able to lock hText 610 | LocalUnlock( hText ); 611 | 612 | if( fPageStarted ) 613 | { 614 | if( EndPage( hPrintDC ) <= 0 ) 615 | { 616 | // if iErr not already set then set it to the new error code. 617 | if( iErr == 0 ) 618 | { 619 | iErr= GetLastError(); 620 | } 621 | 622 | } 623 | } 624 | 625 | if( fDocStarted ) 626 | { 627 | if( fAbort ) { 628 | AbortDoc( hPrintDC ); 629 | } 630 | else { 631 | if( EndDoc( hPrintDC ) <= 0 ) 632 | { 633 | // if iErr not already set then set it to the new error code. 634 | if (iErr == 0) 635 | { 636 | iErr= GetLastError(); 637 | } 638 | } 639 | } 640 | } 641 | 642 | DeleteDC( hPrintDC ); 643 | 644 | DestroyAbortWnd(); 645 | 646 | SetCursor( hStdCursor ); 647 | 648 | if (!fAbort) 649 | { 650 | return( iErr ); 651 | } 652 | else 653 | { 654 | return( SP_USERABORT ); 655 | } 656 | } 657 | 658 | 659 | 660 | if( (iErr= SetAbortProc (hPrintDC, AbortProc)) < 0 ) 661 | { 662 | goto ExitWithThisError; 663 | } 664 | 665 | // get printer to MLE text 666 | hText= (HANDLE) SendMessage( hwndEdit, EM_GETHANDLE, 0, 0 ); 667 | if( !hText ) 668 | { 669 | goto ErrorExit; 670 | } 671 | pStartText= LocalLock( hText ); 672 | if( !pStartText ) 673 | { 674 | goto ErrorExit; 675 | } 676 | 677 | GetWindowText( hwndNP, msgbuf, CharSizeOf(msgbuf) ); 678 | 679 | EnableWindow( hwndNP, FALSE ); // Disable window to prevent reentrancy 680 | 681 | hAbortDlgWnd= CreateDialog( hInstanceNP, 682 | (LPTSTR) MAKEINTRESOURCE(IDD_ABORTPRINT), 683 | hwndNP, 684 | AbortDlgProc); 685 | 686 | if( !hAbortDlgWnd ) 687 | { 688 | goto ErrorExit; 689 | } 690 | 691 | DocInfo.cbSize= sizeof(DOCINFO); 692 | DocInfo.lpszDocName= msgbuf; 693 | DocInfo.lpszOutput= NULL; 694 | DocInfo.lpszDatatype= NULL; // Type of data used to record print job 695 | DocInfo.fwType= 0; // not DI_APPBANDING 696 | 697 | SetLastError(0); // clear error so it reflects errors in the future 698 | 699 | if( StartDoc( hPrintDC, &DocInfo ) <= 0 ) 700 | { 701 | iErr = GetLastError(); 702 | goto ExitWithThisError; 703 | } 704 | fDocStarted= TRUE; 705 | 706 | 707 | // Basicly, this is just a loop surrounding the DrawTextEx API. 708 | // We have to calculate the printable area which will not include 709 | // the header and footer area. 710 | { 711 | INT iTextLeft; // amount of text left to print 712 | INT iSta; // status 713 | UINT dwDTFormat; // drawtext flags 714 | DRAWTEXTPARAMS dtParm; // drawtext control 715 | RECT rect; // rectangle to draw in 716 | UINT dwDTRigh = 0; // drawtext flags (RTL) 717 | 718 | iPageNum= 1; 719 | fPageStarted= FALSE; 720 | 721 | // calculate the size of the printable area for the text 722 | // not including the header and footer 723 | 724 | ZeroMemory( &rect, sizeof(rect) ); 725 | 726 | rect.left= dxLeft; rect.right= xPrintRes-dxRight; 727 | rect.top= dyTop; rect.bottom= yPrintRes-dyBottom; 728 | 729 | if( *chPageText[HEADER] != 0 ) 730 | { 731 | rect.top += yPrintChar; 732 | } 733 | 734 | if( *chPageText[FOOTER] != 0 ) 735 | { 736 | rect.bottom -= yPrintChar; 737 | } 738 | 739 | iTextLeft= lstrlen(pStartText); 740 | 741 | //Get the edit control direction. 742 | if (GetWindowLong(hwndEdit, GWL_EXSTYLE) & WS_EX_RTLREADING) 743 | dwDTRigh = DT_RIGHT | DT_RTLREADING; 744 | 745 | 746 | while( !fAbort && (iTextLeft>0) ) 747 | { 748 | #define MAXSTATUS 100 749 | TCHAR szPagePrinting[MAXSTATUS+1]; 750 | 751 | // update abort dialog box to inform user where we are in the printing 752 | _sntprintf( szPagePrinting, MAXSTATUS, szCurrentPage, iPageNum ); 753 | SetDlgItemText( hAbortDlgWnd, ID_PAGENUMBER, szPagePrinting ); 754 | 755 | PrintHeaderFooter( hPrintDC, HEADER ); 756 | 757 | ZeroMemory( &dtParm, sizeof(dtParm) ); 758 | 759 | dtParm.cbSize= sizeof(dtParm); 760 | dtParm.iTabLength= tabSize; 761 | 762 | dwDTFormat= DT_EDITCONTROL | DT_LEFT | DT_EXPANDTABS | DT_NOPREFIX | 763 | DT_WORDBREAK | dwDTRigh | 0; 764 | 765 | if( StartPage( hPrintDC ) <= 0 ) 766 | { 767 | iErr= GetLastError(); 768 | goto ExitWithThisError; 769 | } 770 | fPageStarted= TRUE; 771 | 772 | #ifdef DBGPRINT 773 | ShowMargins(hPrintDC); 774 | #endif 775 | 776 | /* Ignore errors in printing. EndPage or StartPage will find them */ 777 | iSta= DrawTextEx( hPrintDC, 778 | pStartText, 779 | iTextLeft, 780 | &rect, 781 | dwDTFormat, 782 | &dtParm); 783 | 784 | PrintHeaderFooter( hPrintDC, FOOTER ); 785 | 786 | if( EndPage( hPrintDC ) <= 0 ) 787 | { 788 | iErr= GetLastError(); 789 | goto ExitWithThisError; 790 | } 791 | fPageStarted= FALSE; 792 | 793 | iPageNum++; 794 | 795 | // if we can't print a single character (too big perhaps) 796 | // just bail now. 797 | if( dtParm.uiLengthDrawn == 0 ) 798 | { 799 | goto FontTooBig; 800 | } 801 | 802 | pStartText += dtParm.uiLengthDrawn; 803 | iTextLeft -= dtParm.uiLengthDrawn; 804 | 805 | } 806 | 807 | 808 | } 809 | 810 | iErr=0; // no errors 811 | goto ExitWithThisError; 812 | 813 | } 814 | 815 | 816 | VOID DestroyAbortWnd (void) 817 | { 818 | EnableWindow(hwndNP, TRUE); 819 | DestroyWindow(hAbortDlgWnd); 820 | hAbortDlgWnd = NULL; 821 | } 822 | 823 | 824 | 825 | const DWORD s_PageSetupHelpIDs[] = { 826 | ID_HEADER_LABEL, IDH_PAGE_HEADER, 827 | ID_HEADER, IDH_PAGE_HEADER, 828 | ID_FOOTER_LABEL, IDH_PAGE_FOOTER, 829 | ID_FOOTER, IDH_PAGE_FOOTER, 830 | 0, 0 831 | }; 832 | 833 | /******************************************************************************* 834 | * 835 | * PageSetupHookProc 836 | * 837 | * DESCRIPTION: 838 | * Callback procedure for the PageSetup common dialog box. 839 | * 840 | * PARAMETERS: 841 | * hWnd, handle of PageSetup window. 842 | * Message, 843 | * wParam, 844 | * lParam, 845 | * (returns), 846 | * 847 | *******************************************************************************/ 848 | 849 | UINT_PTR CALLBACK PageSetupHookProc( 850 | HWND hWnd, 851 | UINT Message, 852 | WPARAM wParam, 853 | LPARAM lParam 854 | ) 855 | { 856 | 857 | INT id; /* ID of dialog edit controls */ 858 | POINT pt; 859 | 860 | switch (Message) 861 | { 862 | 863 | case WM_INITDIALOG: 864 | for (id = ID_HEADER; id <= ID_FOOTER; id++) 865 | { 866 | SendDlgItemMessage(hWnd, id, EM_LIMITTEXT, PT_LEN-1, 0L); 867 | SetDlgItemText(hWnd, id, chPageText[id - ID_HEADER]); 868 | } 869 | 870 | SendDlgItemMessage(hWnd, ID_HEADER, EM_SETSEL, 0, 871 | MAKELONG(0, PT_LEN-1)); 872 | return TRUE; 873 | 874 | case WM_DESTROY: 875 | // We don't know if the user hit OK or Cancel, so we don't 876 | // want to replace our real copies until we know! We _should_ get 877 | // a notification from the common dialog code! 878 | for( id = ID_HEADER; id <= ID_FOOTER; id++ ) 879 | { 880 | GetDlgItemText(hWnd, id, chPageTextTemp[id - ID_HEADER],PT_LEN); 881 | } 882 | break; 883 | 884 | case WM_HELP: 885 | // 886 | // We only want to intercept help messages for controls that we are 887 | // responsible for. 888 | // 889 | 890 | id = GetDlgCtrlID(((LPHELPINFO) lParam)-> hItemHandle); 891 | 892 | if (id < ID_HEADER || id > ID_FOOTER_LABEL) 893 | break; 894 | 895 | WinHelp(((LPHELPINFO) lParam)-> hItemHandle, szHelpFile, 896 | HELP_WM_HELP, (UINT_PTR) (LPVOID) s_PageSetupHelpIDs); 897 | return TRUE; 898 | 899 | case WM_CONTEXTMENU: 900 | // 901 | // If the user clicks on any of our labels, then the wParam will 902 | // be the hwnd of the dialog, not the static control. WinHelp() 903 | // handles this, but because we hook the dialog, we must catch it 904 | // first. 905 | // 906 | if( hWnd == (HWND) wParam ) 907 | { 908 | 909 | GetCursorPos(&pt); 910 | ScreenToClient(hWnd, &pt); 911 | wParam = (WPARAM) ChildWindowFromPoint(hWnd, pt); 912 | 913 | } 914 | 915 | // 916 | // We only want to intercept help messages for controls that we are 917 | // responsible for. 918 | // 919 | 920 | id = GetDlgCtrlID((HWND) wParam); 921 | 922 | if (id < ID_HEADER || id > ID_FOOTER_LABEL) 923 | break; 924 | 925 | WinHelp((HWND) wParam, szHelpFile, HELP_CONTEXTMENU, 926 | (UINT_PTR) (LPVOID) s_PageSetupHelpIDs); 927 | return TRUE; 928 | 929 | } 930 | 931 | return FALSE; 932 | 933 | } 934 | 935 | /*************************************************************************** 936 | * VOID TranslateString(TCHAR *src) 937 | * 938 | * purpose: 939 | * translate a header/footer strings 940 | * 941 | * supports the following: 942 | * 943 | * && insert a & char 944 | * &f current file name or (untitled) 945 | * &d date in Day Month Year 946 | * &t time 947 | * &p page number 948 | * &p+num set first page number to num 949 | * 950 | * Alignment: 951 | * &l, &c, &r for left, center, right 952 | * 953 | * params: 954 | * IN/OUT src this is the string to translate 955 | * 956 | * 957 | * used by: 958 | * Header Footer stuff 959 | * 960 | * uses: 961 | * lots of c lib stuff 962 | * 963 | ***************************************************************************/ 964 | 965 | 966 | VOID TranslateString (TCHAR * src) 967 | { 968 | TCHAR buf[MAX_PATH]; 969 | TCHAR *ptr; 970 | INT page; 971 | INT nAlign=CENTER; // current string to add chars to 972 | INT foo; 973 | INT nIndex[RIGHT+1]; // current lengths of (left,center,right) 974 | struct tm *newtime; 975 | time_t long_time; 976 | INT iLen; // length of strings 977 | 978 | nIndex[LEFT] = 0; 979 | nIndex[CENTER] = 0; 980 | nIndex[RIGHT] = 0; 981 | 982 | 983 | /* Get the time we need in case we use &t. */ 984 | time (&long_time); 985 | newtime = localtime (&long_time); 986 | 987 | 988 | while (*src) /* look at all of source */ 989 | { 990 | while (*src && *src != TEXT('&')) 991 | { 992 | chBuff[nAlign][nIndex[nAlign]] = *src++; 993 | nIndex[nAlign] += 1; 994 | } 995 | 996 | if (*src == TEXT('&')) /* is it the escape char? */ 997 | { 998 | src++; 999 | 1000 | if (*src == szLetters[0] || *src == szLetters[1]) 1001 | { /* &f file name (no path) */ 1002 | if (!fUntitled) 1003 | { 1004 | GetFileTitle(szFileName, buf, CharSizeOf(buf)); 1005 | } 1006 | else 1007 | { 1008 | lstrcpy(buf, szUntitled); 1009 | } 1010 | 1011 | /* Copy to the currently aligned string. */ 1012 | if( nIndex[nAlign] + lstrlen(buf) < MAXTITLE ) 1013 | { 1014 | lstrcpy( chBuff[nAlign] + nIndex[nAlign], buf ); 1015 | 1016 | /* Update insertion position. */ 1017 | nIndex[nAlign] += lstrlen (buf); 1018 | } 1019 | 1020 | } 1021 | else if (*src == szLetters[2] || *src == szLetters[3]) /* &P or &P+num page */ 1022 | { 1023 | src++; 1024 | page = 0; 1025 | if (*src == TEXT('+')) /* &p+num case */ 1026 | { 1027 | src++; 1028 | while (_istdigit(*src)) 1029 | { 1030 | /* Convert to int on-the-fly*/ 1031 | page = (10*page) + (*src) - TEXT('0'); 1032 | src++; 1033 | } 1034 | } 1035 | 1036 | wsprintf( buf, TEXT("%d"), iPageNum+page ); // convert to chars 1037 | 1038 | if( nIndex[nAlign] + lstrlen(buf) < MAXTITLE ) 1039 | { 1040 | lstrcpy( chBuff[nAlign] + nIndex[nAlign], buf ); 1041 | nIndex[nAlign] += lstrlen (buf); 1042 | } 1043 | src--; 1044 | } 1045 | else if (*src == szLetters[4] || *src == szLetters[5]) /* &t time */ 1046 | { 1047 | iLen= lstrlen( szFormattedTime ); 1048 | 1049 | /* extract time */ 1050 | if( nIndex[nAlign] + iLen < MAXTITLE ) 1051 | { 1052 | _tcsncpy (chBuff[nAlign] + nIndex[nAlign], szFormattedTime, iLen); 1053 | nIndex[nAlign] += iLen; 1054 | } 1055 | } 1056 | else if (*src == szLetters[6] || *src == szLetters[7]) /* &d date */ 1057 | { 1058 | iLen= lstrlen( szFormattedDate ); 1059 | 1060 | /* extract day month day */ 1061 | if( nIndex[nAlign] + iLen < MAXTITLE ) 1062 | { 1063 | _tcsncpy (chBuff[nAlign] + nIndex[nAlign], szFormattedDate, iLen); 1064 | nIndex[nAlign] += iLen; 1065 | } 1066 | } 1067 | else if (*src == TEXT('&')) /* quote a single & */ 1068 | { 1069 | if( nIndex[nAlign] + 1 < MAXTITLE ) 1070 | { 1071 | chBuff[nAlign][nIndex[nAlign]] = TEXT('&'); 1072 | nIndex[nAlign] += 1; 1073 | } 1074 | } 1075 | /* Set the alignment for whichever has last occured. */ 1076 | else if (*src == szLetters[8] || *src == szLetters[9]) /* &c center */ 1077 | nAlign=CENTER; 1078 | else if (*src == szLetters[10] || *src == szLetters[11]) /* &r right */ 1079 | nAlign=RIGHT; 1080 | else if (*src == szLetters[12] || *src == szLetters[13]) /* &d date */ 1081 | nAlign=LEFT; 1082 | 1083 | src++; 1084 | } 1085 | } 1086 | /* Make sure all strings are null-terminated. */ 1087 | for (nAlign= LEFT; nAlign <= RIGHT ; nAlign++) 1088 | chBuff[nAlign][nIndex[nAlign]] = (TCHAR) 0; 1089 | 1090 | } 1091 | 1092 | /* GetPrinterDC() - returns printer DC or INVALID_HANDLE_VALUE if none. */ 1093 | 1094 | HANDLE GetPrinterDC (VOID) 1095 | { 1096 | LPDEVMODE lpDevMode; 1097 | LPDEVNAMES lpDevNames; 1098 | HDC hDC; 1099 | 1100 | 1101 | if( !g_PageSetupDlg.hDevNames ) /* Retrieve default printer if none selected. */ 1102 | { 1103 | g_PageSetupDlg.Flags |= PSD_RETURNDEFAULT; 1104 | PageSetupDlg(&g_PageSetupDlg); 1105 | g_PageSetupDlg.Flags &= ~PSD_RETURNDEFAULT; 1106 | } 1107 | 1108 | if( !g_PageSetupDlg.hDevNames ) 1109 | { 1110 | MessageBox( hwndNP, szLoadDrvFail, szNN, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 1111 | return INVALID_HANDLE_VALUE; 1112 | } 1113 | 1114 | lpDevNames= (LPDEVNAMES) GlobalLock (g_PageSetupDlg.hDevNames); 1115 | 1116 | 1117 | lpDevMode= NULL; 1118 | 1119 | if( g_PageSetupDlg.hDevMode ) 1120 | lpDevMode= (LPDEVMODE) GlobalLock( g_PageSetupDlg.hDevMode ); 1121 | 1122 | /* For pre 3.0 Drivers,hDevMode will be null from Commdlg so lpDevMode 1123 | * will be NULL after GlobalLock() 1124 | */ 1125 | 1126 | /* The lpszOutput name is null so CreateDC will use the current setting 1127 | * from PrintMan. 1128 | */ 1129 | 1130 | hDC= CreateDC (((LPTSTR)lpDevNames)+lpDevNames->wDriverOffset, 1131 | ((LPTSTR)lpDevNames)+lpDevNames->wDeviceOffset, 1132 | NULL, 1133 | lpDevMode); 1134 | 1135 | GlobalUnlock( g_PageSetupDlg.hDevNames ); 1136 | 1137 | if( g_PageSetupDlg.hDevMode ) 1138 | GlobalUnlock( g_PageSetupDlg.hDevMode ); 1139 | 1140 | 1141 | if( hDC == NULL ) 1142 | { 1143 | MessageBox( hwndNP, szLoadDrvFail, szNN, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 1144 | return INVALID_HANDLE_VALUE; 1145 | } 1146 | 1147 | return hDC; 1148 | } 1149 | 1150 | 1151 | /* GetNonDefPrinterDC() - returns printer DC or INVALID_HANDLE_VALUE if none. */ 1152 | /* using the name of the Printer server */ 1153 | 1154 | HANDLE GetNonDefPrinterDC (VOID) 1155 | { 1156 | HDC hDC; 1157 | HANDLE hPrinter; 1158 | DWORD dwBuf; 1159 | DRIVER_INFO_1 *di1; 1160 | 1161 | 1162 | 1163 | // open the printer and retrieve the driver name. 1164 | if (!OpenPrinter(szPrinterName, &hPrinter, NULL)) 1165 | { 1166 | return INVALID_HANDLE_VALUE; 1167 | } 1168 | 1169 | // get the buffer size. 1170 | GetPrinterDriver(hPrinter, NULL, 1, NULL, 0, &dwBuf); 1171 | di1 = (DRIVER_INFO_1 *) LocalAlloc(LPTR, dwBuf); 1172 | if (!di1) 1173 | { 1174 | ClosePrinter(hPrinter); 1175 | return INVALID_HANDLE_VALUE; 1176 | } 1177 | 1178 | if (!GetPrinterDriver(hPrinter, NULL, 1, (LPBYTE) di1, dwBuf, &dwBuf)) 1179 | { 1180 | LocalFree(di1); 1181 | ClosePrinter(hPrinter); 1182 | return INVALID_HANDLE_VALUE; 1183 | } 1184 | 1185 | // Initialize the PageSetup dlg to default values. 1186 | // using default printer's value for another printer !! 1187 | g_PageSetupDlg.Flags |= PSD_RETURNDEFAULT; 1188 | PageSetupDlg(&g_PageSetupDlg); 1189 | g_PageSetupDlg.Flags &= ~PSD_RETURNDEFAULT; 1190 | 1191 | // create printer dc with default initialization. 1192 | hDC= CreateDC (di1->pName, szPrinterName, NULL, NULL); 1193 | 1194 | // cleanup. 1195 | LocalFree(di1); 1196 | ClosePrinter(hPrinter); 1197 | 1198 | if( hDC == NULL ) 1199 | { 1200 | MessageBox( hwndNP, szLoadDrvFail, szNN, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 1201 | return INVALID_HANDLE_VALUE; 1202 | } 1203 | 1204 | return hDC; 1205 | } 1206 | 1207 | 1208 | /* PrintIt() - print the file, giving popup if some error */ 1209 | 1210 | void PrintIt(PRINT_DIALOG_TYPE type) 1211 | { 1212 | INT iError; 1213 | TCHAR* szMsg= NULL; 1214 | TCHAR msg[400]; // message info on error 1215 | 1216 | /* print the file */ 1217 | 1218 | iError= NpPrint( type ); 1219 | 1220 | if(( iError != 0) && 1221 | ( iError != SP_APPABORT ) && 1222 | ( iError != SP_USERABORT ) ) 1223 | { 1224 | // translate any known spooler errors 1225 | if( iError == SP_OUTOFDISK ) iError= ERROR_DISK_FULL; 1226 | if( iError == SP_OUTOFMEMORY ) iError= ERROR_OUTOFMEMORY; 1227 | if( iError == SP_ERROR ) iError= GetLastError(); 1228 | /* SP_NOTREPORTED not handled. Does it happen? */ 1229 | 1230 | 1231 | // 1232 | // iError may be 0 because the user aborted the printing. 1233 | // Just ignore. 1234 | // 1235 | 1236 | if( iError == 0 ) return; 1237 | 1238 | // Get system to give reasonable error message 1239 | // These will also be internationalized. 1240 | 1241 | if(!FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | 1242 | FORMAT_MESSAGE_FROM_SYSTEM, 1243 | NULL, 1244 | iError, 1245 | GetUserDefaultLangID(), 1246 | msg, // where message will end up 1247 | CharSizeOf(msg), NULL ) ) 1248 | { 1249 | szMsg= szCP; // couldn't get system to say; give generic msg 1250 | } 1251 | else 1252 | { 1253 | szMsg= msg; 1254 | } 1255 | 1256 | AlertBox( hwndNP, szNN, szMsg, fUntitled ? szUntitled : szFileName, 1257 | MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); 1258 | } 1259 | } 1260 | -------------------------------------------------------------------------------- /nputf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * nputf.c - Routines for utf text processing for notepad 3 | * 4 | * Copyright (C) 1998-2001 Microsoft Inc. 5 | */ 6 | 7 | #include "precomp.h" 8 | 9 | 10 | /* IsTextUTF8 11 | * 12 | * UTF-8 is the encoding of Unicode based on Internet Society RFC2279 13 | * ( See http://www.cis.ohio-state.edu/htbin/rfc/rfc2279.html ) 14 | * 15 | * Basicly: 16 | * 0000 0000-0000 007F - 0xxxxxxx (ascii converts to 1 octet!) 17 | * 0000 0080-0000 07FF - 110xxxxx 10xxxxxx ( 2 octet format) 18 | * 0000 0800-0000 FFFF - 1110xxxx 10xxxxxx 10xxxxxx (3 octet format) 19 | * (this keeps going for 32 bit unicode) 20 | * 21 | * 22 | * Return value: TRUE, if the text is in UTF-8 format. 23 | * FALSE, if the text is not in UTF-8 format. 24 | * We will also return FALSE is it is only 7-bit ascii, so the right code page 25 | * will be used. 26 | * 27 | * Actually for 7 bit ascii, it doesn't matter which code page we use, but 28 | * notepad will remember that it is utf-8 and "save" or "save as" will store 29 | * the file with a UTF-8 BOM. Not cool. 30 | */ 31 | 32 | 33 | INT IsTextUTF8( LPSTR lpstrInputStream, INT iLen ) 34 | { 35 | INT i; 36 | DWORD cOctets; // octets to go in this UTF-8 encoded character 37 | UCHAR chr; 38 | BOOL bAllAscii= TRUE; 39 | 40 | cOctets= 0; 41 | for( i=0; i < iLen; i++ ) { 42 | chr= *(lpstrInputStream+i); 43 | 44 | if( (chr&0x80) != 0 ) bAllAscii= FALSE; 45 | 46 | if( cOctets == 0 ) { 47 | // 48 | // 7 bit ascii after 7 bit ascii is just fine. Handle start of encoding case. 49 | // 50 | if( chr >= 0x80 ) { 51 | // 52 | // count of the leading 1 bits is the number of characters encoded 53 | // 54 | do { 55 | chr <<= 1; 56 | cOctets++; 57 | } 58 | while( (chr&0x80) != 0 ); 59 | 60 | cOctets--; // count includes this character 61 | if( cOctets == 0 ) return FALSE; // must start with 11xxxxxx 62 | } 63 | } 64 | else { 65 | // non-leading bytes must start as 10xxxxxx 66 | if( (chr&0xC0) != 0x80 ) { 67 | return FALSE; 68 | } 69 | cOctets--; // processed another octet in encoding 70 | } 71 | } 72 | 73 | // 74 | // End of text. Check for consistency. 75 | // 76 | 77 | if( cOctets > 0 ) { // anything left over at the end is an error 78 | return FALSE; 79 | } 80 | 81 | if( bAllAscii ) { // Not utf-8 if all ascii. Forces caller to use code pages for conversion 82 | return FALSE; 83 | } 84 | 85 | return TRUE; 86 | } 87 | 88 | 89 | /* IsInputTextUnicode 90 | * Verify if the input stream is in Unicode format. 91 | * 92 | * Return value: TRUE, if the text is in Unicode format. 93 | * 94 | * 29 June 1998 95 | */ 96 | 97 | 98 | INT IsInputTextUnicode (LPSTR lpstrInputStream, INT iLen) 99 | { 100 | INT iResult= ~0; // turn on IS_TEXT_UNICODE_DBCS_LEADBYTE 101 | BOOL bUnicode; 102 | 103 | bUnicode= IsTextUnicode( lpstrInputStream, iLen, &iResult); 104 | 105 | // this code is not required as IsTextUnicode does the required checks 106 | // and it's legal to have a unicode char with a DBCS leading byte! 107 | 108 | #ifdef UNUSEDCODE 109 | { 110 | 111 | if (bUnicode && 112 | ((iResult & IS_TEXT_UNICODE_STATISTICS) != 0 ) && 113 | ((iResult & (~IS_TEXT_UNICODE_STATISTICS)) == 0 ) ) 114 | { 115 | CPINFO cpiInfo; 116 | CHAR* pch= (CHAR*)lpstrInputStream; 117 | INT cb; 118 | 119 | // 120 | // If the result depends only upon statistics, check 121 | // to see if there is a possibility of DBCS. 122 | // Only do this check if the ansi code page is DBCS 123 | // 124 | 125 | GetCPInfo( CP_ACP, &cpiInfo); 126 | 127 | if( cpiInfo.MaxCharSize > 1 ) 128 | { 129 | for( cb=0; cb 4 | #include 5 | #include // for NORM_STOP_ON_NULL 6 | 7 | #include 8 | 9 | // 10 | // We need to define BYTE_ORDER_MARK, and figure 11 | // out how to get the system to tell us a font is a 12 | // unicode font, and then we can eliminate uconvert.h 13 | // 14 | #include "uconvert.h" 15 | #include "uniconv.h" 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include "dlgs.h" 24 | -------------------------------------------------------------------------------- /sources: -------------------------------------------------------------------------------- 1 | TARGETNAME=notepad 2 | TARGETPATH=obj 3 | TARGETTYPE=PROGRAM 4 | 5 | INCLUDES=..\..\inc;$(BASE_INC_PATH) 6 | 7 | USE_MSVCRT=1 8 | 9 | SOURCES=notepad.rc \ 10 | notepad.c \ 11 | npinit.c \ 12 | npfile.c \ 13 | npmisc.c \ 14 | npprint.c \ 15 | npdate.c \ 16 | nputf.c 17 | 18 | 19 | C_DEFINES=-DWIN32 -DNT -DUNICODE -D_UNICODE 20 | 21 | UMTYPE=windows 22 | UMENTRY=winmain 23 | 24 | UMLIBS=$(SDK_LIB_PATH)\comdlg32.lib \ 25 | $(SDK_LIB_PATH)\shell32.lib \ 26 | $(SDK_LIB_PATH)\htmlhelp.lib \ 27 | $(SDK_LIB_PATH)\winspool.lib \ 28 | $(SDK_LIB_PATH)\comctl32.lib 29 | 30 | PRECOMPILED_INCLUDE=precomp.h 31 | PRECOMPILED_PCH=precomp.pch 32 | PRECOMPILED_OBJ=precomp.obj 33 | 34 | 35 | # big enough even for checked builds 36 | LINKER_STACKCOMMITSIZE=0x11000 37 | 38 | # 39 | # Fusionized 40 | # 41 | SXS_APPLICATION_MANIFEST=WindowsShell.Manifest 42 | -------------------------------------------------------------------------------- /texttxt/utf-8.txt: -------------------------------------------------------------------------------- 1 | あいうえお -------------------------------------------------------------------------------- /windowsshell.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | Windows Shell 9 | 10 | 11 | 19 | 20 | 21 | 22 | --------------------------------------------------------------------------------