2020-09-30 17:12:29 +02:00

635 lines
14 KiB
C++

// launch.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#pragma hdrstop
#include <direct.h>
#include "launch.h"
#include "hpjdoc.h"
#include "..\common\waitcur.h"
#include "..\common\cinput.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
typedef enum {
LAUNCH_APP,
LAUNCH_POPUP,
LAUNCH_TCARD,
LAUNCH_BOOK,
LAUNCH_INIT_CNT,
LAUNCH_INIT_FTS,
} LAUNCH_TYPE;
PSTR __inline SkipToEndOfWord(PCSTR psz)
{
while (*psz != ' ' && *psz != '\t' && *psz)
psz++;
return (PSTR) psz;
}
static BOOL STDCALL RcGetLogicalLine(CInput* apin[], int* pcurPin, PSTR pszDst);
static LAUNCH_TYPE type = LAUNCH_APP;
static char szCtx[MAX_PATH];
BEGIN_MESSAGE_MAP(CLaunch, CDialog)
//{{AFX_MSG_MAP(CLaunch)
ON_BN_CLICKED(IDC_BROWSE, OnBrowseHelp)
ON_BN_CLICKED(IDOK, OnRun)
ON_BN_CLICKED(IDCANCEL, OnClose)
ON_BN_CLICKED(IDC_BROWSE_HPJ, OnBrowseHpj)
ON_CBN_KILLFOCUS(IDC_COMBO_HPJ_FILES, OnKillfocusCombo)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_CONTEXTMENU, OnContextMenu)
ON_MESSAGE(WM_HELP, OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLaunch dialog
CLaunch::CLaunch(PSTR pszHlpFile, PSTR pszHpjFile, CWnd* pParent)
: CDialog(CLaunch::IDD, pParent)
{
//{{AFX_DATA_INIT(CLaunch)
m_cszHelpFile = pszHlpFile;
m_cszHpjFile = pszHpjFile;
m_cszCtx = szCtx;
m_fIncrement = FALSE;
//}}AFX_DATA_INIT
m_pszHlpFile = pszHlpFile;
m_pszHpjFile = pszHpjFile;
}
void CLaunch::DoDataExchange(CDataExchange* pDX)
{
CComboBox* pcombo;
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLaunch)
DDX_CBString(pDX, IDC_COMBO_HELP_FILES, m_cszHelpFile);
DDV_MaxChars(pDX, m_cszHelpFile, 255);
DDX_CBString(pDX, IDC_COMBO_HPJ_FILES, m_cszHpjFile);
DDV_MaxChars(pDX, m_cszHpjFile, 255);
DDX_Text(pDX, IDC_COMBO_CTX, m_cszCtx);
DDV_MaxChars(pDX, m_cszCtx, 255);
DDX_Check(pDX, IDC_CHECK_INCR, m_fIncrement);
//}}AFX_DATA_MAP
DDV_EmptyFile(pDX, m_cszHelpFile, IDS_PROMPT_EMPTY_FILENAME);
if (pDX->m_bSaveAndValidate) {
switch (GetCheckedRadioButton(IDC_RADIO_APP_INVOKED,
IDC_RADIO_INIT_FTS)) {
case IDC_RADIO_APP_INVOKED:
type = LAUNCH_APP;
strcpy(szCtx, m_cszCtx);
break;
case IDC_RADIO_POPUP:
DDV_EmptyFile(pDX, m_cszCtx, IDS_MISSING_CTX);
type = LAUNCH_POPUP;
strcpy(szCtx, m_cszCtx);
break;
case IDC_RADIO_TCARD:
type = LAUNCH_TCARD;
strcpy(szCtx, m_cszCtx);
break;
case IDC_RADIO_BOOK:
type = LAUNCH_BOOK;
strcpy(szCtx, m_cszCtx);
break;
case IDC_RADIO_INIT_GID:
type = LAUNCH_INIT_CNT;
break;
case IDC_RADIO_INIT_FTS:
type = LAUNCH_INIT_FTS;
break;
}
if (!m_cszHelpFile.IsEmpty()) {
phlpFile->Add(m_cszHelpFile);
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HELP_FILES);
pcombo->ResetContent(); // empty the combo box
pcombo->SetWindowText(m_cszHelpFile);
pcombo->SetEditSel(0, 0); // remove selection
}
if (!m_cszHpjFile.IsEmpty()) {
pHpjFile->Add(m_cszHpjFile);
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HPJ_FILES);
pcombo->ResetContent(); // empty the combo box
pcombo->SetWindowText(m_cszHpjFile);
pcombo->SetEditSel(0, 0); // remove selection
}
// Copy the files irregardless, to zero out if not used
strcpy(m_pszHlpFile, m_cszHelpFile);
strcpy(m_pszHpjFile, m_cszHpjFile);
}
}
BOOL CLaunch::OnInitDialog()
{
CWaitCursor wait;
SetChicagoDialogStyles(m_hWnd);
CDialog::OnInitDialog();
switch (type) {
case LAUNCH_APP:
CheckDlgButton(IDC_RADIO_APP_INVOKED, TRUE);
break;
case LAUNCH_POPUP:
CheckDlgButton(IDC_RADIO_POPUP, TRUE);
break;
case LAUNCH_TCARD:
CheckDlgButton(IDC_RADIO_TCARD, TRUE);
break;
case LAUNCH_BOOK:
CheckDlgButton(IDC_RADIO_BOOK, TRUE);
break;
case LAUNCH_INIT_CNT:
CheckDlgButton(IDC_RADIO_INIT_GID, TRUE);
break;
case LAUNCH_INIT_FTS:
CheckDlgButton(IDC_RADIO_INIT_FTS, TRUE);
break;
}
CComboBox* pcombo;
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HELP_FILES);
phlpFile->FillComboBox(pcombo);
// If a filename wasn't specified when we were called, then
// select the first filename in our list, which will be the
// last filename compiled.
if (m_cszHelpFile.IsEmpty())
pcombo->SetCurSel(0);
else
pcombo->SetWindowText(m_cszHelpFile);
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HPJ_FILES);
pHpjFile->FillComboBox(pcombo);
if (!m_cszHpjFile.IsEmpty())
ProcessHpj();
return TRUE; // return TRUE unless you set the focus to a control
}
/////////////////////////////////////////////////////////////////////////////
// CLaunch message handlers
void CLaunch::OnBrowseHelp()
{
ASSERT(StrRChr(GetStringResource(IDS_EXT_HLP), '.', _fDBCSSystem));
CStr cszExt(StrRChr(GetStringResource(IDS_EXT_HLP), '.', _fDBCSSystem));
CFileDialog cfdlg(TRUE, cszExt, NULL,
OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
GetStringResource(IDS_HLP_EXTENSION));
if (cfdlg.DoModal() == IDOK) {
/*
* Contrary to the docs, the extension is not always added,
* so we make sure it gets added here.
*/
char szFile[_MAX_PATH];
strcpy(szFile, cfdlg.GetPathName());
PSTR psz = StrRChr(szFile, '.', _fDBCSSystem);
if (!psz)
ChangeExtension(szFile, cszExt);
((CComboBox*) GetDlgItem(IDC_COMBO_HELP_FILES))->
SetWindowText(cfdlg.GetPathName());
}
}
void CLaunch::OnRun()
{
CDataExchange DX(this, TRUE);
DoDataExchange(&DX);
CComboBox* pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_CTX);
SzTrimSz(szCtx);
int pos, num;
if ((pos = pcombo->FindString(-1, szCtx)) != CB_ERR)
num = pcombo->GetItemData(pos);
else
num = -1;
char szExec[MAX_PATH + 100];
// Make certain we have a full path
if (!StrChrDBCS(szHlpFile, '.'))
ChangeExtension(szHlpFile, ".hlp");
ConvertToFull(NULL, szHlpFile);
if (GetFileAttributes(szHlpFile) == (DWORD) -1) {
/*
* If we can't find the help file where we expected it to be, then
* ask the user if they still want to launch help. Note that we strip
* off the path, so if the user wants WinHelp to look, then we just
* pass the filename portion ot WinHelp.
*/
PSTR pszFilePart;
char szDummy[MAX_PATH];
GetFullPathName(szHlpFile, sizeof(szDummy), szDummy, &pszFilePart);
CString cstr;
AfxFormatString2(cstr, IDS_LAUNCH_MISSING_HELP,
szHlpFile, pszFilePart);
if (AfxMessageBox(cstr, MB_YESNO, 0) == IDNO)
return;
strcpy(szHlpFile, pszFilePart);
}
switch (type) {
case LAUNCH_APP:
if (num != -1 || isdigit(szCtx[0])) {
if (!::WinHelp(m_hWnd, szHlpFile, HELP_CONTEXT,
(num != -1) ? num : (DWORD) atoi(szCtx)))
MsgBox(IDS_LAUNCH_FAILED);
else
fHelpRunning = TRUE;
}
else if (szCtx[0]) {
strcpy(szExec, "JI(\"\", \"");
strcat(szExec, szCtx);
strcat(szExec, "\")");
if (!::WinHelp(m_hWnd, szHlpFile, HELP_COMMAND,
(DWORD) szExec))
MsgBox(IDS_LAUNCH_FAILED);
else
fHelpRunning = TRUE;
}
else {
if (!::WinHelp(m_hWnd, szHlpFile, HELP_FINDER, 0))
MsgBox(IDS_LAUNCH_FAILED);
else
fHelpRunning = TRUE;
}
break;
case LAUNCH_POPUP:
if (num == -1 && !isdigit(szCtx[0])) {
MsgBox(IDS_MUST_BE_NUMBER);
break;
}
if (!::WinHelp(m_hWnd, szHlpFile, HELP_CONTEXTPOPUP,
(num != -1) ? num : (DWORD) atoi(szCtx)))
MsgBox(IDS_LAUNCH_FAILED);
break;
case LAUNCH_BOOK:
if (!OurExec(szHlpFile, GetStringResource(IDS_WINHELP)))
MsgBox(IDS_LAUNCH_FAILED);
break;
case LAUNCH_INIT_CNT:
strcpy(szExec, "-g ");
strcat(szExec, szHlpFile);
if (!OurExec(szExec, GetStringResource(IDS_WINHELP)))
MsgBox(IDS_LAUNCH_FAILED);
break;
default:
MsgBox(IDS_NOT_IMPLEMENTED);
break;
}
if (m_fIncrement) {
pos = pcombo->GetCurSel();
if (pos != CB_ERR)
pcombo->SetCurSel(pos + 1);
}
}
void CLaunch::OnClose()
{
::PostMessage(GetParent()->m_hWnd, WMP_STOP_RUN_DLG, 0, 0);
}
void CLaunch::OnBrowseHpj()
{
ASSERT(StrRChr(GetStringResource(IDS_HPJEXT), '.', _fDBCSSystem));
CStr cszExt(StrRChr(GetStringResource(IDS_HPJEXT), '.', _fDBCSSystem));
CFileDialog cfdlg(TRUE, cszExt, NULL,
OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
GetStringResource(IDS_HPJ_EXTENSION));
if (cfdlg.DoModal() == IDOK) {
/*
* Contrary to the docs, the extension is not always added,
* so we make sure it gets added here.
*/
char szFile[_MAX_PATH];
strcpy(szFile, cfdlg.GetPathName());
PSTR psz = StrRChr(szFile, '.', _fDBCSSystem);
if (!psz)
ChangeExtension(szFile, cszExt);
((CComboBox*) GetDlgItem(IDC_COMBO_HPJ_FILES))->
SetWindowText(cfdlg.GetPathName());
ProcessHpj();
}
}
/***************************************************************************
FUNCTION: CLaunch::ProcessHpj
PURPOSE: Read a .HPJ file and add the [MAP] section to the Context
ID combobox, and the Help File to the help combobox.
PARAMETERS:
void
RETURNS:
COMMENTS:
MODIFICATION DATES:
14-Aug-1995 [ralphw]
***************************************************************************/
const int MAX_INCLUDE_DEPTH = 20;
const int MAX_LINE = 1024;
const char txtHelpFile[] = "HLP=";
// REVIEW: all of this should be replaced with CMapRead
void CLaunch::ProcessHpj(void)
{
char szHpjFile[MAX_PATH];
CMem line(MAX_LINE);
CInput* apin[MAX_INCLUDE_DEPTH];
int curpin = 0;
CComboBox* pcombo;
((CComboBox*) GetDlgItem(IDC_COMBO_HPJ_FILES))->
GetWindowText(szHpjFile, sizeof(szHpjFile));
SzTrimSz(szHpjFile);
if (!szHpjFile[0] || cszLastHpj == szHpjFile)
return;
cszLastHpj = szHpjFile;
apin[curpin] = new CInput(szHpjFile);
if (!apin[curpin]->fInitialized) {
CString cstr;
AfxFormatString1(cstr, IDS_CANT_OPEN, szHpjFile);
AfxMessageBox(cstr);
return;
}
CWaitCursor wait;
apin[curpin]->SetMaxLine(MAX_LINE);
for (;;) {
if (!apin[curpin]->getline(line)) {
delete apin[curpin--];
return;
}
if (stricmp(line, txtOPTIONS) == 0) {
while (apin[curpin]->getline(line) && line.psz[0] != '[') {
if (nstrisubcmp(line, txtHelpFile)) {
PSTR pszEq = StrChr(line, '=', _fDBCSSystem);
if (pszEq == NULL)
continue;
pszEq = SzTrimSz(pszEq + 1);
strcpy(szHlpFile, pszEq);
ConvertToFull(szHpjFile, szHlpFile);
phlpFile->Add(szHlpFile);
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HELP_FILES);
pcombo->SetWindowText(szHlpFile);
pcombo->SetEditSel(0, 0); // remove selection
break;
}
}
continue;
}
if (stricmp(line, txtMAP) == 0)
break;
}
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_CTX);
pcombo->ResetContent(); // empty the combo box
ChangeDirectory(szHpjFile); // so relative paths will work
for (;;) {
if (!RcGetLogicalLine(apin, &curpin, line.psz)) {
CloseInput:
delete apin[curpin--];
if (curpin < 0) {
goto Done;
}
continue;
}
if (line.psz[0] == '[')
goto CloseInput;
PSTR pszTmp, pszLine;
if (!(pszTmp = StrChr(line, CH_EQUAL, _fDBCSSystem)))
pszTmp = SkipToEndOfWord(line);
if (!pszTmp)
continue;
if (_strnicmp(line, txtDefine, strlen(txtDefine)) == 0) {
pszLine = FirstNonSpace(line.psz + strlen(txtDefine), _fDBCSSystem);
if (*pszTmp != CH_EQUAL)
pszTmp = SkipToEndOfWord(pszLine);
if (!*pszTmp)
continue;
}
else
pszLine = line.psz;
*pszTmp = '\0';
PSTR psz = SzTrimSz(pszLine);
PSTR pszSave = psz;
psz = SzTrimSz(pszTmp + 1);
int num;
if (!FGetUnsigned(psz, &pszTmp, &num))
continue;
int pos = pcombo->AddString(pszSave);
if (pos == CB_ERR)
goto CloseInput;
pcombo->SetItemData(pos, num);
}
Done:
// Select the first entry
pcombo->SetCurSel(0);
pcombo->SetEditSel(0, -1);
// Add this new .HPJ file just in case we didn't already have it.
pcombo = (CComboBox*) GetDlgItem(IDC_COMBO_HPJ_FILES);
pcombo->ResetContent();
pHpjFile->Add(szHpjFile);
pHpjFile->FillComboBox(pcombo);
pcombo->SetWindowText(szHpjFile);
pcombo->SetEditSel(0, 0); // remove selection
((CComboBox*) GetDlgItem(IDC_COMBO_CTX))->SetFocus();
}
static BOOL STDCALL RcGetLogicalLine(CInput* apin[], int* pcurPin,
PSTR pszDst)
{
StartOver:
CInput* pin = apin[*pcurPin];
if (!pin)
return FALSE;
for (;;) {
if (!pin->getline(pszDst)) {
return FALSE;
}
PSTR psz = FirstNonSpace(pszDst, _fDBCSSystem);
switch (*psz) {
case 0:
case ';':
continue;
case '#':
if (nstrisubcmp(pszDst, txtPoundInclude)) {
// process #include
psz = IsThereMore(psz);
if (!psz) {
continue;
}
if (*psz == CH_QUOTE || *psz == '<') {
char ch = (*psz == CH_QUOTE) ? CH_QUOTE : '>';
psz++;
PSTR pszEnd = StrChr(psz, ch, _fDBCSSystem);
if (*pszEnd)
*pszEnd = '\0';
}
CInput* pnew = new CInput(psz);
if (pnew->fInitialized) {
*pcurPin += 1;
apin[*pcurPin] = pnew;
goto StartOver;
}
continue;
}
else if (nstrisubcmp(pszDst, txtDefine))
goto ValidString;
// REVIEW: process #ifdef, #ifndef, #else, #endif
continue;
default:
// We have a valid string.
if (psz != pszDst)
strcpy(pszDst, psz);
// Remove any comments
ValidString:
if ((psz = StrChr(pszDst, ';', _fDBCSSystem)))
*psz = '\0';
if ((psz = strstr(pszDst, "//")))
*psz = '\0';
while ((psz = strstr(pszDst, "/*"))) {
PSTR pszTmp = strstr(psz, "*/");
if (pszTmp)
strcpy(psz, FirstNonSpace(pszTmp + 2, _fDBCSSystem));
else {
char szBuf[MAX_LINE];
do {
if (!pin->getline(szBuf))
return FALSE;
} while (!(pszTmp = strstr(szBuf, "*/")));
strcpy(psz, FirstNonSpace(pszTmp + 2, _fDBCSSystem));
// New line could have comments, so start all over
goto ValidString;
}
}
SzTrimSz(pszDst);
if (!*pszDst)
continue;
return TRUE;
}
}
}
void CLaunch::OnKillfocusCombo()
{
ProcessHpj();
}
static const DWORD aHelpIds[] = {
IDC_COMBO_HELP_FILES, IDH_COMBO_RUN_HELP,
IDC_BROWSE, (DWORD) -1L,
IDC_COMBO_HPJ_FILES, IDH_COMBO_RUN_HPJ,
IDC_BROWSE_HPJ, (DWORD) -1L,
IDC_COMBO_CTX, IDH_COMBO_RUN_ID,
IDC_CHECK_INCR, IDH_CHECK_RUN_NEXT_ID,
IDC_RADIO_APP_INVOKED, IDH_RADIO_RUN_APP,
IDC_RADIO_POPUP, IDH_RADIO_RUN_POPUP,
IDC_RADIO_INIT_GID, IDH_RADIO_RUN_INIT_CNT,
IDC_RADIO_TCARD, IDH_RADIO_RUN_TRAINING,
IDC_RADIO_BOOK, IDH_RADIO_RUN_UNATTACHED,
IDOK, IDH_BTN_RUN_WINHELP,
IDC_GROUP, (DWORD) -1L,
IDC_GROUP2, (DWORD) -1L,
0, 0
};
LRESULT CLaunch::OnContextMenu(WPARAM wParam, LPARAM lParam)
{
::WinHelp((HWND) wParam,
AfxGetApp()->m_pszHelpFilePath,
HELP_CONTEXTMENU, (DWORD) (LPVOID) aHelpIds);
return 0;
}
LRESULT CLaunch::OnHelp(WPARAM wParam, LPARAM lParam)
{
::WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle,
AfxGetApp()->m_pszHelpFilePath,
HELP_WM_HELP, (DWORD) (LPVOID) aHelpIds);
return 0;
}