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.
1136 lines
34 KiB
1136 lines
34 KiB
#include "precomp.h"
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* Windows Cardfile - Written by Mark Cliggett */
|
|
/* (c) Copyright Microsoft Corp. 1985, 1994 - All Rights Reserved */
|
|
/* */
|
|
/************************************************************************/
|
|
|
|
HWND hDlgFind = NULL;
|
|
HANDLE hEditCurs;
|
|
|
|
int fCanPrint = FALSE;
|
|
HANDLE hIndexInstance;
|
|
TCHAR szPrinter[128];
|
|
TCHAR szDec[2];
|
|
|
|
#ifndef OLE_20
|
|
CHAR szSaveName[] = "SaveName";
|
|
#else
|
|
TCHAR szSaveName[] = TEXT("SaveName");
|
|
#endif
|
|
|
|
/* OLE libraries */
|
|
int cOleWait = 0;
|
|
|
|
#ifndef OLE_20
|
|
CHAR szPStatic[] = "Static";
|
|
CHAR szPStdFile[] = "StdFileEditing";
|
|
#else
|
|
TCHAR szPStatic[] = TEXT("Static");
|
|
TCHAR szPStdFile[] = TEXT("StdFileEditing");
|
|
#endif
|
|
|
|
NOEXPORT BOOL NEAR DisplayBusyMessage(LPOLEOBJECT lpObject);
|
|
|
|
|
|
DWORD IndexInput(
|
|
HWND hWindow,
|
|
int event)
|
|
{
|
|
TCHAR *pBuf;
|
|
LPCARDHEADER Cards;
|
|
int i;
|
|
TCHAR buf1[50], szMsg[300];
|
|
RECT rect;
|
|
long ltmp;
|
|
BOOL fIsCard;
|
|
HMENU hMenu;
|
|
LPOLEOBJECT lpObjectSave = NULL;
|
|
TCHAR szFile[PATHMAX];
|
|
WORD fType; /* requested file type of target */
|
|
#ifndef OLE_20
|
|
CHAR aszBuf[PATHMAX];
|
|
#endif
|
|
|
|
switch(event)
|
|
{
|
|
case ABOUT:
|
|
if (ShellAbout (hWindow, szCardfile, TEXT(""),
|
|
LoadIcon (hIndexInstance, (LPTSTR) INDEXICON)) == -1)
|
|
IndexOkError (EINSMEMORY);
|
|
break;
|
|
|
|
case EXIT:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
PostMessage (hWindow, WM_CLOSE, 0, 0L);
|
|
break;
|
|
|
|
case NEW:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
MenuFileNew();
|
|
#ifdef JAPAN //KKBUGFIX // added 18 Aug. 1992 by Hiraisi (in Japan)
|
|
fReadOnly = FALSE;
|
|
#endif
|
|
break;
|
|
|
|
case OPEN:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
MenuFileOpen();
|
|
break;
|
|
|
|
case MERGE: /* merge in another file */
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
MenuFileMerge();
|
|
break;
|
|
|
|
case PAGESETUP: /* page setup options */
|
|
PutUpDB(DTPAGE);
|
|
break;
|
|
|
|
case PRINTSETUP:
|
|
PrinterSetupDlg(hWindow);
|
|
break;
|
|
|
|
case PRINT:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
UpdateEmbObject(&CurCard, MB_YESNO);
|
|
PrintCards(1);
|
|
break;
|
|
|
|
case PRINTALL:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (CardPhone == CCARDFILE)
|
|
{
|
|
UpdateEmbObject(&CurCard, MB_YESNO);
|
|
PrintCards(cCards);
|
|
}
|
|
else
|
|
PrintList();
|
|
break;
|
|
|
|
case SAVE:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (fReadOnly)
|
|
{
|
|
BuildAndDisplayMsg (E_CANTSAVETOREADONLYFILE, CurIFile);
|
|
goto SaveAs;
|
|
}
|
|
if (CurIFile[0])
|
|
{
|
|
lstrcpy (szFile, CurIFile);
|
|
fType= fFileType; // Save: is going to use this
|
|
goto Save;
|
|
}
|
|
|
|
/* fall through... */
|
|
|
|
case SAVEAS:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
SaveAs:
|
|
if (!MyGetSaveFileName(szFile, &fType))
|
|
break;
|
|
if (fReadOnly && lstrcmpi (szFile, CurIFile) == 0)
|
|
{
|
|
/* When a file is readonly(because of sharing/readonly attribute,
|
|
* allow saving to a different file. But if the user does not
|
|
* specify a new filename, complain.
|
|
*/
|
|
BuildAndDisplayMsg(E_CANTSAVETOREADONLYFILE, szFile);
|
|
goto SaveAs;
|
|
}
|
|
UpdateWindow(hIndexWnd);
|
|
Save:
|
|
SetCursor(hWaitCurs);
|
|
if (CardPhone == CCARDFILE)
|
|
ltmp = SendMessage(hEditWnd, EM_GETSEL, 0, 0L);
|
|
|
|
/* If an embedded object is open for editing, try to update */
|
|
if (UpdateEmbObject(&CurCard, MB_YESNOCANCEL) == IDCANCEL)
|
|
break;
|
|
|
|
/* Save the current object.
|
|
*
|
|
* We do this so that the server will not be dismissed
|
|
* when the file is saved. We don't just clone into
|
|
* lpObjectSave because the server will be dismissed
|
|
* if an embedded object is deleted; we must actually
|
|
* maintain the object that is currently being edited.
|
|
*/
|
|
if (fOLE && (lpObjectSave = CurCard.lpObject) &&
|
|
OleError (OleClone (lpObjectSave, lpclient,
|
|
lhcdoc, szSaveName,
|
|
(LPOLEOBJECT FAR *)&(CurCard.lpObject))))
|
|
{
|
|
CurCard.lpObject = lpObjectSave;
|
|
lpObjectSave = NULL;
|
|
}
|
|
|
|
/* In phone mode, no need to save the current card
|
|
* In card mode should save the current card. */
|
|
if (CardPhone == PHONEBOOK || SaveCurrentCard(iFirstCard))
|
|
{
|
|
if (fType == OLD_FORMAT)
|
|
{
|
|
LoadString(hIndexInstance, W_WILLDELETEOBJECTS, szMsg, CharSizeOf(szMsg));
|
|
|
|
if (MessageBox(hIndexWnd, szMsg, szCardfile, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
|
|
break;
|
|
}
|
|
|
|
if (fType != UNICODE_FILE)
|
|
{
|
|
if (MyIsTextUnicode ())
|
|
{
|
|
LoadString(hIndexInstance, E_UNICODETEXT, szMsg, CharSizeOf(szMsg));
|
|
|
|
if (MessageBox(hIndexWnd, szMsg, szWarning, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifndef OLE_20
|
|
WideCharToMultiByte (CP_ACP, 0, szFile, -1, aszBuf, sizeof(aszBuf), NULL, NULL);
|
|
|
|
if (fOLE && OLE_OK != OleRenameClientDoc (lhcdoc, aszBuf))
|
|
#else
|
|
if (fOLE && OLE_OK != OleRenameClientDoc (lhcdoc, szFile))
|
|
#endif
|
|
ErrorMessage (W_FAILED_TO_NOTIFY);
|
|
|
|
if (WriteCardFile (szFile, fType))
|
|
{
|
|
SetCaption ();
|
|
|
|
if (fOLE && OLE_OK != OleSavedClientDoc (lhcdoc))
|
|
ErrorMessage(W_FAILED_TO_NOTIFY);
|
|
|
|
Fdelete (TempFile);
|
|
MakeTempFile ();
|
|
}
|
|
/* if write fails, due to can't create or memfull,
|
|
* return to saveas dialog box.
|
|
*/
|
|
else
|
|
{
|
|
/* We failed, rename the document back */
|
|
#ifndef OLE_20
|
|
WideCharToMultiByte (CP_ACP, 0, CurIFile, -1, aszBuf, sizeof(aszBuf), NULL, NULL);
|
|
|
|
if (fOLE && OLE_OK != OleRenameClientDoc (lhcdoc, aszBuf))
|
|
#else
|
|
if (fOLE && OLE_OK != OleRenameClientDoc (lhcdoc, CurIFile))
|
|
#endif
|
|
ErrorMessage (W_FAILED_TO_NOTIFY);
|
|
|
|
if (lpObjectSave)
|
|
{
|
|
OleError (OleDelete (CurCard.lpObject));
|
|
CurCard.lpObject = lpObjectSave;
|
|
}
|
|
|
|
SetCurCard (iFirstCard);
|
|
goto SaveAs;
|
|
}
|
|
|
|
if (CardPhone == CCARDFILE)
|
|
{
|
|
SetCurCard(iFirstCard);
|
|
SendMessage(hEditWnd, EM_SETSEL, LOWORD(ltmp), HIWORD(ltmp));
|
|
}
|
|
|
|
if (lpObjectSave)
|
|
{
|
|
OleError(OleDelete(CurCard.lpObject));
|
|
CurCard.lpObject = lpObjectSave;
|
|
}
|
|
}
|
|
SetCursor(hArrowCurs);
|
|
|
|
break;
|
|
|
|
case CCARDFILE:
|
|
case PHONEBOOK:
|
|
if (event == CardPhone)
|
|
break; /* nothing new */
|
|
|
|
/* toggle the menu marks */
|
|
hMenu = GetMenu(hWindow);
|
|
CheckMenuItem(hMenu, CardPhone, MF_UNCHECKED);
|
|
CheckMenuItem(hMenu, event, MF_CHECKED);
|
|
|
|
CardPhone = event; /* keep track of mode we are in */
|
|
fIsCard = (CardPhone == CCARDFILE);
|
|
|
|
/*
|
|
* change the main windows background color for the current
|
|
* mode. if we go into list mode full screen we have to
|
|
* paint the region at the bottom of the screen. in
|
|
* card mode we set to the same color as the card window
|
|
* to avoid ugly repaint junk.
|
|
*/
|
|
#if defined( WIN32 )
|
|
SetClassLong(hWindow, GCL_HBRBACKGROUND,
|
|
fIsCard ? COLOR_APPWORKSPACE + 1 : COLOR_WINDOW + 1);
|
|
#else
|
|
SetClassWord(hWindow, GCW_HBRBACKGROUND,
|
|
fIsCard ? COLOR_APPWORKSPACE + 1 : COLOR_WINDOW + 1);
|
|
#endif
|
|
|
|
if (fFullSize)
|
|
{
|
|
GetClientRect(hIndexWnd, &rect);
|
|
rect.top = rect.bottom - CharFixHeight;
|
|
InvalidateRect(hIndexWnd, &rect, TRUE);
|
|
}
|
|
|
|
if (fIsCard)
|
|
{
|
|
SetCurCard(iFirstCard); /* from list mode selection */
|
|
ShowWindow(hListWnd, SW_HIDE);
|
|
ShowWindow(hCardWnd, SW_SHOW);
|
|
}
|
|
else
|
|
{
|
|
ShowWindow(hCardWnd, SW_HIDE);
|
|
SaveCurrentCard(iFirstCard);
|
|
InitPhoneList(hListWnd, iFirstCard);
|
|
SizeListWindow();
|
|
ShowWindow(hListWnd, SW_SHOW);
|
|
}
|
|
|
|
SetFocus(fIsCard ? hCardWnd : hListWnd);
|
|
SetWindowText(hLeftWnd, fIsCard ? szCardView : szListView);
|
|
break;
|
|
|
|
case UNDO:
|
|
if (EditMode == I_TEXT)
|
|
SendMessage(hEditWnd, EM_UNDO, 0, 0L);
|
|
else
|
|
{
|
|
if (CheckForBusyObjects() || InsertObjectInProgress())
|
|
break;
|
|
|
|
if (lpObjectUndo)
|
|
{
|
|
PicDelete (&CurCard);
|
|
CurCard.lpObject = lpObjectUndo;
|
|
CurCard.otObject = otObjectUndo;
|
|
#ifndef OLE_20
|
|
wsprintfA (szObjectName, szObjFormat, CurCard.idObject + 1);
|
|
#else
|
|
wsprintfW (szObjectName, szObjFormat, CurCard.idObject + 1);
|
|
#endif
|
|
OleRename (CurCard.lpObject, szObjectName);
|
|
lpObjectUndo = NULL;
|
|
InvalidateRect(hEditWnd, (LPRECT)&(CurCard.rcObject), TRUE);
|
|
CurCardHead.flags |= FDIRTY;
|
|
|
|
/* If a link is undone, try to reconnect */
|
|
if (CurCard.otObject == LINK
|
|
&& OleError (OleReconnect (CurCard.lpObject)))
|
|
ErrorMessage (E_FAILED_TO_RECONNECT_OBJECT);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HEADER:
|
|
if (CardPhone == PHONEBOOK)
|
|
{
|
|
SetCurCard(iFirstCard);
|
|
SaveCurrentCard(iFirstCard);
|
|
}
|
|
if (pBuf = PutUpDB(DTHEADER))
|
|
{
|
|
/* Preserve the current Index line for restoration later */
|
|
lstrcpy(SavedIndexLine, CurCardHead.line);
|
|
lstrcpy(CurCardHead.line, pBuf);
|
|
|
|
/* !!! Should we be destroying the object here? */
|
|
DeleteCard(iFirstCard); /* take it out of it's current position */
|
|
iFirstCard = AddCurCard(); /* and put it back in the right place */
|
|
fFileDirty = TRUE;
|
|
InvalidateRect(hWindow, NULL, TRUE);
|
|
LocalFree((HANDLE)pBuf);
|
|
}
|
|
break;
|
|
|
|
case RESTORE:
|
|
/* Restore the index line from temporary storage */
|
|
Cards = (LPCARDHEADER) GlobalLock(hCards);
|
|
lstrcpy(Cards[iFirstCard].line, SavedIndexLine);
|
|
lstrcpy(CurCardHead.line, SavedIndexLine);
|
|
InvalidateRect(hWindow, NULL, TRUE);
|
|
GlobalUnlock(hCards);
|
|
if (CurCard.lpObject)
|
|
PicDelete(&CurCard);
|
|
SetCurCard(iFirstCard);
|
|
InvalidateRect(hEditWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case CUT:
|
|
case COPY:
|
|
if (EditMode == I_OBJECT &&
|
|
(CheckForBusyObjects() || InsertObjectInProgress()))
|
|
break;
|
|
DoCutCopy(event);
|
|
break;
|
|
|
|
case PASTE:
|
|
case PASTELINK:
|
|
if (CheckForBusyObjects() || InsertObjectInProgress())
|
|
break;
|
|
|
|
if (CurCard.lpObject && CurCard.otObject == EMBEDDED &&
|
|
OleQueryOpen(CurCard.lpObject) == OLE_OK)
|
|
{
|
|
TCHAR szMsg[300];
|
|
|
|
LoadString(hIndexInstance, W_REPLACEOPENOBJECT, szMsg, CharSizeOf(szMsg));
|
|
|
|
MessageBox(hIndexWnd, szMsg, szWarning, MB_OK);
|
|
break;
|
|
}
|
|
|
|
DoPaste(event);
|
|
break;
|
|
|
|
case IDM_PASTESPECIAL:
|
|
if (CheckForBusyObjects() || InsertObjectInProgress())
|
|
break;
|
|
DoPasteSpecial();
|
|
break;
|
|
|
|
case IDM_INSERTOBJECT:
|
|
if (CheckForBusyObjects() || InsertObjectInProgress())
|
|
break;
|
|
InsertObject();
|
|
break;
|
|
|
|
case I_TEXT:
|
|
case I_OBJECT:
|
|
if (event != EditMode)
|
|
{
|
|
#ifdef RIGHT
|
|
/* Should we add a field to Card to be used as the
|
|
* selection area? It'd make a lot of sense to
|
|
* disable/re-enable the selection area if you switch
|
|
* to and from picture mode.
|
|
*/
|
|
if (event == I_OBJECT)
|
|
{
|
|
DWORD lSel;
|
|
|
|
/* Remove the selection area if going to picture mode */
|
|
lSel = SendMessage(hEditWnd, EM_GETSEL, 0, 0L);
|
|
lSel = (LOWORD(lSel) | (lSel << 8));
|
|
SendMessage(hEditWnd, EM_SETSEL, 0, lSel);
|
|
}
|
|
#endif
|
|
EditMode = event;
|
|
#ifdef JAPAN //KKBUGFIX // #3082: 02/02/1993: Disabling IME while Picture mode
|
|
if (fNowFocus)
|
|
{
|
|
if (event == I_TEXT)
|
|
EnableIME (TRUE);
|
|
else if (CardPhone == CCARDFILE)
|
|
EnableIME (FALSE);
|
|
}
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
//bugbug - get rid of IDD_FONT resource and lpTemplateName initialization
|
|
case IDM_SETFONT:
|
|
{
|
|
RECT rect; // to force re-draw
|
|
CHOOSEFONT cf;
|
|
HDC hDisplayDC; // DC of video
|
|
LOGFONT NewFontStruct; // local copy until succeeds
|
|
|
|
/* calls the font chooser (in commdlg)
|
|
*/
|
|
NewFontStruct= FontStruct; // initialize our font structure
|
|
cf.lStructSize = sizeof(CHOOSEFONT);
|
|
cf.hwndOwner = hWindow;
|
|
cf.hInstance = hIndexInstance;
|
|
cf.lpTemplateName = (LPTSTR) MAKEINTRESOURCE(IDD_FONT);
|
|
cf.hDC = NULL;
|
|
cf.lpLogFont = &NewFontStruct;
|
|
cf.Flags = CF_SCREENFONTS |
|
|
CF_NOVECTORFONTS |
|
|
CF_INITTOLOGFONTSTRUCT |
|
|
0;
|
|
cf.lpfnHook = (LPCFHOOKPROC) NULL;
|
|
if( !(hDisplayDC= GetDC(NULL)) )
|
|
{
|
|
break;
|
|
}
|
|
NewFontStruct.lfHeight= -( (iPointSize * GetDeviceCaps(hDisplayDC,LOGPIXELSY) ) / 720 );
|
|
ReleaseDC( NULL, hDisplayDC );
|
|
|
|
if (ChooseFont (&cf))
|
|
{
|
|
HFONT hNewFont;
|
|
hNewFont= CreateFontIndirect( &NewFontStruct );
|
|
if( !hNewFont )
|
|
{
|
|
break;
|
|
}
|
|
// Update everybody, and write new font data to the registry
|
|
FontStruct= NewFontStruct;
|
|
SetGlobalFont( hNewFont, cf.iPointSize );
|
|
SaveGlobals();
|
|
// windows that need new font
|
|
|
|
SendMessage(hEditWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
|
|
SendMessage(hListWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
|
|
|
|
// fake a window move to re-draw everything
|
|
// also forces re-calc of where cards are
|
|
// send size message so card positions are re-calced
|
|
|
|
GetWindowRect( hCardWnd, &rect );
|
|
SendMessage( hCardWnd, WM_SIZE, SIZE_RESTORED,
|
|
(rect.bottom-rect.top) << 16 + rect.right-rect.left );
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ADD:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (pBuf = PutUpDB(DTADD))
|
|
{
|
|
/* Ensure no busy objects for sure */
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (!ExpandHdrs(1))
|
|
break;
|
|
/* In phone mode, no need to save the current card
|
|
* In card mode should save the current card. */
|
|
if (CardPhone == PHONEBOOK || SaveCurrentCard(iFirstCard))
|
|
{
|
|
MakeBlankCard();
|
|
/* Make sure pBuf has correct length */
|
|
/* Truncate it if longer. */
|
|
if (lstrlen(pBuf) > LINELENGTH)
|
|
pBuf[LINELENGTH] = 0;
|
|
lstrcpy(CurCardHead.line, pBuf);
|
|
CurCardHead.flags |= (FDIRTY + FNEW);
|
|
iFirstCard = AddCurCard();
|
|
|
|
if (CardPhone == PHONEBOOK)
|
|
SaveCurrentCard(iFirstCard);
|
|
#ifdef JAPAN //KKBUGFIX // added 07 Sep. 1992 by Hiraisi (in Japan)
|
|
// I referrd to input.c of WIN30J (BuildMessages())
|
|
// sometimes card number do not update
|
|
SetNumOfCards();
|
|
#endif
|
|
InvalidateRect(hWindow, NULL, TRUE);
|
|
}
|
|
LocalFree((HANDLE)pBuf);
|
|
}
|
|
break;
|
|
|
|
case CARDDELETE:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (CardPhone == PHONEBOOK)
|
|
{
|
|
SetCurCard(iFirstCard);
|
|
SaveCurrentCard(iFirstCard);
|
|
}
|
|
LoadString(hIndexInstance, IDELCURCARD, buf1, CharSizeOf(buf1));
|
|
MergeStrings(buf1, CurCardHead.line, szMsg);
|
|
if (MessageBox(hIndexWnd, szMsg, szWarning, MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK)
|
|
break;
|
|
|
|
if (CurCard.lpObject)
|
|
{
|
|
if (OleQueryOpen(CurCard.lpObject) == OLE_OK)
|
|
{
|
|
TCHAR szMsg[200];
|
|
|
|
LoadString(hIndexInstance, W_DELETEOPENOBJECT, szMsg, CharSizeOf(szMsg));
|
|
if (MessageBox(hIndexWnd, szMsg, szWarning, MB_OKCANCEL) == IDCANCEL)
|
|
break;
|
|
}
|
|
|
|
PicDelete(&CurCard);
|
|
}
|
|
if (cCards > 1)
|
|
{
|
|
DeleteCard(iFirstCard);
|
|
if (iFirstCard == cCards)
|
|
iFirstCard = (CardPhone == CCARDFILE ? 0 : cCards - 1);
|
|
if (CardPhone == CCARDFILE)
|
|
SetCurCard(iFirstCard);
|
|
/* shrinking, so don't have to check (YOU DO FOR WIN32!!)*/
|
|
hCards = GlobalReAlloc(hCards, cCards * sizeof(CARDHEADER),GMEM_MOVEABLE);
|
|
}
|
|
else
|
|
{
|
|
MakeBlankCard();
|
|
Cards = (LPCARDHEADER) GlobalLock(hCards);
|
|
Cards[0] = CurCardHead;
|
|
GlobalUnlock(hCards);
|
|
if (CardPhone == PHONEBOOK)
|
|
{
|
|
SaveCurrentCard(iFirstCard);
|
|
/* update card list */
|
|
InitPhoneList(hListWnd, 0);
|
|
}
|
|
}
|
|
|
|
fFileDirty = TRUE;
|
|
#ifdef JAPAN //KKBUGFIX // added 07 Sep. 1992 by Hiraisi (in Japan)
|
|
// I referrd to input.c of WIN30J (BuildMessages())
|
|
// sometimes card number do not update
|
|
SetNumOfCards();
|
|
#endif
|
|
InvalidateRect(hWindow, (LPRECT)NULL, TRUE);
|
|
|
|
break;
|
|
|
|
case DUPLICATE:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (!ExpandHdrs(1))
|
|
break;
|
|
/* In phone mode, no need to save the current card
|
|
* In card mode should save the current card. */
|
|
if (CardPhone == PHONEBOOK || SaveCurrentCard(iFirstCard))
|
|
{
|
|
SetCurCard(iFirstCard);
|
|
CurCardHead.flags |= (FDIRTY + FNEW);
|
|
iFirstCard = AddCurCard();
|
|
if (CardPhone == PHONEBOOK)
|
|
{
|
|
SaveCurrentCard(iFirstCard);
|
|
GetClientRect(hIndexWnd, (LPRECT)&rect);
|
|
i = rect.bottom / CharFixHeight;
|
|
if (!i)
|
|
i = 1;
|
|
iTopCard = min(iFirstCard-(i-1)/2, (cCards - i));
|
|
if (iTopCard < 0)
|
|
iTopCard = 0;
|
|
}
|
|
#ifdef JAPAN //KKBUGFIX // added 07 Sep. 1992 by Hiraisi (in Japan)
|
|
// I referrd to input.c of WIN30J (BuildMessages())
|
|
// sometimes card number do not update
|
|
SetNumOfCards();
|
|
#endif
|
|
InvalidateRect(hWindow, (LPRECT)NULL, TRUE);
|
|
fFileDirty = TRUE;
|
|
}
|
|
CurCard.idObject = idObjectMax++;
|
|
break;
|
|
|
|
case DIAL:
|
|
if (CardPhone == PHONEBOOK)
|
|
{
|
|
SetCurCard(iFirstCard);
|
|
SaveCurrentCard(iFirstCard);
|
|
}
|
|
if (pBuf = PutUpDB(DTDIAL))
|
|
{
|
|
DoDial(pBuf);
|
|
LocalFree((HANDLE)pBuf);
|
|
}
|
|
break;
|
|
|
|
case GOTO:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (pBuf = PutUpDB(DTGOTO))
|
|
{
|
|
DoGoto(pBuf);
|
|
LocalFree((HANDLE)pBuf);
|
|
}
|
|
break;
|
|
|
|
case FINDNEXT:
|
|
if (szSearch[0])
|
|
{
|
|
fRepeatSearch = TRUE;
|
|
if (fReverse)
|
|
ReverseSearch();
|
|
else
|
|
ForwardSearch();
|
|
break;
|
|
}
|
|
|
|
case FIND:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
if (FR.lpstrFindWhat = GlobalLock(hFind))
|
|
hDlgFind = FindText((LPFINDREPLACE)&FR);
|
|
break;
|
|
|
|
case ID_USEHELP:
|
|
if(!WinHelp(hIndexWnd, NULL, HELP_HELPONHELP, (DWORD)0))
|
|
IndexOkError(EINSMEMORY);
|
|
|
|
break;
|
|
|
|
case ID_INDEX:
|
|
if(!WinHelp(hIndexWnd, szHelpFile, HELP_INDEX, (DWORD)0))
|
|
IndexOkError(EINSMEMORY);
|
|
|
|
break;
|
|
|
|
case ID_SEARCH:
|
|
if(!WinHelp(hIndexWnd, szHelpFile, HELP_PARTIALKEY, (DWORD)TEXT("")))
|
|
IndexOkError(EINSMEMORY);
|
|
|
|
break;
|
|
|
|
default:
|
|
if (fOLE)
|
|
return OleMenu(event);
|
|
break;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
TCHAR * PutUpDB(
|
|
int idb)
|
|
{
|
|
FARPROC lpdbProc;
|
|
int wResult;
|
|
|
|
DBcmd = idb;
|
|
switch(idb)
|
|
{
|
|
case DTLINKS:
|
|
lpdbProc = lpfnLinksDlg;
|
|
break;
|
|
|
|
case DTDIAL:
|
|
lpdbProc = lpfnDial;
|
|
break;
|
|
|
|
case DTPAGE:
|
|
lpdbProc = lpfnPageDlgProc;
|
|
break;
|
|
|
|
default: /* find, find next, goto. all share this one */
|
|
lpdbProc = lpDlgProc;
|
|
break;
|
|
}
|
|
|
|
wResult = DialogBox (hIndexInstance, (LPTSTR) MAKEINTRESOURCE(idb), hIndexWnd, (DLGPROC)lpdbProc);
|
|
|
|
if (wResult == -1)
|
|
{
|
|
MessageBox(NULL, NotEnoughMem, szCardfile, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
|
|
wResult = 0;
|
|
}
|
|
|
|
return((TCHAR *)wResult);
|
|
}
|
|
|
|
#if defined WIN32
|
|
int MapPtToCard(
|
|
MYPOINT pts)
|
|
#else
|
|
int MapPtToCard(
|
|
MYPOINT pt)
|
|
#endif
|
|
{
|
|
int idCard;
|
|
int xCur;
|
|
int yCur;
|
|
int i;
|
|
RECT rect;
|
|
#if defined(WIN32)
|
|
POINT pt ;
|
|
|
|
MYPOINTTOPOINT( pt, pts ) ;
|
|
#endif
|
|
|
|
yCur = yFirstCard - (cScreenCards - 1)*ySpacing;
|
|
xCur = xFirstCard + (cScreenCards - 1)* (2 * CharFixWidth);
|
|
idCard = (iFirstCard + cScreenCards-1) % cCards;
|
|
|
|
for (i = 0; i < cScreenCards; ++i)
|
|
{
|
|
SetRect((LPRECT)&rect, xCur+1, yCur+1, xCur+CardWidth-1, yCur+CharFixHeight+1);
|
|
if (PtInRect((LPRECT)&rect, pt))
|
|
return(idCard);
|
|
SetRect((LPRECT)&rect, rect.right - 2*CharFixWidth + 2, rect.top,rect.right,rect.top+CardHeight-2);
|
|
if (PtInRect((LPRECT)&rect, pt))
|
|
return(idCard);
|
|
xCur -= (2*CharFixWidth);
|
|
yCur += ySpacing;
|
|
idCard--;
|
|
if (idCard < 0)
|
|
idCard = cCards - 1;
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
DWORD OleMenu(
|
|
int event)
|
|
{
|
|
BOOL fTookAction = TRUE;
|
|
WORD fOleErrMsg;
|
|
LPOLEOBJECT lpObject;
|
|
|
|
switch (event)
|
|
{
|
|
case PLAY:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
CurCardHead.flags |= FDIRTY;
|
|
if (OleError(OleActivate(CurCard.lpObject, OLE_PLAY, TRUE, TRUE, hIndexWnd, &(CurCard.rcObject))))
|
|
{
|
|
ErrorMessage(E_FAILED_TO_LAUNCH_SERVER);
|
|
}
|
|
break;
|
|
|
|
case EDIT:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
CurCardHead.flags |= FDIRTY;
|
|
if (OleError(OleActivate(CurCard.lpObject, OLE_EDIT, TRUE, TRUE, hIndexWnd, &(CurCard.rcObject))))
|
|
{
|
|
ErrorMessage(E_FAILED_TO_LAUNCH_SERVER);
|
|
}
|
|
break;
|
|
|
|
case UPDATE:
|
|
if (OleError(OleUpdate(CurCard.lpObject)) == FOLEERROR_NOTGIVEN)
|
|
ErrorMessage(E_FAILED_TO_UPDATE);
|
|
break;
|
|
|
|
case FREEZE:
|
|
/* Make the object static (using a bogus item name) */
|
|
if (fOleErrMsg = OleError(OleObjectConvert(CurCard.lpObject,
|
|
szPStatic, lpclient, lhcdoc, szSaveName, &lpObject)))
|
|
{
|
|
if (fOleErrMsg == FOLEERROR_NOTGIVEN)
|
|
ErrorMessage(E_FAILED_TO_FREEZE);
|
|
}
|
|
else
|
|
{
|
|
WaitForObject (CurCard.lpObject);
|
|
if (OleError(OleDelete(CurCard.lpObject)) == FOLEERROR_NOTGIVEN)
|
|
ErrorMessage(E_FAILED_TO_DELETE_OBJECT);
|
|
|
|
#ifndef OLE_20
|
|
wsprintfA (szObjectName, szObjFormat, CurCard.idObject + 1);
|
|
#else
|
|
wsprintfW (szObjectName, szObjFormat, CurCard.idObject + 1);
|
|
#endif
|
|
OleRename (lpObject, szObjectName);
|
|
|
|
CurCard.lpObject = lpObject;
|
|
CurCard.otObject = STATIC;
|
|
CurCardHead.flags |= FDIRTY;
|
|
InvalidateRect (hEditWnd, NULL, TRUE);
|
|
}
|
|
break;
|
|
|
|
case LINKSDIALOG:
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
PutUpDB(DTLINKS);
|
|
break;
|
|
|
|
default:
|
|
if (event >= OLE_VERB && event <= OLE_VERBMAX)
|
|
{
|
|
if (CheckForBusyObjects())
|
|
break;
|
|
CurCardHead.flags |= FDIRTY;
|
|
|
|
if (CurCard.otObject == EMBEDDED)
|
|
PicSaveUndo(&CurCard);
|
|
if (OleError(OleActivate(CurCard.lpObject, event-OLE_VERB, TRUE, TRUE, hIndexWnd, &(CurCard.rcObject))))
|
|
{
|
|
ErrorMessage(E_FAILED_TO_LAUNCH_SERVER);
|
|
}
|
|
break;
|
|
}
|
|
|
|
fTookAction = FALSE;
|
|
break;
|
|
}
|
|
return fTookAction;
|
|
}
|
|
|
|
/*
|
|
* this and the ScrollIndexVert() do the scrolling of the Index window
|
|
* when scroll bars are present. you will note that the position returned
|
|
* by THUMB type messages gets reversed because we move the scroll box
|
|
* opposite of the direction we scroll the window. See INDEX.C in the
|
|
* WM_SIZE section to see how the scroll limits are defined.
|
|
*
|
|
* note: SB_ENDSCROLL is not supported because it returns ranges that
|
|
* are opposite of those that we work with.
|
|
*/
|
|
void ScrollIndexHorz(
|
|
HWND hWindow,
|
|
int cmd,
|
|
int pos)
|
|
{
|
|
int range_min, range_max;
|
|
int xSave = xFirstCard;
|
|
|
|
GetScrollRange(hWindow, SB_HORZ, &range_min, &range_max);
|
|
|
|
switch (cmd)
|
|
{
|
|
case SB_LINEUP:
|
|
xFirstCard += CharFixWidth;
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
xFirstCard += -CharFixWidth;
|
|
break;
|
|
|
|
case SB_PAGEUP:
|
|
xFirstCard += xCardWnd/2;
|
|
break;
|
|
|
|
case SB_PAGEDOWN:
|
|
xFirstCard += -xCardWnd/2;
|
|
break;
|
|
|
|
case SB_THUMBPOSITION:
|
|
xFirstCard = range_max - (pos - range_min);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
xFirstCard = max(range_min, min(xFirstCard, range_max));
|
|
|
|
SetScrollPos(hWindow, SB_HORZ, range_max - (xFirstCard - range_min), TRUE);
|
|
|
|
/* this moves the edit window as well */
|
|
ScrollWindow(hWindow, xFirstCard-xSave, 0, NULL, NULL);
|
|
|
|
UpdateWindow(hWindow); /* make sure painting is complete */
|
|
UpdateWindow(hEditWnd); /* make sure painting is complete */
|
|
}
|
|
|
|
void ScrollIndexVert(
|
|
HWND hWindow,
|
|
int cmd,
|
|
int pos)
|
|
{
|
|
int ySave = yFirstCard;
|
|
int range_min, range_max;
|
|
|
|
GetScrollRange(hWindow, SB_VERT, &range_min, &range_max);
|
|
|
|
switch (cmd)
|
|
{
|
|
case SB_LINEUP:
|
|
yFirstCard += CharFixHeight;
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
yFirstCard += -CharFixHeight;
|
|
break;
|
|
|
|
case SB_PAGEUP:
|
|
yFirstCard += yCardWnd/2;
|
|
break;
|
|
|
|
case SB_PAGEDOWN:
|
|
yFirstCard += -yCardWnd/2;
|
|
break;
|
|
|
|
case SB_THUMBPOSITION:
|
|
yFirstCard = range_max - (pos - range_min);
|
|
break;
|
|
}
|
|
|
|
yFirstCard = max(range_min, min(yFirstCard, range_max));
|
|
|
|
SetScrollPos(hWindow, SB_VERT, range_max - (yFirstCard - range_min), TRUE);
|
|
|
|
/* this moves the edit window as well */
|
|
ScrollWindow(hWindow, 0, yFirstCard-ySave, NULL, NULL);
|
|
|
|
UpdateWindow(hWindow); /* make sure painting is complete */
|
|
UpdateWindow(hEditWnd); /* make sure painting is complete */
|
|
}
|
|
|
|
void MenuFileNew (void)
|
|
{
|
|
LPCARDHEADER Cards;
|
|
#ifndef OLE_20
|
|
CHAR aszCardfile[60];
|
|
CHAR aszUntitled[60];
|
|
#endif
|
|
|
|
if (fNoTempFile)
|
|
return;
|
|
if (!MaybeSaveFile (FALSE))
|
|
return;
|
|
if (lhcdoc) /* Wipe out the client document */
|
|
ReleaseClientDoc();
|
|
SetCursor (hWaitCurs);
|
|
*szText = (TCHAR) 0;
|
|
CurIFile[0] = (TCHAR) 0;
|
|
if (fhMain != INVALID_HANDLE_VALUE)
|
|
MyCloseFile (fhMain);
|
|
fhMain = INVALID_HANDLE_VALUE;
|
|
szSearch[0] = (TCHAR) 0;
|
|
SetCaption ();
|
|
Fdelete (TempFile);
|
|
MakeTempFile ();
|
|
/* shrinking or leaving the same size, so this should always work */
|
|
GlobalReAlloc (hCards, sizeof(CARDHEADER),GMEM_MOVEABLE);
|
|
cCards = 1;
|
|
iFirstCard = 0;
|
|
iTopCard = 0;
|
|
idObjectMax = 0;
|
|
MakeBlankCard ();
|
|
Cards = (LPCARDHEADER) GlobalLock (hCards);
|
|
Cards[0] = CurCardHead;
|
|
GlobalUnlock (hCards);
|
|
|
|
InvalidateRect (CardPhone == CCARDFILE ? hCardWnd : hListWnd, NULL, TRUE);
|
|
|
|
SetCursor (hArrowCurs);
|
|
|
|
/* Reset the ListView box. */
|
|
InitPhoneList(hListWnd, iFirstCard);
|
|
SetNumOfCards();
|
|
|
|
fFileDirty = FALSE;
|
|
|
|
/* Register "Untitled" */
|
|
if (lhcdoc)
|
|
ReleaseClientDoc();
|
|
|
|
#ifndef OLE_20
|
|
WideCharToMultiByte (CP_ACP, 0, szCardfile, -1, aszCardfile, 60, NULL, NULL);
|
|
WideCharToMultiByte (CP_ACP, 0, szUntitled, -1, aszUntitled, 60, NULL, NULL);
|
|
|
|
if (fOLE && OLE_OK != OleRegisterClientDoc (aszCardfile, aszUntitled, 0L, &lhcdoc))
|
|
#else
|
|
if (fOLE && OLE_OK != OleRegisterClientDoc (szCardfile, szUntitled, 0L, &lhcdoc))
|
|
#endif
|
|
{
|
|
ErrorMessage (W_FAILED_TO_NOTIFY);
|
|
lhcdoc = (LHCLIENTDOC) NULL; // lhb tracks
|
|
}
|
|
}
|
|
|
|
void MakeTempFile (void)
|
|
{
|
|
TCHAR szTemp[PATHMAX];
|
|
HANDLE fh;
|
|
|
|
|
|
fNoTempFile = FALSE;
|
|
|
|
GetTempPath (PATHMAX - 1, szTemp);
|
|
if (GetTempFileName (szTemp, szFileExtension, 0, TempFile))
|
|
{
|
|
if ((fh = MyOpenFile (TempFile, NULL,
|
|
OF_SHARE_EXCLUSIVE | OF_CREATE)) != INVALID_HANDLE_VALUE)
|
|
{
|
|
MyCloseFile (fh);
|
|
return;
|
|
}
|
|
}
|
|
IndexOkError (ECANTMAKETEMP);
|
|
fNoTempFile = TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* set up the list box for the PHONEBOOK mode
|
|
*/
|
|
void InitPhoneList(
|
|
HWND hWindow,
|
|
int iStartCard)
|
|
{
|
|
LPCARDHEADER Cards;
|
|
int i;
|
|
|
|
if (CardPhone == CCARDFILE)
|
|
return;
|
|
|
|
SendMessage (hWindow, LB_RESETCONTENT, 0, 0L); /* clear any old data */
|
|
SendMessage (hWindow, WM_SETREDRAW, FALSE, 0L);
|
|
Cards = (LPCARDHEADER) GlobalLock(hCards);
|
|
|
|
for (i = 0; i < cCards; i++)
|
|
SendMessage(hWindow, LB_INSERTSTRING, i, (LONG)&Cards[i].line);
|
|
|
|
GlobalUnlock(hCards);
|
|
|
|
SendMessage(hWindow, WM_SETREDRAW, TRUE, 0L);
|
|
SendMessage(hWindow, LB_SETCURSEL, iStartCard, 0L);
|
|
}
|
|
|
|
/* return TRUE if there are busy OLE objects, FALSE otherwise */
|
|
int CheckForBusyObjects(
|
|
void)
|
|
{
|
|
BOOL fBusy = FALSE;
|
|
LPOLEOBJECT lpObject = NULL;
|
|
|
|
if (!fOLE) /* for safety */
|
|
return FALSE;
|
|
|
|
while ((OleEnumObjects(lhcdoc, &lpObject) == OLE_OK) && lpObject
|
|
&& lpObject != lpObjectUndo)
|
|
fBusy |= DisplayBusyMessage(lpObject);
|
|
|
|
return fBusy;
|
|
}
|
|
|
|
NOEXPORT BOOL NEAR DisplayBusyMessage (LPOLEOBJECT lpObject)
|
|
{
|
|
LONG objType;
|
|
BOOL fBusy = FALSE;
|
|
HANDLE hLink;
|
|
LPTSTR lpLink;
|
|
PTCHAR pWLink; // unicode version of lpLink
|
|
|
|
if ((OleQueryType (lpObject, &objType) == OLE_OK) &&
|
|
(objType != OT_STATIC) &&
|
|
(OleQueryReleaseStatus(lpObject) == OLE_BUSY))
|
|
{
|
|
TCHAR szStr[300], szMsg[300];
|
|
|
|
fBusy = TRUE;
|
|
LoadString (hIndexInstance, W_FREEBUSYSERVER, szStr, CharSizeOf(szStr));
|
|
if(OleGetData( lpObject,
|
|
(OLECLIPFORMAT) (objType == OT_LINK ? vcfLink : vcfOwnerLink),
|
|
&hLink) == OLE_OK
|
|
&& (lpLink = (LPTSTR) GlobalLock (hLink))
|
|
&& ( pWLink = Ole2Native( lpLink,1 ) ) )
|
|
{
|
|
wsprintf (szMsg, szStr, pWLink);
|
|
GlobalUnlock (hLink);
|
|
LocalFree( pWLink );
|
|
}
|
|
else
|
|
wsprintf (szMsg, szStr, TEXT(""));
|
|
MessageBox (hwndError, szMsg, szCardfile, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
return fBusy;
|
|
}
|
|
|