Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1114 lines
37 KiB

  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. #include "precomp.h"
  10. TCHAR chPageText[2][PT_LEN]; /* Strings to hold PageSetup items. */
  11. TCHAR chPageTextTemp[2][PT_LEN];
  12. TCHAR szPrinterName[256]; /* String to hold printername for PrintTo verb */
  13. static NP_FILETYPE fInitFileType; /* file type override */
  14. static INT fSaveWindowPositions=0; /* true if we are to save window position */
  15. static INT g_WPtop,g_WPleft,g_WPDX,g_WPDY; /* initial window positions */
  16. /* routines to handle saving and restoring information in the registry.
  17. *
  18. * SaveGlobals - saves interesting globals to the registry
  19. *
  20. * GetGlobals - gets interesting globals from the registry
  21. *
  22. * Interesting Globals:
  23. *
  24. * FontStruct information include calculated pointsize
  25. * Codepage
  26. *
  27. * If we want to save PageSetup info, save the margins in some
  28. * units (cm for example) and convert on input and output.
  29. */
  30. /* name of section to save into -- never internationalize */
  31. #define OURKEYNAME TEXT("Software\\Microsoft\\Notepad")
  32. // RegWriteInt - write an integer to the registry
  33. VOID RegWriteInt( HKEY hKey, PTCHAR pszKey, INT iValue )
  34. {
  35. RegSetValueEx( hKey, pszKey, 0, REG_DWORD, (BYTE*)&iValue, sizeof(INT) );
  36. }
  37. // RegWriteString - write a string to the registry
  38. VOID RegWriteString( HKEY hKey, PTCHAR pszKey, PTCHAR pszValue )
  39. {
  40. INT len; // length of string with null in bytes
  41. len= (lstrlen( pszValue )+1) * sizeof(TCHAR);
  42. RegSetValueEx( hKey, pszKey, 0, REG_SZ, (BYTE*)pszValue, len );
  43. }
  44. // RegGetInt - Get integer from registry
  45. DWORD RegGetInt( HKEY hKey, PTCHAR pszKey, DWORD dwDefault )
  46. {
  47. DWORD dwResult= !ERROR_SUCCESS;
  48. LONG lStatus= ERROR_SUCCESS;
  49. DWORD dwSize= sizeof(DWORD);
  50. DWORD dwType= 0;
  51. if( hKey )
  52. {
  53. lStatus= RegQueryValueEx( hKey,
  54. pszKey,
  55. NULL,
  56. &dwType,
  57. (BYTE*) &dwResult,
  58. &dwSize );
  59. }
  60. if( lStatus != ERROR_SUCCESS || dwType != REG_DWORD )
  61. {
  62. dwResult= dwDefault;
  63. }
  64. return( dwResult );
  65. }
  66. // RegGetString - get string from registry
  67. VOID RegGetString( HKEY hKey, PTCHAR pszKey, PTCHAR pszDefault, PTCHAR pszResult, INT iCharLen )
  68. {
  69. LONG lStatus= !ERROR_SUCCESS;
  70. DWORD dwSize; // size of buffer
  71. DWORD dwType;
  72. dwSize= iCharLen * sizeof(TCHAR);
  73. if( hKey )
  74. {
  75. lStatus= RegQueryValueEx( hKey,
  76. pszKey,
  77. NULL,
  78. &dwType,
  79. (BYTE*) pszResult,
  80. &dwSize );
  81. }
  82. if( lStatus != ERROR_SUCCESS || dwType != REG_SZ )
  83. {
  84. CopyMemory( pszResult, pszDefault, iCharLen*sizeof(TCHAR) );
  85. }
  86. }
  87. // lfHeight is calculated using PointSize
  88. // lfWidth set by font mapper
  89. VOID SaveGlobals(VOID)
  90. {
  91. HKEY hKey; // key to our registry root
  92. LONG lStatus; // status from RegCreateKey
  93. WINDOWPLACEMENT wp;
  94. lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey );
  95. if( lStatus != ERROR_SUCCESS )
  96. {
  97. return; // just return quietly
  98. }
  99. RegWriteInt( hKey, TEXT("lfEscapement"), FontStruct.lfEscapement);
  100. RegWriteInt( hKey, TEXT("lfOrientation"), FontStruct.lfOrientation);
  101. RegWriteInt( hKey, TEXT("lfWeight"), FontStruct.lfWeight);
  102. RegWriteInt( hKey, TEXT("lfItalic"), FontStruct.lfItalic);
  103. RegWriteInt( hKey, TEXT("lfUnderline"), FontStruct.lfUnderline);
  104. RegWriteInt( hKey, TEXT("lfStrikeOut"), FontStruct.lfStrikeOut);
  105. RegWriteInt( hKey, TEXT("lfCharSet"), FontStruct.lfCharSet);
  106. RegWriteInt( hKey, TEXT("lfOutPrecision"), FontStruct.lfOutPrecision);
  107. RegWriteInt( hKey, TEXT("lfClipPrecision"), FontStruct.lfClipPrecision);
  108. RegWriteInt( hKey, TEXT("lfQuality"), FontStruct.lfQuality);
  109. RegWriteInt( hKey, TEXT("lfPitchAndFamily"), FontStruct.lfPitchAndFamily);
  110. RegWriteInt( hKey, TEXT("iPointSize"), iPointSize);
  111. RegWriteInt( hKey, TEXT("fWrap"), fWrap);
  112. RegWriteInt( hKey, TEXT("StatusBar"), fStatus);
  113. RegWriteInt( hKey, TEXT("fSaveWindowPositions"),fSaveWindowPositions );
  114. RegWriteString( hKey, TEXT("lfFaceName"), FontStruct.lfFaceName);
  115. RegWriteString( hKey, TEXT("szHeader"), chPageText[HEADER] );
  116. RegWriteString( hKey, TEXT("szTrailer"), chPageText[FOOTER] );
  117. RegWriteInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top );
  118. RegWriteInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom );
  119. RegWriteInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left );
  120. RegWriteInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right );
  121. RegWriteInt( hKey, TEXT("fMLE_is_broken"), fMLE_is_broken );
  122. wp.length= sizeof(wp);
  123. if( GetWindowPlacement( hwndNP, &wp ) )
  124. {
  125. RegWriteInt( hKey, TEXT("iWindowPosX"), wp.rcNormalPosition.left);
  126. RegWriteInt( hKey, TEXT("iWindowPosY"), wp.rcNormalPosition.top);
  127. RegWriteInt( hKey, TEXT("iWindowPosDX"), wp.rcNormalPosition.right - wp.rcNormalPosition.left);
  128. RegWriteInt( hKey, TEXT("iWindowPosDY"), wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
  129. }
  130. RegCloseKey( hKey );
  131. }
  132. // GetGlobals
  133. //
  134. // Pick up font information etc that may be saved in the registry.
  135. //
  136. // We are called pretty early in setup and don't have things like hwndNP valid yet.
  137. //
  138. VOID GetGlobals( VOID )
  139. {
  140. LOGFONT lfDef; // default logical font
  141. HFONT hFont; // standard font to use
  142. LONG lStatus; // status from RegCreateKey
  143. HKEY hKey; // key into registry
  144. //
  145. // quickly get a reasonable set of default parameters
  146. // for the default font if we need it.
  147. //
  148. hFont= GetStockObject( SYSTEM_FIXED_FONT );
  149. if ( hFont )
  150. {
  151. GetObject( hFont, sizeof(LOGFONT), &lfDef );
  152. }
  153. lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey );
  154. if( lStatus != ERROR_SUCCESS )
  155. {
  156. hKey= NULL; // later calls to RegGet... will return defaults
  157. }
  158. FontStruct.lfWidth= 0;
  159. FontStruct.lfEscapement= (LONG)RegGetInt( hKey, TEXT("lfEscapement"), lfDef.lfEscapement);
  160. FontStruct.lfOrientation= (LONG)RegGetInt( hKey, TEXT("lfOrientation"), lfDef.lfOrientation);
  161. FontStruct.lfWeight= (LONG)RegGetInt( hKey, TEXT("lfWeight"), lfDef.lfWeight);
  162. FontStruct.lfItalic= (BYTE)RegGetInt( hKey, TEXT("lfItalic"), lfDef.lfItalic);
  163. FontStruct.lfUnderline= (BYTE)RegGetInt( hKey, TEXT("lfUnderline"), lfDef.lfUnderline);
  164. FontStruct.lfStrikeOut= (BYTE)RegGetInt( hKey, TEXT("lfStrikeOut"), lfDef.lfStrikeOut);
  165. //
  166. // We have to preserve lfCharSet because some fonts (symbol, marlett) don't handle
  167. // 0 (ANSI_CHARSET) or 1 (DEFAULT_CHARSET), and the font mapper will map to a
  168. // different facename. Later we will see if the CreateFont has the same FaceName
  169. // and get a more appropriate lfCharSet if need be.
  170. //
  171. FontStruct.lfCharSet= (BYTE)RegGetInt( hKey, TEXT("lfCharSet"), lfDef.lfCharSet);
  172. FontStruct.lfOutPrecision= (BYTE)RegGetInt( hKey, TEXT("lfOutPrecision"), lfDef.lfOutPrecision);
  173. FontStruct.lfClipPrecision= (BYTE)RegGetInt( hKey, TEXT("lfClipPrecision"), lfDef.lfClipPrecision);
  174. FontStruct.lfQuality= (BYTE)RegGetInt( hKey, TEXT("lfQuality"), lfDef.lfQuality);
  175. FontStruct.lfPitchAndFamily= (BYTE)RegGetInt( hKey, TEXT("lfPitchAndFamily"), lfDef.lfPitchAndFamily);
  176. //
  177. // If there is no FaceName in the registry, use the default "Lucida Console"
  178. // This will show off most of the glyphs except in the FE locales.
  179. // For FE, we can't font link fonts with the glyphs because they would have to have
  180. // the exact width as lucida console, or the console/csrss will AV (July 9, 1999)
  181. //
  182. RegGetString( hKey, TEXT("lfFaceName"), TEXT("Lucida Console"), FontStruct.lfFaceName, LF_FACESIZE);
  183. iPointSize= RegGetInt( hKey, TEXT("iPointSize"), 100);
  184. fWrap= RegGetInt( hKey, TEXT("fWrap"), 0);
  185. fStatus= RegGetInt( hKey, TEXT("StatusBar"), 0);
  186. fSaveWindowPositions= RegGetInt( hKey, TEXT("fSaveWindowPositions"), 0 );
  187. // if page settings not in registry, we will use defaults
  188. RegGetString( hKey, TEXT("szHeader"), chPageText[HEADER], chPageText[HEADER], PT_LEN );
  189. RegGetString( hKey, TEXT("szTrailer"), chPageText[FOOTER], chPageText[FOOTER], PT_LEN );
  190. g_PageSetupDlg.rtMargin.top= (LONG)RegGetInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top );
  191. g_PageSetupDlg.rtMargin.bottom= (LONG)RegGetInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom );
  192. g_PageSetupDlg.rtMargin.left= (LONG)RegGetInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left );
  193. g_PageSetupDlg.rtMargin.right= (LONG)RegGetInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right );
  194. // if window positions in registry use them, otherwise us defaults
  195. g_WPtop= RegGetInt( hKey, TEXT("iWindowPosY"), CW_USEDEFAULT );
  196. g_WPleft= RegGetInt( hKey, TEXT("iWindowPosX"), CW_USEDEFAULT );
  197. g_WPDX= RegGetInt( hKey, TEXT("iWindowPosDX"), CW_USEDEFAULT );
  198. g_WPDY= RegGetInt( hKey, TEXT("iWindowPosDY"), CW_USEDEFAULT );
  199. fMLE_is_broken= RegGetInt( hKey, TEXT("fMLE_is_broken"), FALSE ); // assume edit control works
  200. if( hKey )
  201. {
  202. RegCloseKey( hKey );
  203. }
  204. }
  205. /*
  206. * lstrncmpi( str1, str2, len )
  207. * compares two strings, str1 and str2, up
  208. * to length 'len' ignoring case. If they
  209. * are equal, we will return 0. Otherwise not 0.
  210. */
  211. static
  212. INT lstrncmpi( PTCHAR sz1, PTCHAR sz2 )
  213. {
  214. TCHAR ch1, ch2;
  215. while( *sz1 )
  216. {
  217. ch1= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz1++ );
  218. ch2= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz2++ );
  219. if( ch1 != ch2 )
  220. return 1;
  221. }
  222. return 0; // they are equal
  223. }
  224. static int NPRegister (HANDLE hInstance);
  225. /* GetFileName
  226. *
  227. * Parse off filename from command line and put
  228. * into lpFileName
  229. */
  230. LPTSTR GetFileName( LPTSTR lpFileName, LPTSTR lpCmdLine )
  231. {
  232. LPTSTR lpTemp = lpFileName;
  233. HANDLE hFindFile;
  234. WIN32_FIND_DATA info;
  235. /*
  236. ** Allow for filenames surrounded by double and single quotes
  237. ** like in longfilenames.
  238. */
  239. if( *lpCmdLine == TEXT('\"') || *lpCmdLine == TEXT('\'') )
  240. {
  241. TCHAR chMatch = *lpCmdLine;
  242. DWORD dwSize=0;
  243. // Copy over filename
  244. while( *(++lpCmdLine) && (*lpCmdLine != chMatch) && (dwSize<MAX_PATH) )
  245. {
  246. *lpTemp++ = *lpCmdLine;
  247. dwSize++;
  248. }
  249. // NULL terminate the filename (no embedded quotes allowed in filenames)
  250. *lpTemp = TEXT('\0');
  251. }
  252. else
  253. {
  254. lstrcpyn(lpFileName, lpCmdLine,MAX_PATH);
  255. }
  256. /*
  257. ** Check to see if the unaltered filename exists. If it does then don't
  258. ** append a default extension.
  259. */
  260. hFindFile= FindFirstFile( lpFileName, &info );
  261. if( hFindFile != INVALID_HANDLE_VALUE )
  262. {
  263. FindClose( hFindFile );
  264. }
  265. else
  266. {
  267. /*
  268. ** Add default extension and try again
  269. */
  270. AddExt( lpFileName );
  271. hFindFile= FindFirstFile( lpFileName, &info );
  272. if( hFindFile != INVALID_HANDLE_VALUE )
  273. {
  274. FindClose( hFindFile );
  275. }
  276. }
  277. // return the pointer to the end of the filename.
  278. return lpCmdLine;
  279. }
  280. /* SizeStrings - Get the total size of the resource strings */
  281. /* returns size in 'chars' or zero if failure */
  282. /* we do this in case the international people really change */
  283. /* the size of resources. */
  284. /* Read all the strings into a buffer to size them. Since we */
  285. /* don't know the maximum size of string resource, we may have */
  286. /* to change the size of the read buffer. This is done with */
  287. /* a simple doubling algorithm. */
  288. INT SizeStrings(HANDLE hInstance)
  289. {
  290. INT iElementSize=280; // current max size of string
  291. INT total; // total size of resources
  292. PTCHAR Buf; // buffer to try putting resources into
  293. INT ids; // identifier number for resource
  294. INT len; // length of one resource
  295. while( 1 ) // keep looping til all strings can be read
  296. {
  297. if( !(Buf= LocalAlloc( LPTR, ByteCountOf(iElementSize) ) ) )
  298. return 0; // failure
  299. for( ids=0, total=0; ids < CSTRINGS; ids++ )
  300. {
  301. len= LoadString( hInstance, (UINT) (UINT_PTR) (*rgsz[ids]), Buf, iElementSize );
  302. if( len >= iElementSize-1 )
  303. {
  304. #if DBG
  305. ODS(TEXT("notepad: resource string too long!\n"));
  306. #endif
  307. break;
  308. }
  309. total += len+1; // account for null terminator
  310. }
  311. LocalFree( Buf );
  312. if( ids >= CSTRINGS )
  313. break;
  314. iElementSize= iElementSize*2;
  315. }
  316. return( total );
  317. }
  318. /* InitStrings - Get all text strings from resource file */
  319. BOOL InitStrings (HANDLE hInstance)
  320. {
  321. TCHAR* pch;
  322. INT cchRemaining;
  323. INT ids, cch;
  324. // allocate memory and lock it down forever. we have pointers into it.
  325. // the localrealloc() function will not work well for freeing
  326. // unused memory because it may (and did) move memory.
  327. cchRemaining= SizeStrings( hInstance );
  328. if( !cchRemaining )
  329. return( FALSE ); // fail because we are out of memory
  330. pch= LocalAlloc( LPTR, ByteCountOf(cchRemaining) );
  331. if( !pch )
  332. return( FALSE );
  333. cchRemaining= (INT)LocalSize( pch ) / sizeof(TCHAR);
  334. if( cchRemaining == 0 ) // can't alloc memory - failure
  335. return( FALSE );
  336. for( ids = 0; ids < CSTRINGS; ids++ )
  337. {
  338. cch= 1 + LoadString( hInstance, (UINT) (UINT_PTR) (*rgsz[ids]), pch, cchRemaining );
  339. *rgsz[ids]= pch;
  340. pch += cch;
  341. if( cch > cchRemaining ) // should never happen
  342. {
  343. MessageBox( NULL, TEXT("Out of RC string space!!"),
  344. TEXT("DEV Error!"), MB_OK);
  345. return( FALSE );
  346. }
  347. cchRemaining -= cch;
  348. }
  349. /* Get header and footer strings */
  350. lstrcpyn( chPageText[HEADER], szHeader, PT_LEN );
  351. lstrcpyn( chPageText[FOOTER], szFooter, PT_LEN );
  352. chMerge= *szMerge;
  353. return (TRUE);
  354. }
  355. /*
  356. * SkipBlanks( pszText )
  357. * skips blanks or tabs to either next character or EOL
  358. * returns pointer to same.
  359. */
  360. PTCHAR SkipBlanks( PTCHAR pszText )
  361. {
  362. while( *pszText == TEXT(' ') || *pszText == TEXT('\t') )
  363. pszText++;
  364. return pszText;
  365. }
  366. // if /.SETUP option exists in the command line process it.
  367. BOOL ProcessSetupOption (LPTSTR lpszCmdLine)
  368. {
  369. INT iSta= 0;
  370. /* Search for /.SETUP in the command line */
  371. if( !lstrncmpi( TEXT("/.SETUP"), lpszCmdLine ) )
  372. {
  373. fRunBySetup = TRUE;
  374. /* Save system menu handle for INITMENUPOPUP message */
  375. hSysMenuSetup =GetSystemMenu(hwndNP, FALSE);
  376. /* Allow exit on ^C, ^D and ^Z */
  377. /* Note that LoadAccelerators must be called before */
  378. /* TranslateAccelerator is called, true here */
  379. hAccel = LoadAccelerators(hInstanceNP, TEXT("SlipUpAcc"));
  380. lpszCmdLine += 7;
  381. }
  382. else
  383. return FALSE;
  384. /* Don't offer a minimize button */
  385. SetWindowLong( hwndNP, GWL_STYLE,
  386. WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
  387. WS_THICKFRAME | WS_MAXIMIZEBOX |
  388. WS_VSCROLL | WS_HSCROLL);
  389. /* skip blanks again to get to filename */
  390. lpszCmdLine= SkipBlanks( lpszCmdLine );
  391. if (*lpszCmdLine)
  392. {
  393. /* Get the filename. */
  394. GetFileName(szFileName, lpszCmdLine);
  395. fp= CreateFile( szFileName, // filename
  396. GENERIC_READ, // access mode
  397. FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode
  398. NULL, // security descriptor
  399. OPEN_EXISTING, // how to create
  400. FILE_ATTRIBUTE_NORMAL, //file attributes
  401. NULL); // hnd of file attrs
  402. if( fp == INVALID_HANDLE_VALUE )
  403. {
  404. DWORD dwErr;
  405. // Check GetLastError to see why we failed
  406. dwErr = GetLastError ();
  407. switch (dwErr)
  408. {
  409. case ERROR_ACCESS_DENIED:
  410. iSta= AlertBox( hwndNP, szNN, szACCESSDENY, szFileName,
  411. MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION);
  412. break;
  413. case ERROR_FILE_NOT_FOUND:
  414. iSta= AlertBox(hwndNP, szNN, szFNF, szFileName,
  415. MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  416. if( iSta == IDYES )
  417. {
  418. fp= CreateFile( szFileName, // filename
  419. GENERIC_READ|GENERIC_WRITE, // access
  420. FILE_SHARE_READ|FILE_SHARE_WRITE, // share
  421. NULL, // security descrp
  422. OPEN_ALWAYS, // how to create
  423. FILE_ATTRIBUTE_NORMAL, // file attributes
  424. NULL); // hnd of file attrs
  425. }
  426. break;
  427. case ERROR_INVALID_NAME:
  428. iSta= AlertBox( hwndNP, szNN, szNVF, szFileName,
  429. MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION);
  430. break;
  431. default:
  432. iSta= AlertBox(hwndNP, szNN, szDiskError, szFileName,
  433. MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION);
  434. break;
  435. }
  436. }
  437. if (fp == INVALID_HANDLE_VALUE)
  438. return (FALSE);
  439. LoadFile(szFileName, fInitFileType ); // load setup file
  440. }
  441. if( iSta == IDCANCEL )
  442. return( IDCANCEL );
  443. else
  444. return( IDYES );
  445. }
  446. /*
  447. * ProcessShellOptions(lpszCmdLine)
  448. *
  449. * If the command line has any options specified by the shell
  450. * process them.
  451. * Currently /P <filename> - prints the given file
  452. * /PT "filename" "printer name" "Driver dll" "port"
  453. */
  454. BOOL ProcessShellOptions (LPTSTR lpszCmdLine, int cmdShow)
  455. {
  456. BOOL bDefPrinter = TRUE;
  457. LPTSTR lpszAfterFileName;
  458. // Is it PrintTo ?
  459. if( lstrncmpi( TEXT("/PT"), lpszCmdLine ) == 0)
  460. {
  461. lpszCmdLine= SkipBlanks( lpszCmdLine+3 );
  462. bDefPrinter = FALSE;
  463. }
  464. // Or is it Print ?
  465. else if ( lstrncmpi( TEXT("/P"), lpszCmdLine ) == 0)
  466. {
  467. lpszCmdLine= SkipBlanks( lpszCmdLine+2 );
  468. }
  469. else
  470. return FALSE;
  471. if (!*lpszCmdLine)
  472. return FALSE;
  473. /* Added as per Bug #10923 declaring that the window should show up
  474. * and then the printing should begin. 29 July 1991 Clark Cyr
  475. */
  476. ShowWindow(hwndNP, cmdShow);
  477. /* Get the filename; have the pointer to the end of the filename */
  478. lpszAfterFileName= GetFileName (szFileName, lpszCmdLine) + 1;
  479. if (!bDefPrinter)
  480. {
  481. UINT index;
  482. /* extract the printer name from the command line. */
  483. if (!*lpszAfterFileName)
  484. return FALSE;
  485. lpszAfterFileName = SkipBlanks( lpszAfterFileName );
  486. /* (since we are passing multiple arguments here, the filename, */
  487. /* the printername have to be in quotes. */
  488. if( *lpszAfterFileName != TEXT('\"') )
  489. return FALSE;
  490. // Copy over printername
  491. lpszAfterFileName++; // skip over quote
  492. index= 0;
  493. while( *(lpszAfterFileName) &&
  494. *lpszAfterFileName != TEXT('\"' ) &&
  495. (index+1 < sizeof(szPrinterName)/sizeof(szPrinterName[0]) ) )
  496. {
  497. szPrinterName[index++] = *lpszAfterFileName++;
  498. }
  499. // NULL terminate the printername (no embedded quotes allowed in printernames)
  500. szPrinterName[index] = TEXT('\0');
  501. }
  502. fp= CreateFile( szFileName, // filename
  503. GENERIC_READ, // access mode
  504. FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode
  505. NULL, // security descriptor
  506. OPEN_EXISTING, // how to create
  507. FILE_ATTRIBUTE_NORMAL, // file attributes
  508. NULL); // hnd of file attrs to copy
  509. if( fp == INVALID_HANDLE_VALUE )
  510. {
  511. TCHAR* pszMsg;
  512. // select reasonable error message based on GetLastError
  513. switch( GetLastError() )
  514. {
  515. case ERROR_ACCESS_DENIED:
  516. case ERROR_NETWORK_ACCESS_DENIED:
  517. pszMsg= szACCESSDENY;
  518. break;
  519. case ERROR_FILE_NOT_FOUND:
  520. pszMsg= szFNF;
  521. break;
  522. case ERROR_INVALID_NAME:
  523. pszMsg= szNVF;
  524. break;
  525. default:
  526. pszMsg= szDiskError;
  527. break;
  528. }
  529. AlertBox(hwndNP, szNN, pszMsg, szFileName,
  530. MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION);
  531. return (TRUE);
  532. }
  533. /* load the file into the edit control */
  534. LoadFile( szFileName, fInitFileType ); // get print file
  535. /* print the file */
  536. if (bDefPrinter)
  537. {
  538. PrintIt( DoNotUseDialog );
  539. }
  540. else
  541. {
  542. PrintIt( NoDialogNonDefault );
  543. }
  544. return (TRUE);
  545. }
  546. /* CreateFilter
  547. *
  548. * Creates filters for GetOpenFileName.
  549. *
  550. */
  551. VOID CreateFilter(PTCHAR szFilterSpec )
  552. {
  553. PTCHAR pszFilterSpec;
  554. /* construct default filter string in the required format for
  555. * the new FileOpen and FileSaveAs dialogs
  556. * if you add to this, make sure CCHFILTERMAX is large enough.
  557. */
  558. // .txt first for compatibility
  559. pszFilterSpec= szFilterSpec;
  560. lstrcpy( pszFilterSpec, szAnsiText );
  561. pszFilterSpec += lstrlen( pszFilterSpec ) + 1;
  562. lstrcpy( pszFilterSpec, TEXT("*.txt"));
  563. pszFilterSpec += lstrlen( pszFilterSpec ) + 1;
  564. // and last, all files
  565. lstrcpy( pszFilterSpec, szAllFiles );
  566. pszFilterSpec += lstrlen( pszFilterSpec ) + 1;
  567. lstrcpy(pszFilterSpec, TEXT("*.*") );
  568. pszFilterSpec += lstrlen( pszFilterSpec ) + 1;
  569. *pszFilterSpec = TEXT('\0');
  570. }
  571. // EnumProc
  572. //
  573. // Callback function for EnumFonts
  574. //
  575. // Purpose: sets lfCharSet in passed logfont to a valid lfCharSet
  576. // and terminates enumeration.
  577. //
  578. int CALLBACK EnumProc(
  579. LOGFONT* pLf,
  580. TEXTMETRIC* pTm,
  581. DWORD dwType,
  582. LPARAM lpData )
  583. {
  584. ((LOGFONT*) lpData)-> lfCharSet= pLf->lfCharSet;
  585. return( 0 ); // stop enumeration
  586. }
  587. /* One time initialization */
  588. INT FAR NPInit (HANDLE hInstance, HANDLE hPrevInstance,
  589. LPTSTR lpCmdLine, INT cmdShow)
  590. {
  591. HDC hDisplayDC; /* screen DC */
  592. RECT rcT1; /* for sizing edit window */
  593. RECT rcStatus; /* rect for the status window */
  594. INT iSta;
  595. WINDOWPLACEMENT wp; /* structure to place window at the correct position */
  596. INT iParts[2];
  597. HMENU hMenu; // handle to the menu.
  598. /* determine the message number to be used for communication with
  599. * Find dialog
  600. */
  601. if (!(wFRMsg = RegisterWindowMessage ((LPTSTR)FINDMSGSTRING)))
  602. return FALSE;
  603. if (!(wHlpMsg = RegisterWindowMessage ((LPTSTR)HELPMSGSTRING)))
  604. return FALSE;
  605. /* open a global DC to the display */
  606. hDisplayDC= GetDC(NULL);
  607. if( !hDisplayDC )
  608. return FALSE;
  609. /* Go load strings */
  610. if (!InitStrings (hInstance))
  611. return FALSE;
  612. InitLocale(); // localize strings etc.
  613. /* Load the arrow and hourglass cursors. */
  614. hStdCursor= LoadCursor( NULL,
  615. (LPTSTR) (INT_PTR) (GetSystemMetrics(SM_PENWINDOWS) ? IDC_ARROW : IDC_IBEAM ));
  616. hWaitCursor= LoadCursor( NULL, IDC_WAIT );
  617. /* Load accelerators. */
  618. hAccel= LoadAccelerators(hInstance, TEXT("MainAcc"));
  619. if( !hWaitCursor || !hAccel )
  620. return FALSE;
  621. if( !hPrevInstance )
  622. {
  623. if( !NPRegister( hInstance ) )
  624. return (FALSE);
  625. }
  626. hInstanceNP= hInstance;
  627. /* init. fields of PRINTDLG struct.. */
  628. /* Inserted here since command line print statements are valid. */
  629. g_PageSetupDlg.lStructSize = sizeof(PAGESETUPDLG);
  630. g_PageSetupDlg.hDevMode = NULL;
  631. g_PageSetupDlg.hDevNames = NULL;
  632. g_PageSetupDlg.hInstance = hInstance;
  633. SetPageSetupDefaults();
  634. //
  635. // Pick up information saved in registry
  636. //
  637. GetGlobals();
  638. hwndNP= CreateWindow( szNotepad,
  639. TEXT(""),
  640. WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
  641. WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | 0,
  642. g_WPleft, // x
  643. g_WPtop, // y
  644. g_WPDX, // width
  645. g_WPDY, // height
  646. (HWND)NULL, // parent or owner
  647. (HMENU)NULL, // menu or child window
  648. hInstance, // application instance
  649. NULL); // window creation data
  650. g_PageSetupDlg.hwndOwner = hwndNP;
  651. if( !hwndNP )
  652. return FALSE;
  653. // On multimon machines, the previous position stored of notepad may
  654. // not be in the display area. call SetWindowPlacement to fix this.
  655. // If the information specified in WINDOWPLACEMENT would result in a window
  656. // that is completely off the screen, the system will automatically adjust
  657. // the coordinates so that the window is visible, taking into account
  658. // changes in screen resolution and multiple monitor configuration.
  659. // g_WPDX and g_WPDY are CW_USEDEFAULT when notepad is started for the
  660. // first time on the user machine.
  661. if (g_WPDX != CW_USEDEFAULT && g_WPDY != CW_USEDEFAULT)
  662. {
  663. memset(&wp, 0, sizeof(wp));
  664. wp.length = sizeof(wp);
  665. wp.rcNormalPosition.left = g_WPleft;
  666. wp.rcNormalPosition.right = g_WPleft + g_WPDX;
  667. wp.rcNormalPosition.top = g_WPtop;
  668. wp.rcNormalPosition.bottom = g_WPtop + g_WPDY;
  669. // don't check the return value; if this call fails for any reason,
  670. // just go on with the position of the notepad in the above CreateWindow() call.
  671. SetWindowPlacement(hwndNP, &wp);
  672. }
  673. /* File Drag Drop support added 03/26/91 - prototype only. w-dougw */
  674. /* All processing of drag/drop files is done the under WM_DROPFILES */
  675. /* message. */
  676. DragAcceptFiles( hwndNP,TRUE ); /* Process dragged and dropped files. */
  677. GetClientRect( hwndNP, (LPRECT) &rcT1 );
  678. if (!(hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
  679. TEXT("Edit"), TEXT(""),
  680. (fWrap) ? ES_STD : (ES_STD | WS_HSCROLL),
  681. 0, 0, rcT1.right, rcT1.bottom - 100,
  682. hwndNP, (HMENU)ID_EDIT, hInstance, (LPVOID)NULL)))
  683. return FALSE;
  684. // create a status window.
  685. hwndStatus = CreateStatusWindow ((fStatus?WS_VISIBLE:0)|WS_BORDER|WS_CHILD|WS_CLIPSIBLINGS, TEXT(""), hwndNP, ID_STATUS_WINDOW);
  686. if ( !hwndStatus )
  687. return FALSE;
  688. UpdateStatusBar( TRUE );
  689. GetClientRect( hwndStatus, (LPRECT) &rcStatus );
  690. // determine height of statusbar window and save...
  691. dyStatus = rcStatus.bottom - rcStatus.top;
  692. iParts[0] = 3 * (rcStatus.right-rcStatus.left)/4;
  693. iParts[1] = -1;
  694. // Divide the status window into two parts
  695. SendMessage(hwndStatus, SB_SETPARTS, (WPARAM) sizeof(iParts)/sizeof(INT), (LPARAM) &iParts[0]);
  696. // handle word wrap now if set in registry
  697. SendMessage( hwndEdit, EM_FMTLINES, fWrap, 0L ); // tell MLE
  698. // if wordwrap, disable the statusbar
  699. if (fWrap)
  700. {
  701. hMenu = GetMenu(hwndNP);
  702. EnableMenuItem(GetSubMenu(hMenu, 3), M_STATUSBAR, MF_GRAYED);
  703. }
  704. FontStruct.lfHeight= -MulDiv(iPointSize,
  705. GetDeviceCaps(hDisplayDC,LOGPIXELSY),
  706. 720);
  707. hFont= CreateFontIndirect( &FontStruct );
  708. //
  709. // Make sure the font mapper gives us the same face name.
  710. //
  711. // If the locale changes, a font that use to work just fine gets mapped to
  712. // a different facename because of support for the charset does not exist
  713. // in the new locale.
  714. //
  715. // In this case, we will find one lfCharSet that does exist for this FaceName
  716. // and use that for the CreateFontIndirect.
  717. //
  718. {
  719. HFONT hPrev;
  720. TCHAR szTextFace[LF_FACESIZE];
  721. // Get the facename that was really used.
  722. hPrev= SelectObject( hDisplayDC, hFont );
  723. GetTextFace( hDisplayDC, sizeof(szTextFace)/sizeof(TCHAR), (LPTSTR) &szTextFace[0] );
  724. SelectObject( hDisplayDC, hPrev );
  725. // if not the same, get a lfCharSet that does exist in this font
  726. if( lstrcmpi( szTextFace, FontStruct.lfFaceName ) != 0 )
  727. {
  728. EnumFonts( hDisplayDC, FontStruct.lfFaceName, (FONTENUMPROC) EnumProc, (LPARAM) &FontStruct );
  729. DeleteObject( hFont );
  730. hFont= CreateFontIndirect( &FontStruct );
  731. }
  732. }
  733. SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(FALSE, 0));
  734. ReleaseDC( NULL, hDisplayDC );
  735. /* we will not verify that a unicode font is available until
  736. ** we actually need it. Perhaps we'll get lucky, and only deal
  737. ** with ascii files.
  738. */
  739. szSearch[0] = (TCHAR) 0;
  740. /*
  741. * Win32s does not allow local memory handles to be passed to Win3.1.
  742. * So, hEdit is used for transferring text to and from the edit control.
  743. * Before reading text into it, it must be reallocated to a proper size.
  744. */
  745. hEdit = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, ByteCountOf(1));
  746. /* limit text for safety's sake. */
  747. PostMessage( hwndEdit, EM_LIMITTEXT, (WPARAM)CCHNPMAX, 0L );
  748. /* get visible window on desktop; helps taskman find it */
  749. SetTitle( szUntitled );
  750. ShowWindow( hwndNP, cmdShow );
  751. SetCursor( hStdCursor );
  752. /* Scan for initial /A or /W to override automatic file typing for
  753. * 'notepad /p file' or 'notepad file'
  754. */
  755. lpCmdLine= SkipBlanks( lpCmdLine );
  756. fInitFileType= FT_UNKNOWN;
  757. if( !lstrncmpi( TEXT("/A"), lpCmdLine ) )
  758. fInitFileType= FT_ANSI;
  759. else if( !lstrncmpi( TEXT("/W"), lpCmdLine ) )
  760. fInitFileType= FT_UNICODE;
  761. if( fInitFileType != FT_UNKNOWN ) // skip over option
  762. lpCmdLine= SkipBlanks( lpCmdLine+2 );
  763. /* check for /.SETUP option first.
  764. if /.SETUP absent, check for SHELL options /P
  765. Whenever a SHELL option is processed, post a WM_CLOSE msg.
  766. */
  767. if( iSta= ProcessSetupOption( lpCmdLine ) )
  768. {
  769. if( iSta == IDCANCEL )
  770. {
  771. return( FALSE );
  772. }
  773. }
  774. else if( ProcessShellOptions( lpCmdLine, cmdShow ) )
  775. {
  776. PostMessage( hwndNP, WM_CLOSE, 0, 0L );
  777. return TRUE;
  778. }
  779. else if( *lpCmdLine )
  780. {
  781. /* Get the filename. */
  782. GetFileName( szFileName, lpCmdLine );
  783. fp= CreateFile( szFileName, // filename
  784. GENERIC_READ, // access mode
  785. FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode
  786. NULL, // security descriptor
  787. OPEN_EXISTING, // how to create
  788. FILE_ATTRIBUTE_NORMAL, // file attributes
  789. NULL); // hnd of file attrs to copy
  790. if( fp == INVALID_HANDLE_VALUE )
  791. {
  792. // If the file can't be opened, maybe the user wants a new
  793. // one created.
  794. if( GetLastError() == ERROR_FILE_NOT_FOUND )
  795. {
  796. INT iSta;
  797. iSta= AlertBox( hwndNP, szNN, szFNF, szFileName,
  798. MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  799. if( iSta == IDCANCEL )
  800. {
  801. return( FALSE );
  802. }
  803. if( iSta == IDYES )
  804. {
  805. fp= CreateFile( szFileName, // filename
  806. GENERIC_READ|GENERIC_WRITE, // access
  807. FILE_SHARE_READ|FILE_SHARE_WRITE, // share
  808. NULL, // security descrp
  809. OPEN_ALWAYS, // how to create
  810. FILE_ATTRIBUTE_NORMAL, // file attributes
  811. NULL); // hnd of file attrs
  812. }
  813. }
  814. else
  815. {
  816. AlertUser_FileFail(szFileName);
  817. // now open an untitled file instead of the file that we failed
  818. // to read.
  819. SetTitle( szUntitled );
  820. lstrcpy(szFileName, szUntitled);
  821. }
  822. }
  823. if( fp != INVALID_HANDLE_VALUE )
  824. {
  825. LoadFile( szFileName, fInitFileType ); // get file specified on command line
  826. }
  827. }
  828. CreateFilter( szOpenFilterSpec );
  829. CreateFilter( szSaveFilterSpec );
  830. /* init. some fields of the OPENFILENAME struct used by fileopen and
  831. * filesaveas, but NEVER changed.
  832. */
  833. memset( &OFN, 0, sizeof(OFN) );
  834. OFN.lStructSize = sizeof(OPENFILENAME);
  835. OFN.hwndOwner = hwndNP;
  836. OFN.nMaxFile = MAX_PATH;
  837. OFN.hInstance = hInstance;
  838. /* init.fields of the FINDREPLACE struct used by FindText() */
  839. memset( &FR, 0, sizeof(FR) );
  840. FR.lStructSize = sizeof(FINDREPLACE); /* Don't hard code it */
  841. FR.hwndOwner = hwndNP;
  842. /* Force a scroll to current selection (which could be at eof if
  843. we loaded a log file.) */
  844. {
  845. DWORD dwStart, dwEnd;
  846. SendMessage( hwndEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd );
  847. SendMessage( hwndEdit, EM_SETSEL, dwStart, dwEnd );
  848. SendMessage( hwndEdit, EM_SCROLLCARET, 0, 0 );
  849. }
  850. if (PRIMARYLANGID(LOWORD((DWORD) (INT_PTR) GetKeyboardLayout(0))) == LANG_JAPANESE) {
  851. /*
  852. * If current HKL is Japanese, handle the result string at once.
  853. */
  854. SendMessage(hwndEdit, EM_SETIMESTATUS,
  855. EMSIS_COMPOSITIONSTRING, EIMES_GETCOMPSTRATONCE);
  856. }
  857. return TRUE;
  858. }
  859. /* ** Notepad class registration proc */
  860. BOOL NPRegister (HANDLE hInstance)
  861. {
  862. WNDCLASSEX NPClass;
  863. PWNDCLASSEX pNPClass = &NPClass;
  864. /* Bug 12191: If Pen Windows is running, make the background cursor an
  865. * arrow instead of the edit control ibeam. This way the user will know
  866. * where they can use the pen for writing vs. what will be considered a
  867. * mouse action. 18 October 1991 Clark Cyr
  868. */
  869. pNPClass->cbSize = sizeof(NPClass);
  870. pNPClass->hCursor = LoadCursor(NULL, GetSystemMetrics(SM_PENWINDOWS)
  871. ? IDC_ARROW : IDC_IBEAM);
  872. pNPClass->hIcon = LoadIcon(hInstance,
  873. (LPTSTR) MAKEINTRESOURCE(ID_ICON));
  874. pNPClass->hIconSm = LoadImage(hInstance,
  875. MAKEINTRESOURCE(ID_ICON),
  876. IMAGE_ICON, 16, 16,
  877. LR_DEFAULTCOLOR);
  878. pNPClass->lpszMenuName = (LPTSTR) MAKEINTRESOURCE(ID_MENUBAR);
  879. pNPClass->hInstance = hInstance;
  880. pNPClass->lpszClassName = szNotepad;
  881. pNPClass->lpfnWndProc = NPWndProc;
  882. pNPClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  883. pNPClass->style = 0; // was CS_BYTEALIGNCLIENT (obsolete)
  884. pNPClass->cbClsExtra = 0;
  885. pNPClass->cbWndExtra = 0;
  886. if (!RegisterClassEx((LPWNDCLASSEX)pNPClass))
  887. return (FALSE);
  888. return (TRUE);
  889. }
  890. /* Get Locale info from the Registry, and initialize global vars */
  891. void FAR InitLocale (void)
  892. {
  893. }