/* * Windows Calendar * Copyright (c) 1985 by Microsoft Corporation, all rights reserved. * Written by Mark L. Chamberlin, consultant to Microsoft. * ****** calinit.c * */ /* Get rid of more stuff from windows.h */ #define NOSYSCOMMANDS #define NOSCROLL #define NODRAWTEXT #define NOVIRTUALKEYCODES #include "cal.h" #include "uniconv.h" #define DOTIMER //- OBM_RGARROW & OBM_LFARROW: Use the new arrows instead of old ones. #define OBM_RGARROW 32751 #define OBM_LFARROW 32750 LOGFONT FontStruct; HFONT hFont; #define GSM(SM) GetSystemMetrics(SM) BOOL APIENTRY ProcessShellOptions( LPTSTR lpszCmdLine); /**** CalInit ****/ BOOL APIENTRY CalInit ( HANDLE hInstance, HANDLE hPrevInstance, LPTSTR lpszCmdLine, INT cmdShow) { BITMAP bmBell; WNDCLASS WndClass; HDC hDC; TEXTMETRIC Metrics; INT i; INT cyUseable; TCHAR *pch; INT cchRemaining, cch, cxWnd2C, cyWnd2C; HANDLE hStrings; INT BlankWidth; /* width (in pixels) of a blank char */ TCHAR *pszFilterSpec = vszFilterSpec; /* temp. var. for creating filter text */ TCHAR sz[10]; TCHAR *psz = sz; #if defined (JAPAN)|| defined(KOREA) // JeeP 10/13/92 DWORD dwWnd2CStyle; // Style flag for Wnd2C RECT rcWnd0Client; #endif INT iWidth; SIZE Size; /* Remember our instance handle. */ vhInstance = hInstance; /* determine time setting from "International" section of win.ini */ if (GetProfileInt(TEXT("intl"), TEXT("iTime"), 1) == 1) vfHour24 = TRUE; else vfHour24 = FALSE; InitTimeDate(vhInstance); /* Load strings from resource file. */ cchRemaining = CCHSTRINGSMAX; pch = (LPTSTR) LocalAlloc(LPTR, ByteCountOf(cchRemaining)); if (!pch) return (FALSE); for (i = 0; i < CSTRINGS; i++) { cch = 1 + LoadString(hInstance, i, pch, cchRemaining); /* If LoadString failed, not enough memory. */ if (cch < 2) { MessageBeep(0); return FALSE; } vrgsz [i] = pch; pch += cch; /* If we run out of space it means that CCHSTRINGSMAX is too small. This should only happen when someone changes the strings in the .RC file, and returning FALSE should prevent them from shipping the new version without increasing CCHSTRINGSMAX (and possibly the initial heap size in the .DEF file). Note - we fail on the boundary condition that cchRemaining == 0 because last loadstring will trim the size of the string loaded to be <= cchRemaining. */ if ((cchRemaining -= cch) <= 0) return (FALSE); } //- MergeStr: Changed to string to avoid crossing word boundries. _tcsncpy (vszMergeStr, vrgsz [IDS_MERGE1], 2); /* Get default Page Setup stuff. */ for (i = IDS_HEADER; i <= IDS_BOTTOM; i++) LoadString(hInstance, i, chPageText[i-IDS_HEADER], PT_LEN); /* Allocate the DRs. */ if (!AllocDr ()) return FALSE; /* Create the brushes. */ if (!CreateBrushes ()) /* Destroy any brushes that were created on failure. */ return CalTerminate(0); /* construct default filter string in the required format for * the new FileOpen and FileSaveAs dialogs */ lstrcpy(vszFilterSpec, vszFilterText); pszFilterSpec += lstrlen (vszFilterSpec) + 1; lstrcpy(pszFilterSpec++, TEXT("*")); lstrcpy(pszFilterSpec, vszFileExtension); pszFilterSpec += lstrlen(pszFilterSpec) + 1; lstrcpy(pszFilterSpec, vszAllFiles); pszFilterSpec += lstrlen(pszFilterSpec) + 1; lstrcpy(pszFilterSpec, TEXT("*.*")); pszFilterSpec += lstrlen(pszFilterSpec) + 1; *pszFilterSpec = TEXT('\0'); *vszCustFilterSpec = TEXT('\0'); /* Get cursors. */ if (!(vhcsrArrow = LoadCursor (NULL, IDC_ARROW))) return CalTerminate(0); if (!(vhcsrIbeam = LoadCursor (NULL, IDC_IBEAM))) return CalTerminate(0); if (!(vhcsrWait = LoadCursor (NULL, IDC_WAIT))) return CalTerminate(0); if (hPrevInstance == (HANDLE) NULL) { /* There is no previous instance, so we must register our * window classes. */ memset ((LPVOID)&WndClass, 0, sizeof(WNDCLASS)); if (!(WndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(1)))) return CalTerminate(0); WndClass.lpszMenuName = (LPTSTR)MAKEINTRESOURCE(1); WndClass.lpszClassName = TEXT("CalWndMain"), WndClass.hInstance = hInstance; WndClass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_BYTEALIGNCLIENT; WndClass.lpfnWndProc = (WNDPROC)(CalWndProc); /* Register CalWndMain. */ if (!RegisterClass ((LPWNDCLASS)&WndClass)) { DWORD error = GetLastError(); return CalTerminate(0); } WndClass.lpszMenuName = NULL; WndClass.lpszClassName = TEXT("CalWndSub"); /* Register CalWndSub. */ if (!RegisterClass ((LPWNDCLASS)&WndClass)) return CalTerminate(0); } /* Bind the data segment of this instance to the dialog functions. */ for (i = 0; i < CIDD; i++) { if (vrglpfnDialog[i] == NULL) continue; vrglpfnDialog[i]=MakeProcInstance(vrglpfnDialog [i], hInstance); if (!vrglpfnDialog[i]) return CalTerminate(0); } /* Load in the accelerators. */ vhAccel = LoadAccelerators(hInstance, (LPTSTR) MAKEINTRESOURCE(1)); if (!vhAccel) return CalTerminate(0); /* Get bitmaps. * If LoadBitmaps returns false, must delete those that were loaded. */ if (!LoadBitmaps(hInstance)) return CalTerminate(1); /* Get a screen DC. */ hDC = GetDC(NULL); /* initialize the Unicode font */ GetObject (GetStockObject (SYSTEM_FONT), sizeof(LOGFONT), &FontStruct); FontStruct.lfCharSet = ANSI_CHARSET; lstrcpy (FontStruct.lfFaceName, UNICODE_FONT_NAME); hFont = CreateFontIndirect (&FontStruct); if (hFont == NULL) { TCHAR szStr [514]; LoadString(hInstance, IDS_FONTERR, szStr, CharSizeOf(szStr)); MessageBox (NULL, szStr, NULL, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL); hFont = (HFONT) GetStockObject (SYSTEM_FIXED_FONT); } /* Fetch the text metrics of the system font. */ GetTextMetrics (hDC, &Metrics); /* Create a memory DC for BitBlts. */ vhDCMemory = CreateCompatibleDC(hDC); ReleaseDC (NULL, hDC); if (!vhDCMemory) return CalTerminate(1); /* Remember the text metrics we care about. */ vcyFont = Metrics.tmHeight; vcxFont = Metrics.tmAveCharWidth; vcxFontMax = Metrics.tmMaxCharWidth; vcyDescent = Metrics.tmDescent; vcyExtLead = Metrics.tmExternalLeading; if (vcyExtLead == 0) vcyExtLead = max(1, vcyFont / 8); vcyLineToLine=vcyExtLead+vcyFont; /* Fetch some system metrics. */ vcxBorder = GSM(SM_CXBORDER); vcyBorder = GSM(SM_CYBORDER); vcxVScrollBar = GSM(SM_CXVSCROLL); vcxHScrollBar = GSM(SM_CXHSCROLL); vcyHScrollBar = GSM(SM_CYHSCROLL); /* Find out how big the the bell bitmap is. */ GetObject(vhbmBell, sizeof(BITMAP), (LPBYTE)&bmBell); vcxBell = bmBell.bmWidth; vcyBell = bmBell.bmHeight; /* Calculate the window heights. All heights are client rectangle heights, except for vcyWnd1, which includes the top and bottom borders. */ vcyWnd2A = max(vcyExtLead + vcyLineToLine, vcyHScrollBar + 2 * vcyBorder); vcyWnd2BTop = vcyBorder + vcyExtLead + 2 * vcyLineToLine; /* Note - the assumption is that numeric digits will not have descenders. Therefore, we subtract out the descent when calculating the space below the date digits in the monthly calendar display. */ /* changed from 6 to 9 */ vcyWnd2BBot = 9 * (6 * vcyBorder + max(vcyBorder - vcyDescent, 0) + vcyFont) + vcyBorder; #ifdef DISABLE cyT = 11 * vcyLineToLine + vcyBorder + vcyBorder; if (vcyWnd2BBot < cyT) vcyWnd2BBot = cyT; #endif /* The idea is to make the boxes not look very different in size on the last week of the month for the 4, 5, and 6 week cases. */ vcyWnd2BBot++; vcyWnd2B = vcyWnd2BTop + vcyWnd2BBot + vcyHScrollBar; /* last item added lsr */ cyWnd2C = CLNNOTES * vcyLineToLine; vcyWnd1 = vcyBorder + (vycoNotesBox = vcyWnd2A + vcyWnd2B) + vcyBorder + vcyExtLead + cyWnd2C + vcyBorder; /* Calculate the window widths. All widths are client rectangle widths, except for vcxWnd1, which includes the left and right borders. The width is determined by: Needed for Wnd2A in day mode: "