Source code of Windows XP (NT5)
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.

1079 lines
35 KiB

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