created and maintained by tokd

DonutLModifiedVersion

Donut RAPT #96 を参考に Donut L31 をカスタマイズ

- ナビゲートロック時のタブ名の描写方法を変更


--- DonutL31_src/TabCtrl.h	2006-06-17 14:37:00.000000000 +0900
+++ DonutL31_hacked/TabCtrl.h	2006-12-20 13:57:21.028374400 +0900
@@ -211,6 +211,9 @@
 		else
 			uFortmat = DT_CENTER | DT_NOCLIP;
 		
+	// --84--
+#if 0
+/*
 		if (!(m_fsState & TCISTATE_ENABLED)) {
 			// disabled - draw shadow text shifted down and right 1 pixel (unles selected)
 			CRect rcDisabled = rcBtn + CPoint(1, 1);
@@ -223,6 +226,9 @@
 			dc.DrawText(str, -1, rcDisabled, DT_SINGLELINE | uFortmat | DT_VCENTER | DT_NOPREFIX);
 		}else	// added "else" by RAPT
 		// ENDE
+*/
+#endif
+	// ENDE
 			dc.DrawText(m_strItem, -1, rcBtn, DT_SINGLELINE | uFortmat | DT_VCENTER | DT_NOPREFIX);
 
 		dc.SetTextColor(clrOld);

- 「セキュリティ警告」ダイアログの抑止([はい]を選択)対応


--- DonutL31_src/DialogKiller.h	2006-10-25 00:24:12.000000000 +0900
+++ DonutL31_hacked/DialogKiller.h	2006-12-20 14:03:49.518729600 +0900
@@ -143,6 +143,12 @@
 				if (_Filter_ActiveXWarningDialog(hWnd, strCaption))
 					return true;
 
+				// --69--
+				if (_Filter_SecurityWarningDialog(hWnd, strCaption)){
+					return true;
+				}
+				// ENDE
+
 				_Filter_OfflineDialog(hWnd, strCaption);
 				_Filter_FileMoveErrorDialog(hWnd, strCaption);
 			}
@@ -236,6 +242,35 @@
 
 		return false;
 	}
+
+	// UDT RAPT --69-- test;
+	static bool _Filter_SecurityWarningDialog(CWindow wnd, const CString& strCaption)
+	{
+		if (strCaption.Find(MES_0196) == -1){
+			return false;
+		}
+		CWindow wndFirst = wnd.GetNextDlgGroupItem(NULL);
+		if( wndFirst.m_hWnd == NULL ){
+			return false;
+		}
+		CWindow wndInner = wnd.GetNextDlgGroupItem(wndFirst.m_hWnd);
+		CWindow wndCertificate = wnd.GetDlgItem(0x0000065E); // view certificate
+		if( wndInner.m_hWnd == NULL || wndCertificate.m_hWnd == NULL ){
+			return false;
+		}
+		CString strOneStaticText = MtlGetWindowText(wndInner.m_hWnd);
+		CString strCertificate   = MtlGetWindowText(wndCertificate.m_hWnd);
+		if (strOneStaticText.Find(MES_0197) != -1 &&
+			strCertificate.Find(MES_0198) != -1 )
+		{
+			// the button of dialog saying "Yes/No/View"
+			// each key code is: 1<IDOK>,2<IDNO>,1630<unknown> in decimal;
+			wnd.SendMessage(WM_COMMAND, MAKEWPARAM(IDYES, 0));
+			return true;
+		}
+		return false;
+	}
+	// ENDE
 };
 
 //__declspec(selectany) HHOOK CDialogKiller::s_hCreateHook = NULL;
--- DonutL31_src/LanguageResource.h	2006-04-05 15:10:20.000000000 +0900
+++ DonutL31_hacked/LanguageResource.h	2006-12-19 17:29:03.377033600 +0900
@@ -171,6 +171,9 @@
 
 #endif
 
+#define MES_0196 MSG_LANG("セキュリティの警告", "Security Alert")
+#define MES_0197 MSG_LANG("続行しますか?", "Do you want to proceed?")
+#define MES_0198 MSG_LANG("証明書の表示", "View Certificate")

- タブモードの時、子窓に閉じるボタンを表示しない


--- DonutL31_src/MenuControl.h	2004-04-11 02:24:54.000000000 +0900
+++ DonutL31_hacked/MenuControl.h	2006-12-20 14:37:34.861028800 +0900
@@ -267,7 +267,8 @@
 	void _InvalidateControls()
 	{
 		if (m_bOnlyCloseButton) {// invalidate only close button
-			InvalidateRect(m_arrCaption[0]);
+			if (CMainOption::s_dwMainExtendedStyle & 0) // MAIN_EX_DRAWCLOSEBTN
+				InvalidateRect(m_arrCaption[0]);
 			return;
 		}
 
@@ -279,8 +280,11 @@
 	void _DrawFrameControl(CDCHandle hDC, int nIndex, BOOL bPushed)
 	{
 		if (m_bOnlyCloseButton) {// do only 0(close button)
-			if (nIndex == 1 || nIndex == 2)
+			if (!(CMainOption::s_dwMainExtendedStyle & 0) || // MAIN_EX_DRAWCLOSEBTN
+				nIndex == 1 || nIndex == 2)
+			{
 				return;
+			}
 		}
 
 		// draw frame controls
@@ -295,10 +299,12 @@
 	int _HitTest(CPoint point)
 	{
 		if (m_bOnlyCloseButton) {// only check 0
-			if (m_arrCaption[0].PtInRect(point))
+			if (CMainOption::s_dwMainExtendedStyle & 0 && // MAIN_EX_DRAWCLOSEBTN
+				m_arrCaption[0].PtInRect(point))
+			{
 				return 0;
-			else
-				return -1;
+			}
+			return -1;
 		}
 
 		for (int i = 0; i < 3; ++i) {
@@ -312,11 +318,14 @@
 	int _HitTest(const CRect& rect)
 	{
 		if (m_bOnlyCloseButton) {// only check 0
-			CRect rcCross = m_arrCaption[0] & rect;
-			if (!rcCross.IsRectEmpty())
-				return 0;
-			else
-				return -1;
+			if (CMainOption::s_dwMainExtendedStyle & 0) // MAIN_EX_DRAWCLOSEBTN
+			{
+				CRect rcCross = m_arrCaption[0] & rect;
+				if (!rcCross.IsRectEmpty())
+					return 0;
+
+			}
+			return -1;
 		}
 
 		for (int i = 0; i < 3; ++i) {

- 「最近閉じたファイル」にて「戻る」「進む」の履歴対応


diff -ur DonutL31_src/ChildFrm.h DonutL31_hacked/ChildFrm.h
--- DonutL31_src/ChildFrm.h	2006-10-15 02:28:18.000000000 +0900
+++ DonutL31_hacked/ChildFrm.h	2006-12-20 15:36:08.493384000 +0900
@@ -79,6 +79,7 @@
 	int m_nSecureLockIcon;
 	bool m_bPrivacyImpacted;
 	// ENDE
+	UINT m_nTravelLogIndex;		// --66--
 
 
 // Constructor/Destructor
@@ -90,6 +91,7 @@
 		  m_wndBrowser(this, 7), m_FavMenu(this, ID_INSERTPOINT_CHILDFAVORITEMENU),
 		  m_nProgress(-1), m_nProgressMax(0), m_bPageFocusInitialized(false),
 		  m_bClosing(false), m_bWaitNavigateLock(true), m_hWndFocus(NULL), m_view(dwDefaultDLControlFlags)
+		, m_nTravelLogIndex(-1)		// --66--
 	{
 		// UDT RAPT --20--
 		m_nSecureLockIcon = secureLockIconUnsecure; /* 0 */
@@ -170,6 +172,10 @@
 		MESSAGE_HANDLER(WM_APPCOMMAND, OnAppCommand) // UDT RAPT [5 buttons mouse] (WinUser.h)
 
 		HANDLE_MESSAGE(WM_SETFOCUS)			// baseClass handler is not effective
+		// --66--
+		MSG_WM_APP_SETTRAVELLOGINDEX(OnSetTravelLogIndex)
+		MSG_WM_APP_GETTRAVELLOGINDEX(OnGetTravelLogIndex)
+		// ENDE
 
 		USER_MSG_WM_SAVE_OPTION(OnSaveOption)
 		USER_MSG_WM_MENU_GOBACK(OnMenuGoBack)		// UDT RAPT (UH) --7b-- : Travel History
@@ -282,6 +288,17 @@
 
 	}
 
+	// --66--
+	void OnSetTravelLogIndex(UINT nIndex)
+	{
+		m_nTravelLogIndex = nIndex;
+	}
+	UINT OnGetTravelLogIndex() const
+	{
+		return m_nTravelLogIndex;
+	}
+	// ENDE
+
 	// UDT RAPT [5 buttons mouse] (WinUser.h)
 	LRESULT OnAppCommand(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
 	{
@@ -418,7 +435,8 @@
 
 		// for mdi tab ctrl
 		HWND hWndActiveNext = NULL;
-		if (MDIGetActive() == m_hWnd) {
+		HWND hWndActive = MDIGetActive();
+		if (hWndActive == m_hWnd) {
 			int nIndex = m_MDITab.ManageClose(m_hWnd);
 			if (nIndex != -1) {
 				hWndActiveNext = m_MDITab.GetTabHwnd(nIndex);
@@ -430,8 +448,13 @@
 			MDIActivate(hWndActiveNext);
 
 		CString strURL = GetLocationURL();
+		CString strTitle = MtlGetWindowText(hWndActive);	// --55-- : added
 		if (!strURL.IsEmpty()){
-			CMainOption::s_pMru->AddToList(strURL);
+//			CMainOption::s_pMru->AddToList(strURL);
+			CRecentDocumentListFixed::TLHistory_t back, forward;
+			GetTravelLog(TRUE, back);
+			GetTravelLog(FALSE, forward);
+			CMainOption::s_pMru->AddToList(strURL, strTitle, back, forward);
 		}
 		ShowWindow(SW_HIDE);	// UDT RAPT --23--
 	}
@@ -851,6 +874,17 @@
 			dcfTRACE(_T("CChildFrame::OnDocumentComplete\n"));
 			m_bWaitNavigateLock = false;// you are allowed!
 
+			// --66--
+			if( m_nTravelLogIndex != (UINT)-1 ){
+				CRecentDocumentListFixed::TLHistory_t  back, forward;
+				CMainOption::s_pMru->GetFromList(m_nTravelLogIndex, back, forward);
+				// try to read travel log from ini file
+				SetTravelLog(TRUE, back);
+				SetTravelLog(FALSE, forward);
+				m_nTravelLogIndex = (UINT)-1;
+			}				
+			// ENDE
+
 			if (MDIGetActive() == m_hWnd && DonutBrowserCanSetFocus(m_hWnd)) {
 				_SetPageFocus();
 			}
diff -ur DonutL31_src/Donut.cpp DonutL31_hacked/Donut.cpp
--- DonutL31_src/Donut.cpp	2006-10-15 02:19:38.000000000 +0900
+++ DonutL31_hacked/Donut.cpp	2006-12-20 16:09:49.886900800 +0900
@@ -10,6 +10,7 @@
 
 
 #include "ItemIDList.h"
+#include <vector>
 #include "mtl.h"
 #include "Rtl.h"	// UDT RAPT --12--
 
diff -ur DonutL31_src/DonutDefine.h DonutL31_hacked/DonutDefine.h
--- DonutL31_src/DonutDefine.h	2006-10-15 02:22:46.000000000 +0900
+++ DonutL31_hacked/DonutDefine.h	2006-12-20 15:38:14.394420800 +0900
@@ -46,6 +46,7 @@
 DWORD g_nAbrEncodeType = 0;
 bool g_bEndSession = false;	// --22--
 bool g_bComplementProtocol = false;
+static int  g_nTravelLogMax = 5;	// --66--
 bool g_bFlatScrBar = false; // UDT DGSTR ( dai
 static const CLSID DONUT_CGID_DocHostCommandHandler =
 { 0xf38bc242, 0xb950, 0x11d1, { 0x89, 0x18, 0x00, 0xc0, 0x4f, 0xc2, 0xc8, 0x36 } };
@@ -127,6 +128,27 @@
 
 #define WM_STATUS_SETICON		(WM_APP + 14)
 
+#define WM_APP_SETTRAVELLOGINDEX		(WM_APP + 28)
+#define MSG_WM_APP_SETTRAVELLOGINDEX(func) \
+	if (uMsg == WM_APP_SETTRAVELLOGINDEX) \
+	{ \
+		SetMsgHandled(TRUE); \
+		func((UINT)wParam); \
+		lResult = 0; \
+		if(IsMsgHandled()) \
+			return lResult; \
+	}
+
+#define WM_APP_GETTRAVELLOGINDEX		(WM_APP + 29)
+#define MSG_WM_APP_GETTRAVELLOGINDEX(func) \
+	if (uMsg == WM_APP_GETTRAVELLOGINDEX) \
+	{ \
+		SetMsgHandled(TRUE); \
+		lResult = (LRESULT)func(); \
+		if(IsMsgHandled()) \
+			return lResult; \
+	}
+
 // --26--
 #define WM_APP_GETDLCONTRLFLAGS		(WM_APP + 41)
 #define MSG_WM_APP_GETDLCONTRLFLAGS() \
diff -ur DonutL31_src/MtlBrowser.h DonutL31_hacked/MtlBrowser.h
--- DonutL31_src/MtlBrowser.h	2006-10-21 02:03:50.000000000 +0900
+++ DonutL31_hacked/MtlBrowser.h	2006-12-20 16:08:10.934614400 +0900
@@ -673,6 +673,99 @@
 		MenuChgGo(hMenu, false);
 	}
 	// ENDE
+
+	// --66--
+	typedef std::vector<std::pair<CString, CString> > TLHistory_t;
+	void SetTravelLog(BOOL bBackNoForward, TLHistory_t r_arrTravelLog)
+	{
+		if( g_nTravelLogMax == 0 ){
+			return;
+		}
+		HRESULT hr = S_OK;
+		CComQIPtr<IServiceProvider> spISP(m_spBrowser);
+		if(!spISP){
+			return;
+		}
+
+		CComPtr<ITravelLogStg> spTLStg;
+		if(FAILED(spISP->QueryService(SID_STravelLogCursor, IID_ITravelLogStg, (void**) &spTLStg)) || !spTLStg){
+			return;
+		}
+//		http://www.microsoft.com/japan/msdn/columns/webteam/webteam04022001.asp
+		CComPtr<IEnumTravelLogEntry> spTLEnum;
+		if (FAILED(spTLStg->EnumEntries((bBackNoForward? TLEF_RELATIVE_BACK: TLEF_RELATIVE_FORE), &spTLEnum)) || !spTLEnum){
+			return;
+		}
+		CComPtr<ITravelLogEntry> spTLEntry;
+		if(FAILED(spTLEnum->Next(1, &spTLEntry, NULL))){
+			// spTLEntry will be NULL is OK;
+			return;
+		}
+		USES_CONVERSION;
+		// 最大値が制限
+		int nMaxIndex = r_arrTravelLog.size();
+		if( g_nTravelLogMax > 0 && nMaxIndex > g_nTravelLogMax){
+			nMaxIndex = g_nTravelLogMax;
+		}
+		for (int i = 0; i < nMaxIndex; ++i) {
+			CComPtr<ITravelLogEntry> spTLEntryNew;
+			LPCOLESTR szTitle = T2COLE(r_arrTravelLog[i].first);
+			LPCOLESTR szUrl = T2COLE(r_arrTravelLog[i].second);
+//			spTLStg->CreateEntry(url, title, in_ppEntry, back_as_TRUE_or_forward_as_FALSE, out_ppEntry);
+			spTLStg->CreateEntry( szUrl, szTitle, spTLEntry, bBackNoForward, &spTLEntryNew );
+			spTLEntry = spTLEntryNew;
+		}
+	}
+
+	void GetTravelLog(BOOL bBackNoForward, TLHistory_t& r_arrTravelLog)
+	{
+		if( g_nTravelLogMax == 0 ){
+			return;
+		}
+
+		HRESULT hr = S_OK;
+		CComQIPtr<IServiceProvider> spISP(m_spBrowser);
+		if(!spISP){
+			return;
+		}
+
+		CComPtr<ITravelLogStg> spTLStg;
+		if(FAILED(spISP->QueryService(SID_STravelLogCursor, IID_ITravelLogStg, (void**) &spTLStg)) || !spTLStg){
+			return;
+		}
+//		http://www.microsoft.com/japan/msdn/columns/webteam/webteam04022001.asp
+		CComPtr<IEnumTravelLogEntry> spTLEnum;
+		if (FAILED(spTLStg->EnumEntries((bBackNoForward? TLEF_RELATIVE_BACK: TLEF_RELATIVE_FORE), &spTLEnum)) || !spTLEnum){
+			return;
+		}
+
+		const int nMaxIndex = (g_nTravelLogMax < 0) ? INT_MAX : g_nTravelLogMax;
+		for (int nIndex = 0; nIndex < nMaxIndex;) {
+			CComPtr<ITravelLogEntry> spTLEntry;
+			if(FAILED(spTLEnum->Next(1, &spTLEntry, NULL)) || !spTLEntry){
+				break;
+			}
+
+			LPOLESTR szTitle = NULL, szUrl = NULL;
+			if (	SUCCEEDED(spTLEntry->GetTitle(&szTitle)) && szTitle
+				&&	SUCCEEDED(spTLEntry->GetURL(&szUrl)) && szUrl)
+			{
+				// 履歴を保存する
+				r_arrTravelLog.push_back( std::make_pair<CString, CString>(CString(szTitle), CString(szUrl)) );
+				++nIndex;
+			}
+
+			// --78--
+			if ( szTitle ) {
+				::CoTaskMemFree( szTitle );
+			}
+			if ( szUrl ) {
+				::CoTaskMemFree( szUrl );
+			}
+			// ENDE
+		}
+	}
+	// ENDE
 };
 
 /////////////////////////////////////////////////////////////////////////////
diff -ur DonutL31_src/RecentDocumentListFixed.h DonutL31_hacked/RecentDocumentListFixed.h
--- DonutL31_src/RecentDocumentListFixed.h	2004-11-22 00:46:38.000000000 +0900
+++ DonutL31_hacked/RecentDocumentListFixed.h	2006-12-20 17:26:27.207523200 +0900
@@ -8,11 +8,47 @@
 {
 public:
 // Declarations
+#ifdef TLHistory_t
+#undef TLHistory_t
+#endif
+	typedef std::vector<std::pair<CString, CString> > TLHistory_t;
 	struct _DocEntry
 	{
 		TCHAR szDocName[t_cchItemLen];
+		TCHAR szToolTip[t_cchItemLen];					// --55-- : added
+		TLHistory_t	back, forward;
+		_DocEntry()
+		{
+			*szDocName = 0;
+			*szToolTip = 0;		// --55-- : added
+		}
+		_DocEntry(LPCTSTR szDocName, LPCTSTR szToolTip, TLHistory_t back, TLHistory_t forward)
+		{
+			ATLASSERT( szDocName );
+			if( szDocName == NULL ){
+				return;
+			}
+			*this->szDocName = 0;
+			*this->szToolTip = 0;
+			lstrcpyn(this->szDocName, szDocName, t_cchItemLen);
+			if( szToolTip ){
+				lstrcpyn(this->szToolTip, szToolTip, t_cchItemLen);
+			}
+			this->back = back;
+			this->forward = forward;
+		}
 		bool operator==(const _DocEntry& de) const
 		{ return (lstrcmpi(szDocName, de.szDocName) == 0); }
+		void AddTLHistory(BOOL bBack_as_TRUE_Forward_as_FALSE, CString strTitle, CString strUrl)
+		{
+			if( bBack_as_TRUE_Forward_as_FALSE ){
+//				ATLTRACE( _T("back(%s)\n  title(%s)\n    url(%s)\n"), szDocName, strTitle, strUrl);
+				back.push_back(std::make_pair<CString, CString>(strTitle, strUrl));
+			}else{
+//				ATLTRACE( _T("forward(%s)\n  title(%s)\n    url(%s)\n"), szDocName, strTitle, strUrl);
+				forward.push_back(std::make_pair<CString, CString>(strTitle, strUrl));
+			}
+		}
 	};
 
 	enum
@@ -25,6 +61,8 @@
 
 // Data members
 	CSimpleArray<_DocEntry> m_arrDocs;
+	CSimpleArray<_DocEntry> m_arrDocsRemoved;
+	int m_nDocsRemoved_stackCount;
 	int m_nMaxEntries;	// default is 4
 	HMENU m_hMenu;
 
@@ -83,15 +121,16 @@
 	}
 
 // Operations
-	BOOL AddToList(LPCTSTR lpstrDocName)
+	BOOL AddToList(LPCTSTR lpstrDocName, LPCTSTR lpstrToolTip, TLHistory_t back, TLHistory_t forward)
 	{
-		_DocEntry de;
-		if(lstrcpy(de.szDocName, lpstrDocName) == NULL)
+		if(lpstrDocName == NULL)
 			return FALSE;
 
 		if (m_nMaxEntries < 1)
 			return FALSE; // UDT RAPT --6b--
 
+		_DocEntry de(lpstrDocName, lpstrToolTip, back, forward);
+
 		for(int i = 0; i < m_arrDocs.GetSize(); ++i)
 		{
 			if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0)
@@ -119,9 +158,56 @@
 			return FALSE;
 		return (lstrcpy(lpstrDocName, m_arrDocs[nIndex].szDocName) != NULL);
 	}
-	BOOL RemoveFromList(int nItemID)
+	// --66--
+	BOOL GetFromList(int nItemID, LPTSTR lpstrDocName, LPTSTR lpstrToolTip, TLHistory_t& r_back, TLHistory_t& r_forward)
+	{
+		int nIndex = m_arrDocs.GetSize() - (nItemID - ID_FILE_MRU_FIRST) - 1;
+		if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
+			return FALSE;
+		r_back = m_arrDocs[nIndex].back;
+		r_forward = m_arrDocs[nIndex].forward;
+		lstrcpy(lpstrToolTip, m_arrDocs[nIndex].szToolTip);
+		return (lstrcpy(lpstrDocName, m_arrDocs[nIndex].szDocName) != NULL);
+	}
+	BOOL GetFromList(int nIndex, TLHistory_t& r_back, TLHistory_t& r_forward)
+	{
+		if( nIndex < 0 || nIndex >= m_arrDocsRemoved.GetSize() ){
+			return FALSE;
+		}
+		_DocEntry& de = m_arrDocsRemoved[nIndex];
+		r_back = de.back;
+		r_forward = de.forward;
+		*de.szDocName = 0;
+		m_nDocsRemoved_stackCount++;
+		return TRUE;
+	}
+	void GarbageCollectDocsRemoved()
+	{
+		if( m_nDocsRemoved_stackCount < 30 )
+			return;
+
+		for(int i = m_arrDocsRemoved.GetSize(); i >= 0 ; --i){
+			if( *m_arrDocsRemoved[i].szDocName == 0 ){
+				m_arrDocsRemoved.RemoveAt(i);
+			}
+		}
+		m_nDocsRemoved_stackCount = 0;
+	}
+	// ENDE
+
+	BOOL RemoveFromList(int nItemID, UINT* pnRemovedIndex = NULL)
 	{
 		int nIndex = m_arrDocs.GetSize() - (nItemID - ID_FILE_MRU_FIRST) - 1;
+		// --66--
+		m_arrDocsRemoved.Add(m_arrDocs[nIndex]);
+		if( pnRemovedIndex ){
+			if( g_nTravelLogMax == 0 ){
+				*pnRemovedIndex = -1;
+			}else{
+				*pnRemovedIndex = m_arrDocsRemoved.GetSize() - 1;
+			}
+		}
+		// ENDE
 		BOOL bRet = m_arrDocs.RemoveAt(nIndex);
 		if(bRet)
 		{
@@ -150,13 +236,15 @@
 	BOOL ReadFromIniFile()
 	{
 		BOOL bRet = FALSE; // --11--
-		CIniSection pr;
+		CIniFile pr;
 		pr.Open(g_szIniFileName, _T("Recent Document List"));
+		g_nTravelLogMax = static_cast<int>(pr.GetInt(_T("TravelLogMax"), 5));
+		const int nMaxEntry = (g_nTravelLogMax < 0) ? INT_MAX : g_nTravelLogMax;
 
-		DWORD dwRet;
-		LONG lRet = pr.QueryValue(dwRet, _T("DocumentCount"));
-		if(lRet == ERROR_SUCCESS || dwRet > 0 && dwRet < (ID_FILE_MRU_LAST - ID_FILE_MRU_FIRST + 1))
+		DWORD dwRet = pr.GetInt(_T("DocumentCount"));
+		if(dwRet > 0 && dwRet < (ID_FILE_MRU_LAST - ID_FILE_MRU_FIRST + 1)){
 			m_nMaxEntries = dwRet;
+		}
 
 		m_arrDocs.RemoveAll();
 
@@ -165,17 +253,48 @@
 
 			TCHAR szRetString[t_cchItemLen];
 			_DocEntry de;
+			CString strKey, strTitle, strUrl;
+			int i;
 
+			ATLTRACE(_T("ReadFromIniFile()---\n"));
 			for(int nItem = m_nMaxEntries; nItem > 0; nItem--)
 			{
-				TCHAR szBuff[11];
-				if (nItem > 99)
-					nItem = 99; // UDT RAPT --6b--
-				wsprintf(szBuff, _T("Document%i"), nItem); // nItem : <= 99
-				DWORD dwCount = t_cchItemLen * sizeof(TCHAR);
-				lRet = pr.QueryValue(szRetString, szBuff, &dwCount);
-				if(lRet == ERROR_SUCCESS && (lstrcpy(de.szDocName, szRetString) != NULL))
+				// get url
+				strKey.Format(_T("Document%i"), nItem);
+				pr.GetString(szRetString, t_cchItemLen, strKey);
+				if(lstrcpy(de.szDocName, szRetString) != NULL && de.szDocName[0] != 0){
+					// get tooltip
+					strKey.Format(_T("Title%i"), nItem);
+					pr.GetString(de.szToolTip, t_cchItemLen, strKey);
+
+					// get travel log (back)
+					for(i = 1; i <= nMaxEntry; ++i){
+						strKey.Format(_T("Document%i.Back%i.title"), nItem, i);
+						strTitle = pr.GetString(strKey);
+						strKey.Format(_T("Document%i.Back%i.url"), nItem, i);
+						strUrl = pr.GetString(strKey);
+						if( strTitle.IsEmpty() || strUrl.IsEmpty() ){
+							break;
+						}
+//						ATLTRACE(_T("  Back(%d)\n"), i);
+						de.AddTLHistory(TRUE, strTitle, strUrl);
+					}
+
+					// get travel log (forward)
+					for(i = 1; i <= nMaxEntry; ++i){
+						strKey.Format(_T("Document%i.Forward%i.title"), nItem, i);
+						strTitle = pr.GetString(strKey);
+						strKey.Format(_T("Document%i.Forward%i.url"), nItem, i);
+						strUrl = pr.GetString(strKey);
+						if( strTitle.IsEmpty() || strUrl.IsEmpty() ){
+							break;
+						}
+//						ATLTRACE(_T("  Forward(%d)\n"), i);
+						de.AddTLHistory(FALSE, strTitle, strUrl);
+					}
+//					ATLTRACE(_T(" Document(%d)\n"), nItem);
 					m_arrDocs.Add(de);
+				}
 			}
 		} // UDT RAPT --6b--
 
@@ -189,6 +308,8 @@
 	}
 	BOOL WriteToIniFile()
 	{
+		CIniFile::SetInt(g_szIniFileName, _T("Recent Document List"), _T("TravelLogMax"), g_nTravelLogMax);
+
 		CIniSection pr;
 		pr.Open(g_szIniFileName, _T("Recent Document List"));
 
@@ -198,15 +319,41 @@
 		ATLASSERT(lRet == ERROR_SUCCESS);
 
 		// set new values
-		int nItem;
+		int nItem, i;
+		TCHAR szDocName[t_cchItemLen];
+		TCHAR szToolTip[t_cchItemLen];	// --55-- : added
+		CString strKey;
 		for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--)
 		{
-			TCHAR szBuff[11];
-			wsprintf(szBuff, _T("Document%i"), nItem);
-			TCHAR szDocName[t_cchItemLen];
-			GetFromList(ID_FILE_MRU_FIRST + nItem - 1, szDocName);
-			lRet = pr.SetValue(szDocName, szBuff);
+			*szDocName = *szToolTip = 0;
+			TLHistory_t back, forward;
+			GetFromList(ID_FILE_MRU_FIRST + nItem - 1, szDocName, szToolTip, back, forward);
+
+			strKey.Format(_T("Document%i"), nItem);
+			lRet = pr.SetValue(szDocName, strKey);
 			ATLASSERT(lRet == ERROR_SUCCESS);
+			// --55--
+			strKey.Format(_T("Title%i"), nItem);
+			lRet = pr.SetValue(szToolTip, strKey);
+			// ENDE
+			ATLASSERT(lRet == ERROR_SUCCESS);
+
+			//--66--
+			int nMax = (g_nTravelLogMax < 0 || back.size() < g_nTravelLogMax) ? back.size() : g_nTravelLogMax;
+			for(i = 1; i <= nMax; ++i){
+				strKey.Format(_T("Document%i.back%i.title"), nItem, i);
+				pr.SetValue(back[i-1].first, strKey);
+				strKey.Format(_T("Document%i.back%i.url"), nItem, i);
+				pr.SetValue(back[i-1].second, strKey);
+			}
+			nMax = (g_nTravelLogMax < 0 || forward.size() < g_nTravelLogMax) ? forward.size() : g_nTravelLogMax;
+			for(i = 1; i <= nMax; ++i){
+				strKey.Format(_T("Document%i.forward%i.title"), nItem, i);
+				pr.SetValue(forward[i-1].first, strKey);
+				strKey.Format(_T("Document%i.forward%i.url"), nItem, i);
+				pr.SetValue(forward[i-1].second, strKey);
+			}
+			// ENDE
 		}
 
 		// delete unused keys
diff -ur DonutL31_src/mainfrm.h DonutL31_hacked/mainfrm.h
--- DonutL31_src/mainfrm.h	2006-10-21 02:05:24.000000000 +0900
+++ DonutL31_hacked/mainfrm.h	2006-12-20 16:18:12.309348800 +0900
@@ -986,8 +986,13 @@
 		TCHAR szFile[INTERNET_MAX_PATH_LENGTH];
 		if(CMainOption::s_pMru->GetFromList(wID, szFile))
 		{
-			if(CMainOption::s_pMru->RemoveFromList(wID)) // UDT DGSTR
-				OnUserOpenFile(szFile, DonutGetStdOpenCreateFlag()); // Force New Window // UDT DGSTR
+			UINT nLogIndex = 0;
+			if(CMainOption::s_pMru->RemoveFromList(wID, &nLogIndex)) { // UDT DGSTR
+				HWND hWnd = OnUserOpenFile(szFile, DonutGetStdOpenCreateFlag()); // Force New Window // UDT DGSTR
+				if ( hWnd != NULL ) {
+					::SendMessage( hWnd, WM_APP_SETTRAVELLOGINDEX, nLogIndex, 0L );
+				}
+			}
 		}
 		else
 		{
@@ -1005,10 +1010,34 @@
 		return 0;
 	}
 
+	// --66--
+	struct funcIsNoTravelLogIndex{
+		BOOL bAttached;
+		funcIsNoTravelLogIndex() : bAttached(FALSE){}
+		void operator()(HWND hWnd)
+		{
+			if( bAttached == FALSE ){
+				UINT nIndex = (UINT)::SendMessage(hWnd, WM_APP_GETTRAVELLOGINDEX, 0, 0);
+				if( nIndex != (UINT)-1 ){
+					bAttached = TRUE;
+				}
+			}
+		}
+	};
+	// ENDE
+
 	LRESULT OnViewIdle(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
 	{
 		_OnIdleCritical();
 
+		// --66--
+		funcIsNoTravelLogIndex f;
+		f = MtlForEachMDIChild(m_hWndMDIClient, f);
+		if( f.bAttached == FALSE ){
+			CMainOption::s_pMru->GarbageCollectDocsRemoved();
+		}
+		// ENDE
+
 		return 0;
 	}