Exemple #1
0
// Append something appropriate to strDesc for foreground and background color, depending on whether
// either or both is unspecified (knNinch).
void AppendTextIs(StrApp & strDesc, COLORREF clrFore, COLORREF clrBack, bool & fFirst)
{
	StrApp strT;
	StrApp strT2;
	StrApp strT3;
	if (clrBack == (COLORREF)kclrTransparent)
		clrBack = (COLORREF)knNinch; // treat transparent as no background color.
	// If we have a foreground color but no background display something like "Text is red"
	if (clrFore != knNinch && clrBack == knNinch)
	{
		strT2.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrFore)));
		strT3.Load(kstidTextIsFmt);
		strT.Format(strT3.Chars(), strT2.Chars());
	}
	else if (clrBack != knNinch)
	{
		strT2.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrBack)));
		strT3.Load(kstidTextOnFmt);
		StrApp strT4;
		if (clrFore != knNinch)
			strT4.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrFore)));
		strT.Format(strT3.Chars(), strT4.Chars(), strT2.Chars());
	}
	AppendDescPart(strDesc, strT, fFirst);
}
Exemple #2
0
/*------------------------------------------------------------------------------------------
	Set the root directory for where things are located, which should be the directory
	where this file is located.
------------------------------------------------------------------------------------------*/
void SetTestDir()
{
    if (g_strTestDir.Length())
        return;		// Set this only once!

    // Get the path to the template files.
    HKEY hk;
    if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\SIL\\FieldWorks"), 0,
                       KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS)
    {
        achar rgch[MAX_PATH];
        DWORD cb = isizeof(rgch);
        DWORD dwT;
        if (::RegQueryValueEx(hk, _T("RootCodeDir"), NULL, &dwT, (BYTE *)rgch, &cb)
                == ERROR_SUCCESS)
        {
            Assert(dwT == REG_SZ);
            StrApp str(rgch);
            int ich = str.FindStrCI(_T("\\distfiles"));
            if (ich >= 0)
                str.Replace(ich, str.Length(), _T(""));
            ich = str.FindCh('\\', str.Length() - 1);
            if (ich >= 0)
                str.Replace(ich, str.Length(), _T(""));
            str.Append(_T("\\Src\\Cellar\\Test\\"));
            g_strTestDir.Assign(str);
        }
        RegCloseKey(hk);
    }
    if (!g_strTestDir.Length())
        g_strTestDir.Assign("C:\\FW\\Src\\Cellar\\Test\\");
}
Exemple #3
0
/*----------------------------------------------------------------------------------------------
	This method is called when the user presses Browse button.  It opens a dialog to browse for
	a help file, then if OK is pressed it puts that filename and path into the help edit box.
----------------------------------------------------------------------------------------------*/
void DetailsPropDlgTab::OnBrws()
{
	// Open file dialog.
	achar szFile[MAX_PATH];
	::ZeroMemory(szFile, MAX_PATH);
	OPENFILENAME ofn;
	::ZeroMemory(&ofn, sizeof(OPENFILENAME));
	// the constant below is required for compatibility with Windows 95/98 (and maybe NT4)
	ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
	ofn.Flags		= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
	ofn.hwndOwner	= m_hwnd;
	ofn.lpstrFilter	= _T("Compiled HTML Help Files (*.chm)\0*.chm\0");
	StrApp str(kstidOpenHelp);
	ofn.lpstrTitle	= str.Chars();

	StrApp strHelpPath = AfApp::Papp()->GetFwCodePath().Chars();
	strHelpPath.Append(_T("\\Helps\\"));

	ofn.lpstrInitialDir = strHelpPath.Chars();
	ofn.lpstrFile	= szFile;
	ofn.nMaxFile	= MAX_PATH;
	if (IDOK != ::GetOpenFileName(&ofn))
		return; // We do not save the results
	::SetWindowText(::GetDlgItem(m_hwnd, kctidDetailsPropTabHelpF), szFile);
	m_ppropd->SetHelpFile(szFile);
}
Exemple #4
0
/*----------------------------------------------------------------------------------------------
	Get the version information for a module. It is passed the path name to the module.
----------------------------------------------------------------------------------------------*/
StrUni GetModuleVersion(const OLECHAR * pchPathName)
{
	StrUni stuRet;
#ifdef WIN32
	StrApp staPathName = pchPathName;
	achar * pchaPathName = const_cast<achar *>(staPathName.Chars());

	DWORD dwDum; // Always set to zero.
	DWORD cb = GetFileVersionInfoSize(pchaPathName, &dwDum);

	LPVOID pBlock = (LPVOID) _alloca(cb);

	if (!GetFileVersionInfo(pchaPathName, 0, cb, pBlock))
		return stuRet; // Can't get requested info

	VS_FIXEDFILEINFO * pffi;
	uint nT;
	::VerQueryValue(pBlock, _T("\\"), (void **)&pffi, &nT);

	stuRet.Format(L"Version: %d, %d, %d, %d", HIWORD(pffi->dwFileVersionMS),
		LOWORD(pffi->dwFileVersionMS), HIWORD(pffi->dwFileVersionLS),
		LOWORD(pffi->dwFileVersionLS));
#endif
	return stuRet;
}
Exemple #5
0
// Add the part to the description (preceded by a comma if it isn't the first thing added).
void AppendDescPart(StrApp & strDesc, const achar * pszPart, bool & fFirst)
{
	if (*pszPart == 0)
		return;
	if (fFirst)
		fFirst = false; // Subsequent calls will add a comma.
	else
		strDesc.Append (",");
	strDesc.Append(pszPart);
}
Exemple #6
0
/*----------------------------------------------------------------------------------------------
	Add menu items for the right-click context Insert menu over tree pane.
----------------------------------------------------------------------------------------------*/
void CleDeSplitChild::AddContextInsertItems(HMENU & hmenu)
{
	StrApp str;

	CleMainWnd * pcmw = dynamic_cast<CleMainWnd *>(MainWindow());
	Assert(pcmw);

	PossListInfo * ppli = pcmw->GetPossListInfoPtr();
	AssertPtr(ppli);

	if (!ppli->GetIsSorted())
	{
		str.Assign(_T("List Item &Above"));
		::AppendMenu(hmenu, MF_STRING, kcidInsItemBef, str.Chars());
		str.Assign(_T("List Item &Below"));
		::AppendMenu(hmenu, MF_STRING, kcidInsItemAft, str.Chars());
	}
	else
	{
		str.Assign(_T("List &Item"));
		::AppendMenu(hmenu, MF_STRING, kcidInsItem, str.Chars());
	}
	if (ppli->GetDepth() != 1)
	{
		str.Assign(_T("List &Subitem"));
		::AppendMenu(hmenu, MF_STRING, kcidInsSubItem, str.Chars());
	}
}
Exemple #7
0
/*----------------------------------------------------------------------------------------------
	Process notifications from the user.
----------------------------------------------------------------------------------------------*/
bool FmtGenDlg::OnNotifyChild(int ctidFrom, NMHDR * pnmh, long & lnRet)
{
	AssertPtr(pnmh);

	switch (pnmh->code)
	{
	case EN_KILLFOCUS: // Edit control modified.
		// Suppress updating the style from the control when we are trying to update the
		// control from the style.
		if (m_fSuppressLossOfFocus)
			break;

		if (ctidFrom == kctidFgEdName)
		{
			if (!m_pafsd->StyleIsSelected())
				return true;
			StyleInfo & styiSelected = m_pafsd->SelectedStyle();
			StrApp strOldName(styiSelected.m_stuName); // Save old name.
			StrApp strNewName;
			StrUni stuName;

			strNewName = GetName();

			// If the name has not changed, there is nothing to do.
			if (strNewName.Equals(strOldName))
				return true;

			stuName.Assign(strNewName);

			// If the style cannot be named stuName, put the old name back into the control.
			if (!m_pafsd->SetName(styiSelected, stuName))
			{
				::SetDlgItemText(m_hwnd, kctidFgEdName, strOldName.Chars());
				return true;
			}
			// Otherwise update the comboboxes for BasedOn and Next. Also update the edit box
			// to handle stripping of leading/trailing blanks.
			else
			{
				::SetDlgItemText(m_hwnd, kctidFgEdName, strNewName.Chars());
				UpdateComboboxes(strOldName, strNewName);
			}
		}
		return true;

	case CBN_SELCHANGE: // Combo box item changed.
		return OnComboChange(pnmh, lnRet);

	default:
		break;
	}

	return AfWnd::OnNotifyChild(ctidFrom, pnmh, lnRet);
}
Exemple #8
0
// Append information about one border, if it is defined
void AppendBorderInfo(StrApp & strDesc, int mp, int stid, bool & fFirst)
{
	if (mp == knNinch)
		return;
	StrAppBuf strb;
	AfUtil::MakeMsrStr (mp , knpt, &strb);
	StrApp strFmt(stid);
	StrApp strT;
	strT.Format(strFmt.Chars(), strb.Chars());
	AppendDescPart(strDesc, strT, fFirst);
}
Exemple #9
0
/*----------------------------------------------------------------------------------------------
	Called by the framework to initialize the dialog. All one-time initialization should be
	done here (that is, all controls have been created and have valid hwnd's, but they
	need initial values.)

	See ${AfDialog#FWndProc}
	@param hwndCtrl (not used)
	@param lp (not used)

	@return true if Successful
----------------------------------------------------------------------------------------------*/
bool FwPropDlg::OnInitDlg(HWND hwndCtrl, LPARAM lp)
{
	StrApp str;
	str.Format(_T("%r %r"), AfApp::Papp()->GetAppPropNameId(), kstidPropProperties);
	::SendMessage(m_hwnd, WM_SETTEXT, 0, (LPARAM)str.Chars());

	m_pszHelpUrl = m_strHelpF.Chars();
	GeneralPropDlgTabPtr qgenp;
	qgenp.Attach(NewObj GeneralPropDlgTab(this, m_ctidName));
	qgenp->EnableLocation(true);
	qgenp->EnableSize(true);
	qgenp->EnableModified(true);
	qgenp->EnableDescription(true);
	AfDialogViewPtr qdlgv;
	qdlgv = qgenp;
	m_vqdlgv.Push(qdlgv);

	m_hwndTab = ::GetDlgItem(m_hwnd, kcidLangProjPropDlgTab);

	// WARNING: If this ever gets changed to anything but a fixed length buffer, make sure
	// ti.pszText is set after loading each string, since the memory pointed to by strb
	// could be different each time.
	StrAppBuf strb;
	TCITEM ti;
	ti.mask = TCIF_TEXT;
	ti.pszText = const_cast<achar *>(strb.Chars());

	// Add a tab to the tab control for each dialog view.
	strb.Load(kstidGeneralPropTab);
	TabCtrl_InsertItem(m_hwndTab, 0, &ti);

	// This section must be after at least one tab gets added to the tab control.
	RECT rcTab;
	::GetWindowRect(m_hwndTab, &rcTab);
	TabCtrl_AdjustRect(m_hwndTab, false, &rcTab);
	POINT pt = { rcTab.left, rcTab.top };
	::ScreenToClient(m_hwnd, &pt);
	m_dxsClient = pt.x;
	m_dysClient = pt.y;

	// Subclass the Help button.
	AfButtonPtr qbtn;
	qbtn.Create();
	qbtn->SubclassButton(m_hwnd, kctidHelp, kbtHelp, NULL, 0);

	ShowChildDlg(m_itabInitial);

	AfApp::Papp()->EnableMainWindows(false);

	::SetFocus(m_hwndTab);

	return SuperClass::OnInitDlg(hwndCtrl, lp);
}
Exemple #10
0
/*----------------------------------------------------------------------------------------------
	Return the what's-this help string for the Date Dialog ellipsis button.

	@param pt not used.
	@param pptss Address of a pointer to an ITsString COM object for returning the help string.

	@return true.
----------------------------------------------------------------------------------------------*/
bool AfDeFeEdBoxBut::DeButton::GetHelpStrFromPt(Point pt, ITsString ** pptss)
{
	AssertPtr(pptss);

	StrApp str;
	str.Load(kstidEllipsisBtnDateWhatsThisHelp); // No context help available
	ITsStrFactoryPtr qtsf;
	qtsf.CreateInstance(CLSID_TsStrFactory);
	StrUni stu(str);
	CheckHr(qtsf->MakeString(stu.Bstr(), m_pdee->UserWs(), pptss));
	return true;
}
Exemple #11
0
/*----------------------------------------------------------------------------------------------
	Selects the "basedOn" style of the specified style in the "basedOn" combobox
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::SetBasedOnStyleComboboxValue(StyleInfo & styi)
{
	StrApp strTemp; // Temporary string.
	bool fProtectedStyle = m_pafsd->IsStyleProtected(styi.m_stuName);

	// Select the "Based On" value from styi for the combobox.
	strTemp = m_pafsd->GetNameOfStyle(styi.m_hvoBasedOn);
	int icombobox = ::SendMessage(m_hwndBasedOn, CB_FINDSTRINGEXACT, 0,
		(LPARAM)strTemp.Chars());
	::SendMessage(m_hwndBasedOn, CB_SETCURSEL, icombobox, 0);
	// Disable the control for styles originally provided by FieldWorks.
	::EnableWindow(m_hwndBasedOn, !fProtectedStyle);
}
Exemple #12
0
/*----------------------------------------------------------------------------------------------
	The AfStylesDlg calls this when the user edits the name of a style.
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::SetName(StrApp & strNewName)
{
	StrApp strOldName;

	strOldName = GetName(); // Get the name from the editbox.

	// If the name has not changed, there is nothing to do.
	if (strNewName.Equals(strOldName))
		return;

	::SetDlgItemText(m_hwnd, kctidFgEdName, strNewName.Chars());

	UpdateComboboxes(strOldName, strNewName); // Update the names in the comboboxes.
}
DEFINE_THIS_FILE

#define gle (GetLastError())
#define lenof(a) (sizeof(a) / sizeof((a)[0]))
#define MAXNAMELEN 1024 // max name length for found symbols
#define IMGSYMLEN ( sizeof IMAGEHLP_SYMBOL )
#define TTBUFLEN 65536 // for a temp buffer

/// Add the given string to Sta. If Sta is not empty, add a semi-colon first
void AppendToStaWithSep(StrApp sta, const achar * pch)
{
	if (sta.Length())
		sta.Append(";");
	sta.Append(pch);
}
Exemple #14
0
/*----------------------------------------------------------------------------------------------
	Loads the "next" combobox for the specified style
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::LoadNextStyleCombobox(StyleInfo & styi)
{
	StrApp strTemp; // Temporary string.

	// "Next Style" combobox.
	::SendMessage(m_hwndNext, CB_RESETCONTENT, 0, 0);
	for (int istyi = 0; istyi < m_pafsd->m_vstyi.Size(); istyi++)
	{
		StyleInfo * pstyiTemp = &m_pafsd->m_vstyi[istyi];
		if (pstyiTemp->m_fDeleted)
			continue;
		strTemp = pstyiTemp->m_stuName;
		if (pstyiTemp->m_st == styi.m_st)
			::SendMessage(m_hwndNext, CB_ADDSTRING, 0, (LPARAM)strTemp.Chars());
	}
}
Exemple #15
0
/*----------------------------------------------------------------------------------------------
	Set the values for the dialog controls based
----------------------------------------------------------------------------------------------*/
void TeStylesDlg::SetDialogValues()
{
	// Fill list combobox.
	StrApp staTemp;
	::SendMessage(m_hwndList, CB_RESETCONTENT, 0, 0);
	staTemp.Load(kstidTesdListBasic);
	::SendMessage(m_hwndList, CB_ADDSTRING, 0, (LPARAM)staTemp.Chars()); // 0
	staTemp.Load(kstidTesdListAll);
	::SendMessage(m_hwndList, CB_ADDSTRING, 0, (LPARAM)staTemp.Chars()); // 1
	staTemp.Load(kstidTesdListCustom);
	::SendMessage(m_hwndList, CB_ADDSTRING, 0, (LPARAM)staTemp.Chars()); // 2

	// Select the value in the combo box that represents the selected level.
	int nSelect;
	if (m_nCustomStyleLevel == 0)
		nSelect = ksttBasic;
	else if (m_nCustomStyleLevel > 10)
		nSelect = ksttAll;
	else
		nSelect = ksttCustom;

	::SendMessage(m_hwndList, CB_SETCURSEL, nSelect, 0);

	SuperClass::SetDialogValues();
}
Exemple #16
0
// Append a measurement, never with preceding comma. stid contains a %s which is replaced
// with the nVal (initially mp) converted to the appropriate display units.
void AppendMeasurement(StrApp & strDesc, int nVal, MsrSysType nMsrSys, int stid)
{
	if (nVal == knNinch)
		return;
	StrAppBuf strb;
	AfUtil::MakeMsrStr(nVal , nMsrSys, &strb);
	StrApp strFmt(stid);
	strDesc.FormatAppend(strFmt.Chars(), strb.Chars());
}
Exemple #17
0
/*----------------------------------------------------------------------------------------------
	Overrides the LoadNextStyleCombobox in the FmtGenDlg.cpp file so that we can limit the
	styles by context.
----------------------------------------------------------------------------------------------*/
void TeFmtGenDlg::LoadNextStyleCombobox(StyleInfo & styi)
{
	TeStylesDlg * ptesd = dynamic_cast<TeStylesDlg*>(m_pafsd);
	StrApp strTemp;

	// We have to refill the Next combo box to show only styles with compatible text styles.
	// "Next" styles are compatible if they have the same Context and a compatible Structure.
	::SendMessage(m_hwndNext, CB_RESETCONTENT, 0, 0);
	for (int istyi = 0; istyi < ptesd->m_vstyi.Size(); istyi++)
	{
		StyleInfo& styiTemp = ptesd->m_vstyi[istyi];
		if (styiTemp.m_fDeleted)
			continue;
		strTemp = styiTemp.m_stuName;
			if (CompatibleNextStyle(styi, styiTemp))
				::SendMessage(m_hwndNext, CB_ADDSTRING, 0, (LPARAM)strTemp.Chars());
	}
}
Exemple #18
0
/*----------------------------------------------------------------------------------------------
	Create a new TssEdit. ptss can be NULL if the control should start out empty.
----------------------------------------------------------------------------------------------*/
void TssEdit::Create(HWND hwndPar, int cid, DWORD dwStyle, HWND hwndToolTip, ITsString * ptss,
	ILgWritingSystemFactory * pwsf, int ws, IActionHandler * pacth)
{
	AssertPtr(pwsf);
	PreCreate(pwsf, ws, ptss, pacth);

	m_cid = cid;
	m_hwndToolTip = hwndToolTip;

	m_wsBase = ws;
	m_qwsf = pwsf;
	if (!m_wsBase)
		CheckHr(pwsf->get_UserWs(&m_wsBase));	// get the user interface writing system id.

	// Create the window.
	WndCreateStruct wcs;
	wcs.lpszClass = _T("AfVwWnd");
	wcs.hwndParent = hwndPar;
	wcs.SetWid(cid);
	wcs.style = dwStyle;
	CreateHwnd(wcs);

	// Add a tool tip.
	if (HasToolTip())
	{
		// Add the combo information to the tooltip.
		TOOLINFO ti = { isizeof(ti), TTF_IDISHWND };
#ifdef DEBUG
		static StrApp s_str;
		s_str.Format(_T("Missing a tooltip for edit control with ID %d"), m_cid);
		ti.lpszText = const_cast<achar *>(s_str.Chars());
#else // !DEBUG
		ti.lpszText = _T("Dummy text");
#endif // !DEBUG

		ti.hwnd = Hwnd();
		ti.uId = (uint)ti.hwnd;
		::GetClientRect(Hwnd(), &ti.rect);
		::SendMessage(m_hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
	}

	PostCreate(ptss);
}
Exemple #19
0
/*----------------------------------------------------------------------------------------------
	Selects the "next" style of the specified style in the "next" combobox
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::SetNextStyleComboboxValue(StyleInfo & styi)
{
	StrApp strTemp; // Temporary string.
	int icombobox;
	bool fProtectedStyle = m_pafsd->IsStyleProtected(styi.m_stuName);
	// Select the "Next Style" values from styi for the combobox.
	if (styi.m_st == kstCharacter)
	{
		icombobox = -1; // Makes it blank.
		::EnableWindow(m_hwndNext, false); // And disables it.
	}
	else
	{
		strTemp = m_pafsd->GetNameOfStyle(styi.m_hvoNext);
		icombobox = ::SendMessage(m_hwndNext, CB_FINDSTRINGEXACT, 0,
			(LPARAM)strTemp.Chars());
		// Disable the control for styles originally provided by FieldWorks.
		::EnableWindow(m_hwndNext, !fProtectedStyle);
	}
	::SendMessage(m_hwndNext, CB_SETCURSEL, icombobox, 0);
}
Exemple #20
0
/*----------------------------------------------------------------------------------------------
	Loads the "basedOn" combox for the specified style
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::LoadBasedOnStyleCombobox(StyleInfo & styi)
{
	StrApp strName = styi.m_stuName;
	StrApp strTemp; // Temporary string.
	// "Based On" combobox.
	::SendMessage(m_hwndBasedOn, CB_RESETCONTENT, 0, 0);
	for (int istyi = 0; istyi < m_pafsd->m_vstyi.Size(); istyi++)
	{
		StyleInfo * pstyiTemp = &m_pafsd->m_vstyi[istyi];
		if (pstyiTemp->m_fDeleted)
			continue;
		if ((pstyiTemp->m_nContext == knContextInternal ||
			pstyiTemp->m_nContext == knContextInternalMappable) && !styi.m_fBuiltIn)
			continue;
		strTemp = pstyiTemp->m_stuName;
		if (pstyiTemp->m_st == styi.m_st)
		{
			// The based-on list should not include any style that is already based on the
			// newly selected one, even indirectly.
			if (strName != strTemp && !m_pafsd->IsBasedOn(pstyiTemp, styi.m_hvoStyle))
				::SendMessage(m_hwndBasedOn, CB_ADDSTRING, 0, (LPARAM)strTemp.Chars());
		}
	}
}
Exemple #21
0
/*----------------------------------------------------------------------------------------------
	Replace strOldName with strNewName in the BasedOn and Next comboboxes.
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::UpdateComboboxes(StrApp & strOldName, StrApp & strNewName)
{
	if (!m_pafsd->StyleIsSelected())
		return;

	StyleInfo styiSelected = m_pafsd->SelectedStyle();
	StrApp strTemp;
	int icombobox;

	// Update the name in the BasedOn combobox if it is there.
	icombobox = ::SendMessage(m_hwndBasedOn, CB_FINDSTRINGEXACT, 0, (LPARAM)strOldName.Chars());
	if (CB_ERR != icombobox)
	{
		::SendMessage(m_hwndBasedOn, CB_DELETESTRING, icombobox, 0);
		::SendMessage(m_hwndBasedOn, CB_ADDSTRING, 0, (LPARAM)strNewName.Chars());
		// Select the BasedOn value.
		strTemp = m_pafsd->GetNameOfStyle(styiSelected.m_hvoBasedOn);
		icombobox = ::SendMessage(m_hwndBasedOn, CB_FINDSTRINGEXACT, 0,
			(LPARAM)strTemp.Chars());
		if (CB_ERR != icombobox)
			::SendMessage(m_hwndBasedOn, CB_SETCURSEL, icombobox, 0);
	}

	// Update the name in the Next combobox, but only for a paragraph style.
	if (kstParagraph == styiSelected.m_st)
	{
		icombobox = ::SendMessage(m_hwndNext, CB_FINDSTRINGEXACT, 0,
			(LPARAM)strOldName.Chars());
		if (CB_ERR != icombobox)
		{
			::SendMessage(m_hwndNext, CB_DELETESTRING, icombobox, 0);
			::SendMessage(m_hwndNext, CB_ADDSTRING, 0, (LPARAM)strNewName.Chars());
			// Select the "Next Style" value.
			strTemp = m_pafsd->GetNameOfStyle(styiSelected.m_hvoNext);
			icombobox = ::SendMessage(m_hwndNext, CB_FINDSTRINGEXACT, 0,
				(LPARAM)strTemp.Chars());
			if (CB_ERR != icombobox)
				::SendMessage(m_hwndNext, CB_SETCURSEL, icombobox, 0);
		}
	}
	return;
}
Exemple #22
0
void AppendOffsetInfo(StrApp & strDesc, int mpOffset, bool & fFirst)
{
	if (mpOffset && mpOffset != knNinch)
	{
		StrApp strFmt;
		if (mpOffset < 0)
			strFmt.Load(kstidLoweredFmt);
		else
			strFmt.Load(kstidRaisedFmt);
		StrApp strAmt;
		StrAppBuf strb;
		AfUtil::MakeMsrStr (abs(mpOffset) , knpt, &strb);
		StrApp strT;
		strT.Format(strFmt.Chars(), strb.Chars());
		AppendDescPart(strDesc, strT, fFirst);
	}
}
Exemple #23
0
/*----------------------------------------------------------------------------------------------
	Get the final values for the dialog controls, after the dialog has been closed.
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::GetDialogValues(StyleInfo & styi, bool & fBasedOnChanged)
{
	StrUni stuName = GetName();
	StrApp strName = stuName;
	achar rgcha[1024];
	Vector<achar> vch;
	achar * pszT;
	memcpy(rgcha, strName.Chars(), strName.Length() * isizeof(achar));
	if (stuName != styi.m_stuName)
	{
		StrApp strOldName(styi.m_stuName);
		StrApp strNewName(stuName);
		if (!m_pafsd->SetName(styi, stuName))
		{
			// Error: restore the old name.
			::SetDlgItemText(m_hwnd, kctidFgEdName, strOldName.Chars());
		}
		// Otherwise update the comboboxes for BasedOn and Next.
		// This allows the later code which reads from them to work correctly,
		// so it is worth doing even here in a read routine.
		// Also update the edit box to handle stripping of leading/trailing blanks.
		else
		{
			::SetDlgItemText(m_hwnd, kctidFgEdName, strNewName.Chars());
			UpdateComboboxes(strOldName, strNewName);
		}
	}

	int iitem = ::SendMessage(m_hwndBasedOn, CB_GETCURSEL, 0,0);
	// <0 means the item is blank (e.g., Normal is not based on anything).
	// But if we pass -1 to CB_GETLBTEXT, we get the text of the first item.
	// This can change Normal to be based on Normal, with bad consequences.
	//
	if (iitem < 0)
	{
		pszT = _T("");
	}
	else
	{
		int cch = ::SendMessage(m_hwndBasedOn, CB_GETLBTEXTLEN, (WPARAM)iitem, 0);
		if (cch < 1024)
		{
			pszT = rgcha;
		}
		else
		{
			vch.Resize(cch + 1);
			pszT = vch.Begin();
		}
		cch = ::SendMessage(m_hwndBasedOn, CB_GETLBTEXT, iitem, (long)pszT);
		if (cch < 0)
			pszT = _T("");
	}
	stuName = pszT;
	HVO hvoBasedOn = m_pafsd->GetHvoOfStyleNamed(stuName);
	if (styi.m_hvoBasedOn != hvoBasedOn)
	{
		m_pafsd->SetBasedOn(styi, hvoBasedOn); // Sets m_fDirty.

		// Note that this is initialised to false in AfStylesDlg::UpdateTabCtrl.
		fBasedOnChanged = true;
	}

	iitem = ::SendMessage(m_hwndNext, CB_GETCURSEL, 0,0);
	if (iitem < 0)
	{
		pszT = _T("");
	}
	else
	{
		int cch = ::SendMessage(m_hwndNext, CB_GETLBTEXTLEN, (WPARAM)iitem, 0);
		if (cch < 1024)
		{
			pszT = rgcha;
		}
		else
		{
			vch.Resize(cch + 1);
			pszT = vch.Begin();
		}
		cch = ::SendMessage(m_hwndNext, CB_GETLBTEXT, iitem, (long)pszT);
		if (cch < 0)
			pszT = _T("");
	}
	stuName = pszT;
	HVO hvoNext = m_pafsd->GetHvoOfStyleNamed(stuName);
	if ((styi.m_hvoNext != hvoNext) && (styi.m_st != kstCharacter))
	{
		m_pafsd->SetNext(styi, hvoNext); // Sets m_fDirty.
	}
} //:> FmtGenDlg::GetDialogValues.
Exemple #24
0
/*----------------------------------------------------------------------------------------------
	Set the values for the dialog controls based on the style styi.
	@param vwsProj Union of the current Vernacular and Analysis encodings for the project.
----------------------------------------------------------------------------------------------*/
void FmtGenDlg::SetDialogValues(StyleInfo & styi, Vector<int> & vwsProj)
{
	// During SetDialogValues we never need to handle loss of focus in the name control,
	// because if anything needed to be done about updating that, it was done during
	// GetDialogValues, which is always called before SetDialogValues. We need to suppress it
	// because during this call the current style index and the current value of the control
	// may not agree: the purpose of this method is to update the control from the new style.
	// The normal loss-of-focus code is trying to synchronize in the opposite direction, and
	// can cause problems, for example, when we are disabling the control. For example:
	//  - Disabling the window causes it to lose focus if it previously had focus.
	//  - There is a kill focus event that tries to make the contents of the box agree with
	//		the name of the current style.
	//	- when this method is called, the old style is still the current one, so if we
	//		already changed the text in the box, we wind up trying to rename the old style
	//		to the name of the 'provided' style and produce a name conflict error.

	try
	{
		m_vwsProj = vwsProj;

		StrApp strDesc;
		m_fSuppressLossOfFocus = true;
		StrApp strName = styi.m_stuName;
		StrApp strTemp; // Temporary string.
		bool fProtectedStyle = m_pafsd->IsStyleProtected(styi.m_stuName);

		// Name edit box.
		::SetDlgItemText(m_hwnd, kctidFgEdName, strName.Chars());
		// Diable the control for styles originally provided by FieldWorks.
		::EnableWindow(m_hwndName, !fProtectedStyle);

		// Style type ltext.
		switch (styi.m_st)
		{
		case kstParagraph:
			strTemp.Load(kstidParagraph);
			break;
		case kstCharacter:
			strTemp.Load(kstidCharacter);
			break;
		default:
			Assert(false); // Should not happen.
		}
		::SetWindowText(m_hwndType, strTemp.Chars());

		// Update the "next" and "basedOn" comboboxes
		LoadNextStyleCombobox(styi);
		SetNextStyleComboboxValue(styi);
		LoadBasedOnStyleCombobox(styi);
		SetBasedOnStyleComboboxValue(styi);

		// ENHANCE LarryW(JohnT): When shortcut is implemented initialize the value instead.
		::EnableWindow(m_hwndShortcut, false); // Disables it.

		// **************************************
		m_vesi.Clear();
		strDesc = m_pafsd->GetNameOfStyle(styi.m_hvoBasedOn);
		strDesc.Append(" + ");

		ITsTextProps * pttp = styi.m_qttp;
		if (pttp)
		{
			StrApp strT;
			StrAppBuf strb; // a temp, used for making strings with units

			// Add default font info
			bool fFirstPart = true;
			SmartBstr sbstr;
			CheckHr(pttp->GetStrPropValue(ktptFontFamily, &sbstr));
			StrUni stuFont(sbstr.Chars());
			AppendDescPart(strDesc, FwStyledText::FontStringMarkupToUi(false, stuFont), fFirstPart);
			int val, var;
			CheckHr(pttp->GetIntPropValues(ktptFontSize, &var, &val));
			if (var != -1)
			{
				AfUtil::MakeMsrStr (val , knpt, &strb);
				AppendDescPart(strDesc, strb, fFirstPart);
			}
			CheckHr(pttp->GetIntPropValues(ktptBold, &var, &val));
			if (val == kttvForceOn || val == kttvInvert)
				AppendDescPart(strDesc, kstidBold, fFirstPart);
			CheckHr(pttp->GetIntPropValues(ktptItalic, &var, &val));
			if (val == kttvForceOn || val == kttvInvert)
				AppendDescPart(strDesc, kstidItalic, fFirstPart);
			CheckHr(pttp->GetIntPropValues(ktptSuperscript, &var, &val));
			if (val == kssvSuper)
				AppendDescPart(strDesc, kstidFfdSuperscript, fFirstPart);
			else if (val == kssvSub)
				AppendDescPart(strDesc, kstidFfdSubscript, fFirstPart);

			AppendTextIs(strDesc, (COLORREF)ReadValOrNinch(pttp, ktptForeColor),
				(COLORREF)ReadValOrNinch(pttp, ktptBackColor), fFirstPart);

			AppendUnderlineInfo(strDesc, (COLORREF)ReadValOrNinch(pttp, ktptUnderColor),
				ReadValOrNinch(pttp, ktptUnderline), fFirstPart);

			AppendOffsetInfo(strDesc, ReadValOrNinch(pttp, ktptOffset), fFirstPart);

			// Add info about other tabs
			int nDir = ReadValOrNinch(pttp, ktptRightToLeft);
			AddIf(strDesc, nDir == 0, kstidLeftToRight, fFirstPart);
			AddIf(strDesc, nDir == 1, kstidRightToLeft, fFirstPart);

			static const Keyval rgkeyvals[] =
			{
				{ktalLeading, kstidFpAlignLead},
				{ktalLeft, kstidFpAlignLeft},
				{ktalCenter, kstidFpAlignCenter},
				{ktalRight, kstidFpAlignRight},
				{ktalTrailing, kstidFpAlignTrail},
				{ktalJustify, kstidFpAlignJustify}, //TODO: support when in use.
				{0, 0}
			};
			AddFromList(strDesc, ReadValOrNinch(pttp, ktptAlign), rgkeyvals, fFirstPart);

			int nLeadIndent = ReadValOrNinch(pttp, ktptLeadingIndent);
			int nTrailIndent = ReadValOrNinch(pttp, ktptTrailingIndent);
			int nFirstIndent = ReadValOrNinch(pttp, ktptFirstIndent);
			if (nLeadIndent != knNinch || nTrailIndent != knNinch || nFirstIndent != knNinch)
			{
				AppendDescPart(strDesc, kstidIndentColon, fFirstPart);
				AppendMeasurement(strDesc, nLeadIndent, m_nMsrSys, kstidLeadingFmt);
				if (nFirstIndent != knNinch)
				{
					if (nFirstIndent < 0)
						AppendMeasurement(strDesc, -nFirstIndent, m_nMsrSys, kstidHangingFmt);
					else
						AppendMeasurement(strDesc, nFirstIndent, m_nMsrSys, kstidFirstLineFmt);
				}
				AppendMeasurement(strDesc, nTrailIndent, m_nMsrSys, kstidTrailingFmt);
			}
			// line spacing
			CheckHr(pttp->GetIntPropValues(ktptLineHeight, &var, &val));
			StrApp strSpacing;
			StrApp strFmt;
			if (var == ktpvMilliPoint)
			{
				if (val < 0)
					strFmt.Load(kstidFpLsExactFmt);
				else
					strFmt.Load(kstidFpLsAtLeastFmt);
				StrAppBuf strb;
				AfUtil::MakeMsrStr (val , knpt, &strb);
				strSpacing.Format(strFmt.Chars(), strb.Chars());
			}
			else if (var == ktpvRelative)
			{
				if (val >= kdenTextPropRel * 2)
					strSpacing.Load(kstidFpLsDouble);
				else if (val >= kdenTextPropRel * 3 / 2)
					strSpacing.Load(kstidFpLs15Lines);
				else
					strSpacing.Load(kstidFpLsSingle);
			}
			if (strSpacing.Length() != 0)
			{
				strFmt.Load(kstidLineSpacingFmt);
				strT.Format(strFmt.Chars(), strSpacing.Chars());
				AppendDescPart(strDesc, strT, fFirstPart);
			}

			int mpBefore = ReadValOrNinch(pttp, ktptSpaceBefore);
			int mpAfter = ReadValOrNinch(pttp, ktptSpaceAfter);
			if (mpBefore != knNinch || mpAfter != knNinch)
			{
				AppendDescPart(strDesc, kstidSpace, fFirstPart);
				AppendMeasurement(strDesc, mpBefore, knpt, kstidBeforeFmt);
				AppendMeasurement(strDesc, mpAfter, knpt, kstidAfterFmt);
			}

			int bulnum = ReadValOrNinch(pttp, ktptBulNumScheme);
			AddIf(strDesc, bulnum >= kvbnBulletBase && bulnum < kvbnBulletMax,
				kstidBulleted, fFirstPart);
			AddIf(strDesc, bulnum >= kvbnNumberBase && bulnum < kvbnNumberMax,
				kstidNumbered, fFirstPart);

			int mpBTop = ReadValOrNinch(pttp, ktptBorderTop);
			int mpBB = ReadValOrNinch(pttp, ktptBorderBottom);
			int mpBL = ReadValOrNinch(pttp, ktptBorderLeading);
			int mpBTr = ReadValOrNinch(pttp, ktptBorderTrailing);

			if (mpBTop != knNinch || mpBB != knNinch || mpBL != knNinch || mpBTr != knNinch)
			{
				AppendDescPart(strDesc, kstidBorderColon, fFirstPart);
				int clrBorder = ReadValOrNinch(pttp, ktptBorderColor);
				bool fFirstBorder = true;
				if (clrBorder != knNinch)
				{
					StrApp strClr;
					strClr.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrBorder)));
					strDesc.Append(strClr.Chars());
					fFirstBorder = false;
				}
				AppendBorderInfo(strDesc, mpBTop, kstidTopBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBB, kstidBottomBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBL, kstidLeadingBdrFmt, fFirstBorder);
				AppendBorderInfo(strDesc, mpBTr, kstidTrailingBdrFmt, fFirstBorder);
			}


			// Add info about writing-system overrides of font info.
			Vector<int> vwsSoFar;


			// Get the appropropriate writing system factory.
			ILgWritingSystemFactoryPtr qwsf;
			AssertPtr(m_pafsd);
			m_pafsd->GetLgWritingSystemFactory(&qwsf);
			AssertPtr(qwsf);
		//-		IWritingSystemPtr qws;

			// Each iteration of this loop processes information about one writing system.
			SmartBstr sbstrCharStyles;
			CheckHr(pttp->GetStrPropValue(kspWsStyle, &sbstrCharStyles));
			if (sbstrCharStyles.Length())
			{
				FwStyledText::DecodeFontPropsString(sbstrCharStyles, m_vesi, vwsSoFar);

				SmartBstr sbstrWs;
				StrApp strWs;
				int wsUser;
				CheckHr(qwsf->get_UserWs(&wsUser));
				SmartBstr sbstrAbbr;
				for (int iesi = 0; iesi < m_vesi.Size(); iesi++)
				{
					WsStyleInfo & esi = m_vesi[iesi];
					if (vwsSoFar[iesi] == 0)
						continue;		// Ignore writing system set to 0.
					fFirstPart = true;
					StrApp strT;
					StrApp strT2;
					strT.Format(_T("\n"));
					// Use the abbreviation in the user ws if it exists.
					// else try for an abbreviation in each ws in m_vwsProj in turn,
					// else use the ICU locale name as a last resort.
					IWritingSystemPtr qws;
					CheckHr(qwsf->GetStrFromWs(vwsSoFar[iesi], &sbstrWs));
					CheckHr(qwsf->get_Engine(sbstrWs, &qws));
					CheckHr(qws->get_Abbr(wsUser, &sbstrAbbr));
					if (sbstrAbbr.Length() == 0)
					{
						for (int iws = 0; iws < m_vwsProj.Size(); ++iws)
						{
							CheckHr(qws->get_Abbr(m_vwsProj[iws], &sbstrAbbr));
							if (sbstrAbbr.Length() != 0)
								break;
						}
					}
					if (sbstrAbbr.Length() == 0)
						strWs.Assign(sbstrWs.Chars(), sbstrWs.Length());
					else
						strWs.Assign(sbstrAbbr.Chars(), sbstrAbbr.Length());
					strT2.Format(_T("%s: "), strWs.Chars());
					if (strT2 == _T("___: "))
						strT2.Load(kctidFgUnknown);
					strT.Append(strT2);
					strDesc.Append (strT);
					AppendDescPart(strDesc,
						FwStyledText::FontStringMarkupToUi(false, esi.m_stuFontFamily),
						fFirstPart);
					if (esi.m_mpSize != knNinch)
					{
						AfUtil::MakeMsrStr (esi.m_mpSize , knpt, &strb);
						AppendDescPart(strDesc, strb, fFirstPart);
					}
					if (esi.m_fBold == kttvForceOn || esi.m_fBold == kttvInvert)
						AppendDescPart(strDesc, kstidBold, fFirstPart);
					if (esi.m_fItalic == kttvForceOn || esi.m_fItalic == kttvInvert)
						AppendDescPart(strDesc, kstidItalic, fFirstPart);
					if (esi.m_ssv == kssvSuper)
						AppendDescPart(strDesc, kstidFfdSuperscript, fFirstPart);
					else if (esi.m_ssv == kssvSub)
						AppendDescPart(strDesc, kstidFfdSubscript, fFirstPart);
					AppendTextIs(strDesc, esi.m_clrFore, esi.m_clrBack, fFirstPart);

					AppendUnderlineInfo(strDesc, esi.m_clrUnder, esi.m_unt, fFirstPart);

					AppendOffsetInfo(strDesc, esi.m_mpOffset, fFirstPart);
				} // 'for' loop
			}
		}
		::SetDlgItemText(m_hwnd, kctidFgDescription, strDesc.Chars());
// **************************************
	}
	catch(...)
	{
		m_fSuppressLossOfFocus = false;
		throw;
	}
	m_fSuppressLossOfFocus = false;
} //:> FmtGenDlg::SetDialogValues.
Exemple #25
0
// Append to strDesc appropriate info about underline if any.
void AppendUnderlineInfo(StrApp & strDesc, COLORREF clrUnder, int unt, bool & fFirst)
{
	StrApp strColor;
	if (clrUnder != (COLORREF)knNinch)
		strColor.Load(g_ct.GetColorRid(g_ct.GetIndexFromColor(clrUnder)));
	StrApp strFmt;
	switch (unt)
	{
	case kuntDotted:
		strFmt.Load(kstidDottedUnderFmt);
		break;
	case kuntDashed:
		strFmt.Load(kstidDashedUnderFmt);
		break;
	case kuntStrikethrough:
		strFmt.Load(kstidStrikethroughUnderFmt);
		break;
	case kuntSingle:
		strFmt.Load(kstidSingleUnderFmt);
		break;
	case kuntDouble:
		strFmt.Load(kstidDoubleUnderFmt);
		break;
	default:
		return;
	}
	StrApp strT;
	strT.Format(strFmt.Chars(), strColor.Chars());
	AppendDescPart(strDesc, strT, fFirst);
}
Exemple #26
0
/*----------------------------------------------------------------------------------------------
	Handle a change in a combo box.
----------------------------------------------------------------------------------------------*/
bool FmtGenDlg::OnComboChange(NMHDR * pnmh, long & lnRet)
{
	AssertPtr(pnmh);

	// Do nothing if we're not handling a change in the based on style name combo.
	if (pnmh->idFrom != kctidFgCbBasedOn)
	{
		lnRet = 0;
		return true;
	}

	achar rgchaName[1024]; // Name in the combobox.
	Vector<achar> vch;
	achar * pszT;
	bool fKeepChange = true;

	// Get the name from the combobox.
	int index = ::SendMessage(m_hwndBasedOn, CB_GETCURSEL, 0, 0);
	int cch = ::SendMessage(m_hwndBasedOn, CB_GETLBTEXTLEN, index, (LPARAM)0);
	if (cch < 1024)
		pszT = rgchaName;
	else
	{
		vch.Resize(cch + 1);
		pszT = vch.Begin();
	}

	cch = ::SendMessage(m_hwndBasedOn, CB_GETLBTEXT, index, (long)pszT);
	if (cch < 0)
		pszT = _T("");

	// Trim leading and trailing space characters.
	StrApp strNewBasedOnName;
	StrUtil::TrimWhiteSpace(pszT, strNewBasedOnName);

	// Get the name of the style whose based on style is being changed.
	StrUni stuCurrStyleName(m_pafsd->GetNameOfSelectedStyle());

	// Get the HVO of the new based on style.
	StrUni stuName;
	stuName.Assign(strNewBasedOnName);
	HVO hvoNewBasedOn = m_pafsd->GetHvoOfStyleNamed(stuName);

	// Check that the selected style will not be based on itself.
	if (stuCurrStyleName.Equals(strNewBasedOnName))
		fKeepChange = false;
	else
	{
		int hvo = m_pafsd->GetBasedOnHvoOfStyle(hvoNewBasedOn);

		// Loop through the inheritance chain to make sure none of the based on
		// styles are the same as the currently selected style.
		while (hvo && fKeepChange)
		{
			if (stuCurrStyleName.Equals(m_pafsd->GetNameOfStyle(hvo)))
				fKeepChange = false;
			else
				hvo = m_pafsd->GetBasedOnHvoOfStyle(hvo);
		}
	}

	// If keeping the new based on style, then notify the styles dialog of its change.
	if (fKeepChange)
	{
		StyleInfo styi = m_pafsd->SelectedStyle();
		m_pafsd->SetBasedOn(styi, hvoNewBasedOn);
		m_pafsd->BasedOnStyleChangeNotification(hvoNewBasedOn);
		LoadNextStyleCombobox(styi);
		SetNextStyleComboboxValue(styi);
	}
	else
	{
		StrApp strMsg(kstidAfsdSameBasedOnMsg);
		StrApp strMsgTitle(kstidStyles);
		// Raise a message alerting the user to his mistake.
		::MessageBox(m_hwnd, strMsg.Chars(), strMsgTitle.Chars(), MB_OK | MB_ICONINFORMATION);

		// Return the combobox to its original value.
		strNewBasedOnName = m_pafsd->GetNameOfStyle(m_pafsd->SelectedStyle().m_hvoBasedOn);
		int index = ::SendMessage(m_hwndBasedOn, CB_FINDSTRINGEXACT, 0,
			(LPARAM)strNewBasedOnName.Chars());

		::SendMessage(m_hwndBasedOn, CB_SETCURSEL, index, 0);
	}

	lnRet = 0;
	return true;
} //:> FmtGenDlg::OnComboChange.
void StackDumper::ShowStackCore( HANDLE hThread, CONTEXT& c )
{
	// This makes this code custom for 32-bit windows. There is a technique to find out what
	// machine type we are running on, but this should do us for a good while.
	DWORD imageType = IMAGE_FILE_MACHINE_I386;

	HANDLE hProcess = GetCurrentProcess();
	int frameNum; // counts walked frames
	DWORD offsetFromSymbol; // tells us how far from the symbol we were
	DWORD symOptions; // symbol handler settings
	IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *) malloc( IMGSYMLEN + MAXNAMELEN );
	IMAGEHLP_MODULE Module;
	IMAGEHLP_LINE Line;
	StrApp strSearchPath; // path to search for symbol tables (I think...JT)
	achar *tt = 0;

	STACKFRAME s; // in/out stackframe
	memset( &s, '\0', sizeof s );

	tt = new achar[TTBUFLEN];
	if (!tt)
		return;

	// Build symbol search path.
	// Add current directory
	if (::GetCurrentDirectory( TTBUFLEN, tt ) )
		AppendToStaWithSep(strSearchPath, tt);
	// Add directory containing executable or DLL we are running in.
	if (::GetModuleFileName( 0, tt, TTBUFLEN ) )
	{
		StrUni stuPath = tt; // convert to Unicode if necessary, allows use of wchars
		const OLECHAR * pchPath =  stuPath.Chars();

		const OLECHAR * pch;
		for (pch = pchPath + wcslen(pchPath) - 1; pch >= pchPath; -- pch )
		{
			// locate the rightmost path separator
			if ( *pch == L'\\' || *pch == L'/' || *pch == L':' )
				break;
		}
		// if we found one, p is pointing at it; if not, tt only contains
		// an exe name (no path), and p points before its first byte
		if ( pch != pchPath ) // path sep found?
		{
			if ( *pch == L':' ) // we leave colons in place
				++ pch;
			if (strSearchPath.Length())
				strSearchPath.Append(";");
			strSearchPath.Append(pchPath, (pch - pchPath));
		}
	}
	// environment variable _NT_SYMBOL_PATH
	if (::GetEnvironmentVariable( _T("_NT_SYMBOL_PATH"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);
	// environment variable _NT_ALTERNATE_SYMBOL_PATH
	if (::GetEnvironmentVariable( _T("_NT_ALTERNATE_SYMBOL_PATH"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);
	// environment variable SYSTEMROOT
	if (::GetEnvironmentVariable( _T("SYSTEMROOT"), tt, TTBUFLEN ))
		AppendToStaWithSep(strSearchPath, tt);

	// Why oh why does SymInitialize() want a writeable string? Surely it doesn't modify it...
	// The doc clearly says it is an [in] parameter.
	// Also, there is not a wide character version of this function!
	StrAnsi staT(strSearchPath);
	if ( !::SymInitialize( hProcess, const_cast<char *>(staT.Chars()), false ) )
		goto LCleanup;

	// SymGetOptions()
	symOptions = SymGetOptions();
	symOptions |= SYMOPT_LOAD_LINES;
	symOptions &= ~SYMOPT_UNDNAME;
	SymSetOptions( symOptions ); // SymSetOptions()

	// Enumerate modules and tell imagehlp.dll about them.
	// On NT, this is not necessary, but it won't hurt.
	EnumAndLoadModuleSymbols( hProcess, GetCurrentProcessId() );

	// init STACKFRAME for first call
	// Notes: AddrModeFlat is just an assumption. I hate VDM debugging.
	// Notes: will have to be #ifdef-ed for Alphas; MIPSes are dead anyway,
	// and good riddance.
	s.AddrPC.Offset = c.Eip;
	s.AddrPC.Mode = AddrModeFlat;
	s.AddrFrame.Offset = c.Ebp;
	s.AddrFrame.Mode = AddrModeFlat;

	memset( pSym, '\0', IMGSYMLEN + MAXNAMELEN );
	pSym->SizeOfStruct = IMGSYMLEN;
	pSym->MaxNameLength = MAXNAMELEN;

	memset( &Line, '\0', sizeof Line );
	Line.SizeOfStruct = sizeof Line;

	memset( &Module, '\0', sizeof Module );
	Module.SizeOfStruct = sizeof Module;

	offsetFromSymbol = 0;

	if (!m_pstaDump)
	{
		try
		{
			m_pstaDump = NewObj StrAnsiBufHuge;
		}
		catch (...)
		{
			goto LCleanup;
		}
	}

	// If the stack dump gets too big, we remove some entries from near the
	// middle, and insert a marker. This counts the characters up to the
	// end of the marker.
	int ichEndLowHalf;
	ichEndLowHalf = 0;

	m_pstaDump->FormatAppend( "\r\n--# FV EIP----- RetAddr- FramePtr StackPtr Symbol\r\n" );
	// EberhardB: a stack of 1.000 frames should be enough in most cases; limiting it
	// prevents a mysterious infinite(?) loop on our build machine.
	for ( frameNum = 0; frameNum < 1000; ++ frameNum )
	{
		// get next stack frame (StackWalk(), SymFunctionTableAccess(), SymGetModuleBase())
		// if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
		// assume that either you are done, or that the stack is so hosed that the next
		// deeper frame could not be found.
		if ( ! StackWalk( imageType, hProcess, hThread, &s, &c, NULL,
			SymFunctionTableAccess, SymGetModuleBase, NULL ) )
			break;

		// display its contents
		m_pstaDump->FormatAppend( "%3d %c%c %08x %08x %08x %08x ",
			frameNum, s.Far? 'F': '.', s.Virtual? 'V': '.',
			s.AddrPC.Offset, s.AddrReturn.Offset,
			s.AddrFrame.Offset, s.AddrStack.Offset );

		if ( s.AddrPC.Offset == 0 )
		{
			m_pstaDump->Append( "(-nosymbols- PC == 0)\r\n" );
		}
		else
		{ // we seem to have a valid PC
			char undName[MAXNAMELEN]; // undecorated name
			//char undFullName[MAXNAMELEN]; // undecorated name with all shenanigans
			// show procedure info (SymGetSymFromAddr())
			if ( ! SymGetSymFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, pSym ) )
			{
				if ( gle != 487 )
					m_pstaDump->FormatAppend( "SymGetSymFromAddr(): gle = %u\r\n", gle );
			}
			else
			{
				UnDecorateSymbolName( pSym->Name, undName, MAXNAMELEN, UNDNAME_NAME_ONLY );
				//UnDecorateSymbolName( pSym->Name, undFullName, MAXNAMELEN, UNDNAME_COMPLETE );
				m_pstaDump->Append( undName );
				//if ( offsetFromSymbol != 0 )
				//	m_pstaDump->FormatAppend( " %+d bytes", offsetFromSymbol );
				//m_pstaDump->FormatAppend( "\r\n    Sig:  %s\r\n", pSym->Name );
				//m_pstaDump->FormatAppend( "\r\n    Decl: %s\r\n", undFullName );
			}

			// show line number info, NT5.0-method (SymGetLineFromAddr()). If we can't get this function,
			// or it doesn't work, leave out line number info.
			if (! g_pfnSymGetLineFromAddr)
			{
				StrApp staModName("IMAGEHLP.DLL");
				g_pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR) GetProcAddress(
					GetModuleHandle(staModName.Chars()), "SymGetLineFromAddr");
			}
			if (! g_pfnSymGetLineFromAddr ||
				! g_pfnSymGetLineFromAddr( hProcess, s.AddrPC.Offset, &offsetFromSymbol, &Line ) )
			{
				if ( g_pfnSymGetLineFromAddr && gle != 487 ) // apparently a magic number indicating not in symbol file.
					m_pstaDump->FormatAppend( "SymGetLineFromAddr(): gle = %u\r\n", gle );
				else
					m_pstaDump->FormatAppend( "   (no line # avail)\r\n");

			}
			else
			{
				m_pstaDump->FormatAppend( "   %s(%u)\r\n",
					Line.FileName, Line.LineNumber );
			}

#ifdef JT_20010626_WantModuleInfo
			// If we want this info adapt the printf and _snprintf in the following.

			// show module info (SymGetModuleInfo())
			if ( ! SymGetModuleInfo( hProcess, s.AddrPC.Offset, &Module ) )
			{
				m_pstaDump->FormatAppend( "SymGetModuleInfo): gle = %u\r\n", gle );
			}
			else
			{ // got module info OK
				m_pstaDump->FormatAppend( "    Mod:  %s[%s], base: 0x%x\r\n    Sym:  type: ",
					Module.ModuleName, Module.ImageName, Module.BaseOfImage );
				switch ( Module.SymType )
					{
					case SymNone:
						m_pstaDump->FormatAppend( "-nosymbols-");
						break;
					case SymCoff:
						m_pstaDump->FormatAppend( "COFF");
						break;
					case SymCv:
						m_pstaDump->FormatAppend( "CV");
						break;
					case SymPdb:
						m_pstaDump->FormatAppend( "PDB");
						break;
					case SymExport:
						m_pstaDump->FormatAppend( "-exported-");
						break;
					case SymDeferred:
						m_pstaDump->FormatAppend( "-deferred-");
						break;
					case SymSym:
						m_pstaDump->FormatAppend( "SYM");
						break;
					default:
						m_pstaDump->FormatAppend( "symtype=%d", (long) Module.SymType);
						break;
					}
				m_pstaDump->FormatAppend( ", file: %s\r\n", Module.LoadedImageName);
			} // got module info OK
#endif // JT_20010626_WantModuleInfo

			// We don't want to return more than about 10K of info (enough for an email).
			// This also serves to make sure there's enough room in the buffer for more.
			// The idea is that we'd like to keep both the top and bottom of the stack.
			// So we delete frames from the middle until we have less than 10K.
			if (m_pstaDump->Length() > MAXDUMPLEN)
			{
				if (!ichEndLowHalf)
				{
					static char * pszGap =
						"\r\n\r\n\r\n******************Frames skipped here***************\r\n\r\n\r\n";
					int cchGap = strlen(pszGap);
					ichEndLowHalf = FindStartOfFrame(MAXDUMPLEN / 2);
					// Overwrite some of what's there with the gap marker. The incomplete
					// frame will be part of what gets deleted.
					m_pstaDump->Replace(ichEndLowHalf, ichEndLowHalf + cchGap, pszGap, cchGap);
					ichEndLowHalf += cchGap;
				}
				int cchLeave = m_pstaDump->Length();
				int ichKeep = ichEndLowHalf;
				while (cchLeave > MAXDUMPLEN)
				{
					int ichKeepT = FindStartOfFrame(ichKeep + 1);
					cchLeave -= ichKeepT - ichKeep;
					ichKeep = ichKeepT;
				}
				m_pstaDump->Replace(ichEndLowHalf, ichKeep, (char *)NULL, 0);
			}

		} // we seem to have a valid PC

		// no return address means no deeper stackframe
		if ( s.AddrReturn.Offset == 0 )
		{
			// avoid misunderstandings in the printf() following the loop
			SetLastError( 0 );
			break;
		}

	} // for ( frameNum )

	if ( gle != 0 )
		printf( "\r\nStackWalk(): gle = %u\r\n", gle );

LCleanup:
	ResumeThread( hThread );
	// de-init symbol handler etc.
	SymCleanup( hProcess );
	free( pSym );
	delete [] tt;

#ifdef DEBUG
	::OutputDebugStringA(m_pstaDump->Chars());
#endif

}
Exemple #28
0
/*----------------------------------------------------------------------------------------------
	Set up the crawler to work on a given database.

	@param stuServerName - name of the database server
	@param stuDatabase - name of the database
	@param pstrmLog - pointer to the log stream (may be NULL)
	@param padvi3 - pointer to the progress report object (defaults to NULL)
----------------------------------------------------------------------------------------------*/
bool DbStringCrawler::Init(StrUni stuServerName, StrUni stuDatabase, IStream * pstrmLog,
	IAdvInd3 * padvi3)
{
	m_qstrmLog = pstrmLog;
	m_stuServerName = stuServerName;
	m_stuDatabase = stuDatabase;
	m_qadvi3 = padvi3;

	try
	{
		m_qode.CreateInstance(CLSID_OleDbEncap);
		// Get the IStream pointer for logging. NULL returned if no log file.
		StrUni stuMasterDb(L"master");
		CheckHr(m_qode->Init(m_stuServerName.Bstr(), stuMasterDb.Bstr(), m_qstrmLog,
			koltMsgBox, koltvForever));
		CreateCommand();
	}
	catch (...)
	{
		// Cannot connect to master database.
		StrApp strMsg;
		strMsg.Load(kstidCannotGetMasterDb);
		::MessageBox(NULL, strMsg.Chars(), m_strProgDlgTitle.Chars(), MB_OK | MB_ICONERROR);
		return false;
	}

	if (m_qadvi3)
		m_qadvi3->SetRange(0, 100);

#ifndef NO_AFMAINWINDOW
	if (!m_fDontCloseMainWnd)
	{
		m_fNeedRelaunch = true;
		// In closing the final window, FwTool is going to call
		// AfApp::DecExportedObjects() which would normally post a quit message to
		// the application if there is only one window open. We don't want it to
		// quit yet, so we need to temporarily add an extra count until we get our
		// new window open.
		AfApp::Papp()->IncExportedObjects();
		// Now close the current database with all its windows.
		AfApp::Papp()->CloseDbAndWindows(m_stuDatabase.Chars(), m_stuServerName.Chars(), false);

		// Give users time to log off, then force them off anyway:
		ComBool fDisconnected;
		try
		{
			IDisconnectDbPtr qdscdb;
			qdscdb.CreateInstance(CLSID_FwDisconnect);

			// Set up strings needed for disconnection:
			StrUni stuReason(kstidReasonDisconnectStrCrawl);
			// Get our own name:
			DWORD nBufSize = MAX_COMPUTERNAME_LENGTH + 1;
			achar rgchBuffer[MAX_COMPUTERNAME_LENGTH + 1];
			GetComputerName(rgchBuffer, &nBufSize);
			StrUni stuComputer(rgchBuffer);
			StrUni stuFmt(kstidRemoteReasonStrCrawl);
			StrUni stuExternal;
			stuExternal.Format(stuFmt.Chars(), stuComputer.Chars());

			qdscdb->Init(m_stuDatabase.Bstr(), stuServerName.Bstr(), stuReason.Bstr(),
				stuExternal.Bstr(), (ComBool)false, NULL, 0);
			qdscdb->DisconnectAll(&fDisconnected);
		}
		catch (...)
		{
			fDisconnected = false;
		}
		if (!fDisconnected)
		{
			// User canceled, or it was impossible to disconnect people. This will leave us in
			// possibly a funny state, and nothing will be changed, but at least we'll open up
			// a new window on the app.
			return false;
		}
	}
#endif
	return true;
}