mirror of https://github.com/lianthony/NT4.0
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.
811 lines
26 KiB
811 lines
26 KiB
/*
|
|
* 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:
|
|
"<border> <time> <left arrow><border><right arrow>
|
|
Wednesday, September 25, 1985 <border>"
|
|
Needed for Wnd2B in day mode:
|
|
"<border> <Bell> <time> <40 chars appointment description> \
|
|
<scroll bar>"
|
|
Note that the right border of the scroll bar aligns with the right
|
|
border of Wnd1, so it shouldn't be added in twice.
|
|
*/
|
|
vcxWnd1 = max(
|
|
/* width of header */
|
|
(cchLongDateMax + cchTimeMax + 4) * vcxFont
|
|
+ 2 * vcxHScrollBar + 3 * vcxBorder,
|
|
/* width of line of display */
|
|
|
|
vcxBorder + vcxBell + (40 + 4 + cchTimeMax)
|
|
* vcxFont +vcxVScrollBar);
|
|
|
|
|
|
vcxWnd2A = vcxWnd1 - 2 * vcxBorder ;
|
|
|
|
|
|
/* Note that by adding in vcxBorder here we force the right
|
|
border of the scroll bar to align with the border of the
|
|
enclosing window Wnd1.
|
|
*/
|
|
|
|
vcxWnd2B = vcxWnd2A - vcxVScrollBar + vcxBorder;
|
|
|
|
/* Note - we know there are at least 40+4+1+cchTimeMax characters (from the width of
|
|
wnd1) and we assume that the rest of the stuff (like the scroll
|
|
bar and alarm bell bitmap totals at least one extra character
|
|
(a very safe assumption).
|
|
Leave room to the right of the last character for showing the
|
|
caret when the edit control is full (the caret is vcxBorder
|
|
pixels wide).
|
|
*/
|
|
cxWnd2C = (40 + 4 + 1 + cchTimeMax) * vcxFont + vcxBorder;
|
|
|
|
/* Calculate some x coordinates within Wnd2A. */
|
|
#ifdef BUG_8560
|
|
vxcoLeftArrowMax = (vxcoLeftArrowFirst = (7 + cchTimeMax) * vcxFont) + vcxHScrollBar;
|
|
vxcoRightArrowMax = (vxcoRightArrowFirst = vxcoLeftArrowMax + vcxBorder)+ vcxHScrollBar;
|
|
#else
|
|
vxcoLeftArrowMax = (vxcoLeftArrowFirst = (7 + cchTimeMax) * vcxFont) + vcxHScrollBar + vcxBorder;
|
|
vxcoRightArrowMax = (vxcoRightArrowFirst = vxcoLeftArrowMax)+ vcxHScrollBar + vcxBorder;
|
|
#endif
|
|
|
|
hDC = GetDC(NULL);
|
|
|
|
vxcoDate = vxcoRightArrowMax + vcxFont;
|
|
|
|
/* Calculate some coordinates within wnd2B for day mode. */
|
|
GetTimeSz ( SAMPLETIME, psz);
|
|
GetTextExtentPoint(hDC, vszBlank, 1, &Size);
|
|
iWidth = Size.cx ;
|
|
BlankWidth = iWidth;
|
|
|
|
//MGetTextExtent(hDC, psz, 1, &iHeight, &iWidth);
|
|
GetTextExtentPoint(hDC, psz, 1, &Size) ;
|
|
iWidth = Size.cx ;
|
|
//- KLUDGE: Divide the width of a character by two because it seems to
|
|
//- be too large.
|
|
//- TEMP: vxcoBell = iWidth;
|
|
//- TEMP: vxcoApptTime = vxcoBell + vcxBell + iWidth;
|
|
vxcoBell = iWidth / 2;
|
|
vxcoApptTime = vxcoBell + vcxBell + iWidth / 2;
|
|
|
|
GetTextExtentPoint(hDC, psz, 6, &Size);
|
|
iWidth = Size.cx;
|
|
|
|
vxcoAmPm = vxcoApptTime + iWidth - 1;
|
|
cchTimeMax = 2 * vcxFontMax / BlankWidth;
|
|
|
|
#ifdef DBCS
|
|
/*
|
|
* The reason is as follows.
|
|
* The length of time prefix of AM may be different
|
|
* from the length of time prefix of PM.
|
|
*/
|
|
{
|
|
SIZE sizeAm, sizePm;
|
|
|
|
GetTextExtentPoint( hDC, Time.sz1159, lstrlen(Time.sz1159), &sizeAm);
|
|
GetTextExtentPoint( hDC, Time.sz2359, lstrlen(Time.sz2359), &sizePm);
|
|
if (sizeAm.cx >= sizePm.cx)
|
|
iSuffixWid = sizeAm.cx;
|
|
else
|
|
iSuffixWid = sizePm.cx;
|
|
}
|
|
|
|
cchTimeMaxDBCS = iSuffixWid / BlankWidth;
|
|
#endif
|
|
|
|
/* Release the the DC. */
|
|
ReleaseDC (NULL, hDC);
|
|
|
|
/* Calculate the x boundaries of the appointment descriptions.
|
|
Leave room to the right of the last character for showing the
|
|
caret when the edit control is full (the caret is vcxBorder
|
|
pixels wide).
|
|
*/
|
|
/*
|
|
vxcoQdMax = (vxcoQdFirst = vxcoAmPm + 3 * vcxFont)
|
|
+ CCHQDMAX * vcxFont + vcxBorder;
|
|
*/
|
|
|
|
//- KLUDGE: vxcoQdFirst = vxcoAmPm + 3 * vcxFontMax;
|
|
#ifdef DBCS
|
|
vxcoQdFirst = vxcoAmPm + 3 * vcxFontMax + iSuffixWid;
|
|
#else
|
|
vxcoQdFirst = vxcoAmPm + 6 * vcxFontMax;
|
|
#endif
|
|
|
|
/* This formula limits the Moving edit control to what is visible
|
|
and not to a number of characters. The -2 at the end is simply
|
|
so the caret is not flush with the scrollbar. c-kraigb */
|
|
|
|
vxcoQdMax = vcxWnd1 - vcxBorder - GSM(SM_CXVSCROLL) - 2;
|
|
|
|
/* Calculate the number of ln and the y boundaries of the appointment
|
|
descriptions. Subtract out the top and bottom borders, and subtract
|
|
out the external leading before the first ln to see how much useable
|
|
space there is. Then divide to see how many ln will fit, and
|
|
split the extra pixels between the top and the bottom.
|
|
*/
|
|
cyUseable = vcyWnd2B - 2 * vcyBorder - vcyExtLead;
|
|
vlnLast = (vcln = cyUseable / vcyLineToLine) - 1;
|
|
vycoQdMax = (vycoQdFirst = 2 + (cyUseable % vcyLineToLine) / 2)
|
|
+ vcln * vcyLineToLine;
|
|
|
|
/* Create window CalWnd0. */
|
|
if (!(vhwnd0 = CreateWindow(TEXT("CalWndMain"),
|
|
NULL,
|
|
WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
min(vcxWnd1+GSM(SM_CXFRAME)*2+vcxFont*3,
|
|
GSM(SM_CXSCREEN)),
|
|
min(vcyWnd1+GSM(SM_CYCAPTION)+ GSM(SM_CYFRAME)*2+
|
|
GSM(SM_CYMENU)+(vcyFont*2),
|
|
GSM(SM_CYSCREEN)),
|
|
NULL, NULL,
|
|
hInstance, NULL)))
|
|
|
|
return CalTerminate(2);
|
|
|
|
|
|
/* Create window CalWnd1. */
|
|
if (!(vhwnd1 = CreateWindow (TEXT("CalWndSub"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
|
XcoWnd1 (), YcoWnd1 (), vcxWnd1, vcyWnd1,
|
|
vhwnd0, NULL, hInstance, NULL)))
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* Create window CalWnd2A. */
|
|
if (!(vhwnd2A = CreateWindow (TEXT("CalWndSub"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD,
|
|
0, 0, vcxWnd2A, vcyWnd2A,
|
|
vhwnd1, NULL, hInstance, NULL)))
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Enable this line for the Unicode font. */
|
|
SendMessage(vhwnd2A, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
|
|
|
|
|
|
#ifndef BUG_8560
|
|
/* Create the scrollbar control as a child of hwnd2A */
|
|
if (!(vhScrollWnd = CreateWindow (TEXT("scrollbar"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD | SBS_HORZ,
|
|
vxcoLeftArrowFirst, 0, (vcxHScrollBar + vcxBorder)<<1, vcyWnd2A,
|
|
vhwnd2A, (HMENU)IDHORZSCROLL, hInstance, NULL)))
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
/* Create window CalWnd2B. Note - use width of vcxWnd1 - vcxBorder
|
|
in order to overlay the right border of the scroll bar with the
|
|
right border of Wnd1.
|
|
*/
|
|
if (!(vhwnd2B = CreateWindow (TEXT("CalWndSub"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD | WS_VSCROLL| WS_HSCROLL,
|
|
0, vcyWnd2A, vcxWnd1 - vcxBorder, vcyWnd2B,
|
|
vhwnd1, NULL, hInstance, NULL)))
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
hmScrollMax = 0;
|
|
vmScrollPos = 0;
|
|
vmScrollMax = 0;
|
|
hmScrollPos = 0;
|
|
|
|
#if defined (JAPAN)||defined(KOREA) // JeeP 10/13/92
|
|
/*
|
|
* On 640x400 System, we need a v_scrbar in the notewindow.
|
|
*/
|
|
GetClientRect(vhwnd0,&rcWnd0Client);
|
|
if( rcWnd0Client.bottom - (vcyBorder*3+vycoNotesBox+vcyExtLead)<cyWnd2C )
|
|
{
|
|
cyWnd2C=rcWnd0Client.bottom - (vcyBorder*3+vycoNotesBox+vcyExtLead);
|
|
dwWnd2CStyle = WS_VISIBLE | WS_CHILD | ES_MULTILINE | WS_VSCROLL |
|
|
ES_AUTOVSCROLL;
|
|
} else
|
|
dwWnd2CStyle = WS_VISIBLE | WS_CHILD | ES_MULTILINE;
|
|
#endif
|
|
|
|
/* Create window CalWnd2C. */
|
|
#if defined (JAPAN)||defined(KOREA) // JeeP 10/13/92
|
|
if (!(vhwnd2C = CreateWindow (TEXT("Edit"),
|
|
NULL,
|
|
dwWnd2CStyle,
|
|
vxcoWnd2C = (vcxWnd2A - cxWnd2C) / 2,
|
|
vycoWnd2C = vcyBorder*3 + vycoNotesBox + vcyExtLead,
|
|
cxWnd2C, cyWnd2C,
|
|
vhwnd1, (HMENU)IDECNOTES, hInstance, NULL)))
|
|
#else
|
|
if (!(vhwnd2C = CreateWindow (TEXT("Edit"),
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD | ES_MULTILINE,
|
|
vxcoWnd2C = (vcxWnd2A - cxWnd2C) / 2,
|
|
vycoWnd2C = vcyWnd1 - 2 * vcyBorder - cyWnd2C,
|
|
cxWnd2C, cyWnd2C,
|
|
vhwnd1, (HMENU)IDECNOTES, hInstance, NULL)))
|
|
#endif
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Enable this line for the Unicode font. */
|
|
SendMessage(vhwnd2C, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
|
|
|
|
|
|
/* limit text in notes area to number of chars that fit.
|
|
* this is done to get around a bug in edit controls when
|
|
* you paste in text which has tabs.
|
|
* 05-Oct-1987. davidhab.
|
|
*/
|
|
#if VARIABLENOTELENGTH
|
|
SendMessage(vhwnd2C, EM_LIMITTEXT, (cyWnd2C / vcyFont) * (cxWnd2C / vcxFont) * 2, 0L);
|
|
#else
|
|
SendMessage(vhwnd2C, EM_LIMITTEXT, CBNOTESMAX, 0L);
|
|
#endif
|
|
|
|
/* Create window CalWnd3. c-kraigb : ES_AUTOHSCROLL added to allow
|
|
more text in the appointment area without having to alter the
|
|
size of the entire layout.*/
|
|
|
|
if (!(vhwnd3 = CreateWindow (TEXT("Edit"),
|
|
NULL,
|
|
WS_CHILD | ES_AUTOHSCROLL,
|
|
0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
vhwnd2B, (HMENU)IDECQD, hInstance, NULL)))
|
|
|
|
{
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
/* Enable this line for the Unicode font. */
|
|
SendMessage(vhwnd3, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
|
|
|
|
|
|
/* Limit the Appointment Edit to it's maximum. 80 chars should be
|
|
sufficient for all intensive purposes , c-kraigb
|
|
*/
|
|
SendMessage(vhwnd3, EM_LIMITTEXT, CCHQDMAX, 0L);
|
|
|
|
/* Make all the files look closed. */
|
|
for (i=0; i < CFILE; i++)
|
|
hFile[i] = INVALID_HANDLE_VALUE;
|
|
|
|
/* Get a handle for the tdd. Note - the tdd will get initialized
|
|
when we call CleanSlate or LoadCal below.
|
|
*/
|
|
//- Calinit: Changed Allocation because of bug in LocalReAlloc.
|
|
//- vhlmTdd = LocalAlloc (LMEM_MOVEABLE, 0);
|
|
|
|
/* Fetch the current date and time. */
|
|
ReadClock(&vd3Cur, &vftCur.tm);
|
|
vftCur.dt = DtFromPd3 (&vd3Cur);
|
|
|
|
/* Set up the timer event for updating the time and date. */
|
|
|
|
#ifdef DOTIMER
|
|
if (!SetTimer (vhwnd0, 0, 1000, (TIMERPROC)NULL))
|
|
{
|
|
AlertBox (vrgsz[IDS_NOTIMER], (TCHAR *)NULL,
|
|
MB_SYSTEMMODAL | MB_OK | MB_ICONHAND);
|
|
DestroyWindow(vhwnd0);
|
|
return FALSE;
|
|
}
|
|
#endif /* #ifdef DOTIMER */
|
|
|
|
/* init. some fields of the OPENFILENAME struct used by fileopen and
|
|
* filesaveas
|
|
*/
|
|
/* changed to sizeof instead of constant. 18 Jan 1991 clarkc */
|
|
vOFN.lStructSize = sizeof(OPENFILENAME);
|
|
vOFN.hwndOwner = vhwnd0;
|
|
vOFN.lpstrFileTitle = 0;
|
|
vOFN.nMaxCustFilter = CCHFILTERMAX;
|
|
vOFN.nFilterIndex = vFilterIndex;
|
|
vOFN.nMaxFile = CCHFILESPECMAX;
|
|
vOFN.lpfnHook = NULL;
|
|
|
|
/* init fields of the PRINTDLG structure */
|
|
/* changed to sizeof instead of constant. 18 Jan 1991 clarkc */
|
|
vPD.lStructSize = sizeof(PRINTDLG);
|
|
vPD.hwndOwner = vhwnd0;
|
|
vPD.hDevMode = NULL;
|
|
vPD.hDevNames = NULL;
|
|
vPD.hDC = NULL;
|
|
vPD.Flags = PD_NOSELECTION | PD_NOPAGENUMS; /* disable "pages" and "Selection" radiobuttons */
|
|
vPD.nFromPage = 0;
|
|
vPD.nToPage = 0;
|
|
vPD.nMinPage = 0;
|
|
vPD.nMaxPage = 0;
|
|
vPD.nCopies = 1;
|
|
|
|
/* determine the message number to be used for communication with
|
|
* Find dialog
|
|
*/
|
|
if (!(vHlpMsg = RegisterWindowMessage ((LPTSTR)HELPMSGSTRING)))
|
|
return FALSE;
|
|
|
|
/* Prevent grabbing of focus if we are coming up iconic. */
|
|
vfNoGrabFocus = (cmdShow == SW_SHOWMINNOACTIVE);
|
|
|
|
|
|
/* Initialize according to values from win.ini */
|
|
CalWinIniChange();
|
|
|
|
if (ProcessShellOptions(lpszCmdLine))
|
|
{
|
|
PostMessage(vhwnd0, WM_CLOSE, 0, 0L);
|
|
return (TRUE);
|
|
}
|
|
else if (*lpszCmdLine == TEXT('\0')) /* Not invoked with a file. */
|
|
{
|
|
CleanSlate (TRUE);
|
|
}
|
|
else
|
|
{
|
|
DWORD PathLength;
|
|
LPTSTR FilePart;
|
|
|
|
/* Try to load the file. */
|
|
AddDefExt(lpszCmdLine);
|
|
|
|
PathLength = SearchPath(NULL,lpszCmdLine,NULL,CCHFILESPECMAX,
|
|
vszOFSFileSpec[IDFILEORIGINAL],&FilePart);
|
|
if(PathLength)
|
|
hFile[IDFILEORIGINAL]= CreateFile(
|
|
vszOFSFileSpec[IDFILEORIGINAL],
|
|
GENERIC_READ | GENERIC_WRITE,0, NULL,
|
|
OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0) ;
|
|
|
|
LoadCal ();
|
|
}
|
|
|
|
/* If we didn't grab the focus we need to set up vhwndFocus so
|
|
we correctly set the focus when we get activated later on.
|
|
Initially we are in day mode with the focus on the appointment
|
|
edit control.
|
|
*/
|
|
if (vfNoGrabFocus)
|
|
{
|
|
vhwndFocus = vhwnd3;
|
|
vfNoGrabFocus = FALSE;
|
|
}
|
|
|
|
|
|
/* Make the windows visible. */
|
|
ShowWindow (vhwnd0, cmdShow);
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
BOOL APIENTRY ProcessShellOptions(
|
|
LPTSTR lpszCmdLine)
|
|
{
|
|
TCHAR szFileName[80];
|
|
DWORD PathLength ;
|
|
LPTSTR FilePart ;
|
|
|
|
CharUpper(lpszCmdLine);
|
|
|
|
if (*lpszCmdLine != TEXT('/') || *lpszCmdLine != TEXT('P'))
|
|
return FALSE;
|
|
|
|
lpszCmdLine += 2;
|
|
|
|
// skip blanks
|
|
while (*lpszCmdLine == TEXT(' ') || *lpszCmdLine == TEXT('\t'))
|
|
lpszCmdLine++;
|
|
|
|
if (!*lpszCmdLine)
|
|
return FALSE;
|
|
|
|
/* Get the filename. */
|
|
lstrcpy((LPTSTR)szFileName, lpszCmdLine);
|
|
AddDefExt(szFileName);
|
|
|
|
PathLength = SearchPath(NULL,szFileName,NULL,CCHFILESPECMAX,
|
|
vszOFSFileSpec[IDFILEORIGINAL],&FilePart);
|
|
if (PathLength == 0)
|
|
hFile[IDFILEORIGINAL] = INVALID_HANDLE_VALUE ;
|
|
else
|
|
hFile[IDFILEORIGINAL]= CreateFile(
|
|
vszOFSFileSpec[IDFILEORIGINAL],
|
|
GENERIC_READ | GENERIC_WRITE,0, NULL,
|
|
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0) ;
|
|
|
|
if (hFile[IDFILEORIGINAL] == INVALID_HANDLE_VALUE)
|
|
{
|
|
AlertBox (vszCannotReadFile, szFileName, MB_SYSTEMMODAL | MB_OK | MB_ICONEXCLAMATION);
|
|
return TRUE;
|
|
}
|
|
|
|
LoadCal();
|
|
|
|
// need to set the first and last dates for which appts have to be
|
|
// printed.
|
|
// Since the data structures are utterly incomprehensible,
|
|
// the following method appeared to provide the easiest solution
|
|
vdtFrom = DTFIRST; // from 1/1/1980
|
|
vdtTo = DTLAST; // to December 31, 2099.
|
|
|
|
FSearchTdd (vdtFrom, &vitddFirst); // first day in the file
|
|
FSearchTdd (vdtTo, &vitddMax); // last day in the file
|
|
Print ();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**** AllocDr ****/
|
|
|
|
BOOL APIENTRY AllocDr ()
|
|
{
|
|
register INT i;
|
|
|
|
for (i = 0; i < CDR; i++)
|
|
{
|
|
/* Note - the DRs get marked free by New. */
|
|
if (!(vrghlmDr [i] = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, CBDRMAX)))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/**** Return TRUE iff all bitmaps loaded. If we fail to load any bitmap,
|
|
DeleteBitmaps will deleted the ones already loaded. */
|
|
BOOL APIENTRY LoadBitmaps(HANDLE hInstance)
|
|
{
|
|
vhbmLeftArrow = LoadBitmap (NULL, MAKEINTRESOURCE (OBM_LFARROW));
|
|
vhbmRightArrow = LoadBitmap (NULL, MAKEINTRESOURCE (OBM_RGARROW));
|
|
vhbmBell = LoadBitmap (hInstance, MAKEINTRESOURCE(1));
|
|
return (vhbmBell && vhbmLeftArrow && vhbmRightArrow);
|
|
}
|
|
|
|
|
|
|
|
/**** Delete bitmaps that have been loaded. Depends on handles having been
|
|
initialized to 0. */
|
|
VOID APIENTRY DeleteBitmaps()
|
|
{
|
|
if (vhbmBell)
|
|
DeleteObject(vhbmBell);
|
|
|
|
if (vhbmLeftArrow)
|
|
DeleteObject(vhbmLeftArrow);
|
|
|
|
if (vhbmRightArrow)
|
|
DeleteObject(vhbmRightArrow);
|
|
}
|
|
|
|
/**** Destroy Global Objects.
|
|
iLevel determines which objects will be deleted.
|
|
Always returns FALSE */
|
|
BOOL APIENTRY CalTerminate(INT iLevel)
|
|
{
|
|
/* Note case statement falls thru every arm. */
|
|
switch (iLevel)
|
|
{
|
|
case 2:
|
|
DeleteDC (vhDCMemory);
|
|
|
|
case 1:
|
|
DeleteBitmaps();
|
|
|
|
case 0:
|
|
DestroyBrushes();
|
|
}
|
|
|
|
/* Leave handy value in ax for calinit to return. */
|
|
return FALSE;
|
|
}
|
|
|
|
|