/* * SxSpad application * * Copyright (C) 1984-2000 Microsoft Inc. * * SPInit - One time init for sxspad. * Routines are in a separate segment. */ #include "precomp.h" TCHAR chPageText[2][PT_LEN]; /* Strings to hold PageSetup items. */ TCHAR chPageTextTemp[2][PT_LEN]; TCHAR szPrinterName[256]; /* String to hold printername for PrintTo verb */ static SP_FILETYPE fInitFileType; /* file type override */ static INT fSavePageSettings=0; /* if true, save page settings in registry */ static INT fSaveWindowPositions=0; /* true if we are to save window position */ static INT g_WPtop,g_WPleft,g_WPDX,g_WPDY; /* initial window positions */ /* routines to handle saving and restoring information in the registry. * * SaveGlobals - saves interesting globals to the registry * * GetGlobals - gets interesting globals from the registry * * Interesting Globals: * * FontStruct information include calculated pointsize * Codepage * * If we want to save PageSetup info, save the margins in some * units (cm for example) and convert on input and output. */ /* name of section to save into -- never internationalize */ #define OURKEYNAME TEXT("Software\\Microsoft\\Sxspad") // RegWriteInt - write an integer to the registry VOID RegWriteInt( HKEY hKey, PTCHAR pszKey, INT iValue ) { RegSetValueEx( hKey, pszKey, 0, REG_DWORD, (BYTE*)&iValue, sizeof(INT) ); } // RegWriteString - write a string to the registry VOID RegWriteString( HKEY hKey, PTCHAR pszKey, PTCHAR pszValue ) { INT len; // length of string with null in bytes len= (lstrlen( pszValue )+1) * sizeof(TCHAR); RegSetValueEx( hKey, pszKey, 0, REG_SZ, (BYTE*)pszValue, len ); } // RegGetInt - Get integer from registry DWORD RegGetInt( HKEY hKey, PTCHAR pszKey, DWORD dwDefault ) { DWORD dwResult= !ERROR_SUCCESS; LONG lStatus= ERROR_SUCCESS; DWORD dwSize= sizeof(DWORD); DWORD dwType= 0; if( hKey ) { lStatus= RegQueryValueEx( hKey, pszKey, NULL, &dwType, (BYTE*) &dwResult, &dwSize ); } if( lStatus != ERROR_SUCCESS || dwType != REG_DWORD ) { dwResult= dwDefault; } return( dwResult ); } // RegGetString - get string from registry VOID RegGetString( HKEY hKey, PTCHAR pszKey, PTCHAR pszDefault, PTCHAR pszResult, INT iCharLen ) { LONG lStatus= !ERROR_SUCCESS; DWORD dwSize; // size of buffer DWORD dwType; dwSize= iCharLen * sizeof(TCHAR); if( hKey ) { lStatus= RegQueryValueEx( hKey, pszKey, NULL, &dwType, (BYTE*) pszResult, &dwSize ); } if( lStatus != ERROR_SUCCESS || dwType != REG_SZ ) { CopyMemory( pszResult, pszDefault, iCharLen*sizeof(TCHAR) ); } } // lfHeight is calculated using PointSize // lfWidth set by font mapper VOID SaveGlobals(VOID) { HKEY hKey; // key to our registry root LONG lStatus; // status from RegCreateKey WINDOWPLACEMENT wp; lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey ); if( lStatus != ERROR_SUCCESS ) { return; // just return quietly } RegWriteInt( hKey, TEXT("lfEscapement"), FontStruct.lfEscapement); RegWriteInt( hKey, TEXT("lfOrientation"), FontStruct.lfOrientation); RegWriteInt( hKey, TEXT("lfWeight"), FontStruct.lfWeight); RegWriteInt( hKey, TEXT("lfItalic"), FontStruct.lfItalic); RegWriteInt( hKey, TEXT("lfUnderline"), FontStruct.lfUnderline); RegWriteInt( hKey, TEXT("lfStrikeOut"), FontStruct.lfStrikeOut); RegWriteInt( hKey, TEXT("lfCharSet"), FontStruct.lfCharSet); RegWriteInt( hKey, TEXT("lfOutPrecision"), FontStruct.lfOutPrecision); RegWriteInt( hKey, TEXT("lfClipPrecision"), FontStruct.lfClipPrecision); RegWriteInt( hKey, TEXT("lfQuality"), FontStruct.lfQuality); RegWriteInt( hKey, TEXT("lfPitchAndFamily"), FontStruct.lfPitchAndFamily); RegWriteInt( hKey, TEXT("iPointSize"), iPointSize); RegWriteInt( hKey, TEXT("fWrap"), fWrap); RegWriteInt( hKey, TEXT("fSavePageSettings"),fSavePageSettings ); RegWriteInt( hKey, TEXT("fSaveWindowPositions"),fSaveWindowPositions ); RegWriteString( hKey, TEXT("lfFaceName"), FontStruct.lfFaceName); if( fSavePageSettings ) { RegWriteString( hKey, TEXT("szHeader"), chPageText[HEADER] ); RegWriteString( hKey, TEXT("szTrailer"), chPageText[FOOTER] ); RegWriteInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top ); RegWriteInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom ); RegWriteInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left ); RegWriteInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right ); } wp.length= sizeof(wp); if( GetWindowPlacement( hwndSP, &wp ) ) { RegWriteInt( hKey, TEXT("iWindowPosX"), wp.rcNormalPosition.left); RegWriteInt( hKey, TEXT("iWindowPosY"), wp.rcNormalPosition.top); RegWriteInt( hKey, TEXT("iWindowPosDX"), wp.rcNormalPosition.right - wp.rcNormalPosition.left); RegWriteInt( hKey, TEXT("iWindowPosDY"), wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); } RegCloseKey( hKey ); } // GetGlobals // // Pick up font information etc that may be saved in the registry. // // We are called pretty early in setup and don't have things like hwndSP valid yet. // VOID GetGlobals( VOID ) { LOGFONT lfDef; // default logical font HFONT hFont; // standard font to use LONG lStatus; // status from RegCreateKey HKEY hKey; // key into registry // // quickly get a reasonable set of default parameters // for the default font if we need it. // hFont= GetStockObject( SYSTEM_FIXED_FONT ); GetObject( hFont, sizeof(LOGFONT), &lfDef ); lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey ); if( lStatus != ERROR_SUCCESS ) { hKey= NULL; // later calls to RegGet... will return defaults } FontStruct.lfWidth= 0; FontStruct.lfEscapement= (LONG)RegGetInt( hKey, TEXT("lfEscapement"), lfDef.lfEscapement); FontStruct.lfOrientation= (LONG)RegGetInt( hKey, TEXT("lfOrientation"), lfDef.lfOrientation); FontStruct.lfWeight= (LONG)RegGetInt( hKey, TEXT("lfWeight"), lfDef.lfWeight); FontStruct.lfItalic= (BYTE)RegGetInt( hKey, TEXT("lfItalic"), lfDef.lfItalic); FontStruct.lfUnderline= (BYTE)RegGetInt( hKey, TEXT("lfUnderline"), lfDef.lfUnderline); FontStruct.lfStrikeOut= (BYTE)RegGetInt( hKey, TEXT("lfStrikeOut"), lfDef.lfStrikeOut); // // We have to preserve lfCharSet because some fonts (symbol, marlett) don't handle // 0 (ANSI_CHARSET) or 1 (DEFAULT_CHARSET), and the font mapper will map to a // different facename. Later we will see if the CreateFont has the same FaceName // and get a more appropriate lfCharSet if need be. // FontStruct.lfCharSet= (BYTE)RegGetInt( hKey, TEXT("lfCharSet"), lfDef.lfCharSet); FontStruct.lfOutPrecision= (BYTE)RegGetInt( hKey, TEXT("lfOutPrecision"), lfDef.lfOutPrecision); FontStruct.lfClipPrecision= (BYTE)RegGetInt( hKey, TEXT("lfClipPrecision"), lfDef.lfClipPrecision); FontStruct.lfQuality= (BYTE)RegGetInt( hKey, TEXT("lfQuality"), lfDef.lfQuality); FontStruct.lfPitchAndFamily= (BYTE)RegGetInt( hKey, TEXT("lfPitchAndFamily"), lfDef.lfPitchAndFamily); // // If there is no FaceName in the registry, use the default "Lucida Console" // This will show off most of the glyphs except in the FE locales. // For FE, we can't font link fonts with the glyphs because they would have to have // the exact width as lucida console, or the console/csrss will AV (July 9, 1999) // RegGetString( hKey, TEXT("lfFaceName"), TEXT("Lucida Console"), FontStruct.lfFaceName, LF_FACESIZE); iPointSize= RegGetInt( hKey, TEXT("iPointSize"), 100); fWrap= RegGetInt( hKey, TEXT("fWrap"), 0); fSavePageSettings= RegGetInt( hKey, TEXT("fSavePageSettings"), 0 ); fSaveWindowPositions= RegGetInt( hKey, TEXT("fSaveWindowPositions"), 0 ); // if page settings not in registry, we will use defaults RegGetString( hKey, TEXT("szHeader"), chPageText[HEADER], chPageText[HEADER], PT_LEN ); RegGetString( hKey, TEXT("szTrailer"), chPageText[FOOTER], chPageText[FOOTER], PT_LEN ); g_PageSetupDlg.rtMargin.top= (LONG)RegGetInt( hKey, TEXT("iMarginTop"), g_PageSetupDlg.rtMargin.top ); g_PageSetupDlg.rtMargin.bottom= (LONG)RegGetInt( hKey, TEXT("iMarginBottom"), g_PageSetupDlg.rtMargin.bottom ); g_PageSetupDlg.rtMargin.left= (LONG)RegGetInt( hKey, TEXT("iMarginLeft"), g_PageSetupDlg.rtMargin.left ); g_PageSetupDlg.rtMargin.right= (LONG)RegGetInt( hKey, TEXT("iMarginRight"), g_PageSetupDlg.rtMargin.right ); // if window positions in registry use them, otherwise us defaults g_WPtop= RegGetInt( hKey, TEXT("iWindowPosY"), CW_USEDEFAULT ); g_WPleft= RegGetInt( hKey, TEXT("iWindowPosX"), CW_USEDEFAULT ); g_WPDX= RegGetInt( hKey, TEXT("iWindowPosDX"), CW_USEDEFAULT ); g_WPDY= RegGetInt( hKey, TEXT("iWindowPosDY"), CW_USEDEFAULT ); if( hKey ) { RegCloseKey( hKey ); } } /* * lstrncmpi( str1, str2, len ) * compares two strings, str1 and str2, up * to length 'len' ignoring case. If they * are equal, we will return 0. Otherwise not 0. */ static INT lstrncmpi( PTCHAR sz1, PTCHAR sz2 ) { TCHAR ch1, ch2; while( *sz1 ) { ch1= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz1++ ); ch2= (TCHAR) (INT_PTR) CharUpper( (LPTSTR) (INT_PTR) *sz2++ ); if( ch1 != ch2 ) return 1; } return 0; // they are equal } static int SPRegister (HANDLE hInstance); /* GetFileName * * Parse off filename from command line and put * into lpFileName */ LPTSTR GetFileName( LPTSTR lpFileName, LPTSTR lpCmdLine ) { LPTSTR lpTemp = lpFileName; HANDLE hFindFile; WIN32_FIND_DATA info; /* ** Allow for filenames surrounded by double and single quotes ** like in longfilenames. */ if( *lpCmdLine == TEXT('\"') || *lpCmdLine == TEXT('\'') ) { TCHAR chMatch = *lpCmdLine; DWORD dwSize=0; // Copy over filename while( *(++lpCmdLine) && (*lpCmdLine != chMatch) && (dwSize= iElementSize-1 ) { #if DBG ODS(TEXT("sxspad: resource string too long!\n")); #endif break; } total += len+1; // account for null terminator } LocalFree( Buf ); if( ids >= CSTRINGS ) break; iElementSize= iElementSize*2; } return( total ); } /* InitStrings - Get all text strings from resource file */ BOOL InitStrings (HANDLE hInstance) { TCHAR* pch; INT cchRemaining; INT ids, cch; // allocate memory and lock it down forever. we have pointers into it. // the localrealloc() function will not work well for freeing // unused memory because it may (and did) move memory. cchRemaining= SizeStrings( hInstance ); if( !cchRemaining ) return( FALSE ); // fail because we are out of memory pch= LocalAlloc( LPTR, ByteCountOf(cchRemaining) ); if( !pch ) return( FALSE ); cchRemaining= (INT)LocalSize( pch ) / sizeof(TCHAR); if( cchRemaining == 0 ) // can't alloc memory - failure return( FALSE ); for( ids = 0; ids < CSTRINGS; ids++ ) { cch= 1 + LoadString( hInstance, (UINT) (UINT_PTR) (*rgsz[ids]), pch, cchRemaining ); *rgsz[ids]= pch; pch += cch; if( cch > cchRemaining ) // should never happen { MessageBox( NULL, TEXT("Out of RC string space!!"), TEXT("DEV Error!"), MB_OK); return( FALSE ); } cchRemaining -= cch; } /* Get header and footer strings */ lstrcpyn( chPageText[HEADER], szHeader, PT_LEN ); lstrcpyn( chPageText[FOOTER], szFooter, PT_LEN ); chMerge= *szMerge; return (TRUE); } /* * SkipBlanks( pszText ) * skips blanks or tabs to either next character or EOL * returns pointer to same. */ PTCHAR SkipBlanks( PTCHAR pszText ) { while( *pszText == TEXT(' ') || *pszText == TEXT('\t') ) pszText++; return pszText; } // if /.SETUP option exists in the command line process it. BOOL ProcessSetupOption (LPTSTR lpszCmdLine) { INT iSta= 0; /* Search for /.SETUP in the command line */ if( !lstrncmpi( TEXT("/.SETUP"), lpszCmdLine ) ) { fRunBySetup = TRUE; /* Save system menu handle for INITMENUPOPUP message */ hSysMenuSetup =GetSystemMenu(hwndSP, FALSE); /* Allow exit on ^C, ^D and ^Z */ /* Note that LoadAccelerators must be called before */ /* TranslateAccelerator is called, true here */ hAccel = LoadAccelerators(hInstanceSP, TEXT("SlipUpAcc")); lpszCmdLine += 7; } else return FALSE; /* Don't offer a minimize button */ SetWindowLong( hwndSP, GWL_STYLE, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_VSCROLL | WS_HSCROLL); /* skip blanks again to get to filename */ lpszCmdLine= SkipBlanks( lpszCmdLine ); if (*lpszCmdLine) { /* Get the filename. */ GetFileName(szFileName, lpszCmdLine); fp= CreateFile( szFileName, // filename GENERIC_READ, // access mode FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode NULL, // security descriptor OPEN_EXISTING, // how to create FILE_ATTRIBUTE_NORMAL, //file attributes NULL); // hnd of file attrs if( fp == INVALID_HANDLE_VALUE ) { DWORD dwErr; // Check GetLastError to see why we failed dwErr = GetLastError (); switch (dwErr) { case ERROR_ACCESS_DENIED: iSta= AlertBox( hwndSP, szNN, szACCESSDENY, szFileName, MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); break; case ERROR_FILE_NOT_FOUND: iSta= AlertBox(hwndSP, szNN, szFNF, szFileName, MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION); if( iSta == IDYES ) { fp= CreateFile( szFileName, // filename GENERIC_READ|GENERIC_WRITE, // access FILE_SHARE_READ|FILE_SHARE_WRITE, // share NULL, // security descrp OPEN_ALWAYS, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL); // hnd of file attrs } break; case ERROR_INVALID_NAME: iSta= AlertBox( hwndSP, szNN, szNVF, szFileName, MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); break; default: iSta= AlertBox(hwndSP, szNN, szDiskError, szFileName, MB_APPLMODAL | MB_OKCANCEL | MB_ICONEXCLAMATION); break; } } if (fp == INVALID_HANDLE_VALUE) return (FALSE); LoadFile(szFileName, fInitFileType ); // load setup file } if( iSta == IDCANCEL ) return( IDCANCEL ); else return( IDYES ); } /* * ProcessShellOptions(lpszCmdLine) * * If the command line has any options specified by the shell * process them. * Currently /P - prints the given file * /PT "filename" "printer name" "Driver dll" "port" */ BOOL ProcessShellOptions (LPTSTR lpszCmdLine, int cmdShow) { BOOL bDefPrinter = TRUE; LPTSTR lpszAfterFileName; INT i = 0; // Is it PrintTo ? if( lstrncmpi( TEXT("/PT"), lpszCmdLine ) == 0) { lpszCmdLine= SkipBlanks( lpszCmdLine+3 ); bDefPrinter = FALSE; } // Or is it Print ? else if ( lstrncmpi( TEXT("/P"), lpszCmdLine ) == 0) { lpszCmdLine= SkipBlanks( lpszCmdLine+2 ); } else return FALSE; if (!*lpszCmdLine) return FALSE; /* Added as per Bug #10923 declaring that the window should show up * and then the printing should begin. 29 July 1991 Clark Cyr */ ShowWindow(hwndSP, cmdShow); /* Get the filename; have the pointer to the end of the filename */ lpszAfterFileName= GetFileName (szFileName, lpszCmdLine) + 1; if (!bDefPrinter) { /* extract the printer name from the command line. */ if (!*lpszAfterFileName) return FALSE; lpszAfterFileName = SkipBlanks( lpszAfterFileName ); /* (since we are passing multiple arguments here, the filename, */ /* the printername have to be in quotes. */ if( *lpszAfterFileName != TEXT('\"') ) return FALSE; // Copy over printername while( *(++lpszAfterFileName) && *lpszAfterFileName != TEXT('\"') ) { szPrinterName[i++] = *lpszAfterFileName; } // NULL terminate the printername (no embedded quotes allowed in printernames) szPrinterName[i] = TEXT('\0'); } fp= CreateFile( szFileName, // filename GENERIC_READ, // access mode FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode NULL, // security descriptor OPEN_EXISTING, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL); // hnd of file attrs to copy if( fp == INVALID_HANDLE_VALUE ) { TCHAR* pszMsg; // select reasonable error message based on GetLastError switch( GetLastError() ) { case ERROR_ACCESS_DENIED: case ERROR_NETWORK_ACCESS_DENIED: pszMsg= szACCESSDENY; break; case ERROR_FILE_NOT_FOUND: pszMsg= szFNF; break; case ERROR_INVALID_NAME: pszMsg= szNVF; break; default: pszMsg= szDiskError; break; } AlertBox(hwndSP, szNN, pszMsg, szFileName, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION); return (TRUE); } /* load the file into the edit control */ LoadFile( szFileName, fInitFileType ); // get print file /* print the file */ if (bDefPrinter) { PrintIt( DoNotUseDialog ); } else { PrintIt( NoDialogNonDefault ); } return (TRUE); } /* CreateFilter * * Creates filters for GetOpenFileName. * */ VOID CreateFilter(PTCHAR szFilterSpec ) { PTCHAR pszFilterSpec; /* construct default filter string in the required format for * the new FileOpen and FileSaveAs dialogs * if you add to this, make sure CCHFILTERMAX is large enough. */ // .Manifest first for compatibility pszFilterSpec= szFilterSpec; lstrcpy( pszFilterSpec, szAnsiText ); pszFilterSpec += lstrlen( pszFilterSpec ) + 1; lstrcpy( pszFilterSpec, TEXT("*.Manifest")); pszFilterSpec += lstrlen( pszFilterSpec ) + 1; // and last, all files lstrcpy( pszFilterSpec, szAllFiles ); pszFilterSpec += lstrlen( pszFilterSpec ) + 1; lstrcpy(pszFilterSpec, TEXT("*.*") ); pszFilterSpec += lstrlen( pszFilterSpec ) + 1; *pszFilterSpec = TEXT('\0'); } // EnumProc // // Callback function for EnumFonts // // Purpose: sets lfCharSet in passed logfont to a valid lfCharSet // and terminates enumeration. // int CALLBACK EnumProc( LOGFONT* pLf, TEXTMETRIC* pTm, DWORD dwType, LPARAM lpData ) { ((LOGFONT*) lpData)-> lfCharSet= pLf->lfCharSet; return( 0 ); // stop enumeration } /* One time initialization */ INT FAR SPInit (HANDLE hInstance, HANDLE hPrevInstance, LPTSTR lpCmdLine, INT cmdShow) { HDC hDisplayDC; /* screen DC */ RECT rcT1; /* for sizing edit window */ INT iSta; WINDOWPLACEMENT wp; /* structure to place window at the correct position */ /* determine the message number to be used for communication with * Find dialog */ if (!(wFRMsg = RegisterWindowMessage ((LPTSTR)FINDMSGSTRING))) return FALSE; if (!(wHlpMsg = RegisterWindowMessage ((LPTSTR)HELPMSGSTRING))) return FALSE; /* open a global DC to the display */ hDisplayDC= GetDC(NULL); if( !hDisplayDC ) return FALSE; /* Go load strings */ if (!InitStrings (hInstance)) return FALSE; InitLocale(); // localize strings etc. /* Load the arrow and hourglass cursors. */ hStdCursor= LoadCursor( NULL, (LPTSTR) (INT_PTR) (GetSystemMetrics(SM_PENWINDOWS) ? IDC_ARROW : IDC_IBEAM )); hWaitCursor= LoadCursor( NULL, IDC_WAIT ); /* Load accelerators. */ hAccel= LoadAccelerators(hInstance, TEXT("MainAcc")); if( !hWaitCursor || !hAccel ) return FALSE; if( !hPrevInstance ) { if( !SPRegister( hInstance ) ) return (FALSE); } hInstanceSP= hInstance; /* init. fields of PRINTDLG struct.. */ /* Inserted here since command line print statements are valid. */ g_PageSetupDlg.lStructSize = sizeof(PAGESETUPDLG); g_PageSetupDlg.hDevMode = NULL; g_PageSetupDlg.hDevNames = NULL; g_PageSetupDlg.hInstance = hInstance; SetPageSetupDefaults(); // // Pick up information saved in registry // GetGlobals(); hwndSP= CreateWindow( szSxspad, TEXT(""), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | 0, g_WPleft, // x g_WPtop, // y g_WPDX, // width g_WPDY, // height (HWND)NULL, // parent or owner (HMENU)NULL, // menu or child window hInstance, // application instance NULL); // window creation data g_PageSetupDlg.hwndOwner = hwndSP; if( !hwndSP ) return FALSE; // On multimon machines, the previous position stored of sxspad may // not be in the display area. call SetWindowPlacement to fix this. // If the information specified in WINDOWPLACEMENT would result in a window // that is completely off the screen, the system will automatically adjust // the coordinates so that the window is visible, taking into account // changes in screen resolution and multiple monitor configuration. // g_WPDX and g_WPDY are CW_USEDEFAULT when sxspad is started for the // first time on the user machine. if (g_WPDX != CW_USEDEFAULT && g_WPDY != CW_USEDEFAULT) { memset(&wp, 0, sizeof(wp)); wp.length = sizeof(wp); wp.rcNormalPosition.left = g_WPleft; wp.rcNormalPosition.right = g_WPleft + g_WPDX; wp.rcNormalPosition.top = g_WPtop; wp.rcNormalPosition.bottom = g_WPtop + g_WPDY; // don't check the return value; if this call fails for any reason, // just go on with the position of the sxspad in the above CreateWindow() call. SetWindowPlacement(hwndSP, &wp); } /* File Drag Drop support added 03/26/91 - prototype only. w-dougw */ /* All processing of drag/drop files is done the under WM_DROPFILES */ /* message. */ DragAcceptFiles( hwndSP,TRUE ); /* Process dragged and dropped files. */ GetClientRect( hwndSP, (LPRECT) &rcT1 ); if (!(hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""), (fWrap) ? ES_STD : (ES_STD | WS_HSCROLL), 0, 0, rcT1.right, rcT1.bottom, hwndSP, (HMENU)ID_EDIT, hInstance, (LPVOID)NULL))) return FALSE; // handle word wrap now if set in registry SendMessage( hwndEdit, EM_FMTLINES, fWrap, 0L ); // tell MLE FontStruct.lfHeight= -MulDiv(iPointSize, GetDeviceCaps(hDisplayDC,LOGPIXELSY), 720); hFont= CreateFontIndirect( &FontStruct ); // // Make sure the font mapper gives us the same face name. // // If the locale changes, a font that use to work just fine gets mapped to // a different facename because of support for the charset does not exist // in the new locale. // // In this case, we will find one lfCharSet that does exist for this FaceName // and use that for the CreateFontIndirect. // { HFONT hPrev; TCHAR szTextFace[LF_FACESIZE]; // Get the facename that was really used. hPrev= SelectObject( hDisplayDC, hFont ); GetTextFace( hDisplayDC, sizeof(szTextFace)/sizeof(TCHAR), (LPTSTR) &szTextFace ); SelectObject( hDisplayDC, hPrev ); // if not the same, get a lfCharSet that does exist in this font if( lstrcmpi( szTextFace, FontStruct.lfFaceName ) != 0 ) { EnumFonts( hDisplayDC, FontStruct.lfFaceName, (FONTENUMPROC) EnumProc, (LPARAM) &FontStruct ); DeleteObject( hFont ); hFont= CreateFontIndirect( &FontStruct ); } } SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(FALSE, 0)); ReleaseDC( NULL, hDisplayDC ); /* we will not verify that a unicode font is available until ** we actually need it. Perhaps we'll get lucky, and only deal ** with ascii files. */ szSearch[0] = (TCHAR) 0; /* * Win32s does not allow local memory handles to be passed to Win3.1. * So, hEdit is used for transferring text to and from the edit control. * Before reading text into it, it must be reallocated to a proper size. */ hEdit = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, ByteCountOf(1)); /* limit text for safety's sake. */ PostMessage( hwndEdit, EM_LIMITTEXT, (WPARAM)CCHSPMAX, 0L ); /* get visible window on desktop; helps taskman find it */ SetTitle( szUntitled ); ShowWindow( hwndSP, cmdShow ); SetCursor( hStdCursor ); /* Scan for initial /A or /W to override automatic file typing for * 'sxspad /p file' or 'sxspad file' */ lpCmdLine= SkipBlanks( lpCmdLine ); fInitFileType= FT_UNKNOWN; if( !lstrncmpi( TEXT("/A"), lpCmdLine ) ) fInitFileType= FT_ANSI; else if( !lstrncmpi( TEXT("/W"), lpCmdLine ) ) fInitFileType= FT_UNICODE; if( fInitFileType != FT_UNKNOWN ) // skip over option lpCmdLine= SkipBlanks( lpCmdLine+2 ); /* check for /.SETUP option first. if /.SETUP absent, check for SHELL options /P Whenever a SHELL option is processed, post a WM_CLOSE msg. */ if( iSta= ProcessSetupOption( lpCmdLine ) ) { if( iSta == IDCANCEL ) { return( FALSE ); } } else if( ProcessShellOptions( lpCmdLine, cmdShow ) ) { PostMessage( hwndSP, WM_CLOSE, 0, 0L ); return TRUE; } else if( *lpCmdLine ) { /* Get the filename. */ GetFileName( szFileName, lpCmdLine ); fp= CreateFile( szFileName, // filename GENERIC_READ, // access mode FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode NULL, // security descriptor OPEN_EXISTING, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL); // hnd of file attrs to copy if( fp == INVALID_HANDLE_VALUE ) { // If the file can't be opened, maybe the user wants a new // one created. if( GetLastError() == ERROR_FILE_NOT_FOUND ) { INT iSta; iSta= AlertBox( hwndSP, szNN, szFNF, szFileName, MB_APPLMODAL | MB_YESNOCANCEL | MB_ICONEXCLAMATION); if( iSta == IDCANCEL ) { return( FALSE ); } if( iSta == IDYES ) { fp= CreateFile( szFileName, // filename GENERIC_READ|GENERIC_WRITE, // access FILE_SHARE_READ|FILE_SHARE_WRITE, // share NULL, // security descrp OPEN_ALWAYS, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL); // hnd of file attrs } } else { AlertUser_FileFail(szFileName); // now open an untitled file instead of the file that we failed // to read. SetTitle( szUntitled ); lstrcpy(szFileName, szUntitled); } } if( fp != INVALID_HANDLE_VALUE ) { LoadFile( szFileName, fInitFileType ); // get file specified on command line } } CreateFilter( szOpenFilterSpec ); CreateFilter( szSaveFilterSpec ); /* init. some fields of the OPENFILENAME struct used by fileopen and * filesaveas, but NEVER changed. */ memset( &OFN, 0, sizeof(OFN) ); OFN.lStructSize = sizeof(OPENFILENAME); OFN.hwndOwner = hwndSP; OFN.nMaxFile = MAX_PATH; OFN.hInstance = hInstance; /* init.fields of the FINDREPLACE struct used by FindText() */ memset( &FR, 0, sizeof(FR) ); FR.lStructSize = sizeof(FINDREPLACE); /* Don't hard code it */ FR.hwndOwner = hwndSP; /* Force a scroll to current selection (which could be at eof if we loaded a log file.) */ { DWORD dwStart, dwEnd; SendMessage( hwndEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd ); SendMessage( hwndEdit, EM_SETSEL, dwStart, dwEnd ); SendMessage( hwndEdit, EM_SCROLLCARET, 0, 0 ); } if (PRIMARYLANGID(LOWORD((DWORD) (INT_PTR) GetKeyboardLayout(0))) == LANG_JAPANESE) { /* * If current HKL is Japanese, handle the result string at once. */ SendMessage(hwndEdit, EM_SETIMESTATUS, EMSIS_COMPOSITIONSTRING, EIMES_GETCOMPSTRATONCE); } return TRUE; } /* ** Sxspad class registration proc */ BOOL SPRegister (HANDLE hInstance) { WNDCLASSEX SPClass; PWNDCLASSEX pSPClass = &SPClass; /* Bug 12191: If Pen Windows is running, make the background cursor an * arrow instead of the edit control ibeam. This way the user will know * where they can use the pen for writing vs. what will be considered a * mouse action. 18 October 1991 Clark Cyr */ pSPClass->cbSize = sizeof(SPClass); pSPClass->hCursor = LoadCursor(NULL, GetSystemMetrics(SM_PENWINDOWS) ? IDC_ARROW : IDC_IBEAM); pSPClass->hIcon = LoadIcon(hInstance, (LPTSTR) MAKEINTRESOURCE(ID_ICON)); pSPClass->hIconSm = LoadImage(hInstance, MAKEINTRESOURCE(ID_ICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); pSPClass->lpszMenuName = (LPTSTR) MAKEINTRESOURCE(ID_MENUBAR); pSPClass->hInstance = hInstance; pSPClass->lpszClassName = szSxspad; pSPClass->lpfnWndProc = SPWndProc; pSPClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1); pSPClass->style = 0; // was CS_BYTEALIGNCLIENT (obsolete) pSPClass->cbClsExtra = 0; pSPClass->cbWndExtra = 0; if (!RegisterClassEx((LPWNDCLASSEX)pSPClass)) return (FALSE); return (TRUE); } /* Get Locale info from the Registry, and initialize global vars */ void FAR InitLocale (void) { }