Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

734 lines
22 KiB

#define NOMINMAX
#define WIN31
#include "precomp.h"
/************************************************************************/
/* */
/* Windows Cardfile - Written by Mark Cliggett */
/* (c) Copyright Microsoft Corp. 1985, 1994 - All Rights Reserved */
/* */
/************************************************************************/
typedef VOID (FAR PASCAL *PENAPPPROC)(WORD, BOOL);
int NEAR PASCAL LogHimetricToPels(HDC hDC,BOOL bHoriz, int mmHimetric);
extern TCHAR szCardfileSect[];
int fEnglish = 1; // default system of measurement is English, 0 for metric
int fNeedToUpdateObject = FALSE;
DWORD CdHt = 0;
DWORD CdWd = 0;
BOOL fOLE;
HDC hDisplayDC;
// from picture.c
extern BOOL fDropOperationFailure ;
/* use this buffer for reading in text from a card or as a scratch buffer */
TCHAR szText[CARDTEXTSIZE];
/* Let Cardfile save font values to the registry.*/
/* name of section to save into -- never internationalize */
#define OURKEYNAME TEXT("Software\\Microsoft\\Cardfile")
// 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;
DWORD dwSize= sizeof(DWORD);
DWORD dwType;
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) );
}
}
BOOL fUnicodeFont=FALSE; // true if unicode font found
VOID VerifyUnicodeFont()
{
TCHAR szBuf[200],szOutbuf[200+LF_FACESIZE]; // message buffers
// give user a warning if we can't create the unicode font or
// the font gets mapped to a non-unicode font.
// actually, we just want to know if it is a unicode font, but
// there is no easy way to know this.
if( !fUnicodeFont )
{
LoadString( hIndexInstance, E_NOUNICODEFONT, szBuf, CharSizeOf(szBuf) );
wsprintf( szOutbuf, szBuf, UNICODE_FIXED_FONT_NAME );
MessageBox( NULL, szOutbuf, szWarning, MB_OK|MB_ICONHAND|MB_SYSTEMMODAL);
}
}
// Save current global font data to the registry.
VOID SaveGlobals(VOID) {
HKEY hKey; // key to our registry root
LONG lStatus; // status from RegCreateKey
lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey );
if( lStatus != ERROR_SUCCESS ) {
return; // too bad
}
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);
RegWriteString( hKey, TEXT("lfFaceName"), FontStruct.lfFaceName);
}
// Read global font data from the registry. If the registry doesn't have the data,
// fall back to the unicode font. If that isn't installed, use a regular fixed
//font.
VOID GetGlobals (VOID) {
LOGFONT lfDef; // default logical font, hopefully UNICODE
HFONT hFont; // standard font to use
LONG lStatus; // Status from RegCreateKey
HKEY hKey; // key into registry
TCHAR szFaceName[LF_FACESIZE+1];
/* initialize the Unicode font */
GetObject( GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lfDef );
lfDef.lfHeight= -( INITPOINTSIZE * GetDeviceCaps(hDisplayDC,LOGPIXELSY) ) / 720;
lfDef.lfCharSet= ANSI_CHARSET;
lfDef.lfWidth= 0; // use native width blah blah blah
lstrcpy( lfDef.lfFaceName, UNICODE_FIXED_FONT_NAME );
hFont= CreateFontIndirect( &lfDef );
// get name of actual font that will be used on screen
if( hFont )
{
HFONT hPrevFont; // previously selected font from screen dc
hPrevFont= (HFONT)SelectObject( hDisplayDC, hFont );
GetTextFace( hDisplayDC, CharSizeOf(szFaceName), szFaceName );
SelectObject( hDisplayDC, hPrevFont );
}
// give user a warning if we can't create or mapped font isn't unicode
// actually, we just want to know if it is a unicode font, but
// there is no easy way to know this.
fUnicodeFont= TRUE;
if (hFont == NULL || lstrcmp(szFaceName, lfDef.lfFaceName) )
{
fUnicodeFont= FALSE;
if( hFont ) // delete font if wrong one
{
DeleteObject( hFont );
}
// Use the system font if we can't get the unicode font
// The system font better have a iPointSize of INITPOINTSIZE
hFont = (HFONT) GetStockObject (SYSTEM_FIXED_FONT);
GetObject( hFont, sizeof(LOGFONT), &lfDef );
}
// Now read the registry keys, backed up by lfDef defaults
lStatus= RegCreateKey( HKEY_CURRENT_USER, OURKEYNAME, &hKey );
if( lStatus != ERROR_SUCCESS )
{
hKey= NULL; // later calls to RegGet... will return defaults
}
FontStruct.lfWidth= lfDef.lfWidth;
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);
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);
RegGetString( hKey, TEXT("lfFaceName"), lfDef.lfFaceName, FontStruct.lfFaceName, LF_FACESIZE);
iPointSize= RegGetInt( hKey, TEXT("iPointSize"), INITPOINTSIZE);
FontStruct.lfHeight= -( iPointSize * GetDeviceCaps(hDisplayDC,LOGPIXELSY) ) / 720;
hFont = CreateFontIndirect (&FontStruct);
SetGlobalFont (hFont, iPointSize);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpAnsiCmdLine,
int cmdShow)
{
MSG msg;
HDC hDC;
VOID (FAR PASCAL *lpfnRegisterPenApp)(WORD, BOOL) = NULL;
LPTSTR lpCmdLine = GetCommandLine ();
TCHAR szBuf[12];
#if DBG
GdiSetBatchLimit( 1 ); // disable batching
#endif
hDisplayDC= CreateDC( TEXT("DISPLAY"), NULL, NULL, NULL );
#if !defined( WIN32 )
fOLE = GetWinFlags() & WF_PMODE; /* Are we in real mode today? */
#else
fOLE = TRUE; // No real mode on NT
#endif
Hourglass(TRUE);
hIndexInstance = hInstance;
fEnglish= GetProfileInt( TEXT("intl"), TEXT("iMeasure"), 1 );
//GetUnicodeFont();
GetGlobals();
if (!hPrevInstance)
{
if (!IndexInit())
{
Hourglass(FALSE);
goto InitError;
}
}
else
GetOldData(hPrevInstance);
/* Create a seperate hbrCard and hbrBorder for each instance */
if(!(hbrCard = CreateSolidBrush(GetSysColor(COLOR_WINDOW))) ||
!(hbrBorder = CreateSolidBrush(GetSysColor(COLOR_WINDOWFRAME))))
goto InitError;
if (InitInstance(hInstance, SkipProgramName (lpCmdLine), cmdShow))
{
Hourglass(FALSE);
VerifyUnicodeFont();
if (lpfnRegisterPenApp = (PENAPPPROC)GetProcAddress((HINSTANCE) GetSystemMetrics (SM_PENWINDOWS),
"RegisterPenApp"))
(*lpfnRegisterPenApp)(1, TRUE);
while(TRUE)
{
if (IsWindow(hEditWnd) && !PeekMessage(&msg, hEditWnd, WM_KEYFIRST, WM_KEYLAST, FALSE))
{
if (fNeedToUpdateObject)
{
hDC = GetDC(hEditWnd);
SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
CardPaint(hDC);
ReleaseDC(hEditWnd, hDC);
fNeedToUpdateObject = FALSE;
}
}
if (!ProcessMessage(hIndexWnd, hAccel))
break;
}
if (lpfnRegisterPenApp)
(*lpfnRegisterPenApp)(1, FALSE);
Hourglass(TRUE);
}
else
{
InitError:
MessageBox(NULL, NotEnoughMem, NULL, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
}
/* Free any global memory used by Printer Setup. */
if(PD.hDevMode)
GlobalFree(PD.hDevMode);
if(PD.hDevNames)
GlobalFree(PD.hDevNames);
wsprintf(szBuf, TEXT("%d"), fValidate);
WriteProfileString (szCardfileSect, szValidateFileWrite, szBuf);
Hourglass(FALSE);
return(0);
}
/*
* Set card count on the right top corner
*/
void SetNumOfCards(
void)
{
TCHAR szString[20];
TCHAR szWndText[50];
if (cCards == 1)
LoadString(hIndexInstance, IONECARD, szWndText, 10);
else
{
LoadString(hIndexInstance, ICARDS, szString, 10);
wsprintf(szWndText, TEXT("%d %s"), cCards, szString);
}
SetWindowText(hRightWnd, szWndText);
}
/* Why is it here? Because the DWORD mul/div routines are in _TEXT */
void FixBounds(
LPRECT lprc)
{
HDC hDC;
DWORD xDiff;
DWORD yDiff;
if (!CdHt)
{
CdHt = (CARDLINES * CharFixHeight);
CdWd = (LINELENGTH * CharFixWidth);
}
/* First map from HIMETRIC back to screen coordinates */
hDC = GetDC(NULL);
lprc->right = LogHimetricToPels(hDC, TRUE, lprc->right);
lprc->bottom = LogHimetricToPels(hDC, FALSE, -lprc->bottom);
ReleaseDC(NULL, hDC);
/* Preserve the Aspect Ratio of the picture */
xDiff = (DWORD) (lprc->right - lprc->left + 1);
yDiff = (DWORD) (lprc->bottom - lprc->top + 1);
/* Don't use *= here because of integer arithmetic... */
if ((xDiff > CdWd) || (yDiff > CdHt))
{
if ((xDiff * CdHt) > (yDiff * CdWd))
{
yDiff = ((yDiff * CdWd) / xDiff);
xDiff = CdWd;
}
else
{
xDiff = ((xDiff * CdHt) / yDiff);
yDiff = CdHt;
}
}
SetRect(lprc, 0, 0, (int)xDiff - 1, (int)yDiff - 1);
}
/* ProcessMessage() - Spin in a message dispatch loop.
*/
BOOL ProcessMessage(
HWND hwndFrame,
HANDLE hAccTable)
{
BOOL fReturn;
MSG msg;
if (fReturn = GetMessage((LPMSG)&msg, NULL, 0, 0))
{
if (!hDlgFind || !IsDialogMessage(hDlgFind, &msg))
{
if (!TranslateAccelerator(hIndexWnd, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return fReturn;
}
INT Scale(
INT coord,
INT s1,
INT s2)
{
return ((INT) (((LONG)coord * (LONG)s1) / (LONG)s2));
}
BOOL IndexOkError(
int strid)
{
TCHAR buf[300];
LPTSTR lpbuf;
if (strid == EINSMEMORY)
lpbuf = NotEnoughMem;
else if(!LoadString (hIndexInstance, strid, buf, 300))
lpbuf = NotEnoughMem;
else if (strid == E_FLOPPY_WITH_SOURCE_REMOVED)
{
WORD wLen = lstrlen(buf);
if(!LoadString(hIndexInstance, strid + 1, buf + wLen, 300 - wLen))
lpbuf = NotEnoughMem;
else
lpbuf = buf;
}
else
lpbuf = buf;
MessageBox(hIndexWnd, lpbuf, szWarning, MB_OK | MB_ICONEXCLAMATION);
return FALSE; /* caller can return this to indicate failure */
}
/* Scan lpSrc for merge spec.
* If found, insert string lpMerge at that point.
* Then append rest of lpSrc.
* NOTE! Merge spec guaranteed to be two chars.
* returns TRUE if it does a merge, false otherwise.
*/
BOOL MergeStrings(
LPTSTR lpSrc,
LPTSTR lpMerge,
LPTSTR lpDst)
{
LPTSTR lpMatch;
int nChars;
/* Find merge spec */
if (!(lpMatch = _tcsstr (lpSrc, szMerge)))
return FALSE; /* none found */
/* copy from src to dest, upto the merge spec char */
nChars = lpMatch - lpSrc;
_tcsncpy(lpDst, lpSrc, nChars);
lpDst += nChars;
/* If merge spec found, insert string to be merged. */
if (lpMerge)
{
lstrcpy(lpDst, lpMerge);
lpDst += lstrlen(lpMerge);
}
/* copy rest of the source after the merge spec */
lstrcpy(lpDst, lpMatch+2);
return TRUE;
}
void MakeBlankCard(
void)
{
CurCardHead.line[0] = (TCHAR) 0;
SavedIndexLine[0] = (TCHAR) 0;
szText[0] = (TCHAR) 0;
CurCard.lpObject = NULL;
SetEditText (TEXT(""));
CurCardHead.flags = FNEW;
}
void SetCaption(
void)
{
TCHAR buf[100];
BuildCaption(buf, CharSizeOf(buf));
SetWindowText(hIndexWnd, buf);
}
/*
* build a string to display in the caption bar
*
* note: the caption is used in the printing options. check there
* before you change this.
*
*/
void BuildCaption( TCHAR *pBuf, WORD wLen )
{
LPTSTR pFile;
pFile = (*CurIFile) ? FileFromPath(CurIFile) : szUntitled;
wsprintf(pBuf, TEXT("%s - "), szCardfile);
_tcsncpy (pBuf + lstrlen(pBuf), pFile, wLen - 1 - lstrlen(pBuf));
pBuf[wLen - 1] = TEXT('\0');
}
/* Get country info from win.ini file, and initialize global vars
that determine format of date/time string. */
void FAR InitLocale (void)
{
LCID lcid;
int i, id;
TCHAR szBuf[3];
extern TIME Time;
extern DATE Date;
lcid = GetUserDefaultLCID ();
/* Get short date format */
GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, (LPWSTR) Date.szFormat, MAX_FORMAT);
/* Get time related info */
GetLocaleInfoW (lcid, LOCALE_ITIME, (LPWSTR) szBuf, 3);
Time.iTime = MyAtoi (szBuf);
GetLocaleInfoW (lcid, LOCALE_ITLZERO, (LPWSTR) szBuf, 3);
Time.iTLZero = MyAtoi (szBuf);
GetLocaleInfoW (lcid, LOCALE_S1159, (LPWSTR) Time.sz1159, 6);
GetLocaleInfoW (lcid, LOCALE_S2359, (LPWSTR) Time.sz2359, 6);
GetLocaleInfoW (lcid, LOCALE_STIME, (LPWSTR) Time.szSep, 2);
/* Get system of measurement */
fEnglish= GetProfileInt( TEXT("intl"), TEXT("iMeasure"), 1 );
/* Get decimal character */
szBuf[0] = szDec[0];
GetLocaleInfoW (lcid, LOCALE_SDECIMAL, (LPWSTR) szDec, 2);
/* Scan for . and replace with intl decimal */
for (id = 2; id < 6; id++)
{
for (i = 0; i < lstrlen (chPageText[id]); i++)
if (chPageText[id][i] == szBuf[0])
chPageText[id][i] = szDec[0];
}
}
/*
* check for printer availablilty
*/
void IndexWinIniChange(
void)
{
HANDLE hMenu;
TCHAR ch;
TCHAR msgbuf[120];
int fEnabled = MF_GRAYED;
static bszDecRead=FALSE;
/* Set decimal to scan for */
if (bszDecRead)
ch=szDec[0]; /* If we already changed it. */
else
ch=TEXT('.'); /* First time. */
bszDecRead = TRUE;
hMenu = GetMenu(hIndexWnd);
/* Bug 8017: If we're setup for the default printer, throw away whatever
* we've got as the settings may have changed. We'll grab the new default
* immediately before we print. Clark Cyr 5 December 1991
*/
if (PD.hDevNames)
{
BOOL bIsDefault;
LPDEVNAMES lpDevNames = (LPDEVNAMES)GlobalLock(PD.hDevNames);
bIsDefault = lpDevNames->wDefault & DN_DEFAULTPRN;
GlobalUnlock(PD.hDevNames);
if (bIsDefault)
FreePrintHandles(); /* bPrinterSetupDone is set to NULL */
}
if (bPrinterSetupDone ||
GetProfileString(szWindows, szDevice, DefaultNullStr, msgbuf, 120))
{
fCanPrint = TRUE;
}
else
fCanPrint = FALSE;
InitLocale ();
}
BOOL BuildAndDisplayMsg(
int idError,
TCHAR szString[])
{
TCHAR szError[300];
TCHAR szMsg[600];
/* load specified error msg */
LoadString(hIndexInstance, idError, szError, CharSizeOf(szError));
/* Merge in the given string into the error msg */
MergeStrings(szError, szString, szMsg);
MessageBox(hIndexWnd, szMsg, szNote, MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
OLESTATUS OleStatusCallBack = OLE_OK;
int CallBack(
LPOLECLIENT lpclient,
OLE_NOTIFICATION flags,
LPOLEOBJECT lpObject)
{
OLE_RELEASE_METHOD method;
WORD fOleErrMsg;
RECT rc;
switch(flags)
{
case OLE_CLOSED:
/* After an InsertObject, the server was closed without updating the
* embedded object */
if (fInsertComplete == FALSE)
PicDelete(&CurCard);
fInsertComplete = TRUE;
break;
case OLE_SAVED:
case OLE_CHANGED:
/* in case we did an InsertObject, the object is updated now. */
fInsertComplete = TRUE;
/*
* The OLE libraries make sure that we only receive
* update messages according to the Auto/Manual flags.
*/
CurCardHead.flags |= FDIRTY;
InvalidateRect(hEditWnd, NULL, TRUE);
/* recalc size */
if (CurCard.lpObject)
{
if (OleQueryBounds(CurCard.lpObject, &rc) != OLE_OK)
{
Hourglass(FALSE);
ErrorMessage(E_BOUNDS_QUERY_FAILED);
return( 0 ); //bugbug Is this right?
}
FixBounds(&rc);
SetRect(&(CurCard.rcObject),
CurCard.rcObject.left, CurCard.rcObject.top,
CurCard.rcObject.left + (rc.right - rc.left),
CurCard.rcObject.top + (rc.bottom - rc.top));
}
break;
case OLE_RELEASE:
--cOleWait;
method = OleQueryReleaseMethod(lpObject);
if (method == OLE_LOADFROMSTREAM)
{
oleloadstat = OleQueryReleaseError(lpObject);
break;
}
else if (method == OLE_SETDATA ||
method == OLE_UPDATE)
{
OleStatusCallBack = OleQueryReleaseError(lpObject);
break;
}
switch (fOleErrMsg = OleError(OleQueryReleaseError(lpObject)))
{
case FOLEERROR_NOTGIVEN:
case FOLEERROR_GIVEN:
switch (OleQueryReleaseMethod(lpObject))
{
case OLE_CREATEFROMFILE:
PicDelete(&CurCard);
InvalidateRect(hEditWnd, NULL, TRUE);
if (fOleErrMsg == FOLEERROR_NOTGIVEN)
ErrorMessage(E_DRAG_DROP_FAILED);
break;
default:
break;
}
break;
case FOLEERROR_OK:
switch (OleQueryReleaseMethod(lpObject))
{
case OLE_SETUPDATEOPTIONS:
if (hwndLinkWait)
PostMessage(hwndLinkWait, WM_COMMAND, IDD_LINKDONE, 0L);
default:
break;
}
default:
break;
}
break;
case OLE_QUERY_RETRY:
case OLE_QUERY_PAINT:
return TRUE; /* Always continue painting, for now */
break;
default:
break;
}
return 0;
}
int NEAR PASCAL LogHimetricToPels(HDC hDC,BOOL bHoriz, int mmHimetric)
{
#define nHMPerInch 2540
#define nPelsPerLogInch GetDeviceCaps(hDC, bHoriz ? LOGPIXELSX : LOGPIXELSY)
return MulDiv(mmHimetric,nPelsPerLogInch,nHMPerInch);
}