NT4/private/windows/win4help/winhelp/hdlgbkmk.c
2020-09-30 17:12:29 +02:00

746 lines
16 KiB
C

/*****************************************************************************
* *
* HDLGBKMK.C *
* *
* Copyright (C) Microsoft Corporation 1990. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* *
* Implements UI dependent portion of creating and displaying bookmarks. *
*
*****************************************************************************/
#include "help.h"
#include "inc\bookmark.h"
#include "inc\helpids.h"
INLINE static void STDCALL ClearBMMenu(HMENU hMenu);
static INLINE int STDCALL CountBookmarks(BMK bmk);
BOOL STDCALL UpdBMMenu( HDE, HMENU );
static int STDCALL FillBMListBox(HDE, HWND);
static BOOL STDCALL FIstoTerminate(int err);
static BOOL STDCALL DispBMKError(HWND hwnd);
static int STDCALL InitBMDialog(HWND hwndDlg);
/*****************************************************************************
* *
* Prototypes *
* *
*****************************************************************************/
void DisplayConversionMessage(HWND);
/*******************
-
- Name: BookmarkDlg
*
* Purpose: Dialog proc for viewing and using bookmarks
*
* Arguments:
*
* Returns:
*
* The call to EndDialog() will cause the calling function's
* DialogBox() call to return one more than the index of the
* found topic. This allows Cancel to return 0, the index's
* index. DialogBox() returns -1 if it fails.
*
* Method:
*
******************/
#ifndef NO_PRAGMAS
#pragma data_seg(".text", "CODE")
#endif
static DWORD aBookmarkIds[] = {
DLGEDIT, IDH_BOOK_NAME,
DLGLISTBOX, IDH_BOOK_LIST,
DLGDELETE, IDH_BOOK_DELETE,
0, 0
};
#ifndef NO_PRAGMAS
#pragma data_seg()
#endif
DLGRET BookMarkDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
int iT;
char rgchScratch[128];
switch( msg ){
case WM_HELP: // F1
OnF1Help(lParam, aBookmarkIds);
return TRUE;
case WM_CONTEXTMENU: // right mouse click
OnContextMenu(wParam, aBookmarkIds);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case DLGLISTBOX:
if (HIWORD(wParam) != LBN_DBLCLK)
return( FALSE );
// Fall through is intentional
case IDOK:
iT = SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_GETCURSEL, 0, 0L);
if (iT < 0) {
// error
iT = 0; // index topic
}
else{
if (SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_GETTEXT, iT,
(long) ((LPSTR) rgchScratch)) == LB_ERR) {
ASSERT(FALSE);
iT = 0; // index topic
}
else{
iT = GetBkMkIdx(HdeGetEnv(), rgchScratch);
if (iT < 0)
EndDialog(hwndDlg, 0);
//iT = 0;
}
}
EndDialog(hwndDlg, iT + 1); // correct after discussion with Rob
return(TRUE);
case DLGFOCUS1:
SetFocus(GetDlgItem(hwndDlg, DLGLISTBOX));
break;
case IDCANCEL:
EndDialog(hwndDlg, 0);
break;
default:
break;
}
break;
case WM_ACTIVATEAPP:
// if ( wParam )
// BringWindowToTop( ahwnd[iCurWindow].hwndParent );
if ( wParam == 0 )
{
CloseAndCleanUpBMFS();
}
else
{
// repaint the dialog box with latest bookmark list.
if ( hfsBM == NULL )
OpenBMFS();
// NOTE: FillBMListBox() displays error messages.
iT = FillBMListBox(HdeGetEnv(), GetDlgItem(hwndDlg, DLGLISTBOX));
// Select first item in list
SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_SETCURSEL, 0, 0L);
if (iT < 0)
return(TRUE);
SetFocus(GetDlgItem(hwndDlg, DLGLISTBOX));
}
break;
// REVIEW: who sends us MSG_ERROR?? 29-Jul-1994 [ralphw]
case MSG_ERROR:
ErrorHwnd(hwndDlg, wParam, wERRA_RETURN, wParam);
if (FIstoTerminate(wParam)) {
EndDialog( hwndDlg, FALSE );
break;
}
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
return(FALSE);
case WM_INITDIALOG:
ChangeDlgFont(hwndDlg);
if (hfsBM == NULL) { // can happen if called through api
OpenBMFS();
if (IsErrorBMFS()) {
DispBMKError( hwndDlg );
}
}
iT = FillBMListBox( HdeGetEnv(), GetDlgItem( hwndDlg, DLGLISTBOX ) );
/* If the list box is empty or there was an error filling it,
** disable the OK button.
*/
EnableWindow( GetDlgItem( hwndDlg, IDOK ), iT > 0 );
SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_SETCURSEL, 0, 0L);
if(iT < 0){
/* error */
return( TRUE );
}
SetFocus( GetDlgItem( hwndDlg, DLGLISTBOX ) );
#if 0
if ( iT )
SendMessage(GetDlgItem( hwndDlg, DLGLISTBOX), LB_SETCURSEL, 0, 0L );
#endif
break;
default:
return( FALSE );
}
return( FALSE );
}
/*******************
**
** Name: DefineDlg
**
** Purpose: Dialog proc for defining bookmarks
**
** Arguments:
**
** Returns:
**
**
** Method:
**
*******************/
DLGRET DefineDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
char rgchTitle[BMTITLESIZE+1];
LPSTR pszName;
int iT;
switch(msg) {
case WM_COMMAND:
switch(LOWORD(wParam)) {
case DLGLISTBOX:
if (HIWORD(wParam) == LBN_SELCHANGE) {
iT = SendDlgItemMessage(hwndDlg, DLGLISTBOX,
LB_GETCURSEL, 0, 0L);
if (iT == LB_ERR)
break;
if (SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_GETTEXT,
iT, (LONG) ((LPSTR) rgchTitle)) == LB_ERR)
break;
SetDlgItemText(hwndDlg, DLGEDIT, rgchTitle);
break;
}
else if (HIWORD(wParam) == LBN_SETFOCUS) {
/* When tabbing to the dialog box, set focus
** to the first item (unless there's already a selection).
*/
iT = SendDlgItemMessage(hwndDlg, DLGLISTBOX,
LB_GETCURSEL, 0, 0L );
if (iT != LB_ERR)
break;
iT = SendDlgItemMessage( hwndDlg, DLGLISTBOX,
LB_SETCURSEL, 0, 0L );
/* Huh???? We're not getting a LBN_SELCHANGE message.
** OK, just copy the code above.
*/
if (iT == LB_ERR)
break;
if (SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_GETTEXT,
0, (LONG) ((LPSTR) rgchTitle)) == LB_ERR)
break;
SetDlgItemText(hwndDlg, DLGEDIT, rgchTitle);
break;
}
else if (HIWORD(wParam) != LBN_DBLCLK)
break;
// fall through intentional
case IDOK:
GetDlgItemText(hwndDlg, DLGEDIT, rgchTitle, BMTITLESIZE + 1);
pszName = FirstNonSpace(rgchTitle);
if (*pszName != '\0') {
if (InsertBkMk(HdeGetEnv(), pszName) == iBMKFailure) {
DispBMKError(hwndDlg);
break;
}
}
EndDialog(hwndDlg, FALSE);
break;
case DLGDELETE:
GetDlgItemText(hwndDlg, DLGEDIT, rgchTitle, BMTITLESIZE + 1);
if (DeleteBkMk(HdeGetEnv(), rgchTitle) == iBMKFailure) {
DispBMKError(hwndDlg);
break;
}
else {
iT = FillBMListBox(HdeGetEnv(), GetDlgItem(hwndDlg, DLGLISTBOX));
if (iT < 0) {
break;
}
else if (!iT) {
EnableWindow(GetDlgItem(hwndDlg, DLGDELETE), FALSE);
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
rgchTitle[0] = '\0';
}
else {
SendMessage(GetDlgItem(hwndDlg, DLGLISTBOX), LB_SETCURSEL, 0, 0L);
if (SendDlgItemMessage(hwndDlg, DLGLISTBOX, LB_GETTEXT,
0, (LONG) ((LPSTR) rgchTitle)) == LB_ERR)
iT = 0;
if (!iT) { // error or no bookmark present
rgchTitle[0] = '\0';
}
}
SetDlgItemText(hwndDlg, DLGEDIT, rgchTitle);
return(FALSE);
}
break;
case DLGFOCUS1:
SetFocus(GetDlgItem(hwndDlg, DLGLISTBOX));
break;
case DLGFOCUS2:
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
break;
case IDCANCEL:
EndDialog(hwndDlg, TRUE);
break;
default:
break;
}
break;
case MSG_ERROR:
ErrorHwnd(hwndDlg, wParam, wERRA_RETURN, wParam);
if (FIstoTerminate(wParam) || (GetBMKError() & iBMKReadOnly)) {
EndDialog(hwndDlg, FALSE);
break;
}
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
return(FALSE);
case WM_ACTIVATEAPP:
if (wParam) {
if (hfsBM == NULL)
OpenBMFS();
/*
* NOTE: If InitBMDialog() returns -1, it's already displayed the
* error message box (inside FillBMListBox().)
*/
iT = InitBMDialog(hwndDlg);
if (iT < 0)
return(TRUE);
else if (!iT) // disable Delete item
EnableWindow(GetDlgItem(hwndDlg, DLGDELETE), FALSE);
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
SendMessage(GetDlgItem(hwndDlg, DLGEDIT), EM_SETSEL, 0, -1);
}
else
CloseAndCleanUpBMFS();
break;
case WM_HELP: // F1
OnF1Help(lParam, aBookmarkIds);
return TRUE;
case WM_CONTEXTMENU: // right mouse click
OnContextMenu(wParam, aBookmarkIds);
return TRUE;
case WM_INITDIALOG:
ChangeDlgFont(hwndDlg);
if (hfsBM == NULL) { // can happen if called through api
OpenBMFS();
/* REVIEW: can the following test be simplified to
** REVIEW: "if ( GetBMKError() )" ?
*/
if (IsErrorBMFS() || (GetBMKError() & iBMKReadOnly))
DispBMKError(hwndDlg);
}
else if (GetBMKError() & iBMKReadOnly)
DispBMKError(hwndDlg);
// PlaceDlg( hwndDlg ); // Place the dialog if required
iT = InitBMDialog(hwndDlg);
if(iT < 0)
return( TRUE );
else if (!iT) // disable Delete item
EnableWindow(GetDlgItem(hwndDlg, DLGDELETE), FALSE);
#if 0
else /* select the first item in the list box */
SendMessage(GetDlgItem( hwndDlg, DLGLISTBOX), LB_SETCURSEL, 0, 0L );
#endif
SetFocus(GetDlgItem(hwndDlg, DLGEDIT));
SendMessage(GetDlgItem(hwndDlg, DLGEDIT), EM_SETSEL, 0, -1);
// fall through is intentional
default:
return(FALSE);
}
return(TRUE);
}
/*******************
-
- Name: FillBMListBox( HDE, HWND)
*
* Purpose: Fills the BM Listbox with BM entries.
*
* Arguments:
* 1. HDE - Handle to Display ENvironment.
* 2. HWND - Handle to the ListBox window. The parent of this
* listbox must be able to handle the MSG_ERROR message.
*
* Returns:
* -1 if error.
* -2 if Adding to the list box fails.
* else the count of bookmarks in the BM list
* Nothing
*
* Method:
* It checks if the BM List ia already loaded into memory else it loads.
* Then it fills the listbox by walking though the BM list sequentially i.e
* in the order of entry.
*
******************/
static int STDCALL FillBMListBox(HDE hde, HWND hWnd)
{
BMINFO BkMk;
char rgchTitle[BMTITLESIZE+1];
UINT wWalk = 0;
int iIdx;
int wT;
QDE qde;
int cBookmarks = 0;
RC rc;
ASSERT(hWnd != NULL);
qde = QdeFromGh(hde);
if (
(rc = RcLoadBookmark(qde)) != rcSuccess)
{
DispBMKError(GetParent(hWnd));
return(-1);
}
SendMessage(hWnd, LB_RESETCONTENT, 0, 0L);
if (QDE_BMK(qde)) {
cBookmarks = CountBookmarks(QDE_BMK(qde));
BkMk.qTitle = rgchTitle;
BkMk.iSizeTitle = BMTITLESIZE;
SendMessage(hWnd, WM_SETREDRAW, FALSE, 0L);
for (wT = 0; wT < cBookmarks; wT++) {
if (GetBkMkNext(qde, &BkMk, wWalk) > 0) {
if (wT == cBookmarks - 1)
SendMessage(hWnd, WM_SETREDRAW, TRUE, 0L);
iIdx = SendMessage(hWnd, LB_ADDSTRING, 0,
(LPARAM)(LPVOID) BkMk.qTitle);
if (iIdx == LB_ERR || iIdx == LB_ERRSPACE) {
// Give error
cBookmarks = -2;
break;
}
wWalk = BKMKSEQNEXT;
}
else {
ASSERT(FALSE);
cBookmarks = 0;
break;
}
}
}
return cBookmarks;
}
/*******************
-
- Name: ClearBMMenu
*
* Purpose: Cleares BM SubMenu
*
* Arguments:
* 1. HMENU - Handle to BM Sub Menu
*
* Returns:
* Nothing
*
* Method:
*
******************/
INLINE static void STDCALL ClearBMMenu(HMENU hMenu)
{
while(DeleteMenu(hMenu, 1, MF_BYPOSITION));
}
/*******************
-
- Name: UpdBMMenu
*
* Purpose: Updates the BM Menu
*
* Arguments:
* 1. HDE - Handle to Display Environment
* 2. HMENU - Handle to BM Sub Menu
*
* Returns:
* returns TRUE if successful
* else FALSE
*
* Method:
* Reads the BM List from the file system if not already loaded. It updates
* BM Menu with titles of first ten bookamrks entered. If the count of
* bookmarks are more than 10, it displays 'More' to evoke the BM dialog.
*
******************/
BOOL STDCALL UpdBMMenu(HDE hde, HMENU hMenu)
{
QDE qde;
int iRetVal = TRUE;
int cBookmarks;
BMINFO BkMk;
char rgchTitle[BMTITLESIZE+4];
int wT, wWalk = 0;
RC rc = rcSuccess;
qde = QdeFromGh(hde);
ClearBMMenu(hMenu);
if (
( rc = RcLoadBookmark( qde ) ) == rcFailure )
{
iRetVal = FALSE;
DispBMKError(ahwnd[iCurWindow].hwndParent);
iRetVal = FALSE ;
}
else {
if (QDE_BMK(qde))
cBookmarks = CountBookmarks(QDE_BMK(qde));
else
iRetVal = FALSE;
}
if (
(GetBMKError() & iBMKReadOnly))
{
EnableMenuItem( hMenu, HLPMENUBOOKMARKDEFINE, MF_BYCOMMAND | MF_GRAYED);
}
else
EnableMenuItem( hMenu, HLPMENUBOOKMARKDEFINE, MF_BYCOMMAND | MF_ENABLED );
if (iRetVal && cBookmarks) {
BkMk.qTitle = rgchTitle + 3;
BkMk.iSizeTitle = BMTITLESIZE+1;
// update the menu
rgchTitle[0] = ACCESS_KEY;
rgchTitle[2] = ' ';
for (wT = 0; wT < cBookmarks && wT < BMMOREPOS; wT++) {
if (GetBkMkNext(qde, &BkMk, wWalk) > 0) {
rgchTitle[1] = (char) (wT + '1');
AppendMenu(hMenu, MF_STRING, MNUBOOKMARK1 + wT, (LPSTR) rgchTitle);
}
else
break;
wWalk = BKMKSEQNEXT;
}
if (wT == BMMOREPOS && cBookmarks > BMMOREPOS && iRetVal) {
// Show More item
AppendMenu(hMenu, MF_SEPARATOR, 0xffff, NULL);
AppendMenu(hMenu, MF_STRING, HLPMENUBOOKMARKMORE,
(LPSTR) GetStringResource(sidMore));
}
}
return(iRetVal);
}
/*******************
-
- Name: InitBMDialog(HWND)
*
* Purpose: Initialises the Bookmark and Define dialogs.
*
* Arguments:
* 1. HWND - Handle to dialog window
*
* Returns:
* returns -1 if errorr or
* the count of bookmarks
*
* Method:
*
******************/
static int STDCALL InitBMDialog(HWND hwndDlg)
{
char szTitle[MAX_TOPIC_TITLE];
int iRetVal;
iRetVal = FillBMListBox(HdeGetEnv(), GetDlgItem(hwndDlg, DLGLISTBOX));
if (iRetVal >= 0) {
GetCurrentTitleQde(QdeFromGh(HdeGetEnv()), szTitle, sizeof(szTitle));
SendDlgItemMessage(hwndDlg, DLGEDIT, EM_LIMITTEXT, BMTITLESIZE, 0L);
SetDlgItemText(hwndDlg, DLGEDIT, szTitle);
}
return (iRetVal);
}
/***************************************************************************
*
- Name: DispBMKError(hwnd)
-
* Purpose: If there is a bookmark error, display it.
*
* Arguments:
*
* Returns: TRUE if the bookmark file is unwritable or bogus ??
*
* Globals Used:
*
* +++
*
* Notes: The bookmark error stuff is very fragile.
*
***************************************************************************/
static BOOL STDCALL DispBMKError(HWND hwnd)
{
BOOL fReturn = FALSE;
int iBMKErr = GetBMKError(), err=-1;
/*
Test these BEFORE testing iBMKFSError because the latter is the
one that's tested in various places in the code and in some cases
it is set along with another flag.
*/
if (iBMKErr & (iBMKFSReadWrite | iBMKCorrupted)) {
err = wERRS_BMKCorrupted;
fReturn = TRUE;
}
else if (iBMKErr & iBMKOom) {
err = wERRS_OOM;
fReturn = TRUE;
}
else if (iBMKErr & iBMKDiskFull) {
err = wERRS_DiskFull;
fReturn = TRUE;
}
else if (iBMKErr & iBMKFSError) {
err = wERRS_BMKFSError;
fReturn = TRUE;
}
else if (iBMKErr & iBMKDup) {
err = wERRS_BMKDUP;
}
else if (iBMKErr & iBMKDelErr) {
err = wERRS_BMKDEL;
}
else if (iBMKErr & iBMKReadOnly) {
err = wERRS_BMKReadOnly;
fReturn = TRUE;
}
if (err == -1)
return( TRUE );
ResetBMKError();
PostMessage( hwnd, MSG_ERROR, err, (long)wERRA_RETURN);
return( fReturn );
}
static BOOL STDCALL FIstoTerminate(int err)
{
if ( err == wERRS_OOM || err == wERRS_BMKFSError ||
err == wERRS_BMKCorrupted || err == wERRS_DiskFull )
return( TRUE );
return( FALSE );
}
/***************************************************************************
*
- Name: CloseAndCleanUpBMFS()
-
* Purpose: closes the file bookmark file system and releases the
* the bookmark data structure.
*
* Arguments:
*
* Returns: none
*
* Globals Used:
*
* +++
*
* Notes:
*
***************************************************************************/
void STDCALL CloseAndCleanUpBMFS()
{
HDE hde;
QDE qde;
if (hfsBM != NULL) {
RcCloseHfs(hfsBM);
hfsBM = NULL;
hde = HdeGetEnv();
if (hde != NULL) {
// release bookmarks from memory.
qde = QdeFromGh(hde);
if (QDE_BMK(qde)) {
FreeGh(QDE_BMK(qde));
QDE_BMK(qde) = NULL;
}
}
}
}
/***************************************************************************\
*
- Function: CountBookmarks( bmk )
-
* Purpose: Return the count of bookmarks for the current helpfile.
*
* ASSUMES
* args IN: bmk - the current bmk
*
* PROMISES
* returns: number of bookmarks or 0 on failure
*
\***************************************************************************/
static INLINE int STDCALL CountBookmarks(BMK bmk)
{
return (int) ((QBMKHDR_RAM) PtrFromGh(bmk))->cBookmarks;
}