770 lines
18 KiB
C
770 lines
18 KiB
C
/*****************************************************************************
|
|
* *
|
|
* HISTORY.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1990. *
|
|
* All Rights reserved. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* App side of the History list. *
|
|
* Some of these functions are called by Nav. This may change some day. *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
#include "help.h"
|
|
#pragma hdrstop
|
|
|
|
#include "inc\hwproc.h"
|
|
#include "inc\winclass.h"
|
|
|
|
#define PATH_LB 1 // Child window IDs
|
|
#define PATH_STATIC 2
|
|
|
|
#define PREPEND TRUE
|
|
#define STRIP FALSE
|
|
|
|
// Since we can't say "tlp = tlpNil", we let this suffice.
|
|
|
|
#define FIsNilQtlp(qtlp) (vaNil == (qtlp) ->va.dword)
|
|
#define SetNilQtlp(qtlp) ((qtlp) ->va.dword = vaNil)
|
|
|
|
// History stack element
|
|
|
|
typedef struct {
|
|
TLP tlp;
|
|
WORD ifm;
|
|
VA va; // for duplicate removal
|
|
CTX ctx; // context number (if non-zero)
|
|
HLOCAL hTitle;
|
|
} HSE;
|
|
|
|
HSTACK hstackHistory; // also used by hwproc.c for toggling
|
|
static BOOL fHistoryInit;
|
|
static LRESULT cSavedMax;
|
|
static BOOL fHistoryMagic;
|
|
static WRECT rcHist;
|
|
static int iTopic;
|
|
|
|
INLINE void static STDCALL FillPathLB(void);
|
|
INLINE static RC STDCALL RcInsertTopic(PCSTR psz);
|
|
static RC STDCALL RcModifyString(int i, PCSTR pszFileRoot, BOOL fAdd);
|
|
INLINE RC static STDCALL RcMungeList(int, int);
|
|
void static STDCALL SetPathRedraw(BOOL);
|
|
|
|
void STDCALL FreeTitle(QV); // stack callback function
|
|
|
|
|
|
/* FUNCTIONS */
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: HistoryProc( hWnd, msg, p1, p2 )
|
|
-
|
|
* Purpose: History Window proc.
|
|
*
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LRESULT EXPORT HistoryProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TLPHELP tlphelp;
|
|
FM fm;
|
|
|
|
switch(msg) {
|
|
#if defined(BIDI_MULT) // jgross
|
|
case WM_LANGUAGE:
|
|
DefWindowProc(hWnd, imsz, wParam, lParam | LANG_NO_PASSON);
|
|
if (wParam != -1) {
|
|
extern BOOL RtoL;
|
|
|
|
RtoL = (wParam == Arabic) || (wParam == Hebrew);
|
|
SendMessage(hwndList, LB_SETALIGN, RtoL ? LBS_RTL : 0, NULL);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case WM_INITDIALOG:
|
|
ASSERT(hfontDefault);
|
|
SendMessage(hwndList, WM_SETFONT, (WPARAM) hfontDefault, FALSE);
|
|
break;
|
|
|
|
case HWM_LBTWIDDLE:
|
|
// We mess with the listbox selection when the user selects the
|
|
// history button, but not if they just mouse click on the history
|
|
// window. This scheme avoids the need to use the WM_MOUSEACTIVATE
|
|
// message.
|
|
SendMessage(hwndList, LB_SETCURSEL, 1, 0L);
|
|
SendMessage(hwndList, LB_SETTOPINDEX, 0, 0L);
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
if (wParam == WA_INACTIVE)
|
|
SendMessage(hwndList, LB_SETCURSEL, (WPARAM) -1, 0L);
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
if (wParam != SIZEICONIC)
|
|
MoveWindow(hwndList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == PATH_LB) {
|
|
switch(HIWORD(wParam)) {
|
|
case LBN_DBLCLK:
|
|
iTopic = (int) SendMessage(hwndList, LB_GETCURSEL, 0, 0);
|
|
|
|
if (iTopic == LB_ERR)
|
|
break;
|
|
|
|
RcGetIthTopic(iTopic, &tlphelp.tlp, &fm);
|
|
tlphelp.cb = sizeof(TLPHELP);
|
|
|
|
fHistoryMagic = TRUE;
|
|
if (!FWinHelp(PszFromGh(fm), cmdTLP, (DWORD) &tlphelp))
|
|
Error(wERRS_OOM, wERRA_RETURN);
|
|
|
|
break;
|
|
|
|
default:
|
|
goto defwinproc;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_VKEYTOITEM:
|
|
if (LOWORD(wParam) == VK_RETURN)
|
|
PostMessage(hwnd, WM_COMMAND, MAKELONG(PATH_LB, LBN_DBLCLK), 0);
|
|
else if (LOWORD(wParam) == VK_ESCAPE)
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
|
goto defwinproc;
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
SetFocus(hwndList);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
hwndHistory = NULL;
|
|
hwndList = NULL;
|
|
WriteWinPosHwnd(hwnd, FALSE, WCH_HISTORY);
|
|
break;
|
|
|
|
default:
|
|
defwinproc:
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: FCallPath( hIns )
|
|
-
|
|
* Purpose: Create path windows and initialize listbox list.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: hIns - instance handle
|
|
*
|
|
* globals IN: rcHist.left, rcHist.top, rcHist.right, rcHist.bottom
|
|
* fHistoryInit
|
|
*
|
|
* state IN:
|
|
*
|
|
* PROMISES
|
|
* returns: TRUE on success; FALSE on failure (OOM is only case)
|
|
*
|
|
* globals OUT: hwndHistory, hwndList
|
|
*
|
|
* state OUT:
|
|
*
|
|
* Side Effects:
|
|
*
|
|
* Bugs: Move caption to string table.
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL STDCALL FCallPath(void)
|
|
{
|
|
BOOL fInitialized = FALSE;
|
|
|
|
if (!fInitialized) {
|
|
ReadWinRect(&rcHist, WCH_HISTORY, NULL);
|
|
fInitialized = TRUE;
|
|
}
|
|
|
|
// Create Path window
|
|
|
|
hwndHistory = CreateWindow(pchPath,
|
|
GetStringResource(sidHistoryCaption),
|
|
WS_CAPTION | WS_THICKFRAME | WS_SYSMENU,
|
|
rcHist.left, rcHist.top, rcHist.cx, rcHist.cy,
|
|
ahwnd[MAIN_HWND].hwndParent,
|
|
NULL, // window menu handle
|
|
hInsNow, // instance handle
|
|
NULL); // create parameters
|
|
|
|
if (hwndHistory == NULL)
|
|
return FALSE;
|
|
|
|
// Create the path Listbox.
|
|
|
|
hwndList = CreateWindow((LPSTR) WC_LISTBOX,
|
|
NULL, // window caption
|
|
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
|
|
LBS_NOTIFY | LBS_NOINTEGRALHEIGHT |
|
|
LBS_WANTKEYBOARDINPUT,
|
|
0, 0, 0, 0,
|
|
hwndHistory, (HMENU) PATH_LB, hInsNow, NULL);
|
|
|
|
if (!hwndList) {
|
|
DestroyWindow(hwndHistory);
|
|
return FALSE;
|
|
}
|
|
|
|
#if defined(BIDI_MULT) // jgross - determine if vert scroll bars go on
|
|
// the left or right
|
|
{
|
|
extern BOOL IsSetup, RtoL;
|
|
|
|
if (IsSetup)
|
|
EnableMenuItem(GetSystemMenu(hwndPath, FALSE),
|
|
8, MF_BYPOSITION | MF_GRAYED);
|
|
|
|
MakeScrollBarsRtoL(hwndList, RtoL, TRUE);
|
|
SendMessage(hwndList, LB_SETALIGN, RtoL ? LBS_RTL : 0, NULL);
|
|
}
|
|
#endif
|
|
|
|
// Use a small font in the list box
|
|
|
|
SendMessage(hwndList, WM_SETFONT, (WPARAM) HfontGetSmallSysFont(), FALSE);
|
|
|
|
FillPathLB();
|
|
|
|
// Show the Path window.
|
|
|
|
ShowWindow(hwndHistory, SW_SHOW);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcHistoryInit( c )
|
|
-
|
|
* Purpose: Initialize History list
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: c - stack size
|
|
*
|
|
* globals IN: hstackHistory - our HSTACK
|
|
* pszCaption - the name of the win.ini help section
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess - successful initialization
|
|
* rcOutOfMemory - out of memory
|
|
*
|
|
* globals OUT: path - initialized path struct
|
|
* fHistoryInit - TRUE on success
|
|
* fDisplayTopicOnce -
|
|
*
|
|
* Notes: someday we may want to save path in a file (WINHELP.BMK?)
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcHistoryInit(int c)
|
|
{
|
|
ASSERT(!fHistoryInit);
|
|
|
|
cSavedMax = (c <= 0) ? DEFAULT_HISTORY : c;
|
|
|
|
if (RcInitStack(&hstackHistory, cSavedMax, sizeof(HSE), FreeTitle) ==
|
|
rcSuccess)
|
|
fHistoryInit = TRUE;
|
|
|
|
// We return success on failure so we don't try again
|
|
|
|
return rcSuccess;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcHistoryPush( tlpOld, va, pszTitle, fm )
|
|
-
|
|
* Purpose: Push a new topic onto path stack. This happens when we
|
|
* leave a topic (i.e. current topic not on path list.)
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: tlpOld - TLP of old topic (so we can update it)
|
|
* va - va of first FCL in topic (for unique model)
|
|
* pszTitle - topic title
|
|
* fm - fm of helpfile
|
|
*
|
|
* globals IN: szSearchNoTitle -
|
|
* fHistoryInit - if FALSE, exit with error code
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess -
|
|
* rcOutOfMemory -
|
|
* rcFailure - history stack wasn't initalized successfully
|
|
*
|
|
* globals OUT: path
|
|
*
|
|
* state OUT: FMT unlocked
|
|
*
|
|
* +++
|
|
*
|
|
* Method: If the TLP of the topic we're leaving is valid, this means
|
|
* a Push has failed previously. Otherwise, update it with
|
|
* tlpOld.
|
|
* Do all the things that can fail if OOM: get title, ifm,
|
|
* add string to listbox, munge other strings in listbox.
|
|
* If any of these fail, abort.
|
|
* If all this succeeded, push new info (va, pszTitle, ifm)
|
|
* onto stack, leaving tlp invalid.
|
|
*
|
|
* Notes: Might want to optimize by storing all the info in one hse.
|
|
* The cost would be that RcGetIthTopic() etc get hairier.
|
|
* But this happens more often...
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcHistoryPush(TLP tlpOld, VA va, PSTR pszTitle, FM fm)
|
|
{
|
|
HSE hse;
|
|
static int posOldFm = 0;
|
|
RC rc = rcOutOfMemory;
|
|
int posCurFm;
|
|
// char szUntitled[100];
|
|
|
|
ASSERT(fHistoryInit);
|
|
|
|
if (fHistoryMagic) {
|
|
|
|
/*
|
|
* If this call is the result of a history jump, then all we do is
|
|
* check to see if our filename has changed, and update our list
|
|
* accordingly. We do not record the jump.
|
|
*/
|
|
|
|
|
|
posCurFm = GetFmIndex(fm);
|
|
fHistoryMagic = FALSE;
|
|
|
|
if (posOldFm != posCurFm) {
|
|
SetPathRedraw(FALSE);
|
|
RcMungeList(posOldFm, posCurFm);
|
|
SetPathRedraw(TRUE);
|
|
posOldFm = posCurFm;
|
|
}
|
|
SetFocus(hwndHistory); // keep focus on history window
|
|
if (iTopic != LB_ERR && iTopic < (SendMessage(hwndList, LB_GETCOUNT, 0, 0) - 1))
|
|
SendMessage(hwndList, LB_SETCURSEL, ++iTopic, 0);
|
|
return rcSuccess;
|
|
}
|
|
|
|
// Only main window history jumps are recorded in history.
|
|
|
|
if (ahwnd[iCurWindow].hwndParent != ahwnd[MAIN_HWND].hwndParent)
|
|
return rcSuccess;
|
|
|
|
ASSERT(pszTitle);
|
|
#if 0
|
|
if (!pszTitle || !strlen(pszTitle)) {
|
|
if (!pszUntitled)
|
|
pszUntitled = LocalStrDup(GetStringResource(sidUntitled));
|
|
wsprintf(szUntitled, pszUntitled, QdeFromGh(HdeGetEnv())->top.mtop.lTopicNo);
|
|
pszTitle = szUntitled;
|
|
}
|
|
#endif
|
|
|
|
if (va.dword == vaNil)
|
|
return rcSuccess;
|
|
|
|
hse.va = va;
|
|
hse.tlp = tlpOld;
|
|
|
|
SetPathRedraw(FALSE);
|
|
|
|
if (!(hse.ifm = (WORD) GetFmIndex(fm))) {
|
|
goto egress;
|
|
}
|
|
|
|
if (!(hse.hTitle = LocalStrDup(pszTitle)))
|
|
goto egress;
|
|
|
|
// Munge the list if we've changed files.
|
|
// The test for posOldFm is for the case where the stack is empty
|
|
// because a push has failed and the stack is empty.
|
|
|
|
if (posOldFm != hse.ifm && posOldFm) {
|
|
if (rcSuccess != (rc = RcMungeList((WORD) posOldFm, hse.ifm)))
|
|
goto egress;
|
|
}
|
|
posOldFm = hse.ifm;
|
|
|
|
if ((rc = RcInsertTopic(pszTitle)) != rcSuccess) {
|
|
FreeGh(hse.hTitle);
|
|
goto egress;
|
|
}
|
|
|
|
RcPushStack(hstackHistory, &hse);
|
|
|
|
// if (hwndList)
|
|
// SendMessage(hwndList, LB_SETTOPINDEX, 0, 0L);
|
|
|
|
egress:
|
|
SetPathRedraw(TRUE);
|
|
return rc;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcGetIthTopic( i, qtlp, qfm)
|
|
-
|
|
* Purpose: Get the data associated with the Ith topic in stack.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: i - index of topic
|
|
* qtlp - pointer to user's TLP
|
|
* qfm - pointer to user's FM (don't UnlockFmt()
|
|
* until you're done with it)
|
|
*
|
|
* globals IN: hstackHistory
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess
|
|
* rc
|
|
*
|
|
* args OUT: *qtlp - copy of ith topic's TLP
|
|
* *qfm - copy of Ith topic's FM
|
|
*
|
|
* state OUT: FMT is locked
|
|
*
|
|
* Notes: The meaning of the index 'I' is the reverse of the stack indices:
|
|
* 0 is most recently pushed hse.
|
|
*
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcGetIthTopic(int i, QTLP qtlp, FM* qfm)
|
|
{
|
|
HSE hse;
|
|
int iMax = CElementsStack(hstackHistory);
|
|
|
|
ASSERT(i < iMax);
|
|
|
|
i = iMax - i - 1;
|
|
|
|
ENSURE(RcGetIthStack(hstackHistory, i, &hse), rcSuccess);
|
|
|
|
*qtlp = hse.tlp;
|
|
*qfm = GetFmPtr(hse.ifm);
|
|
return rcSuccess;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: FreeTitle( qv )
|
|
-
|
|
* Purpose: Callback function for stack: frees hTitle.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: qv - points to the HSE that needs title freed
|
|
*
|
|
* PROMISES
|
|
*
|
|
* args OUT: qv->hTitle is free (or was NULL)
|
|
*
|
|
\***************************************************************************/
|
|
|
|
void STDCALL FreeTitle(QV qv)
|
|
{
|
|
HLOCAL hTitle = ((HSE *)qv)->hTitle;
|
|
|
|
if (hTitle )
|
|
FreeLh(hTitle);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcMungeList( posOldFm, posNewFm )
|
|
-
|
|
* Purpose: Update (i.e. strip or prepend) file root prefixes in
|
|
* listbox list because current help file has changed.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: qpe - initially points to 0th in rgpe array
|
|
* posOldFm - old ifm; prepend file names on match
|
|
* posNewFm - new ifm; strip file names on match
|
|
*
|
|
* globals IN: hwndList
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess -
|
|
* rcFailure - weird LB failure
|
|
* rcOutOfMemory - out of memory in LB
|
|
*
|
|
* state OUT: FMT is locked
|
|
*
|
|
* +++
|
|
*
|
|
* Method: Munging takes place before the current topic is added to
|
|
* the list or pushed onto the stack.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
INLINE static RC STDCALL RcMungeList(int posOldFm, int posNewFm)
|
|
{
|
|
HSE hse;
|
|
int i, iMax; // LB indices
|
|
char szRoot[MAX_PATH];
|
|
RC rc = rcSuccess;
|
|
|
|
if (hwndList) {
|
|
GetFmParts(GetFmPtr(posOldFm), szRoot, PARTBASE);
|
|
|
|
iMax = CElementsStack(hstackHistory);
|
|
|
|
for (i = 0; i < iMax; i++) {
|
|
RcGetIthStack(hstackHistory, (iMax - 1 - i), &hse);
|
|
|
|
if (hse.ifm == posOldFm)
|
|
rc = RcModifyString(i, szRoot, PREPEND);
|
|
else if (hse.ifm == posNewFm)
|
|
rc = RcModifyString(i, szRoot, STRIP);
|
|
|
|
if (rcSuccess != rc)
|
|
break;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcModifyString( i, pszFileRoot, fAdd )
|
|
-
|
|
* Purpose: Prepend root file name to, or strip it from, a listbox entry.
|
|
* e.g.: "Commands" -> "CALC:Commands"
|
|
* or "WINHELP:Index" -> "Index"
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: i - index into listbox of string to modify
|
|
* pszFileRoot - filename to prepend if fAdd
|
|
* fAdd - PREPEND: prepend the root name from *fm
|
|
* STRIP: strip the root name from the string
|
|
*
|
|
* globals IN: path, hwndList valid
|
|
*
|
|
* state IN: Assume i'th string has file root iff it should
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess - it worked
|
|
* rcOutOfMemory - out of memory (LB_ERRSPACE)
|
|
* rcFailure - something else failed
|
|
*
|
|
* globals OUT: hwndList listbox string modified
|
|
*
|
|
\***************************************************************************/
|
|
|
|
static RC STDCALL RcModifyString(int i, PCSTR pszFileRoot, BOOL fAdd)
|
|
{
|
|
char szBuf[512];
|
|
PSTR psz;
|
|
LRESULT result;
|
|
|
|
if (fAdd == PREPEND) {
|
|
strcpy(szBuf, pszFileRoot);
|
|
psz = szBuf + strlen(szBuf);
|
|
*psz++ = ':';
|
|
}
|
|
else
|
|
psz = szBuf;
|
|
|
|
if (SendMessage(hwndList, LB_GETTEXT, i, (LPARAM) psz) == LB_ERR)
|
|
return rcFailure;
|
|
|
|
if (fAdd == PREPEND)
|
|
psz = szBuf;
|
|
else {
|
|
psz = StrChrDBCS(psz, ':');
|
|
if (psz)
|
|
psz++;
|
|
}
|
|
|
|
// Insert before deletion so list won't get as screwed up on failure.
|
|
|
|
result = SendMessage(hwndList, LB_INSERTSTRING, i, (LPARAM) psz);
|
|
|
|
if (result == LB_ERRSPACE)
|
|
return rcOutOfMemory;
|
|
else if (result == LB_ERR)
|
|
return rcFailure;
|
|
|
|
if (SendMessage(hwndList, LB_DELETESTRING, i + 1, 0) == LB_ERR)
|
|
return rcFailure; // bad news: list screwed up
|
|
|
|
return rcSuccess;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcInsertTopic( sz )
|
|
-
|
|
* Purpose: Insert a new topic name at the top of the listbox.
|
|
* If the stack is full, delete the oldest entry.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: sz - the string to insert
|
|
*
|
|
* globals IN: hwndList - path listbox
|
|
* cSavedMax - max count of topics we can save
|
|
* path.cpe-1st element is one to remove (?)
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess -
|
|
* rcFailure - weird LB error
|
|
* rcOutOfMemory - out of memory in LB operation
|
|
*
|
|
* globals OUT: hwndList listbox contains another string
|
|
*
|
|
\***************************************************************************/
|
|
|
|
INLINE static RC STDCALL RcInsertTopic(PCSTR psz)
|
|
{
|
|
LRESULT result;
|
|
|
|
if (hwndList) {
|
|
result = SendMessage(hwndList, LB_GETCOUNT, 0, 0L);
|
|
|
|
if (result == LB_ERR)
|
|
return rcFailure;
|
|
else if (cSavedMax == result) {
|
|
result = SendMessage(hwndList, LB_DELETESTRING, cSavedMax - 1, 0);
|
|
if (result == LB_ERR) {
|
|
return rcFailure;
|
|
}
|
|
}
|
|
result = SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM) psz);
|
|
if (result == LB_ERRSPACE)
|
|
return rcOutOfMemory;
|
|
else if (result == LB_ERR)
|
|
return rcFailure;
|
|
}
|
|
return rcSuccess;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: FillPathLB()
|
|
-
|
|
* Purpose: Fill the listbox with topic titles and file root names
|
|
* from the path stack.
|
|
*
|
|
* Method:
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* globals IN: path, hwndList
|
|
*
|
|
* state IN:
|
|
*
|
|
* PROMISES
|
|
*
|
|
* globals OUT: listbox is full of stuff
|
|
*
|
|
* Side Effects:
|
|
*
|
|
* Bugs:
|
|
*
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
|
|
INLINE void static STDCALL FillPathLB()
|
|
{
|
|
int ifm;
|
|
HSE hse;
|
|
PSTR psz;
|
|
int i, iMax;
|
|
char szTitle[MAX_TOPIC_TITLE];
|
|
|
|
iMax = (int) CElementsStack(hstackHistory);
|
|
|
|
if (iMax == 0)
|
|
return;
|
|
|
|
Ensure(RcTopStack(hstackHistory, &hse), rcSuccess);
|
|
ifm = hse.ifm;
|
|
|
|
for (i = 0; i < iMax; i++) {
|
|
Ensure(RcGetIthStack(hstackHistory, i, &hse), rcSuccess);
|
|
|
|
if (hse.ifm == ifm) {
|
|
if (hse.hTitle)
|
|
strcpy(szTitle, PszFromGh(hse.hTitle));
|
|
}
|
|
else {
|
|
GetFmParts(GetFmPtr(hse.ifm), szTitle, PARTBASE);
|
|
psz = szTitle + strlen(szTitle);
|
|
*psz++ = ':';
|
|
if (hse.hTitle)
|
|
strcpy(psz, PszFromGh(hse.hTitle));
|
|
}
|
|
|
|
SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM) szTitle);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: SetPathRedraw( f )
|
|
-
|
|
* Purpose: Set or reset redraw of the history listbox.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: f - TRUE means turn redraw on; FALSE means turn it off
|
|
*
|
|
* globals IN: hwndList - needn't be valid: we check
|
|
*
|
|
* PROMISES
|
|
*
|
|
* globals OUT: hwndList - redraw affected as described
|
|
*
|
|
\***************************************************************************/
|
|
|
|
void static STDCALL SetPathRedraw(BOOL fRedraw)
|
|
{
|
|
if (hwndList) {
|
|
SendMessage(hwndList, WM_SETREDRAW, fRedraw, 0L);
|
|
|
|
if (fRedraw) {
|
|
InvalidateRect(hwndList, NULL, TRUE);
|
|
UpdateWindow(hwndList);
|
|
}
|
|
}
|
|
}
|