diff --git a/RLogin/AnyPastDlg.cpp b/RLogin/AnyPastDlg.cpp index c729abd..7af146a 100755 --- a/RLogin/AnyPastDlg.cpp +++ b/RLogin/AnyPastDlg.cpp @@ -21,8 +21,10 @@ CAnyPastDlg::CAnyPastDlg(CWnd* pParent /*=NULL*/) m_bDelayPast = FALSE; m_bUpdateEnable = FALSE; m_CtrlCode[0] = m_CtrlCode[1] = m_CtrlCode[2] = 0; - m_pView = NULL; + m_pMain = NULL; m_bCtrlView = FALSE; + m_DocSeqNumber = 0; + m_bDiffViewEnable = FALSE; } CAnyPastDlg::~CAnyPastDlg() @@ -48,6 +50,7 @@ BEGIN_MESSAGE_MAP(CAnyPastDlg, CDialogExt) ON_BN_CLICKED(IDC_SHELLESC, &CAnyPastDlg::OnShellesc) ON_BN_CLICKED(IDC_ONELINE, &CAnyPastDlg::OnOneLine) ON_BN_CLICKED(IDC_CHECK4, &CAnyPastDlg::OnCtrlView) + ON_WM_CLOSE() END_MESSAGE_MAP() static const INITDLGTAB ItemTab[] = { @@ -198,6 +201,10 @@ BOOL CAnyPastDlg::OnInitDialog() m_IconBox.SetIcon(LoadIcon(NULL, IDI_QUESTION)); m_bUpdateEnable = FALSE; + m_bDelayPast = AfxGetApp()->GetProfileInt(_T("AnyPastDlg"), _T("DelayPast"), FALSE); + m_bCtrlView = AfxGetApp()->GetProfileInt(_T("AnyPastDlg"), _T("CtrlView"), FALSE); + m_NoCheck = m_pMain->m_PastNoCheck; + UpdateData(FALSE); if ( m_bCtrlView ) { @@ -210,6 +217,7 @@ BOOL CAnyPastDlg::OnInitDialog() CtrlCount(); CRect rect; + int sx = 0, sy = 0; int cx, cy; GetWindowRect(rect); @@ -221,38 +229,115 @@ BOOL CAnyPastDlg::OnInitDialog() if ( cy < rect.Height() ) cy = rect.Height(); - MoveWindow(rect.left, rect.top, cx, cy, FALSE); + AfxGetMainWnd()->GetWindowRect(rect); + sx = rect.left + (rect.Width() - cx) / 2; + sy = rect.top + (rect.Height() - cy) / 2; + + MoveWindow(sx, sy, cx, cy, FALSE); AddShortCutKey(0, VK_RETURN, MASK_CTRL, 0, IDOK); return TRUE; } -void CAnyPastDlg::SaveWindowRect() +BOOL CAnyPastDlg::SendBracketedPaste(LPCTSTR str) +{ + CRLoginDoc *pDoc; + CRLoginView *pView; + + if ( (pDoc = m_pMain->GetMDIActiveDocument()) == NULL ) + return FALSE; + + if ( (pView = (CRLoginView *)pDoc->GetAciveView()) == NULL ) + return FALSE; + + if ( !m_bDiffViewEnable && (m_DocSeqNumber == 0 || m_DocSeqNumber != pDoc->m_DocSeqNumber) ) { + if ( AfxMessageBox(IDS_ANYPASTVIEWMSG, MB_ICONWARNING | MB_YESNO) != IDYES ) + return FALSE; + m_bDiffViewEnable = TRUE; + } + + if ( pView->m_HisOfs != 0 ) { + pView->m_HisOfs = 0; + pDoc->UpdateAllViews(NULL, UPDATE_INVALIDATE, NULL); + } + + pView->SendBracketedPaste(TstrToUni(str), m_bDelayPast); + + return TRUE; +} + +BOOL CAnyPastDlg::UpdateTextData(BOOL bOk) { + ASSERT(m_pMain != NULL); + if ( !IsIconic() ) { CRect rect; GetWindowRect(rect); AfxGetApp()->WriteProfileInt(_T("AnyPastDlg"), _T("cx"), MulDiv(rect.Width(), m_InitDpi.cx, m_NowDpi.cx)); AfxGetApp()->WriteProfileInt(_T("AnyPastDlg"), _T("cy"), MulDiv(rect.Height(), m_InitDpi.cy, m_NowDpi.cy)); } + + AfxGetApp()->WriteProfileInt(_T("AnyPastDlg"), _T("DelayPast"), m_bDelayPast); + AfxGetApp()->WriteProfileInt(_T("AnyPastDlg"), _T("CtrlView"), m_bCtrlView); + m_pMain->m_PastNoCheck = m_NoCheck; + + if ( !bOk ) + return FALSE; + + if ( m_bUpdateText ) + m_pMain->SetClipboardText(m_EditText); + + return SendBracketedPaste(m_EditText); +} +void CAnyPastDlg::SetEditText(LPCTSTR str, int DocSeqNumber) +{ + if ( m_bCtrlView ) + str = CtrlStr(str, TRUE); + m_EditWnd.SetSel(0, -1, FALSE); + m_EditWnd.ReplaceSel(str, TRUE); + m_DocSeqNumber = DocSeqNumber; } void CAnyPastDlg::OnOK() { UpdateData(TRUE); + m_EditWnd.GetWindowText(m_EditText); if ( m_bCtrlView ) m_EditText = CtrlStr(m_EditText, FALSE); - SaveWindowRect(); - CDialogExt::OnOK(); + + //CDialogExt::OnOK(); + + if ( UpdateTextData(TRUE) ) + DestroyWindow(); } void CAnyPastDlg::OnCancel() { UpdateData(TRUE); - SaveWindowRect(); - CDialogExt::OnCancel(); + + //CDialogExt::OnCancel(); + + UpdateTextData(FALSE); + DestroyWindow(); +} +void CAnyPastDlg::OnClose() +{ + UpdateData(TRUE); + + CDialogExt::OnClose(); + + UpdateTextData(FALSE); + DestroyWindow(); } +void CAnyPastDlg::PostNcDestroy() +{ + CDialogExt::PostNcDestroy(); + + if ( m_pMain != NULL ) + m_pMain->m_pAnyPastDlg = NULL; + delete this; +} void CAnyPastDlg::OnUpdateEdit() { m_bUpdateEnable = TRUE; @@ -340,7 +425,6 @@ void CAnyPastDlg::OnOneLine() { int st, ed, mx; LPCTSTR p; - CBuffer tmp; CString str; UpdateData(TRUE); @@ -368,23 +452,13 @@ void CAnyPastDlg::OnOneLine() } else { // 範囲指定を送信 - if ( st < ed && m_pView != NULL ) { + if ( st < ed ) { str = m_EditText.Mid(st, ed - st); if ( m_bCtrlView ) str = CtrlStr(str, FALSE); - for ( LPCTSTR s = str ; *s != _T('\0') ; ) { - if ( s[0] == L'\r' && s[1] == L'\n' ) { - // 改行は\rだけにする - tmp.PutWord(*s); - s += 2; - } else - tmp.PutWord(*(s++)); - } - - if ( tmp.GetSize() > 0 ) - m_pView->SendBuffer(tmp, FALSE, m_bDelayPast); + SendBracketedPaste(str); } // 次行を範囲指定 diff --git a/RLogin/AnyPastDlg.h b/RLogin/AnyPastDlg.h index f1563c2..65303a1 100755 --- a/RLogin/AnyPastDlg.h +++ b/RLogin/AnyPastDlg.h @@ -28,12 +28,16 @@ class CAnyPastDlg : public CDialogExt CString m_EditText; BOOL m_bUpdateEnable; - class CRLoginView *m_pView; + class CMainFrame *m_pMain; + int m_DocSeqNumber; + BOOL m_bDiffViewEnable; public: void CtrlCount(); - void SaveWindowRect(); LPCTSTR CtrlStr(LPCTSTR str, BOOL bCtrl); + BOOL SendBracketedPaste(LPCTSTR str); + BOOL UpdateTextData(BOOL bOk); + void SetEditText(LPCTSTR str, int DocSeqNumber); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート @@ -41,6 +45,7 @@ class CAnyPastDlg : public CDialogExt virtual void OnOK(); virtual void OnCancel(); virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual void PostNcDestroy(); protected: DECLARE_MESSAGE_MAP() @@ -49,4 +54,5 @@ class CAnyPastDlg : public CDialogExt afx_msg void OnShellesc(); afx_msg void OnOneLine(); afx_msg void OnCtrlView(); + afx_msg void OnClose(); }; diff --git a/RLogin/Data.cpp b/RLogin/Data.cpp index be5cfab..9cfe0c8 100755 --- a/RLogin/Data.cpp +++ b/RLogin/Data.cpp @@ -5760,7 +5760,7 @@ static const struct _CmdsKeyTab { { IDM_SEARCH_NEXT, L"$SEARCH_NEXT" }, { IDM_SEARCH_REG, L"$SEARCH_REG" }, { IDM_SECPORICY, L"$SECURITYCOLICY" }, - { IDM_SPEEKALL, L"$SPEEK_ALL" }, + { IDM_SPEAKALL, L"$SPEAK_ALL" }, { ID_SPLIT_HEIGHT, L"$SPLIT_HEIGHT" }, { IDM_SPLIT_HEIGHT_NEW, L"$SPLIT_HEIGHTNEW" }, { ID_SPLIT_OVER, L"$SPLIT_OVER" }, diff --git a/RLogin/DialogExt.cpp b/RLogin/DialogExt.cpp index 79b924f..be80513 100755 --- a/RLogin/DialogExt.cpp +++ b/RLogin/DialogExt.cpp @@ -240,6 +240,20 @@ BOOL CDialogExt::IsDialogExt(CWnd *pWnd) return FALSE; } +void CDialogExt::GetDlgFontBase(CDC *pDC, CFont *pFont, CSize &size) +{ + CSize TextSize; + TEXTMETRIC TextMetric; + CFont *pOld; + + pOld = pDC->SelectObject(pFont); + pDC->GetTextMetrics(&TextMetric); + ::GetTextExtentPoint32(pDC->GetSafeHdc(), _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &TextSize); + size.cx = (TextSize.cx + 26) / 52; + size.cy = (TextMetric.tmHeight + TextMetric.tmExternalLeading); + pDC->SelectObject(pOld); +} + void CDialogExt::CheckMoveWindow(CRect &rect, BOOL bRepaint) { HMONITOR hMonitor; diff --git a/RLogin/DialogExt.h b/RLogin/DialogExt.h index 94e9d5e..7b61de5 100755 --- a/RLogin/DialogExt.h +++ b/RLogin/DialogExt.h @@ -78,6 +78,7 @@ class CDialogExt : public CDialog static void GetActiveDpi(CSize &dpi, CWnd *pWnd, CWnd *pParent); static BOOL IsDialogExt(CWnd *pWnd); + static void GetDlgFontBase(CDC *pDC, CFont *pFont, CSize &size); // オーバーライド public: diff --git a/RLogin/ExtFileDialog.cpp b/RLogin/ExtFileDialog.cpp index 28ff26d..7c934a2 100755 --- a/RLogin/ExtFileDialog.cpp +++ b/RLogin/ExtFileDialog.cpp @@ -386,6 +386,58 @@ BEGIN_MESSAGE_MAP(CExtFileDialog, CFileDialog) ON_WM_DESTROY() ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CExtFileDialog::OnTcnSelchangeTab1) END_MESSAGE_MAP() + +void CExtFileDialog::FontSizeCheck() +{ + CDC *pDc = GetDC(); + CFont *pFont; + CSize ZoomMul, ZoomDiv, AddSize; + int AddTop; + CRect rect; + WINDOWPLACEMENT place; + CString FontName = ::AfxGetApp()->GetProfileString(_T("Dialog"), _T("FontName"), _T("")); + int FontSize = MulDiv(::AfxGetApp()->GetProfileInt(_T("Dialog"), _T("FontSize"), 9), SCREEN_DPI_Y, SYSTEM_DPI_Y); + + if ( FontName.IsEmpty() && FontSize == 9 ) + return; + + if ( m_NewFont.GetSafeHandle() != NULL ) { + CDialogExt::GetDlgFontBase(pDc, &m_NewFont, ZoomDiv); + m_NewFont.DeleteObject(); + } else if ( (pFont = GetFont()) != NULL ) { + CDialogExt::GetDlgFontBase(pDc, pFont, ZoomDiv); + } else + return; + + if ( !m_NewFont.CreatePointFont(FontSize * 10, FontName) ) + return; + + CDialogExt::GetDlgFontBase(pDc, &m_NewFont, ZoomMul); + ReleaseDC(pDc); + + m_TabCtrl.GetWindowPlacement(&place); + AddTop = place.rcNormalPosition.bottom; + place.rcNormalPosition.right = place.rcNormalPosition.left + (place.rcNormalPosition.right - place.rcNormalPosition.left) * ZoomMul.cx / ZoomDiv.cx; + place.rcNormalPosition.bottom = place.rcNormalPosition.top + (place.rcNormalPosition.bottom - place.rcNormalPosition.top) * ZoomMul.cy / ZoomDiv.cy; + AddTop = place.rcNormalPosition.bottom - AddTop; + m_TabCtrl.SetWindowPlacement(&place); + m_TabCtrl.SetFont(&m_NewFont, TRUE); + + m_Frame.GetWindowPlacement(&place); + AddSize.cx = place.rcNormalPosition.right - place.rcNormalPosition.left; + AddSize.cy = place.rcNormalPosition.bottom - place.rcNormalPosition.top; + place.rcNormalPosition.right = place.rcNormalPosition.left + (place.rcNormalPosition.right - place.rcNormalPosition.left) * ZoomMul.cx / ZoomDiv.cx; + place.rcNormalPosition.bottom = place.rcNormalPosition.top + (place.rcNormalPosition.bottom - place.rcNormalPosition.top) * ZoomMul.cy / ZoomDiv.cy; + place.rcNormalPosition.top += AddTop; + place.rcNormalPosition.bottom += AddTop; + AddSize.cx = (place.rcNormalPosition.right - place.rcNormalPosition.left) - AddSize.cx; + AddSize.cy = (place.rcNormalPosition.bottom - place.rcNormalPosition.top) - AddSize.cy; + m_Frame.SetWindowPlacement(&place); + m_Frame.SetFont(&m_NewFont, TRUE); + + GetWindowRect(rect); + SetWindowPos(NULL, 0, 0, rect.Width() + AddSize.cx, rect.Height() + AddSize.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_SHOWWINDOW); +} BOOL CExtFileDialog::OnInitDialog() { @@ -397,8 +449,10 @@ BOOL CExtFileDialog::OnInitDialog() // WM_GETDLGCODE loop ... HELP!!! // https://groups.google.com/forum/#!topic/comp.os.ms-windows.programmer.controls/y0tPgUrDpGk - if ( m_DialogMode != 0 ) + if ( m_DialogMode != 0 ) { ModifyStyleEx(0, WS_EX_CONTROLPARENT); + FontSizeCheck(); + } switch(m_DialogMode) { case EXTFILEDLG_DOWNLOAD: diff --git a/RLogin/ExtFileDialog.h b/RLogin/ExtFileDialog.h index fe738a0..5260279 100755 --- a/RLogin/ExtFileDialog.h +++ b/RLogin/ExtFileDialog.h @@ -172,6 +172,10 @@ class CExtFileDialog : public CFileDialog CFileUpSendPage *m_pUpSend; CFileDownPage *m_pDownPage; + CFont m_NewFont; + + void FontSizeCheck(); + public: virtual BOOL OnInitDialog(); virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート diff --git a/RLogin/MainFrm.cpp b/RLogin/MainFrm.cpp index e603eee..41e6711 100755 --- a/RLogin/MainFrm.cpp +++ b/RLogin/MainFrm.cpp @@ -13,6 +13,7 @@ #include "ToolDlg.h" #include "richedit.h" #include "TraceDlg.h" +#include "AnyPastDlg.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -812,7 +813,7 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_MESSAGE(WM_DPICHANGED, OnDpiChanged) ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString) ON_MESSAGE(WM_NULL, OnNullMessage) - ON_MESSAGE(WM_SPEEKMSG, OnSpeekMsg) + ON_MESSAGE(WM_SPEAKMSG, OnSpeakMsg) ON_COMMAND(ID_FILE_ALL_LOAD, OnFileAllLoad) ON_COMMAND(ID_FILE_ALL_SAVE, OnFileAllSave) @@ -878,8 +879,8 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_BN_CLICKED(IDC_CONNECT, &CMainFrame::OnQuickConnect) ON_UPDATE_COMMAND_UI(IDC_CONNECT, &CMainFrame::OnUpdateConnect) - ON_COMMAND(IDM_SPEEKALL, &CMainFrame::OnSpeekText) - ON_UPDATE_COMMAND_UI(IDM_SPEEKALL, &CMainFrame::OnUpdateSpeekText) + ON_COMMAND(IDM_SPEAKALL, &CMainFrame::OnSpeakText) + ON_UPDATE_COMMAND_UI(IDM_SPEAKALL, &CMainFrame::OnUpdateSpeakText) END_MESSAGE_MAP() @@ -942,6 +943,8 @@ CMainFrame::CMainFrame() m_pServerSelect = NULL; m_pHistoryDlg = NULL; m_bVoiceEvent = FALSE; + m_pAnyPastDlg = NULL; + m_PastNoCheck = FALSE; } CMainFrame::~CMainFrame() @@ -2493,6 +2496,28 @@ BOOL CMainFrame::GetClipboardText(CString &str) return TRUE; } +void CMainFrame::AnyPastDlgClose(int DocSeqNumber) +{ + if ( m_pAnyPastDlg != NULL && m_pAnyPastDlg->m_DocSeqNumber == DocSeqNumber ) + m_pAnyPastDlg->m_DocSeqNumber = 0; +} +void CMainFrame::AnyPastDlgOpen(LPCWSTR str, int DocSeqNumber) +{ + if ( m_pAnyPastDlg == NULL ) { + m_pAnyPastDlg = new CAnyPastDlg; + m_pAnyPastDlg->m_EditText = str; + m_pAnyPastDlg->m_DocSeqNumber = DocSeqNumber; + m_pAnyPastDlg->m_pMain = this; + + m_pAnyPastDlg->Create(IDD_ANYPASTDIG, this); + m_pAnyPastDlg->ShowWindow(SW_SHOW); + + } else { + m_pAnyPastDlg->SetEditText(str, DocSeqNumber); + m_pAnyPastDlg->SetFocus(); + } +} + ///////////////////////////////////////////////////////////////////////////// static UINT VersionCheckThead(LPVOID pParam) @@ -2515,7 +2540,7 @@ void CMainFrame::VersionCheckProc() if ( version.CompareDigit(str) < 0 ) version = str; - if ( !http.GetRequest(CStringLoad(IDS_VERSIONCHECKURL), buf) ) + if ( !http.GetRequest(CStringLoad(IDS_VERSIONCHECKURL), buf) && !http.GetRequest(CStringLoad(IDS_VERSIONCHECKURL2), buf) ) return; p = (CHAR *)buf.GetPtr(); @@ -2832,6 +2857,9 @@ void CMainFrame::OnClose() if ( m_pHistoryDlg != NULL ) m_pHistoryDlg->SendMessage(WM_CLOSE); + if ( m_pAnyPastDlg != NULL ) + m_pAnyPastDlg->SendMessage(WM_CLOSE); + CMDIFrameWnd::OnClose(); } @@ -4138,55 +4166,55 @@ LRESULT CMainFrame::OnNullMessage(WPARAM wParam, LPARAM lParam) return TRUE; } -BOOL CMainFrame::SpeekQueIn() +BOOL CMainFrame::SpeakQueIn() { - if ( m_SpeekAbs > m_pSpeekDoc->m_TextRam.m_HisAbs ) { - m_SpeekLine -= m_SpeekAbs; - m_SpeekAbs = m_pSpeekDoc->m_TextRam.m_HisAbs; - m_SpeekLine += m_SpeekAbs; + if ( m_SpeakAbs > m_pSpeakDoc->m_TextRam.m_HisAbs ) { + m_SpeakLine -= m_SpeakAbs; + m_SpeakAbs = m_pSpeakDoc->m_TextRam.m_HisAbs; + m_SpeakLine += m_SpeakAbs; } BOOL bContinue; - int line = m_SpeekLine - m_pSpeekDoc->m_TextRam.m_HisAbs; + int line = m_SpeakLine - m_pSpeakDoc->m_TextRam.m_HisAbs; ISpVoice *pVoice = ((CRLoginApp *)::AfxGetApp())->m_pVoice; - if ( line < (0 - m_pSpeekDoc->m_TextRam.m_HisLen + m_pSpeekDoc->m_TextRam.m_Lines) ) { - line = 0 - m_pSpeekDoc->m_TextRam.m_HisLen + m_pSpeekDoc->m_TextRam.m_Lines + 1; - m_SpeekAbs = m_pSpeekDoc->m_TextRam.m_HisAbs; - m_SpeekLine = line + m_SpeekAbs; + if ( line < (0 - m_pSpeakDoc->m_TextRam.m_HisLen + m_pSpeakDoc->m_TextRam.m_Lines) ) { + line = 0 - m_pSpeakDoc->m_TextRam.m_HisLen + m_pSpeakDoc->m_TextRam.m_Lines + 1; + m_SpeakAbs = m_pSpeakDoc->m_TextRam.m_HisAbs; + m_SpeakLine = line + m_SpeakAbs; } - while ( m_SpeekQueLen < SPEEKQUESIZE ) { - if ( line >= m_pSpeekDoc->m_TextRam.m_Lines ) + while ( m_SpeakQueLen < SPEAKQUESIZE ) { + if ( line >= m_pSpeakDoc->m_TextRam.m_Lines ) return FALSE; - m_SpeekData[m_SpeekQuePos].text.Empty(); - m_SpeekData[m_SpeekQuePos].pos.RemoveAll(); - m_SpeekData[m_SpeekQuePos].skip = 0; - m_SpeekData[m_SpeekQuePos].abs = m_SpeekAbs; - m_SpeekData[m_SpeekQuePos].line = m_SpeekLine; + m_SpeakData[m_SpeakQuePos].text.Empty(); + m_SpeakData[m_SpeakQuePos].pos.RemoveAll(); + m_SpeakData[m_SpeakQuePos].skip = 0; + m_SpeakData[m_SpeakQuePos].abs = m_SpeakAbs; + m_SpeakData[m_SpeakQuePos].line = m_SpeakLine; - for ( int n = 0 ; n < 3 && line < m_pSpeekDoc->m_TextRam.m_Lines ; n++ ) { - bContinue = m_pSpeekDoc->m_TextRam.SpeekLine(line++, m_SpeekData[m_SpeekQuePos].text, m_SpeekData[m_SpeekQuePos].pos); - m_SpeekLine++; + for ( int n = 0 ; n < 3 && line < m_pSpeakDoc->m_TextRam.m_Lines ; n++ ) { + bContinue = m_pSpeakDoc->m_TextRam.SpeakLine(line++, m_SpeakData[m_SpeakQuePos].text, m_SpeakData[m_SpeakQuePos].pos); + m_SpeakLine++; if ( !bContinue ) break; } - if ( m_SpeekData[m_SpeekQuePos].text.IsEmpty() || m_SpeekData[m_SpeekQuePos].pos.GetSize() == 0 ) + if ( m_SpeakData[m_SpeakQuePos].text.IsEmpty() || m_SpeakData[m_SpeakQuePos].pos.GetSize() == 0 ) continue; - pVoice->Speak(m_SpeekData[m_SpeekQuePos].text, SPF_ASYNC | SPF_IS_NOT_XML, &(m_SpeekData[m_SpeekQuePos].num)); + pVoice->Speak(m_SpeakData[m_SpeakQuePos].text, SPF_ASYNC | SPF_IS_NOT_XML, &(m_SpeakData[m_SpeakQuePos].num)); - if ( ++m_SpeekQuePos >= SPEEKQUESIZE ) - m_SpeekQuePos = 0; - m_SpeekQueLen++; + if ( ++m_SpeakQuePos >= SPEAKQUESIZE ) + m_SpeakQuePos = 0; + m_SpeakQueLen++; } return TRUE; } -void CMainFrame::Speek(LPCTSTR str) +void CMainFrame::Speak(LPCTSTR str) { ISpVoice *pVoice = ((CRLoginApp *)::AfxGetApp())->m_pVoice; @@ -4197,26 +4225,26 @@ void CMainFrame::Speek(LPCTSTR str) m_bVoiceEvent = FALSE; pVoice->SetInterest(0, 0); pVoice->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK | SPF_IS_NOT_XML, NULL); - m_pSpeekView->SpeekTextPos(FALSE, NULL, NULL); + m_pSpeakView->SpeakTextPos(FALSE, NULL, NULL); } pVoice->Speak(TstrToUni(str), SPF_ASYNC, NULL); } -void CMainFrame::SpeekUpdate(int x, int y) +void CMainFrame::SpeakUpdate(int x, int y) { int pos; - pos = m_SpeekQueTop; - for ( int n = 0 ; n < m_SpeekQueLen ; n++ ) { - m_SpeekData[pos].skip = 1; - if ( ++pos >= SPEEKQUESIZE ) + pos = m_SpeakQueTop; + for ( int n = 0 ; n < m_SpeakQueLen ; n++ ) { + m_SpeakData[pos].skip = 1; + if ( ++pos >= SPEAKQUESIZE ) pos = 0; } - m_SpeekAbs = m_pSpeekDoc->m_TextRam.m_HisAbs; - m_SpeekLine = m_SpeekAbs + y; + m_SpeakAbs = m_pSpeakDoc->m_TextRam.m_HisAbs; + m_SpeakLine = m_SpeakAbs + y; } -LRESULT CMainFrame::OnSpeekMsg(WPARAM wParam, LPARAM lParam) +LRESULT CMainFrame::OnSpeakMsg(WPARAM wParam, LPARAM lParam) { SPEVENT eventItem; ISpVoice *pVoice = ((CRLoginApp *)::AfxGetApp())->m_pVoice; @@ -4232,71 +4260,71 @@ LRESULT CMainFrame::OnSpeekMsg(WPARAM wParam, LPARAM lParam) switch(eventItem.eEventId) { case SPEI_WORD_BOUNDARY: - if ( m_SpeekQueLen <= 0 ) + if ( m_SpeakQueLen <= 0 ) break; - if ( eventItem.ulStreamNum != m_SpeekData[m_SpeekQueTop].num ) + if ( eventItem.ulStreamNum != m_SpeakData[m_SpeakQueTop].num ) break; pVoice->GetStatus(&status, NULL); if ( status.dwRunningState != SPRS_IS_SPEAKING ) break; - if ( status.ulCurrentStream != m_SpeekData[m_SpeekQueTop].num ) + if ( status.ulCurrentStream != m_SpeakData[m_SpeakQueTop].num ) break; - if ( m_SpeekData[m_SpeekQueTop].skip != 0 ) { - pVoice->Skip(L"SENTENCE", m_SpeekData[m_SpeekQueTop].skip, &skipd); - m_SpeekData[m_SpeekQueTop].skip = 0; + if ( m_SpeakData[m_SpeakQueTop].skip != 0 ) { + pVoice->Skip(L"SENTENCE", m_SpeakData[m_SpeakQueTop].skip, &skipd); + m_SpeakData[m_SpeakQueTop].skip = 0; break; } if ( status.ulInputWordLen <= 0 ) break; - if ( (ULONG)m_SpeekData[m_SpeekQueTop].pos.GetSize() < (status.ulInputWordPos + status.ulInputWordLen - 1) ) + if ( (ULONG)m_SpeakData[m_SpeakQueTop].pos.GetSize() < (status.ulInputWordPos + status.ulInputWordLen - 1) ) break; - spos = m_SpeekData[m_SpeekQueTop].pos[status.ulInputWordPos]; - epos = m_SpeekData[m_SpeekQueTop].pos[status.ulInputWordPos + status.ulInputWordLen - 1]; - if ( !m_pSpeekDoc->m_TextRam.SpeekCheck(spos, epos, (LPCTSTR)m_SpeekData[m_SpeekQueTop].text + status.ulInputWordPos) ) { + spos = m_SpeakData[m_SpeakQueTop].pos[status.ulInputWordPos]; + epos = m_SpeakData[m_SpeakQueTop].pos[status.ulInputWordPos + status.ulInputWordLen - 1]; + if ( !m_pSpeakDoc->m_TextRam.SpeakCheck(spos, epos, (LPCTSTR)m_SpeakData[m_SpeakQueTop].text + status.ulInputWordPos) ) { pVoice->Skip(L"SENTENCE", 1, &skipd); - m_SpeekAbs = m_SpeekData[m_SpeekQueTop].abs; - m_SpeekLine = m_SpeekData[m_SpeekQueTop].line; - m_pSpeekView->SpeekTextPos(FALSE, NULL, NULL); + m_SpeakAbs = m_SpeakData[m_SpeakQueTop].abs; + m_SpeakLine = m_SpeakData[m_SpeakQueTop].line; + m_pSpeakView->SpeakTextPos(FALSE, NULL, NULL); break; } - m_pSpeekView->SpeekTextPos(TRUE, &spos, &epos); + m_pSpeakView->SpeakTextPos(TRUE, &spos, &epos); break; case SPEI_SENTENCE_BOUNDARY: case SPEI_START_INPUT_STREAM: - if ( m_SpeekQueLen <= 0 ) + if ( m_SpeakQueLen <= 0 ) break; - if ( eventItem.ulStreamNum != m_SpeekData[m_SpeekQueTop].num ) + if ( eventItem.ulStreamNum != m_SpeakData[m_SpeakQueTop].num ) break; - if ( m_SpeekData[m_SpeekQueTop].skip != 0 ) { - pVoice->Skip(L"SENTENCE", m_SpeekData[m_SpeekQueTop].skip, &skipd); - m_SpeekData[m_SpeekQueTop].skip = 0; + if ( m_SpeakData[m_SpeakQueTop].skip != 0 ) { + pVoice->Skip(L"SENTENCE", m_SpeakData[m_SpeakQueTop].skip, &skipd); + m_SpeakData[m_SpeakQueTop].skip = 0; break; } break; case SPEI_END_INPUT_STREAM: - if ( m_SpeekQueLen <= 0 ) + if ( m_SpeakQueLen <= 0 ) break; - if ( eventItem.ulStreamNum != m_SpeekData[m_SpeekQueTop].num ) + if ( eventItem.ulStreamNum != m_SpeakData[m_SpeakQueTop].num ) break; - m_SpeekData[m_SpeekQueTop].text.Empty(); - m_SpeekData[m_SpeekQueTop].pos.RemoveAll(); - if ( ++m_SpeekQueTop >= SPEEKQUESIZE ) - m_SpeekQueTop = 0; - m_SpeekQueLen--; - if ( !SpeekQueIn() && m_SpeekQueLen <= 0 ) { + m_SpeakData[m_SpeakQueTop].text.Empty(); + m_SpeakData[m_SpeakQueTop].pos.RemoveAll(); + if ( ++m_SpeakQueTop >= SPEAKQUESIZE ) + m_SpeakQueTop = 0; + m_SpeakQueLen--; + if ( !SpeakQueIn() && m_SpeakQueLen <= 0 ) { pVoice->SetInterest(0, 0); m_bVoiceEvent = FALSE; } - m_pSpeekView->SpeekTextPos(FALSE, NULL, NULL); + m_pSpeakView->SpeakTextPos(FALSE, NULL, NULL); break; } } return TRUE; } -void CMainFrame::OnSpeekText() +void CMainFrame::OnSpeakText() { ISpVoice *pVoice = ((CRLoginApp *)::AfxGetApp())->m_pVoice; CChildFrame *pChild = (CChildFrame *)MDIGetActive(); @@ -4312,15 +4340,15 @@ void CMainFrame::OnSpeekText() ULONGLONG ev = SPFEI(SPEI_WORD_BOUNDARY) | SPFEI(SPEI_SENTENCE_BOUNDARY) | SPFEI(SPEI_END_INPUT_STREAM); pVoice->SetInterest(ev, ev); - pVoice->SetNotifyWindowMessage(GetSafeHwnd(), WM_SPEEKMSG, 0, 0); + pVoice->SetNotifyWindowMessage(GetSafeHwnd(), WM_SPEAKMSG, 0, 0); - m_pSpeekView = pView; - m_pSpeekDoc = pDoc; + m_pSpeakView = pView; + m_pSpeakDoc = pDoc; - m_SpeekQueLen = m_SpeekQuePos = m_SpeekQueTop = 0; - m_SpeekAbs = m_pSpeekDoc->m_TextRam.m_HisAbs; - m_SpeekLine = m_SpeekAbs - m_pSpeekView->m_HisOfs; - SpeekQueIn(); + m_SpeakQueLen = m_SpeakQuePos = m_SpeakQueTop = 0; + m_SpeakAbs = m_pSpeakDoc->m_TextRam.m_HisAbs; + m_SpeakLine = m_SpeakAbs - m_pSpeakView->m_HisOfs; + SpeakQueIn(); m_bVoiceEvent = TRUE; @@ -4328,10 +4356,10 @@ void CMainFrame::OnSpeekText() m_bVoiceEvent = FALSE; pVoice->SetInterest(0, 0); pVoice->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK | SPF_IS_NOT_XML, NULL); - m_pSpeekView->SpeekTextPos(FALSE, NULL, NULL); + m_pSpeakView->SpeakTextPos(FALSE, NULL, NULL); } } -void CMainFrame::OnUpdateSpeekText(CCmdUI *pCmdUI) +void CMainFrame::OnUpdateSpeakText(CCmdUI *pCmdUI) { pCmdUI->Enable(((CRLoginApp *)::AfxGetApp())->m_pVoice != NULL ? TRUE : FALSE); pCmdUI->SetCheck(m_bVoiceEvent ? 1 : 0); @@ -4802,6 +4830,8 @@ void CQuickBar::InitDialog() // EntryName Update Connect Button Flag OnCbnEditchangeEntryname(); + + DpiChanged(); } void CQuickBar::SaveDialog() { @@ -4882,6 +4912,10 @@ static BOOL CALLBACK DpiChangedProc(HWND hWnd , LPARAM lParam) rect.top = MulDiv(rect.top, pParent->m_ZoomMul.cy, pParent->m_ZoomDiv.cy); rect.bottom = MulDiv(rect.bottom, pParent->m_ZoomMul.cy, pParent->m_ZoomDiv.cy); + int height = rect.Height(); + rect.top = (pParent->m_sizeDefault.cy - height) / 2; + rect.bottom = rect.top + height; + if ( pWnd->SendMessage(WM_DPICHANGED, MAKEWPARAM(SCREEN_DPI_X, SCREEN_DPI_Y), (LPARAM)((RECT *)rect)) == FALSE ) { if ( pParent->m_DpiFont.GetSafeHandle() != NULL ) pWnd->SetFont(&(pParent->m_DpiFont), FALSE); @@ -4960,6 +4994,10 @@ static BOOL CALLBACK FontSizeCheckProc(HWND hWnd , LPARAM lParam) rect.top = MulDiv(rect.top, pParent->m_ZoomMul.cy, pParent->m_ZoomDiv.cy); rect.bottom = MulDiv(rect.bottom, pParent->m_ZoomMul.cy, pParent->m_ZoomDiv.cy); + int height = rect.Height(); + rect.top = (pParent->m_sizeDefault.cy - height) / 2; + rect.bottom = rect.top + height; + pWnd->SetFont(&(pParent->m_NewFont), FALSE); pWnd->MoveWindow(rect, FALSE); @@ -4969,19 +5007,15 @@ void CQuickBar::FontSizeCheck() { CFont *pFont; CDC *pDc = GetDC(); - CFont *pOld; CRect rect; - TEXTMETRIC OldMetric, NewMetric; CString FontName = ::AfxGetApp()->GetProfileString(_T("Dialog"), _T("FontName"), _T("")); int FontSize = MulDiv(::AfxGetApp()->GetProfileInt(_T("Dialog"), _T("FontSize"), 9), SCREEN_DPI_Y, SYSTEM_DPI_Y); if ( m_NewFont.GetSafeHandle() != NULL ) { - pOld = pDc->SelectObject(&m_NewFont); - pDc->GetTextMetrics(&OldMetric); + CDialogExt::GetDlgFontBase(pDc, &m_NewFont, m_ZoomDiv); m_NewFont.DeleteObject(); } else if ( (pFont = GetFont()) != NULL ) { - pOld = pDc->SelectObject(pFont); - pDc->GetTextMetrics(&OldMetric); + CDialogExt::GetDlgFontBase(pDc, pFont, m_ZoomDiv); } else return; @@ -4993,17 +5027,9 @@ void CQuickBar::FontSizeCheck() SetFont(&m_NewFont); - pDc->SelectObject(&m_NewFont); - pDc->GetTextMetrics(&NewMetric); - - pDc->SelectObject(pOld); + CDialogExt::GetDlgFontBase(pDc, &m_NewFont, m_ZoomMul); ReleaseDC(pDc); - m_ZoomMul.cx = NewMetric.tmAveCharWidth; - m_ZoomDiv.cx = OldMetric.tmAveCharWidth; - m_ZoomMul.cy = NewMetric.tmHeight; - m_ZoomDiv.cy = OldMetric.tmHeight; - GetWindowRect(rect); rect.left = MulDiv(rect.left, m_ZoomMul.cx, m_ZoomDiv.cx); diff --git a/RLogin/MainFrm.h b/RLogin/MainFrm.h index b80c28f..3bf8e28 100755 --- a/RLogin/MainFrm.h +++ b/RLogin/MainFrm.h @@ -243,7 +243,7 @@ class CTabDlgBar : public CControlBar #define SCREEN_DPI_X ((CMainFrame *)::AfxGetMainWnd())->m_ScreenDpiX #define SCREEN_DPI_Y ((CMainFrame *)::AfxGetMainWnd())->m_ScreenDpiY -#define SPEEKQUESIZE 2 +#define SPEAKQUESIZE 2 class CMainFrame : public CMDIFrameWnd { @@ -318,6 +318,8 @@ class CMainFrame : public CMDIFrameWnd clock_t m_LastClipUpdate; class CServerSelect *m_pServerSelect; class CHistoryDlg *m_pHistoryDlg; + class CAnyPastDlg *m_pAnyPastDlg; + BOOL m_PastNoCheck; BOOL WageantQuery(CBuffer *pInBuf, CBuffer *pOutBuf); BOOL PageantQuery(CBuffer *pInBuf, CBuffer *pOutBuf); @@ -405,6 +407,8 @@ class CMainFrame : public CMDIFrameWnd BOOL CopyClipboardData(CString &str); BOOL GetClipboardText(CString &str); BOOL SetClipboardText(LPCTSTR str, LPCSTR rtf = NULL); + void AnyPastDlgClose(int DocSeqNumber); + void AnyPastDlgOpen(LPCWSTR str, int DocSeqNumber); inline BOOL IsTimerIdleBusy() { return (m_IdleTimer != 0 ? TRUE : FALSE); } BOOL TrackPopupMenuIdle(CMenu *pMenu, UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = 0); @@ -420,26 +424,26 @@ class CMainFrame : public CMDIFrameWnd void VersionCheck(); BOOL m_bVoiceEvent; - struct _SpeekData { + struct _SpeakData { ULONG num; CString text; CArray pos; long skip; int abs; int line; - } m_SpeekData[SPEEKQUESIZE]; - int m_SpeekQueLen; - int m_SpeekQuePos; - int m_SpeekQueTop; - class CRLoginView *m_pSpeekView; - class CRLoginDoc *m_pSpeekDoc; - int m_SpeekLine; - int m_SpeekAbs; - - BOOL SpeekQueIn(); - void Speek(LPCTSTR str); - void SpeekUpdate(int x, int y); - inline BOOL SpeekViewCheck(class CRLoginView *pWnd) { return (m_bVoiceEvent && m_pSpeekView == pWnd ? TRUE : FALSE); } + } m_SpeakData[SPEAKQUESIZE]; + int m_SpeakQueLen; + int m_SpeakQuePos; + int m_SpeakQueTop; + class CRLoginView *m_pSpeakView; + class CRLoginDoc *m_pSpeakDoc; + int m_SpeakLine; + int m_SpeakAbs; + + BOOL SpeakQueIn(); + void Speak(LPCTSTR str); + void SpeakUpdate(int x, int y); + inline BOOL SpeakViewCheck(class CRLoginView *pWnd) { return (m_bVoiceEvent && m_pSpeakView == pWnd ? TRUE : FALSE); } inline CImageList *GetTabImageList() { return &(m_wndTabBar.m_ImageList); } inline int GetTabImageIndex(LPCTSTR filename) { return m_wndTabBar.GetImageIndex(filename); } @@ -529,8 +533,8 @@ class CMainFrame : public CMDIFrameWnd afx_msg void OnNewVersionFound(); afx_msg void OnClipchain(); afx_msg void OnUpdateClipchain(CCmdUI *pCmdUI); - afx_msg void OnSpeekText(); - afx_msg void OnUpdateSpeekText(CCmdUI *pCmdUI); + afx_msg void OnSpeakText(); + afx_msg void OnUpdateSpeakText(CCmdUI *pCmdUI); afx_msg void OnFileAllLoad(); afx_msg void OnFileAllSave(); @@ -552,7 +556,7 @@ class CMainFrame : public CMDIFrameWnd afx_msg LRESULT OnDpiChanged(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSetMessageString(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnNullMessage(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnSpeekMsg(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnSpeakMsg(WPARAM wParam, LPARAM lParam); }; diff --git a/RLogin/MidiData.cpp b/RLogin/MidiData.cpp index 7326b3f..87295da 100755 --- a/RLogin/MidiData.cpp +++ b/RLogin/MidiData.cpp @@ -133,7 +133,7 @@ int CNode::GetEventSize() switch(m_Cmd) { case 0xFF51: // Tempo return n; - case 0xFF80: // Speek + case 0xFF80: // Speak return (n + 4 + ((m_Len + (sizeof(DWORD) - 1)) / sizeof(DWORD)) * sizeof(DWORD)); default: return 0; @@ -170,7 +170,7 @@ int CNode::SetEvent(DWORD pos, BYTE *pData) n += sizeof(DWORD); return n; - case 0xFF80: // Speek + case 0xFF80: // Speak tmp = ((MEVT_COMMENT << 24) | MEVT_F_CALLBACK | ((DWORD)sizeof(DWORD) + m_Len)); memcpy(pData + n, &tmp, sizeof(DWORD)); n += sizeof(DWORD); @@ -2736,9 +2736,9 @@ DWORD WINAPI CMidiData::ThreadProc(void *lpParameter) if ( !pMidi->StreamQueIn() ) pMidi->Stop(); break; - case 0x0001: // Speek + case 0x0001: // Speak if ( pMidi->m_pMainWnd != NULL ) - pMidi->m_pMainWnd->Speek(MbsToTstr((LPCSTR)((BYTE *)(pEvent->dwParms) + sizeof(DWORD)))); + pMidi->m_pMainWnd->Speak(MbsToTstr((LPCSTR)((BYTE *)(pEvent->dwParms) + sizeof(DWORD)))); break; } } diff --git a/RLogin/RLogin.cpp b/RLogin/RLogin.cpp index b87aef1..e619925 100755 --- a/RLogin/RLogin.cpp +++ b/RLogin/RLogin.cpp @@ -493,6 +493,8 @@ class CAboutDlg : public CDialogExt protected: DECLARE_MESSAGE_MAP() afx_msg void OnNMClickSyslink(NMHDR *pNMHDR, LRESULT *pResult); +public: + afx_msg void OnStnClickedVersionstr(); }; CAboutDlg::CAboutDlg() : CDialogExt(CAboutDlg::IDD) @@ -535,6 +537,7 @@ BEGIN_MESSAGE_MAP(CAboutDlg, CDialogExt) ON_NOTIFY(NM_CLICK, IDC_SYSLINK1, &CAboutDlg::OnNMClickSyslink) ON_NOTIFY(NM_CLICK, IDC_SYSLINK2, &CAboutDlg::OnNMClickSyslink) ON_NOTIFY(NM_CLICK, IDC_SYSLINK3, &CAboutDlg::OnNMClickSyslink) + ON_STN_CLICKED(IDC_VERSIONSTR, &CAboutDlg::OnStnClickedVersionstr) END_MESSAGE_MAP() ////////////////////////////////////////////////////////////////////// @@ -3632,3 +3635,9 @@ void CRLoginApp::EmojiImageInit(LPCTSTR pFontName, LPCTSTR pImageDir) } #endif + + +void CAboutDlg::OnStnClickedVersionstr() +{ + // TODO: ここにコントロール通知ハンドラー コードを追加します。 +} diff --git a/RLogin/RLogin.h b/RLogin/RLogin.h index e4cc68d..ceb4f66 100755 --- a/RLogin/RLogin.h +++ b/RLogin/RLogin.h @@ -25,7 +25,7 @@ // CRLoginView #define WM_LOGWRITE (WM_APP + 21) -#define WM_SPEEKMSG (WM_APP + 22) +#define WM_SPEAKMSG (WM_APP + 22) // CSFtp #define WM_RECIVEBUFFER (WM_APP + 23) diff --git a/RLogin/RLogin.rc b/RLogin/RLogin.rc index ab6280f..e9fc8db 100755 --- a/RLogin/RLogin.rc +++ b/RLogin/RLogin.rc @@ -268,7 +268,7 @@ BEGIN MENUITEM "スクリプトの停止(&S)", ID_CHARSCRIPT_END MENUITEM "Break信号を送る(&B)", ID_SEND_BREAK MENUITEM "マウスイベントを無効(&M)", ID_MOUSE_EVENT - MENUITEM "音声で読み上げる(&Y)", IDM_SPEEKALL + MENUITEM "音声で読み上げる(&Y)", IDM_SPEAKALL MENUITEM SEPARATOR MENUITEM "ブロードキャスト(&A)", IDM_BROADCAST MENUITEM "別のRLoginにも送信(&O)", IDM_OTHERCAST @@ -627,9 +627,9 @@ BEGIN "SysLink",WS_TABSTOP,44,178,189,8 DEFPUSHBUTTON "OK",IDOK,91,193,60,14,WS_GROUP ICON IDR_MAINFRAME,IDC_STATIC,7,7,20,20 - LTEXT "RLogin (%s) Version 2.25.9 (2021/03/01)",IDC_VERSIONSTR,44,7,189,8,SS_NOPREFIX + LTEXT "RLogin (%s) Version 2.26.0 (2021/04/05)",IDC_VERSIONSTR,44,7,189,8,SS_NOPREFIX LTEXT "Copyright (C) 1998-2021 Culti",IDC_STATIC,44,16,189,8 - LTEXT "OpenSSL 1.1.1j 16 Feb 2021",IDC_STATIC,44,52,189,8 + LTEXT "OpenSSL 1.1.1k 25 Mar 2021",IDC_STATIC,44,52,189,8 LTEXT "Copyright (c) 1998-2021 The OpenSSL Project",IDC_STATIC,44,61,189,8 LTEXT "Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson",IDC_STATIC,44,70,189,8 LTEXT "All rights reserved.",IDC_STATIC,44,79,189,8 @@ -2152,8 +2152,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,25,9,0 - PRODUCTVERSION 2,25,9,0 + FILEVERSION 2,26,0,0 + PRODUCTVERSION 2,26,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -2170,12 +2170,12 @@ BEGIN BEGIN VALUE "CompanyName", "Culti" VALUE "FileDescription", "RLogin MFC アプリケーション" - VALUE "FileVersion", "2.25.9.0" + VALUE "FileVersion", "2.26.0.0" VALUE "InternalName", "RLogin.exe" VALUE "LegalCopyright", "Copyright (C) 2019 Culti All rights reserved." VALUE "OriginalFilename", "RLogin.exe" VALUE "ProductName", "RLogin アプリケーション" - VALUE "ProductVersion", "2.25.9.0" + VALUE "ProductVersion", "2.26.0.0" END END BLOCK "VarFileInfo" @@ -4436,6 +4436,9 @@ BEGIN IDS_REGAPPSETMSG "既定のアプリにRLoginを登録しますか?" IDS_REGAPPDELMSG "すべての関連付け及び既定のアプリへの登録を削除しますか?" IDS_EMOJIMAGEMSG "絵文字の画像が保存されたフォルダを選択" + IDS_ANYPASTVIEWMSG "呼び出した接続と違う接続にペーストしますか?" + IDS_VERSIONCHECKURL2 "https://kmiya-culti.github.io/RLogin/version.txt" + IDS_SCRIPTDLGSTEP "ステップ" END STRINGTABLE @@ -4918,7 +4921,7 @@ BEGIN IDM_CMDHIS_MSG "コマンド終了時にメッセージを表示\n終了メッセージ" IDM_CMDHIS_SCRM "スクロールモードの着替え\nスクロールモード" IDM_HISTORYDLG "ヒストリーウィンドウを表示・非表示\nヒストリーウィンドウ" - IDM_SPEEKALL "表示されている画面を音声で読み上げます\n音声で読み上げ" + IDM_SPEAKALL "表示されている画面を音声で読み上げます\n音声で読み上げ" END #endif // 日本語 (日本) resources diff --git a/RLogin/RLogin.vcxproj b/RLogin/RLogin.vcxproj index 569548d..3d36389 100755 --- a/RLogin/RLogin.vcxproj +++ b/RLogin/RLogin.vcxproj @@ -97,7 +97,7 @@ Disabled - openssl-1.1.1j-x32;openssl-1.1.1j-x32\include;openssl-1.1.1j-x32\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) + openssl-1.1.1k-x32;openssl-1.1.1k-x32\include;openssl-1.1.1k-x32\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) true EnableFastChecks @@ -113,7 +113,7 @@ d2d1.lib;dwrite.lib;windowscodecs.lib;dxgi.lib;d3d10_1.lib;imm32.lib;ComCtl32.lib;libcrypto.lib;libssl.lib;iconv.lib;zlib.lib;Wininet.lib;%(AdditionalDependencies) - openssl-1.1.1j-x32;libiconv-1.16\lib\x32;zlib-1.2.11\x32;%(AdditionalLibraryDirectories) + openssl-1.1.1k-x32;libiconv-1.16\lib\x32;zlib-1.2.11\x32;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) %(DelayLoadDLLs) true @@ -140,7 +140,7 @@ AnySuitable true Speed - openssl-1.1.1j-x32;openssl-1.1.1j-x32\include;openssl-1.1.1j-x32\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) + openssl-1.1.1k-x32;openssl-1.1.1k-x32\include;openssl-1.1.1k-x32\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) false MultiThreaded @@ -155,7 +155,7 @@ imm32.lib;ComCtl32.lib;libcrypto.lib;libssl.lib;iconv.lib;zlib.lib;Wininet.lib;%(AdditionalDependencies) - openssl-1.1.1j-x32;libiconv-1.16\lib\x32;zlib-1.2.11\x32;%(AdditionalLibraryDirectories) + openssl-1.1.1k-x32;libiconv-1.16\lib\x32;zlib-1.2.11\x32;%(AdditionalLibraryDirectories) true Windows true @@ -186,7 +186,7 @@ AnySuitable true Speed - openssl-1.1.1j;openssl-1.1.1j\include;openssl-1.1.1j\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) + openssl-1.1.1k;openssl-1.1.1k\include;openssl-1.1.1k\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) false MultiThreaded @@ -203,7 +203,7 @@ imm32.lib;ComCtl32.lib;libcrypto.lib;libssl.lib;iconv.lib;zlib.lib;Wininet.lib;%(AdditionalDependencies) - openssl-1.1.1j;libiconv-1.16\lib\x64;zlib-1.2.11\x64;%(AdditionalLibraryDirectories) + openssl-1.1.1k;libiconv-1.16\lib\x64;zlib-1.2.11\x64;%(AdditionalLibraryDirectories) true Windows true @@ -231,7 +231,7 @@ false - openssl-1.1.1j;openssl-1.1.1j\include;openssl-1.1.1j\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) + openssl-1.1.1k;openssl-1.1.1k\include;openssl-1.1.1k\crypto\include;libiconv-1.16\include;zlib-1.2.11;%(AdditionalIncludeDirectories) Level3 Disabled false @@ -243,7 +243,7 @@ ProgramDatabase - openssl-1.1.1j;libiconv-1.16\lib\x64;zlib-1.2.11\x64;%(AdditionalLibraryDirectories) + openssl-1.1.1k;libiconv-1.16\lib\x64;zlib-1.2.11\x64;%(AdditionalLibraryDirectories) imm32.lib;ComCtl32.lib;libcrypto.lib;libssl.lib;iconv.lib;zlib.lib;Wininet.lib;%(AdditionalDependencies) true Windows diff --git a/RLogin/RLoginDoc.cpp b/RLogin/RLoginDoc.cpp index 6bb959d..8df9dcb 100755 --- a/RLogin/RLoginDoc.cpp +++ b/RLogin/RLoginDoc.cpp @@ -83,6 +83,7 @@ END_MESSAGE_MAP() CRLoginDoc::CRLoginDoc() { + m_DocSeqNumber = 0; m_pSock = NULL; m_TextRam.m_pDocument = this; m_pLogFile = NULL; @@ -176,6 +177,8 @@ BOOL CRLoginDoc::ScriptInit() } BOOL CRLoginDoc::InitDocument() { + static int SeqNumber = 0; + m_TextRam.SetKanjiMode(m_ServerEntry.m_KanjiCode); SetTitle(m_ServerEntry.m_EntryName); @@ -194,6 +197,8 @@ BOOL CRLoginDoc::InitDocument() pView->ImmOpenCtrl(0); } + m_DocSeqNumber = ++SeqNumber; + return TRUE; } BOOL CRLoginDoc::OnNewDocument() @@ -623,7 +628,10 @@ void CRLoginDoc::DeleteContents() delete m_pScript; m_pScript = NULL; } + + ((CMainFrame *)::AfxGetMainWnd())->AnyPastDlgClose(m_DocSeqNumber); + m_DocSeqNumber = 0; m_ServerEntry.Init(); m_TextRam.m_bOpen = FALSE; m_InPane = FALSE; diff --git a/RLogin/RLoginDoc.h b/RLogin/RLoginDoc.h index e1d0510..cb80086 100755 --- a/RLogin/RLoginDoc.h +++ b/RLogin/RLoginDoc.h @@ -82,6 +82,7 @@ class CRLoginDoc : public CDocument // オペレーション public: + int m_DocSeqNumber; CExtSocket *m_pSock; CTextRam m_TextRam; CKeyNodeTab m_KeyTab; diff --git a/RLogin/RLoginView.cpp b/RLogin/RLoginView.cpp index bdb9678..19c58e7 100755 --- a/RLogin/RLoginView.cpp +++ b/RLogin/RLoginView.cpp @@ -13,7 +13,6 @@ #include "Data.h" #include "SearchDlg.h" #include "Script.h" -#include "AnyPastDlg.h" #include "GrapWnd.h" #include "MsgWnd.h" @@ -335,11 +334,7 @@ CRLoginView::CRLoginView() m_MatrixCols.SetSize(COLS_MAX); - m_PastNoCheck = FALSE; - m_PastDelaySend = FALSE; - m_PastCtrlView = FALSE; - - m_bSpeekDispText = FALSE; + m_bSpeakDispText = FALSE; } CRLoginView::~CRLoginView() @@ -1353,10 +1348,10 @@ int CRLoginView::OnCreate(LPCREATESTRUCT lpCreateStruct) } void CRLoginView::OnDestroy() { - if ( ((CMainFrame *)::AfxGetMainWnd())->SpeekViewCheck(this) ) - ((CMainFrame *)::AfxGetMainWnd())->SendMessage(WM_COMMAND, IDM_SPEEKALL); + if ( ((CMainFrame *)::AfxGetMainWnd())->SpeakViewCheck(this) ) + ((CMainFrame *)::AfxGetMainWnd())->SendMessage(WM_COMMAND, IDM_SPEAKALL); - DelayInvalThreadEndof(); + DelayInvalThreadEndof(); ((CRLoginApp *)AfxGetApp())->DelIdleProc(IDLEPROC_VIEW, this); CView::OnDestroy(); @@ -2680,9 +2675,9 @@ void CRLoginView::OnLButtonDown(UINT nFlags, CPoint point) CView::OnLButtonDown(nFlags, point); SetCapture(); - if ( ((CMainFrame *)::AfxGetMainWnd())->SpeekViewCheck(this) ) { + if ( ((CMainFrame *)::AfxGetMainWnd())->SpeakViewCheck(this) ) { CalcGrapPoint(point, &x, &y); - ((CMainFrame *)::AfxGetMainWnd())->SpeekUpdate(x, y); + ((CMainFrame *)::AfxGetMainWnd())->SpeakUpdate(x, y); return; } @@ -3201,17 +3196,32 @@ void CRLoginView::OnRButtonDblClk(UINT nFlags, CPoint point) if ( !pDoc->m_TextRam.IsOptEnable(TO_RLRSPAST) && pDoc->m_TextRam.IsOptEnable(TO_RLRCLICK) ) OnEditPaste(); } +void CRLoginView::SendBracketedPaste(LPCWSTR str, BOOL bDelay) +{ + CBuffer tmp; + CRLoginDoc *pDoc = GetDocument(); -BOOL CRLoginView::SendPasteText(LPCWSTR wstr) + if ( pDoc->m_TextRam.IsOptEnable(TO_XTBRPAMD) ) + tmp.Apend((LPBYTE)(L"\033[200~"), 6 * sizeof(WCHAR)); + + for ( ; *str != 0 ; str++ ) { + if ( *str != L'\x0A' ) + tmp.Apend((LPBYTE)str, sizeof(WCHAR)); + } + + if ( pDoc->m_TextRam.IsOptEnable(TO_XTBRPAMD) ) + tmp.Apend((LPBYTE)(L"\033[201~"), 6 * sizeof(WCHAR)); + + SendBuffer(tmp, FALSE, bDelay); +} +void CRLoginView::SendPasteText(LPCWSTR wstr) { int ct = 0; int len = 0; LPCWSTR p; - CBuffer tmp; - BOOL rt = FALSE; - CAnyPastDlg dlg; - CRLoginDoc *pDoc = GetDocument(); CStringW wrk; + CRLoginDoc *pDoc = GetDocument(); + CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd(); for ( p = wstr ; *p != 0 ; ) { if ( p[0] == L'\x0D' && p[1] == L'\x0A' ) { @@ -3247,52 +3257,10 @@ BOOL CRLoginView::SendPasteText(LPCWSTR wstr) ct--; } - wstr = wrk; - - if ( pDoc->m_TextRam.IsOptEnable(TO_RLEDITPAST) || (m_PastNoCheck == FALSE && (len > 500 || ct > 0)) ) { - dlg.m_NoCheck = m_PastNoCheck; - dlg.m_EditText = wstr; - dlg.m_bDelayPast = pDoc->m_TextRam.IsOptEnable(TO_RLDELYPAST) || m_PastDelaySend ? TRUE : FALSE; - dlg.m_bUpdateText = pDoc->m_TextRam.IsOptEnable(TO_RLUPDPAST) ? TRUE : FALSE; - dlg.m_bCtrlView = m_PastCtrlView; - dlg.m_pView = this; - - if ( dlg.DoModal() != IDOK ) { - m_PastDelaySend = dlg.m_bDelayPast; - m_PastCtrlView = dlg.m_bCtrlView; - return FALSE; - } - - m_PastNoCheck = dlg.m_NoCheck; - m_PastDelaySend = dlg.m_bDelayPast; - m_PastCtrlView = dlg.m_bCtrlView; - - wstr = TstrToUni(dlg.m_EditText); - - if ( dlg.m_bUpdateText != pDoc->m_TextRam.IsOptEnable(TO_RLUPDPAST) ) { - pDoc->m_TextRam.SetOption(TO_RLUPDPAST, dlg.m_bUpdateText); - pDoc->SetModifiedFlag(TRUE); - } - - if ( dlg.m_bUpdateText ) { - ((CMainFrame *)::AfxGetMainWnd())->SetClipboardText(dlg.m_EditText); - rt = TRUE; - } - } - - if ( pDoc->m_TextRam.IsOptEnable(TO_XTBRPAMD) ) - tmp.Apend((LPBYTE)(L"\033[200~"), 6 * sizeof(WCHAR)); - - for ( p = wstr ; *p != 0 ; p++ ) { - if ( *p != L'\x0A' ) - tmp.Apend((LPBYTE)p, sizeof(WCHAR)); - } - - if ( pDoc->m_TextRam.IsOptEnable(TO_XTBRPAMD) ) - tmp.Apend((LPBYTE)(L"\033[201~"), 6 * sizeof(WCHAR)); - - SendBuffer(tmp, FALSE, m_PastDelaySend); - return rt; + if ( pDoc->m_TextRam.IsOptEnable(TO_RLEDITPAST) || pMain->m_pAnyPastDlg != NULL || (!pMain->m_PastNoCheck && (len > 500 || ct > 0)) ) + pMain->AnyPastDlgOpen(wrk, pDoc->m_DocSeqNumber); + else + SendBracketedPaste(wrk, pDoc->m_TextRam.IsOptEnable(TO_RLDELYPAST)); } void CRLoginView::OnEditPaste() { @@ -3335,8 +3303,8 @@ void CRLoginView::ClipboardPaste(UINT nID) // Global Clipboard Update if ( pos != NULL ) { - if ( !SendPasteText(pMain->m_ClipBoard.GetAt(pos)) ) - ((CMainFrame *)::AfxGetMainWnd())->SetClipboardText(pMain->m_ClipBoard.GetAt(pos)); + SendPasteText(pMain->m_ClipBoard.GetAt(pos)); + ((CMainFrame *)::AfxGetMainWnd())->SetClipboardText(pMain->m_ClipBoard.GetAt(pos)); } // Local Clipboard Update @@ -3735,7 +3703,7 @@ BOOL CRLoginView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) } #endif - if ( hCursor == NULL && ((CMainFrame *)::AfxGetMainWnd())->SpeekViewCheck(this) ) + if ( hCursor == NULL && ((CMainFrame *)::AfxGetMainWnd())->SpeakViewCheck(this) ) hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND); if ( hCursor == NULL ) { @@ -3965,36 +3933,36 @@ LRESULT CRLoginView::OnLogWrite(WPARAM wParam, LPARAM lParam) return TRUE; } -void CRLoginView::SpeekTextPos(BOOL bDisp, CCurPos *pStaPos, CCurPos *pEndPos) +void CRLoginView::SpeakTextPos(BOOL bDisp, CCurPos *pStaPos, CCurPos *pEndPos) { CRect rect; if ( bDisp ) { ASSERT(pStaPos != NULL && pEndPos != NULL); - if ( m_bSpeekDispText ) { - if ( m_SpeekStaPos == *pStaPos && m_SpeekEndPos == *pEndPos ) + if ( m_bSpeakDispText ) { + if ( m_SpeakStaPos == *pStaPos && m_SpeakEndPos == *pEndPos ) return; - CalcPosRect(rect, m_SpeekStaPos, m_SpeekEndPos, TRUE); + CalcPosRect(rect, m_SpeakStaPos, m_SpeakEndPos, TRUE); InvalidateTextRect(rect); } - m_SpeekStaPos = *pStaPos; - m_SpeekEndPos = *pEndPos; - m_bSpeekDispText = TRUE; + m_SpeakStaPos = *pStaPos; + m_SpeakEndPos = *pEndPos; + m_bSpeakDispText = TRUE; - } else if ( m_bSpeekDispText ) { - m_bSpeekDispText = FALSE; + } else if ( m_bSpeakDispText ) { + m_bSpeakDispText = FALSE; } else { return; } - CalcPosRect(rect, m_SpeekStaPos, m_SpeekEndPos, TRUE); + CalcPosRect(rect, m_SpeakStaPos, m_SpeakEndPos, TRUE); InvalidateTextRect(rect); - if ( !bDisp && !((CMainFrame *)::AfxGetMainWnd())->SpeekViewCheck(this) ) + if ( !bDisp && !((CMainFrame *)::AfxGetMainWnd())->SpeakViewCheck(this) ) OnSetCursor(NULL, 0, 0); } diff --git a/RLogin/RLoginView.h b/RLogin/RLoginView.h index 14887bf..ce3137e 100755 --- a/RLogin/RLoginView.h +++ b/RLogin/RLoginView.h @@ -84,9 +84,6 @@ class CRLoginView : public CView BOOL m_ScrollOut; BOOL m_ClipUpdateLine; CBitmap m_TekBitmap; - BOOL m_PastNoCheck; - BOOL m_PastDelaySend; - BOOL m_PastCtrlView; clock_t m_RDownClock; CPoint m_RDownPoint; @@ -215,15 +212,16 @@ class CRLoginView : public CView void CreateGrapImage(int type); void GetMousePos(int *sw, int *x, int *y); void PopUpMenu(CPoint point); - BOOL SendPasteText(LPCWSTR wstr); + void SendBracketedPaste(LPCWSTR str, BOOL bDelay); + void SendPasteText(LPCWSTR wstr); void KillScrollTimer(); BOOL SetDropFile(LPCTSTR FileName, BOOL &doCmd, BOOL &doSub); - BOOL m_bSpeekDispText; - CCurPos m_SpeekStaPos, m_SpeekEndPos; + BOOL m_bSpeakDispText; + CCurPos m_SpeakStaPos, m_SpeakEndPos; - void SpeekTextPos(BOOL bDisp, CCurPos *pStaPos, CCurPos *pEndPos); + void SpeakTextPos(BOOL bDisp, CCurPos *pStaPos, CCurPos *pEndPos); inline int CalcGrapX(int x) { CRLoginDoc *pDoc = GetDocument(); return (m_Width * x / m_Cols + pDoc->m_TextRam.m_ScrnOffset.left); } inline int CalcGrapY(int y) { CRLoginDoc *pDoc = GetDocument(); return (m_Height * y / m_Lines + pDoc->m_TextRam.m_ScrnOffset.top + m_TopOffset); } diff --git a/RLogin/Regex.cpp b/RLogin/Regex.cpp index 6816206..448886f 100755 --- a/RLogin/Regex.cpp +++ b/RLogin/Regex.cpp @@ -134,6 +134,10 @@ LPCWSTR CStringD::WStr(CStringW &str) str.Empty(); for ( n = 0 ; n < len ; n++ ) { ch = m_Data[n]; + + if ( IsRegSpChar(ch) ) + continue; + if ( (ch & 0xFFFF0000) != 0 ) { // 000? **** **** **xx xxxx xxxx U+010000 - U+10FFFF 21 bit // 1101 10** **** **** U+D800 - U+DBFF 上位サロゲート @@ -164,6 +168,10 @@ LPCWSTR CStringD::GetAt(int idx) return m_Work; ch = m_Data[idx]; + + if ( IsRegSpChar(ch) ) + return m_Work; + if ( (ch & 0xFFFF0000) != 0 ) { // 000? **** **** **xx xxxx xxxx U+010000 - U+10FFFF 21 bit // 1101 10** **** **** U+D800 - U+DBFF 上位サロゲート @@ -332,7 +340,7 @@ CRegExNode::CRegExNode(void) m_Left = NULL; m_Right = NULL; - m_Type = 0; + m_Type = RGE_NONE; m_SChar = 0; m_EChar = (-1); m_Map = NULL; @@ -351,8 +359,8 @@ const CRegExNode & CRegExNode::operator = (CRegExNode &data) delete [] m_Map; m_Map = NULL; if ( data.m_Map != NULL ) { - m_Map = new DWORD[MAPARRAY]; - memcpy(m_Map, data.m_Map, MAPBYTE); + m_Map = new DWORD[REG_MAPARRAY]; + memcpy(m_Map, data.m_Map, REG_MAPBYTE); } return *this; } @@ -436,7 +444,6 @@ CRegEx::CRegEx(void) m_QueHead[0] = m_QueHead[1] = m_QueHead[2] = NULL; m_WorkTop = m_WorkFree = m_WorkHead = NULL; m_WorkSeq = 0; - m_QueSw = 0; m_CompStrBuf = NULL; m_ErrMsg.Empty(); } @@ -511,7 +518,7 @@ void CRegEx::UnGetChar(DCHAR ch) m_CompStrBuf->m_SaveCh = ch; } -CRegExNode *CRegEx::AllocNode(int type) +CRegExNode *CRegEx::AllocNode(enum RegCmdType type) { int n; CRegExNode *np; @@ -630,31 +637,38 @@ CRegExNode *CRegEx::CompileExtChar(DCHAR ch, CRegExNode *rp) switch(ch) { case L'd': - rp->m_Left = AllocNode('c'); + rp->m_Left = AllocNode(RGE_RANGECHAR); rp = rp->m_Left; rp->m_SChar = L'0'; rp->m_EChar = L'9'; break; case L'D': - rp->m_Left = AllocNode('C'); + rp->m_Left = AllocNode(RGE_NEGCHAR); rp = rp->m_Left; rp->m_SChar = L'0'; rp->m_EChar = L'9'; break; case L's': - rp->m_Left = AllocNode('c'); + rp->m_Left = AllocNode(RGE_RANGECHAR); rp = rp->m_Left; rp->m_SChar = L'\0'; rp->m_EChar = L' '; break; case L'S': - rp->m_Left = AllocNode('C'); + rp->m_Left = AllocNode(RGE_NEGCHAR); rp = rp->m_Left; rp->m_SChar = L'\0'; rp->m_EChar = L' '; break; + case L'h': + rp = CompleInline(rp, _T("[0-9a-fA-F]")); + break; + case L'H': + rp = CompleInline(rp, _T("[^0-9a-fA-F]")); + break; + case L'w': rp = CompleInline(rp, _T("[A-Za-z0-9_]")); break; @@ -685,16 +699,16 @@ CRegExNode *CRegEx::CompileExtChar(DCHAR ch, CRegExNode *rp) if ( (nx = GetChar()) == L'{' ) { for ( ; ; ) { nx = CompileEscape(ch); - rp->m_Left = AllocNode('c'); + rp->m_Left = AllocNode(RGE_RANGECHAR); rp = rp->m_Left; rp->m_SChar = rp->m_EChar = nx; if ( (nx = GetChar()) == EOF ) - throw _T("RegEx syntax error\n{... no end to character list \"}\""); + throw _T("RegEx syntax error\n{... no end to character list \"}\""); else if ( nx == L'}' ) break; else if ( nx > L' ' ) - throw _T("RegEx syntax error\n{0...} character list overflow ?"); + throw _T("RegEx syntax error\n{0...} character list overflow ?"); } } else { UnGetChar(nx); @@ -714,32 +728,34 @@ void CRegEx::CompileReverse(CRegExNode *rp) return; switch(rp->m_Type) { - case 'c': - rp->m_Type = 'C'; + case RGE_BRANCHES: + CompileReverse(rp->m_Right); break; - case 'C': - rp->m_Type = 'c'; + + case RGE_LINETOP: + rp->m_Type = RGE_NEGTOP; break; - case 'm': - rp->m_Type = 'M'; + case RGE_NEGTOP: + rp->m_Type = RGE_LINETOP; break; - case 'M': - rp->m_Type = 'm'; + case RGE_LINEBTM: + rp->m_Type = RGE_NEGBTM; break; - case '^': - rp->m_Type = '1'; + case RGE_NEGBTM: + rp->m_Type = RGE_LINEBTM; break; - case '$': - rp->m_Type = '2'; + + case RGE_CHKMAP: + rp->m_Type = RGE_NEGMAP; break; - case '1': - rp->m_Type = '^'; + case RGE_NEGMAP: + rp->m_Type = RGE_CHKMAP; break; - case '2': - rp->m_Type = '$'; + case RGE_RANGECHAR: + rp->m_Type = RGE_NEGCHAR; break; - case 'b': - CompileReverse(rp->m_Right); + case RGE_NEGCHAR: + rp->m_Type = RGE_RANGECHAR; break; } @@ -748,14 +764,14 @@ void CRegEx::CompileReverse(CRegExNode *rp) CRegExNode *CRegEx::CompileRange(CRegExNode *rp) { DCHAR ch; - int type = 'c'; + enum RegCmdType type = RGE_RANGECHAR; int count = 0; CRegExNode tmp, *tp, *np, *ap, *bp = NULL; DCHAR nch = 0xFFFF; DCHAR mch = 0x0000; if ( (ch = GetChar()) == '^' ) - type = 'C'; + type = RGE_NEGCHAR; else UnGetChar(ch); @@ -769,14 +785,14 @@ CRegExNode *CRegEx::CompileRange(CRegExNode *rp) break; // -(a)-[n]-+ // +--[n]-(b)- - ap = AllocNode('b'); + ap = AllocNode(RGE_BRANCHES); ap->m_Right = tmp.m_Left; if ( (np = CompileExtChar(ch, ap)) != NULL ) { if ( bp == NULL ) - bp = AllocNode('b'); + bp = AllocNode(RGE_BRANCHES); np->m_Left = bp; tmp.m_Left = ap; - if ( type == 'C' ) + if ( type == RGE_NEGCHAR ) CompileReverse(ap->m_Left); continue; } else { @@ -811,7 +827,7 @@ CRegExNode *CRegEx::CompileRange(CRegExNode *rp) } } else { UnGetChar(ch); - ch = 0x0010FFFF; + ch = UNICODE_MAX; } if ( tp->m_SChar > ch ) @@ -829,18 +845,18 @@ CRegExNode *CRegEx::CompileRange(CRegExNode *rp) } if ( ch != L']' ) - throw _T("RegEx syntax error\n[... no end to character list \"]\""); + throw _T("RegEx syntax error\n[... no end to character list \"]\""); - if ( tmp.m_Right != NULL && (mch - nch) < MAPSIZE && count > 2 ) { - np = AllocNode(type == 'c' ? 'm' : 'M'); + if ( tmp.m_Right != NULL && (mch - nch) < REG_MAPSIZE && count > 2 ) { + np = AllocNode(type == RGE_RANGECHAR ? RGE_CHKMAP : RGE_NEGMAP); np->m_SChar = nch; np->m_EChar = mch; - np->m_Map = new DWORD[MAPARRAY]; - memset(np->m_Map, 0, MAPBYTE); + np->m_Map = new DWORD[REG_MAPARRAY]; + memset(np->m_Map, 0, REG_MAPBYTE); for ( tp = tmp.m_Right ; tp != NULL ; tp = tp->m_Right ) { for ( ch = tp->m_SChar ; ch <= tp->m_EChar ; ch++ ) - np->m_Map[(ch - nch) / MAPBITS] |= (1 << ((ch - nch) % MAPBITS)); + np->m_Map[(ch - nch) / REG_MAPBITS] |= (1 << ((ch - nch) % REG_MAPBITS)); } while ( (tp = tmp.m_Right) != NULL ) { @@ -904,11 +920,11 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) case L'.': lp = rp; - rp->m_Left = AllocNode('C'); + rp->m_Left = AllocNode(RGE_NEGCHAR); rp = rp->m_Left; rp->m_SChar = 0x0A; rp->m_EChar = 0x0A; - rp->m_Right = AllocNode('C'); + rp->m_Right = AllocNode(RGE_NEGCHAR); rp->m_Right->m_SChar = 0x0D; rp->m_Right->m_EChar = 0x0D; break; @@ -916,11 +932,11 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) case L'^': // -(s)-(^)-(e)- lp = NULL; - rp->m_Left = AllocNode('s'); + rp->m_Left = AllocNode(RGE_GROUPSTART); rp->m_Left->m_EChar = m_Arg++; - rp->m_Left->m_Left = AllocNode('^'); - rp->m_Left->m_Left->m_Left = AllocNode('e'); - rp->m_Left->m_Left->m_Left->m_EChar = 2; + rp->m_Left->m_Left = AllocNode(RGE_LINETOP); + rp->m_Left->m_Left->m_Left = AllocNode(RGE_GROUPEND); + rp->m_Left->m_Left->m_Left->m_EChar = REG_BLOCK_LEFT; rp->m_Left->m_Left->m_Left->m_SChar = m_ArgStack.GetHead(); rp->m_Left->m_Right = rp->m_Left->m_Left->m_Left; rp->m_Left->m_Left->m_Left->m_Right = rp->m_Left; @@ -929,11 +945,11 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) case L'$': // -(s)-($)-(e)- lp = NULL; - rp->m_Left = AllocNode('s'); + rp->m_Left = AllocNode(RGE_GROUPSTART); rp->m_Left->m_EChar = m_Arg++; - rp->m_Left->m_Left = AllocNode('$'); - rp->m_Left->m_Left->m_Left = AllocNode('e'); - rp->m_Left->m_Left->m_Left->m_EChar = 1; + rp->m_Left->m_Left = AllocNode(RGE_LINEBTM); + rp->m_Left->m_Left->m_Left = AllocNode(RGE_GROUPEND); + rp->m_Left->m_Left->m_Left->m_EChar = REG_BLOCK_RIGHT; rp->m_Left->m_Left->m_Left->m_SChar = m_ArgStack.GetHead(); rp->m_Left->m_Right = rp->m_Left->m_Left->m_Left; rp->m_Left->m_Left->m_Left->m_Right = rp->m_Left; @@ -944,13 +960,13 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) if ( lp == NULL ) goto CHARMATCH; min = 0; - max = 0; + max = REG_MAXREP; goto REPENT; case L'+': if ( lp == NULL ) goto CHARMATCH; min = 1; - max = 0; + max = REG_MAXREP; goto REPENT; case L'?': if ( lp == NULL ) @@ -967,12 +983,15 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) min = min * 10 + (ch - L'0'); max = min; if ( ch == L',' ) { - max = 0; - while ( (ch = GetChar()) >= L'0' && ch <= L'9' ) - max = max * 10 + (ch - L'0'); + if ( (ch = GetChar()) >= L'0' && ch <= L'9' ) { + max = ch - L'0'; + while ( (ch = GetChar()) >= L'0' && ch <= L'9' ) + max = max * 10 + (ch - L'0'); + } else + max = REG_MAXREP; } if ( ch != L'}' ) - throw _T("RegEx syntax error\n{... no end to character list \"}\""); + throw _T("RegEx syntax error\n{... no end to character list \"}\""); REPENT: nx = GetChar(); @@ -990,24 +1009,41 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) if ( max > REG_MAXREP ) max = REG_MAXREP; - // +-------------->+ - // -(n)-(?)-[a]-(x)-(b)- - // +<------+ - tp = AllocNode('n'); - np = AllocNode('b'); - if ( noMore != 0 ) { - tp->m_Left = AllocNode('?'); + if ( min > max ) { + n = min; min = max; max = n; + noMore = 2; + } + + tp = AllocNode(RGE_LOOPSTART); + np = AllocNode(RGE_BRANCHES); + if ( noMore == 1 ) { + // +-------------->+ + // -(n)-(?)-[a]-(x)-(b)- + // +<------+ + tp->m_Left = AllocNode(RGE_LOOPSHORT); tp->m_Left->m_EChar = m_ArgStack.GetHead(); tp->m_Left->m_Left = lp->m_Left; lp->m_Left = tp; + } else if ( noMore == 2 ) { + // +------------------>+ + // -(n)-(+)-[a]-(+)-(x)-(b)- + // +<----------+ + tp->m_Left = AllocNode(RGE_GREEDSTART); + tp->m_Left->m_Left = lp->m_Left; + lp->m_Left = tp; + rp->m_Left = AllocNode(RGE_GREEDEND); + rp = rp->m_Left; } else { + // +---------->+ + // -(n)-[a]-(x)-(b)- + // +<--+ tp->m_Left = lp->m_Left; lp->m_Left = tp; } tp->m_SChar = m_Count++; tp->m_EChar = min; tp->m_Right = np; - rp->m_Left = AllocNode('x'); + rp->m_Left = AllocNode(RGE_LOOPEND); rp = rp->m_Left; rp->m_SChar = tp->m_SChar; rp->m_EChar = (min << 16) | max; @@ -1022,6 +1058,8 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) if ( (ch = GetChar()) == L'?' ) { if ( (ch = GetChar()) == L':' ) { n = 020; + } else if ( ch == L'>' ) { + n = 040; } else { if ( ch == L'<' ) { n |= 010; @@ -1036,12 +1074,18 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) n = 000; } } + } else if ( ch == L'#' ) { + while ( (ch = GetChar()) != L')' ) { + if ( ch == EOF ) + throw _T("RegEx syntax error\n(#... no end to character \")\""); + } + break; } else UnGetChar(ch); // +<----->+ // -(s)-[a]-(e)- lp = rp; - rp->m_Left = AllocNode('s'); + rp->m_Left = AllocNode(RGE_GROUPSTART); rp->m_Left->m_EChar = m_Arg++; m_ArgStack.AddHead(rp->m_Left->m_EChar); rp->m_Left->m_Left = CompileSub(')'); @@ -1049,25 +1093,37 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) CompileReverse(rp->m_Left->m_Left); while ( rp->m_Left != NULL ) rp = rp->m_Left; - rp->m_Left = AllocNode('e'); - rp = rp->m_Left; + m_ArgStack.RemoveHead(); + rp->m_Left = AllocNode(RGE_GROUPEND); switch(n) { case 001: // ...(?=...) case 002: // ...(?!...) - rp->m_EChar = 1; + rp->m_Left->m_EChar = REG_BLOCK_RIGHT; break; case 011: // (?<=...)... case 012: // (?m_EChar = 2; + rp->m_Left->m_EChar = REG_BLOCK_LEFT; break; case 020: // (?:...) - rp->m_EChar = 3; + rp->m_Left->m_EChar = REG_BLOCK_NONE; + break; + case 040: // (?>...) + // +<------------->+ + // -(s)-(+)-[a]-(+)-(e)- + rp->m_Left->m_EChar = REG_BLOCK_STD; + tp = AllocNode(RGE_GREEDSTART); + np = AllocNode(RGE_GREEDEND); + tp->m_Left = lp->m_Left->m_Left; + lp->m_Left->m_Left = tp; + np->m_Left = rp->m_Left; + rp->m_Left = np; + rp = np; break; default: - rp->m_EChar = 0; + rp->m_Left->m_EChar = REG_BLOCK_STD; break; } - m_ArgStack.RemoveHead(); + rp = rp->m_Left; rp->m_SChar = m_ArgStack.GetHead(); rp->m_Right = lp->m_Left; lp->m_Left->m_Right = rp; @@ -1076,11 +1132,11 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) case L'|': // -(b)- -(b)- // +- [a]--+ - tp = AllocNode('b'); + tp = AllocNode(RGE_BRANCHES); tp->m_Right = tmp.m_Left; tmp.m_Left = tp; if ( pLast == NULL ) - pLast = AllocNode('b'); + pLast = AllocNode(RGE_BRANCHES); rp->m_Left = pLast; lp = NULL; rp = tp; @@ -1089,7 +1145,7 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) CHARMATCH: default: lp = rp; - rp->m_Left = AllocNode('c'); + rp->m_Left = AllocNode(RGE_RANGECHAR); rp = rp->m_Left; rp->m_SChar = rp->m_EChar = ch; break; @@ -1097,7 +1153,7 @@ CRegExNode *CRegEx::CompileSub(DCHAR endc) } if ( ch != endc && endc != EOF ) - throw _T("RegEx syntax error\n(... no end to character list \")\""); + throw _T("RegEx syntax error\n(... no end to character list \")\""); if ( pLast != NULL ) rp->m_Left = pLast; @@ -1130,14 +1186,14 @@ BOOL CRegEx::Compile(LPCTSTR str) try { // +<----->+ // -(s)-[a]-(e)- - m_NodeHead = AllocNode('s'); + m_NodeHead = AllocNode(RGE_GROUPSTART); m_NodeHead->m_EChar = 0; m_NodeHead->m_SChar = 0; m_ArgStack.AddHead(0); m_NodeHead->m_Left = CompileSub(EOF); for ( np = m_NodeHead ; np->m_Left != NULL ; ) np = np->m_Left; - np->m_Left = AllocNode('e'); + np->m_Left = AllocNode(RGE_GROUPEND); np->m_Left->m_EChar = 0; m_ArgStack.RemoveHead(); m_NodeHead->m_Right = np->m_Left; @@ -1150,33 +1206,27 @@ BOOL CRegEx::Compile(LPCTSTR str) EndofChar(); - m_WorkTmp.m_Work.SetSize(m_Arg); - m_WorkTmp.m_Done.SetSize(m_Arg); - m_WorkTmp.m_Counter.SetSize(m_Count); - m_WorkTmp.m_Seq = 0; - return (m_NodeHead != NULL ? TRUE : FALSE); } BOOL CRegEx::IsSimple() { CRegExNode *np = m_NodeHead; - if ( np == NULL || np->m_Type != 's' ) + if ( np == NULL || np->m_Type != RGE_GROUPSTART ) return FALSE; - for ( np = np->m_Left ; np != NULL && np->m_Type == 'c' ; np = np->m_Left ) { + for ( np = np->m_Left ; np != NULL && np->m_Type == RGE_RANGECHAR ; np = np->m_Left ) { if ( np->m_SChar != np->m_EChar || np->m_Right != NULL ) return FALSE; } - if ( np == NULL || np->m_Type != 'e' || np->m_Left != NULL ) + if ( np == NULL || np->m_Type != RGE_GROUPEND || np->m_Left != NULL ) return FALSE; return TRUE; } -void CRegEx::AddQue(int sw, CRegExNode *np, CRegExWork *wp) +void CRegEx::AddQue(int sw, CRegExNode *np, CRegExWork *wp, int Flag) { - int n; CRegExQue *qp; if ( np == NULL ) @@ -1184,9 +1234,20 @@ void CRegEx::AddQue(int sw, CRegExNode *np, CRegExWork *wp) for ( qp = m_QueHead[sw] ; qp != NULL ; qp = qp->m_Next ) { if ( qp->m_Node == np ) { - if ( qp->m_Work->m_Seq > wp->m_Seq ) - qp->m_Work = wp; - return; + // 同じワークの同じノードの場合追加しない(リピート処理で起こりえる) + if ( qp->m_Work->m_Seq == wp->m_Seq ) + return; + // 条件付きで別ワークの同じノードを削除 + else { + int qc = (qp->m_Flag & REG_NQFLAG_LOOP) == 0 ? 0 : qp->m_Work->m_Loop; + int wc = (Flag & REG_NQFLAG_LOOP) == 0 ? 0 : wp->m_Loop; + + if ( qc == wc ) { + if ( qp->m_Work->m_Seq > wp->m_Seq ) + qp->m_Work = wp; + return; + } + } } } @@ -1194,7 +1255,7 @@ void CRegEx::AddQue(int sw, CRegExNode *np, CRegExWork *wp) qp = new CRegExQue[REG_TABMEM_SIZE]; qp->m_List = m_QueTop; m_QueTop = qp; - for ( n = 0 ; n < REG_TABMEM_SIZE ; n++ ) { + for ( int n = 0 ; n < REG_TABMEM_SIZE ; n++ ) { qp->m_Next = m_QueFree; m_QueFree = qp++; } @@ -1204,6 +1265,7 @@ void CRegEx::AddQue(int sw, CRegExNode *np, CRegExWork *wp) qp->m_Node = np; qp->m_Work = wp; + qp->m_Flag = Flag; qp->m_Next = m_QueHead[sw]; m_QueHead[sw] = qp; @@ -1221,199 +1283,25 @@ CRegExQue *CRegEx::HeadQue(int sw) return qp; } -BOOL CRegEx::MatchStrSub(CStringD &str, int start, int end, CRegExRes *res) -{ - int n, i, Pos; - int min, max; - CRegExNode *np, *ip; - CRegExQue *qp; - CRegExWork *wp = NULL; - - m_QueSw = 0; - while ( HeadQue(0) != NULL ); - while ( HeadQue(1) != NULL ); - - m_WorkTmp.m_Work.Clear(); - m_WorkTmp.m_Done.Clear(); - - AddQue(m_QueSw, m_NodeHead, &m_WorkTmp); - - for ( n = start ; n <= end ; n++ ) { - - while ( (qp = HeadQue(m_QueSw)) != NULL ) { - np = qp->m_Node; - wp = qp->m_Work; - - switch(np->m_Type) { - case 's': - i = np->m_EChar; - - if ( wp->m_Work[i].m_SPos >= wp->m_Work[i].m_EPos || wp->m_Work[i].m_EPos != wp->m_Pos ) { - wp->m_Work[i].m_SPos = n; - wp->m_Work[i].m_EPos = n; - } - - wp->m_Work[i].m_FrArg.RemoveAll(); - wp->m_Work[i].m_BkArg.RemoveAll(); - wp->m_Work[i].m_Done = FALSE; - - AddQue(m_QueSw, np->m_Left, wp); - break; - case 'e': - i = np->m_Right->m_EChar; - wp->m_Work[i].m_EPos = n; - wp->m_Work[i].m_Done = TRUE; - wp->m_Work[i].m_Del = (np->m_EChar == 0 ? FALSE : TRUE); - - while ( !wp->m_Work[i].m_FrArg.IsEmpty() ) { - Pos = wp->m_Work[i].m_FrArg.RemoveHead(); - if ( wp->m_Work[i].m_SPos == wp->m_Work[Pos].m_SPos ) - wp->m_Work[i].m_SPos = wp->m_Work[Pos].m_SPos = wp->m_Work[Pos].m_EPos; - } - while ( !wp->m_Work[i].m_BkArg.IsEmpty() ) { - Pos = wp->m_Work[i].m_BkArg.RemoveHead(); - if ( wp->m_Work[i].m_EPos == wp->m_Work[Pos].m_EPos ) - wp->m_Work[i].m_EPos = wp->m_Work[Pos].m_EPos = wp->m_Work[Pos].m_SPos; - } - - wp->m_Work[i].m_Str = wp->m_Str.Mid(wp->m_Work[i].m_SPos, wp->m_Work[i].m_EPos - wp->m_Work[i].m_SPos); - - switch(np->m_EChar) { - case 1: // ...(?=...) or ...(?!...) - wp->m_Work[np->m_SChar].m_BkArg.AddHead(i); - break; - case 2: // (?<=...)... or (?m_Work[np->m_SChar].m_FrArg.AddTail(i); - break; - } - - if ( i == 0 ) - wp->m_Done = wp->m_Work; - - AddQue(m_QueSw, np->m_Left, wp); - break; - - case 'n': - wp->m_Counter[np->m_SChar] = 0; - AddQue(m_QueSw, np->m_Left, wp); - if ( np->m_EChar == 0 ) - AddQue(m_QueSw, np->m_Right, wp); - break; - case 'x': - i = ++(wp->m_Counter[np->m_SChar]); - min = np->m_EChar >> 16; - max = np->m_EChar & 0xFFFF; - if ( i >= min ) - AddQue(m_QueSw, np->m_Left, wp); - if ( max == 0 || min > max || i < max ) - AddQue(m_QueSw, np->m_Right, wp); - break; - case '?': - i = np->m_EChar; - if ( wp->m_Work[i].m_Done ) - break; - AddQue(m_QueSw, np->m_Left, wp); - break; - - case 'b': - AddQue(m_QueSw, np->m_Left, wp); - AddQue(m_QueSw, np->m_Right, wp); - break; - case '^': - if ( n == 0 ) - AddQue(m_QueSw, np->m_Left, wp); - else if ( n < end && str[n] == L'\n' ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - case '1': - if ( n != 0 ) - AddQue(m_QueSw, np->m_Left, wp); - else if ( n < end && str[n] != L'\n' ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - - case '$': - if ( n >= end ) - AddQue(m_QueSw, np->m_Left, wp); - else if ( str[n] == L'\r' ) - AddQue(m_QueSw, np->m_Left, wp); - break; - case '2': - if ( n < end ) - AddQue(m_QueSw, np->m_Left, wp); - else if ( str[n] != L'\r' ) - AddQue(m_QueSw, np->m_Left, wp); - break; - - case 'm': - if ( n >= end ) - break; - if ( str[n] >= np->m_SChar && str[n] <= np->m_EChar && (np->m_Map[(str[n] - np->m_SChar) / MAPBITS] & (1 << ((str[n] - np->m_SChar) % MAPBITS))) != 0 ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - case 'M': - if ( n >= end ) - break; - if ( str[n] < np->m_SChar || str[n] > np->m_EChar || (np->m_Map[(str[n] - np->m_SChar) / MAPBITS] & (1 << ((str[n] - np->m_SChar) % MAPBITS))) == 0 ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - - case 'c': - if ( n >= end ) - break; - for ( ip = np ; ip != NULL ; ip = ip->m_Right ) { - if ( str[n] >= ip->m_SChar && str[n] <= ip->m_EChar ) - break; - } - if ( ip != NULL ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - case 'C': - if ( n >= end ) - break; - for ( ip = np ; ip != NULL ; ip = ip->m_Right ) { - if ( str[n] >= ip->m_SChar && str[n] <= ip->m_EChar ) - break; - } - if ( ip == NULL ) - AddQue(m_QueSw^1, np->m_Left, wp); - break; - } - } - m_QueSw ^= 1; - - if ( m_QueHead[m_QueSw] == NULL ) - break; - } - - if ( m_WorkTmp.m_Done[0].m_SPos >= m_WorkTmp.m_Done[0].m_EPos ) { - if ( res != NULL ) - res->m_Status = (m_QueHead[m_QueSw] != NULL ? REG_CONTINUE : REG_NOMATCH); - return FALSE; - } - - if ( res != NULL && wp != NULL ) { - *res = wp->m_Done; - res->m_Status = (m_QueHead[m_QueSw] != NULL ? REG_MATCHMORE : REG_MATCH); - for ( n = 0 ; n < m_Arg ; n++ ) - (*res)[n].m_Str = str.Mid((*res)[n].m_SPos, (*res)[n].m_EPos - (*res)[n].m_SPos); - } - - return TRUE; -} BOOL CRegEx::MatchStr(LPCTSTR str, CRegExRes *res) { int n, len; CStringD tmp; tmp = TstrToUni(str); + tmp.Insert(0, REGSPCHAR_LINETOP); + tmp += REGSPCHAR_LINEEND; + len = tmp.GetLength(); + MatchCharInit(); + for ( n = 0 ; n < len ; n++ ) { - if ( MatchStrSub(tmp, n, len, res) ) + if ( MatchChar(tmp[n], n, res) && (res->m_Status == REG_MATCH || res->m_Status == REG_MATCHOVER) ) return TRUE; } + return FALSE; } void CRegEx::ConvertRes(LPCWSTR pat, CStringW &buf, CRegExRes *res) @@ -1437,27 +1325,35 @@ void CRegEx::ConvertRes(LPCWSTR pat, CStringW &buf, CRegExRes *res) } BOOL CRegEx::ConvertStr(LPCTSTR str, LPCTSTR pat, CString &buf) { - int n, len; - BOOL rt = FALSE; - CStringD wrk; - CStringW tmp[4]; + int n, a, len; + CStringD tmp, wrk; + CStringW wstr; CRegExRes res; + BOOL rt = FALSE; + + tmp = TstrToUni(str); + tmp.Insert(0, REGSPCHAR_LINETOP); + tmp += REGSPCHAR_LINEEND; + + len = tmp.GetLength(); - wrk = TstrToUni(str); - tmp[1] = pat; - len = wrk.GetLength(); + MatchCharInit(); - for ( n = 0 ; n < len ; ) { - if ( MatchStrSub(wrk, n, len, &res) ) { - ConvertRes(tmp[1], tmp[3], &res); - tmp[2] += tmp[3]; - n = res[0].m_EPos; + for ( n = a = 0 ; n < len ; n++ ) { + if ( MatchChar(tmp[n], n, &res) && (res.m_Status == REG_MATCH || res.m_Status == REG_MATCHOVER) ) { + while ( a < (int)res.m_Idx[res[0].m_SPos] ) + wrk += tmp[a++]; + ConvertRes(TstrToUni(pat), wstr, &res); + wrk += wstr; + a = res.m_Idx[res[0].m_EPos]; rt = TRUE; - } else { - tmp[2] += wrk.GetAt(n++); } } - buf = tmp[2]; + + while ( a < len ) + wrk += tmp[a++]; + + buf = wrk; return rt; } int CRegEx::SplitStr(LPCTSTR str, CStringArray &data) @@ -1467,18 +1363,25 @@ int CRegEx::SplitStr(LPCTSTR str, CStringArray &data) CRegExRes res; tmp = TstrToUni(str); + tmp.Insert(0, REGSPCHAR_LINETOP); + tmp += REGSPCHAR_LINEEND; + len = tmp.GetLength(); + MatchCharInit(); data.RemoveAll(); + for ( n = a = 0 ; n < len ; ) { - if ( MatchStrSub(tmp, n, len, &res) ) { - data.Add(UniToTstr(tmp.Mid(a, res[0].m_SPos - a))); - n = a = res[0].m_EPos; + if ( MatchChar(tmp[n], n, &res) && (res.m_Status == REG_MATCH || res.m_Status == REG_MATCHOVER) ) { + data.Add(UniToTstr(tmp.Mid(a, res.m_Idx[res[0].m_SPos] - a))); + n = a = res.m_Idx[res[0].m_EPos]; } else n++; } - if ( a < n ) - data.Add(UniToTstr(tmp.Mid(a, n - a))); + + if ( a < (len - 1) ) + data.Add(UniToTstr(tmp.Mid(a, len - 1 - a))); + return (int)data.GetSize(); } @@ -1486,7 +1389,6 @@ void CRegEx::MatchCharInit() { CRegExWork *wp; - m_QueSw = 0; while ( HeadQue(0) != NULL ); while ( HeadQue(1) != NULL ); while ( HeadQue(2) != NULL ); @@ -1507,13 +1409,14 @@ BOOL CRegEx::MatchChar(DCHAR ch, int idx, CRegExRes *res) CRegExWork *wp, *wtp; CRegExWork *whp = NULL; CRegExWork *wop = NULL; + int Flag; if ( m_NodeHead == NULL ) { if ( res != NULL ) { res->Clear(); - res->m_Status = REG_MATCH; + res->m_Status = REG_NOMATCH; } - return TRUE; + return FALSE; } else if ( ch == 0 || (ch >= 0x180B && ch <= 0x180D) || (ch >= 0xFE00 && ch <= 0xFE0F) || (ch >= 0xE0100 && ch <= 0xE01EF) ) return FALSE; @@ -1536,28 +1439,34 @@ BOOL CRegEx::MatchChar(DCHAR ch, int idx, CRegExRes *res) wp->m_Work.SetSize(m_Arg); wp->m_Done.SetSize(m_Arg); wp->m_Counter.SetSize(m_Count); + wp->m_DupDone = FALSE; wp->m_Pos = 0; wp->m_Str.Empty(); wp->m_Seq = m_WorkSeq++; wp->m_Idx.RemoveAll(); - AddQue(0, m_NodeHead, wp); + AddQue(0, m_NodeHead, wp, 0); + m_WorkCount = 0; for ( wp = m_WorkHead ; wp != NULL ; wp = wp->m_Next ) { wp->m_Die = TRUE; wp->m_Pos = wp->m_Str.GetLength(); wp->m_Str += ch; wp->m_Idx.Add(idx); + m_WorkCount++; } + //TRACE("%d\n", m_WorkCount); + for ( Que = 0 ; Que < 2 ; Que++ ) { while ( (qp = HeadQue(Que)) != NULL ) { np = qp->m_Node; wp = qp->m_Work; + Flag = qp->m_Flag; - //TRACE("%d(%c:%d) ", wp->m_Seq, np->m_Type, Que); + //TRACE("%d(%d:%d) ", wp->m_Seq, np->m_Type, Que); switch(np->m_Type) { - case 's': + case RGE_GROUPSTART: i = np->m_EChar; Pos = wp->m_Pos + Que; @@ -1568,13 +1477,13 @@ BOOL CRegEx::MatchChar(DCHAR ch, int idx, CRegExRes *res) wp->m_Work[i].m_BkArg.RemoveAll(); wp->m_Work[i].m_Done = FALSE; - AddQue(Que, np->m_Left, wp); + AddQue(Que, np->m_Left, wp, Flag); break; - case 'e': + case RGE_GROUPEND: i = np->m_Right->m_EChar; wp->m_Work[i].m_EPos = wp->m_Pos + Que; wp->m_Work[i].m_Done = TRUE; - wp->m_Work[i].m_Del = (np->m_EChar == 0 ? FALSE : TRUE); + wp->m_Work[i].m_Del = (np->m_EChar == REG_BLOCK_STD ? FALSE : TRUE); while ( !wp->m_Work[i].m_FrArg.IsEmpty() ) { Pos = wp->m_Work[i].m_FrArg.RemoveHead(); @@ -1590,114 +1499,134 @@ BOOL CRegEx::MatchChar(DCHAR ch, int idx, CRegExRes *res) wp->m_Work[i].m_Str = wp->m_Str.Mid(wp->m_Work[i].m_SPos, wp->m_Work[i].m_EPos - wp->m_Work[i].m_SPos); switch(np->m_EChar) { - case 1: // ...(?=...) or ...(?!...) + case REG_BLOCK_RIGHT: // ...(?=...) or ...(?!...) wp->m_Work[np->m_SChar].m_BkArg.AddHead(i); break; - case 2: // (?<=...)... or (?m_Work[np->m_SChar].m_FrArg.AddTail(i); break; } if ( i == 0 ) { wp->m_Done = wp->m_Work; - if ( wp->m_Work[i].m_SPos < wp->m_Work[i].m_EPos && (whp == NULL || whp->m_Seq >= wp->m_Seq) ) - whp = wp; + if ( wp->m_Work[i].m_SPos < wp->m_Work[i].m_EPos ) { + // 先のワークを優先して後ワークを削除 + if ( whp == NULL ) + whp = wp; + else if ( whp->m_Seq > wp->m_Seq ) { + whp->m_DupDone = TRUE; + whp = wp; + } else if ( whp->m_Seq < wp->m_Seq ) + wp->m_DupDone = TRUE; + } } - AddQue(Que, np->m_Left, wp); + AddQue(Que, np->m_Left, wp, Flag); break; - case 'n': + case RGE_LOOPSTART: wp->m_Counter[np->m_SChar] = 0; - AddQue(Que, np->m_Left, wp); + AddQue(Que, np->m_Left, wp, Flag); if ( np->m_EChar == 0 ) - AddQue(Que, np->m_Right, wp); + AddQue(Que, np->m_Right, wp, Flag); break; - case 'x': + case RGE_LOOPEND: i = ++(wp->m_Counter[np->m_SChar]); min = np->m_EChar >> 16; max = np->m_EChar & 0xFFFF; + Flag &= ~REG_NQFLAG_LOOP; if ( i >= min ) - AddQue(Que, np->m_Left, wp); - if ( max == 0 || min > max || i < max ) - AddQue(Que, np->m_Right, wp); + AddQue(Que, np->m_Left, wp, Flag); + if ( i < max ) { + wp->m_Loop = i; + AddQue(Que, np->m_Right, wp, Flag | (max < REG_MAXREP ? REG_NQFLAG_LOOP : 0)); + } break; - case '?': + case RGE_LOOPSHORT: i = np->m_EChar; if ( wp->m_Work[i].m_Done ) break; if ( Que > 0 ) - AddQue(2, np, wp); + AddQue(2, np, wp, Flag); else - AddQue(Que, np->m_Left, wp); + AddQue(Que, np->m_Left, wp, Flag); + break; + + case RGE_GREEDSTART: + Flag |= REG_NQFLAG_GREED; + AddQue(Que, np->m_Left, wp, Flag); + break; + case RGE_GREEDEND: + Flag &= ~REG_NQFLAG_GREED; + AddQue(Que, np->m_Left, wp, Flag); break; - case 'b': - AddQue(Que, np->m_Left, wp); - AddQue(Que, np->m_Right, wp); + case RGE_BRANCHES: + AddQue(Que, np->m_Left, wp, Flag); + AddQue(Que, np->m_Right, wp, Flag); break; - case '^': + case RGE_LINETOP: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch == L'\n' ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch == L'\n' || ch == REGSPCHAR_LINETOP ) + AddQue(1, np->m_Left, wp, Flag); break; - case '1': + case RGE_NEGTOP: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch != L'\n' ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch != L'\n' && ch != REGSPCHAR_LINETOP ) + AddQue(1, np->m_Left, wp, Flag); break; - case '$': + case RGE_LINEBTM: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch == L'\r' ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch == L'\r' || ch == REGSPCHAR_LINEEND ) + AddQue(1, np->m_Left, wp, Flag); break; - case '2': + case RGE_NEGBTM: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch != L'\r' ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch != L'\r' && ch != REGSPCHAR_LINEEND ) + AddQue(1, np->m_Left, wp, Flag); break; - case 'm': + case RGE_CHKMAP: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch >= np->m_SChar && ch <= np->m_EChar && (np->m_Map[(ch - np->m_SChar) / MAPBITS] & (1 << ((ch - np->m_SChar) % MAPBITS))) != 0 ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch >= np->m_SChar && ch <= np->m_EChar && (np->m_Map[(ch - np->m_SChar) / REG_MAPBITS] & (1 << ((ch - np->m_SChar) % REG_MAPBITS))) != 0 ) + AddQue(1, np->m_Left, wp, Flag); break; - case 'M': + case RGE_NEGMAP: if ( Que > 0 ) - AddQue(2, np, wp); - else if ( ch < np->m_SChar || ch > np->m_EChar || (np->m_Map[(ch - np->m_SChar) / MAPBITS] & (1 << ((ch - np->m_SChar) % MAPBITS))) == 0 ) - AddQue(1, np->m_Left, wp); + AddQue(2, np, wp, Flag); + else if ( ch < np->m_SChar || ch > np->m_EChar || (np->m_Map[(ch - np->m_SChar) / REG_MAPBITS] & (1 << ((ch - np->m_SChar) % REG_MAPBITS))) == 0 ) + AddQue(1, np->m_Left, wp, Flag); break; - case 'c': + case RGE_RANGECHAR: if ( Que > 0 ) - AddQue(2, np, wp); + AddQue(2, np, wp, Flag); else { for ( ip = np ; ip != NULL ; ip = ip->m_Right ) { if ( ch >= ip->m_SChar && ch <= ip->m_EChar ) break; } if ( ip != NULL ) - AddQue(1, np->m_Left, wp); + AddQue(1, np->m_Left, wp, Flag); } break; - case 'C': + case RGE_NEGCHAR: if ( Que > 0 ) - AddQue(2, np, wp); + AddQue(2, np, wp, Flag); else { for ( ip = np ; ip != NULL ; ip = ip->m_Right ) { if ( ch >= ip->m_SChar && ch <= ip->m_EChar ) break; } if ( ip == NULL ) - AddQue(1, np->m_Left, wp); + AddQue(1, np->m_Left, wp, Flag); } break; } @@ -1710,10 +1639,13 @@ BOOL CRegEx::MatchChar(DCHAR ch, int idx, CRegExRes *res) qtp = NULL; while ( (qp = m_QueHead[2]) != NULL ) { m_QueHead[2] = qp->m_Next; - if ( qp->m_Work->m_Pos > REG_MAXREP ) { + // ワークの文字数と重なった終了を基準に削除 + if ( qp->m_Work->m_Pos > REG_MAXREP || qp->m_Work->m_DupDone ) { qp->m_Next = m_QueFree; m_QueFree = qp; } else { + if ( qp->m_Work == whp && (qp->m_Flag & REG_NQFLAG_GREED) != 0 ) + whp = NULL; qp->m_Work->m_Die = FALSE; qp->m_Next = qtp; qtp = qp; diff --git a/RLogin/Regex.h b/RLogin/Regex.h index a428521..0602012 100755 --- a/RLogin/Regex.h +++ b/RLogin/Regex.h @@ -1,15 +1,15 @@ #pragma once #include "afx.h" -#define MAPSIZE 512 -#define MAPBYTE (MAPSIZE / 8) -#define MAPARRAY (MAPBYTE / sizeof(DWORD)) -#define MAPBITS (8 * sizeof(DWORD)) - typedef DWORD DCHAR; typedef DWORD * LPDSTR; typedef const DWORD * LPCDSTR; +#define IsRegSpChar(ch) (((ch) & 0xFFFFFFF0) == 0xFFFFFFF0) + +#define REGSPCHAR_LINETOP 0xFFFFFFF0 +#define REGSPCHAR_LINEEND 0xFFFFFFF1 + class CStringD : public CObject { public: @@ -64,6 +64,43 @@ class CStringD : public CObject inline operator LPCWSTR() { return WStr(m_Work); } }; +////////////////////////////////////////////////////////////////////// + +#define REG_NOMATCH 0 +#define REG_CONTINUE 1 +#define REG_MATCH 2 +#define REG_MATCHMORE 3 +#define REG_MATCHOVER 4 + +#define REG_MAXREP 1024 +#define REG_MAXWORK 256 + +#define REG_TABMEM_SIZE 32 + +#define REG_MAPSIZE 512 +#define REG_MAPBYTE (REG_MAPSIZE / 8) +#define REG_MAPARRAY (REG_MAPBYTE / sizeof(DWORD)) +#define REG_MAPBITS (8 * sizeof(DWORD)) + +enum RegCmdType { + RGE_GROUPSTART, RGE_GROUPEND, + RGE_LOOPSTART, RGE_LOOPEND, RGE_LOOPSHORT, + RGE_GREEDSTART, RGE_GREEDEND, + RGE_BRANCHES, + RGE_LINETOP, RGE_NEGTOP, RGE_LINEBTM, RGE_NEGBTM, + RGE_CHKMAP, RGE_NEGMAP, + RGE_RANGECHAR, RGE_NEGCHAR, + RGE_NONE, +}; + +#define REG_BLOCK_STD 0 +#define REG_BLOCK_RIGHT 1 +#define REG_BLOCK_LEFT 2 +#define REG_BLOCK_NONE 3 + +#define REG_NQFLAG_GREED 001 +#define REG_NQFLAG_LOOP 002 + class CRegExIdx : public CDWordArray { public: @@ -77,10 +114,10 @@ class CRegExNode : public CObject class CRegExNode *m_Right; class CRegExNode *m_List; - int m_Type; - DCHAR m_SChar; - DCHAR m_EChar; - DWORD *m_Map; + enum RegCmdType m_Type; + DCHAR m_SChar; + DCHAR m_EChar; + DWORD *m_Map; const CRegExNode & operator = (CRegExNode &data); @@ -96,6 +133,7 @@ class CRegExQue : public CObject class CRegExNode *m_Node; class CRegExWork *m_Work; + int m_Flag; CRegExQue(void); ~CRegExQue(void); @@ -116,15 +154,6 @@ class CRegExArg : public CObject CRegExArg(void); }; -#define REG_NOMATCH 0 -#define REG_CONTINUE 1 -#define REG_MATCH 2 -#define REG_MATCHMORE 3 -#define REG_MATCHOVER 4 - -#define REG_MAXREP 1024 -#define REG_TABMEM_SIZE 32 - class CRegExRes : public CObject { public: @@ -155,6 +184,8 @@ class CRegExWork : public CObject int m_Seq; BOOL m_Die; CRegExIdx m_Idx; + BOOL m_DupDone; + int m_Loop; CRegExWork(void); ~CRegExWork(void); @@ -175,11 +206,10 @@ class CRegEx : public CObject CRegExWork *m_WorkFree; CRegExWork *m_WorkHead; - int m_QueSw; int m_Arg; int m_Count; int m_WorkSeq; - CRegExWork m_WorkTmp; + int m_WorkCount; CList m_ArgStack; typedef struct _CompStrBuf { @@ -200,7 +230,7 @@ class CRegEx : public CObject DCHAR GetChar(); void UnGetChar(DCHAR ch); - CRegExNode *AllocNode(int type); + CRegExNode *AllocNode(enum RegCmdType type); void FreeNode(CRegExNode *np); void RemoveAllNode(); @@ -213,10 +243,9 @@ class CRegEx : public CObject BOOL Compile(LPCTSTR str); BOOL IsSimple(); - void AddQue(int sw, CRegExNode *np, CRegExWork *wp); + void AddQue(int sw, CRegExNode *np, CRegExWork *wp, int Flag); CRegExQue *HeadQue(int sw); - BOOL MatchStrSub(CStringD &str, int start, int end, CRegExRes *res); BOOL MatchStr(LPCTSTR str, CRegExRes *res); void ConvertRes(LPCWSTR pat, CStringW &buf, CRegExRes *res); BOOL ConvertStr(LPCTSTR str, LPCTSTR pat, CString &buf); diff --git a/RLogin/Script.cpp b/RLogin/Script.cpp index 7ff8385..5e915cc 100755 --- a/RLogin/Script.cpp +++ b/RLogin/Script.cpp @@ -106,6 +106,7 @@ CScriptValue::CScriptValue() m_Left = m_Right = m_Child = m_Next = m_Root = NULL; m_DocCmds = (-1); m_bNoCase = FALSE; + m_PtrType = PTRTYPE_NONE; } CScriptValue::~CScriptValue() { @@ -124,6 +125,14 @@ int CScriptValue::GetType() return ((CScriptValue *)(m_Value.m_Ptr))->GetType(); return m_Type; } +int CScriptValue::GetPtrType() +{ + if ( m_Type == VALTYPE_IDENT ) + return ((CScriptValue *)(m_Value.m_Ptr))->GetPtrType(); + if ( m_Type != VALTYPE_PTR ) + return PTRTYPE_NONE; + return m_PtrType; +} CBuffer *CScriptValue::GetBuf() { if ( m_Type == VALTYPE_IDENT ) @@ -219,6 +228,7 @@ const CScriptValue & CScriptValue::operator = (CScriptValue &data) m_ArrayPos = sp->m_ArrayPos; m_FuncPos = sp->m_FuncPos; m_FuncExt = sp->m_FuncExt; + m_PtrType = sp->m_PtrType; m_bNoCase = sp->m_bNoCase; @@ -539,6 +549,7 @@ const void * CScriptValue::operator = (void *ptr) { m_Type = VALTYPE_PTR; m_Value.m_Ptr = ptr; + m_PtrType = PTRTYPE_NONE; return ptr; } @@ -3313,6 +3324,7 @@ int CScript::Exec() sp->m_Complex = dp->m_Complex; sp->m_FuncPos = dp->m_FuncPos; sp->m_FuncExt = dp->m_FuncExt; + sp->m_PtrType = dp->m_PtrType; sp->ArrayCopy(*dp); } } @@ -6065,15 +6077,23 @@ int CScript::Func03(int cmd, CScriptValue &local) case 2: n = _SH_DENYWR; break; // ファイルの書き込みを禁止します case 3: n = _SH_DENYRW; break; // ファイルの読み出しと書き込みを禁止します } - (*acc) = (void *)_fsopen((LPCSTR)local[0], (LPCSTR)local[1], n); - } else - (*acc) = (void *)fopen((LPCSTR)local[0], (LPCSTR)local[1]); + if ( ((*acc) = (void *)_tfsopen((LPCTSTR)local[0], (LPCTSTR)local[1], n)) != NULL ) + acc->m_PtrType = PTRTYPE_FILE; + } else { + if ( ((*acc) = (void *)_tfopen((LPCTSTR)local[0], (LPCTSTR)local[1])) != NULL ) + acc->m_PtrType = PTRTYPE_FILE; + } break; case 1: // fclose(f) - fclose((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() == PTRTYPE_FILE ) + (*acc) = (int)fclose((FILE *)(void *)local[0]); + else if ( local[0].GetPtrType() == PTRTYPE_PIPE ) + (*acc) = (int)_pclose((FILE *)(void *)local[0]); + else + throw _T("fclose not fopen ptr"); break; case 2: // fread(s, f) - { + if ( local[1].GetPtrType() != PTRTYPE_NONE ) { int n; CBuffer tmp; n = (int)local[0]; @@ -6081,49 +6101,77 @@ int CScript::Func03(int cmd, CScriptValue &local) acc->m_Type = VALTYPE_STRING; acc->m_Buf.Clear(); acc->m_Buf.Apend(tmp.GetPtr(), n); - } + } else + throw _T("fread not (f|p)open ptr"); break; case 3: // fwrite(b, f) - { + if ( local[1].GetPtrType() != PTRTYPE_NONE ) { CBuffer *bp = local[0].GetBuf(); (*acc) = (int)fwrite(bp->GetPtr(), 1, bp->GetSize(), (FILE *)(void *)local[1]); - } + } else + throw _T("fwrite not (f|p)open ptr"); break; case 4: // fgets(f) - { + if ( local[0].GetPtrType() != PTRTYPE_NONE ) { char *p; char tmp[4096]; if ( (p = fgets(tmp, 4096, (FILE *)(void *)local[0])) != NULL ) (*acc) = (LPCSTR)p; else (*acc) = (int)0; - } + } else + throw _T("fgets not (f|p)open ptr"); break; case 5: // fputs(s, f) - (*acc) = (int)fputs((LPCSTR)local[0], (FILE *)(void *)local[1]); + if ( local[1].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)fputs((LPCSTR)local[0], (FILE *)(void *)local[1]); + else + throw _T("fputs not (f|p)open ptr"); break; case 6: // fgetc(f) - (*acc) = (int)fgetc((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)fgetc((FILE *)(void *)local[0]); + else + throw _T("fgetc not (f|p)open ptr"); break; case 7: // fputc(c, f) - (*acc) = (int)fputc((int)local[0], (FILE *)(void *)local[1]); + if ( local[1].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)fputc((int)local[0], (FILE *)(void *)local[1]); + else + throw _T("fputc not (f|p)open ptr"); break; case 8: // feof - (*acc) = (int)feof((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)feof((FILE *)(void *)local[0]); + else + throw _T("feof not (f|p)open ptr"); + break; case 9: // ferror - (*acc) = (int)ferror((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)ferror((FILE *)(void *)local[0]); + else + throw _T("ferror not (f|p)open ptr"); break; case 10: // fflush - (*acc) = (int)fflush((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (int)fflush((FILE *)(void *)local[0]); + else + throw _T("fflush not (f|p)open ptr"); break; case 11: // ftell - (*acc) = (LONGLONG)_ftelli64((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (LONGLONG)_ftelli64((FILE *)(void *)local[0]); + else + throw _T("ftell not (f|p)open ptr"); break; case 12: // fseek(f, o, s); // 0 = SEEK_SET ファイルの先頭。 // 1 = SEEK_CUR ファイル ポインタの現在位置。 // 2 = SEEK_END ファイルの終端。 - (*acc) = (LONGLONG)_fseeki64((FILE *)(void *)local[0], (LONGLONG)local[1], (int)local[2]); + if ( local[0].GetPtrType() != PTRTYPE_NONE ) + (*acc) = (LONGLONG)_fseeki64((FILE *)(void *)local[0], (LONGLONG)local[1], (int)local[2]); + else + throw _T("fseek not (f|p)open ptr"); break; case 13: // file(f) @@ -6132,7 +6180,7 @@ int CScript::Func03(int cmd, CScriptValue &local) FILE *fp; char tmp[4096]; acc->RemoveAll(); - if ( (fp = fopen((LPCSTR)local[0], "r")) != NULL ) { + if ( (fp = _tfopen((LPCTSTR)local[0], _T("r"))) != NULL ) { for ( n = 0 ; fgets(tmp, 4096, fp) != NULL; n++ ) (*acc)[(LPCSTR)NULL] = (LPCSTR)tmp; (*acc) = (int)n; @@ -6211,15 +6259,21 @@ int CScript::Func03(int cmd, CScriptValue &local) PlaySound((LPCTSTR)local[0], NULL, SND_ASYNC | SND_FILENAME); break; - case 23: // speek(s) - ((CMainFrame *)::AfxGetMainWnd())->Speek((LPCTSTR)local[0]); + case 23: // speak(s) + ((CMainFrame *)::AfxGetMainWnd())->Speak((LPCTSTR)local[0]); break; case 24: // popen(c, m) - (*acc) = (void *)_popen((LPCSTR)local[0], (LPCSTR)local[1]); + if ( ((*acc) = (void *)_tpopen((LPCTSTR)local[0], (LPCTSTR)local[1])) != NULL ) + acc->m_PtrType = PTRTYPE_PIPE; break; case 25: // pclose(f) - (*acc) = (int)_pclose((FILE *)(void *)local[0]); + if ( local[0].GetPtrType() == PTRTYPE_FILE ) + (*acc) = (int)fclose((FILE *)(void *)local[0]); + else if ( local[0].GetPtrType() == PTRTYPE_PIPE ) + (*acc) = (int)_pclose((FILE *)(void *)local[0]); + else + throw _T("pclose not popen ptr"); break; } return FUNC_RET_NOMAL; @@ -6718,7 +6772,7 @@ void CScript::FuncInit() { "dirname", 16, &CScript::Func03 }, { "copy", 17, &CScript::Func03 }, { "rename", 18, &CScript::Func03 }, { "delete", 19, &CScript::Func03 }, { "getcwd", 20, &CScript::Func03 }, { "chdir", 21, &CScript::Func03 }, - { "play", 22, &CScript::Func03 }, { "speek", 23, &CScript::Func03 }, + { "play", 22, &CScript::Func03 }, { "speak", 23, &CScript::Func03 }, { "popen", 24, &CScript::Func03 }, { "pclose", 25, &CScript::Func03 }, { "rand", 0, &CScript::Func04 }, { "srand", 1, &CScript::Func04 }, diff --git a/RLogin/Script.h b/RLogin/Script.h index 18cabc2..0c946ca 100755 --- a/RLogin/Script.h +++ b/RLogin/Script.h @@ -5,36 +5,36 @@ #include "RegEx.h" #include "ScriptDlg.h" -#define VALTYPE_INT 0 -#define VALTYPE_DOUBLE 1 -#define VALTYPE_COMPLEX 2 -#define VALTYPE_INT64 3 -#define VALTYPE_STRING 4 -#define VALTYPE_WSTRING 5 -#define VALTYPE_DSTRING 6 -#define VALTYPE_LPBYTE 7 -#define VALTYPE_LPWCHAR 8 -#define VALTYPE_LPDCHAR 9 -#define VALTYPE_LPDDOUB 10 -#define VALTYPE_IDENT 11 -#define VALTYPE_PTR 12 -#define VALTYPE_EMPTY 13 - -#define DATA_BUF_NONE 0 -#define DATA_BUF_BOTH 1 -#define DATA_BUF_HAVE 2 -#define DATA_BUF_LIMIT (128 * 1024) - -#define LOOP_COUNT 300 - -#define DOC_MODE_SAVE 0 -#define DOC_MODE_IDENT 1 -#define DOC_MODE_CALL 2 - -#define FUNC_RET_NOMAL 0 -#define FUNC_RET_ABORT 1 -#define FUNC_RET_EXIT 2 -#define FUNC_RET_EVENT 3 +#define VALTYPE_INT 0 +#define VALTYPE_DOUBLE 1 +#define VALTYPE_COMPLEX 2 +#define VALTYPE_INT64 3 +#define VALTYPE_STRING 4 +#define VALTYPE_WSTRING 5 +#define VALTYPE_DSTRING 6 +#define VALTYPE_LPBYTE 7 +#define VALTYPE_LPWCHAR 8 +#define VALTYPE_LPDCHAR 9 +#define VALTYPE_LPDDOUB 10 +#define VALTYPE_IDENT 11 +#define VALTYPE_PTR 12 +#define VALTYPE_EMPTY 13 + +#define DATA_BUF_NONE 0 +#define DATA_BUF_BOTH 1 +#define DATA_BUF_HAVE 2 +#define DATA_BUF_LIMIT (128 * 1024) + +#define LOOP_COUNT 300 + +#define DOC_MODE_SAVE 0 +#define DOC_MODE_IDENT 1 +#define DOC_MODE_CALL 2 + +#define FUNC_RET_NOMAL 0 +#define FUNC_RET_ABORT 1 +#define FUNC_RET_EXIT 2 +#define FUNC_RET_EVENT 3 #define SCP_EVENT_TIMER 0001 #define SCP_EVENT_CONS 0002 @@ -49,7 +49,11 @@ #define VALTYPE_TSTRING VALTYPE_STRING #endif -#define DOUBLE_ZERO 1e-20 +#define DOUBLE_ZERO 1e-20 + +#define PTRTYPE_NONE 0 +#define PTRTYPE_FILE 1 +#define PTRTYPE_PIPE 2 typedef struct _ScriptCmdsDefs { LPCSTR name; @@ -95,6 +99,7 @@ class CScriptValue : public CObject LONGLONG m_Int64; } m_Value; CComplex m_Complex; + int m_PtrType; CBuffer m_Buf; CBuffer m_Work; int m_ArrayPos; @@ -161,6 +166,7 @@ class CScriptValue : public CObject void RemoveAll(); int GetType(); + int GetPtrType(); CBuffer *GetBuf(); CBuffer *GetWBuf(); CBuffer *GetDBuf(); diff --git a/RLogin/ScriptDlg.cpp b/RLogin/ScriptDlg.cpp index f3290fa..7575173 100755 --- a/RLogin/ScriptDlg.cpp +++ b/RLogin/ScriptDlg.cpp @@ -62,7 +62,7 @@ BOOL CScriptDlg::OnInitDialog() m_CodeStack.EnableWindow(FALSE); } else { if ( (pWnd = GetDlgItem(IDOK)) != NULL ) - pWnd->SetWindowText(_T("ステップ")); + pWnd->SetWindowText(CStringLoad(IDS_SCRIPTDLGSTEP)); for ( cp = m_pScript->m_CodeStack ; cp != NULL ; cp = cp->next ) m_CodeStack.AddString(cp->name); m_CodeStack.SetCurSel(0); @@ -93,7 +93,15 @@ void CScriptDlg::OnClose() void CScriptDlg::OnOK() { if ( m_pScript != NULL ) { - m_pScript->Exec(); + try { + m_pScript->Exec(); + } catch(LPCTSTR pMsg) { + CString tmp; + tmp.Format(_T("Script Error '%s'"), pMsg); + MessageBox(tmp); + } catch(...) { + MessageBox(_T("Script Unkown Error")); + } return; } diff --git a/RLogin/TextRam.cpp b/RLogin/TextRam.cpp index ed7690c..e6f9069 100755 --- a/RLogin/TextRam.cpp +++ b/RLogin/TextRam.cpp @@ -5070,7 +5070,7 @@ void CTextRam::GetVram(int staX, int endX, int staY, int endY, CBuffer *pBuf) } } } -BOOL CTextRam::SpeekLine(int line, CString &text, CArray &pos) +BOOL CTextRam::SpeakLine(int line, CString &text, CArray &pos) { int n, x, sx, ex; CCharCell *vp; @@ -5115,7 +5115,7 @@ BOOL CTextRam::SpeekLine(int line, CString &text, CArray &po return bContinue; } -BOOL CTextRam::SpeekCheck(CCurPos sPos, CCurPos ePos, LPCTSTR str) +BOOL CTextRam::SpeakCheck(CCurPos sPos, CCurPos ePos, LPCTSTR str) { int n, x, y, tx, bx; int sx, sy, ex, ey; @@ -6393,10 +6393,10 @@ void CTextRam::DrawVram(CDC *pDC, int x1, int y1, int x2, int y2, class CRLoginV } } - // Speek Text - if ( pView->m_bSpeekDispText && x >= 0 && x < m_Cols && top != NULL ) { + // Speak Text + if ( pView->m_bSpeakDispText && x >= 0 && x < m_Cols && top != NULL ) { cpos = GetCalcPos(x, y - pView->m_HisOfs + pView->m_HisMin); - if ( pView->m_SpeekStaPos <= cpos && cpos <= pView->m_SpeekEndPos ) + if ( pView->m_SpeakStaPos <= cpos && cpos <= pView->m_SpeakEndPos ) work.attr ^= ATT_UNDER; } diff --git a/RLogin/TextRam.h b/RLogin/TextRam.h index d16a6b3..683242d 100755 --- a/RLogin/TextRam.h +++ b/RLogin/TextRam.h @@ -1292,8 +1292,8 @@ class CTextRam : public COptObject void GetCellSize(int *x, int *y); void GetScreenSize(int *pCx, int *pCy, int *pSx, int *pSy); - BOOL SpeekLine(int line, CString &text, CArray &pos); - BOOL SpeekCheck(CCurPos sPos, CCurPos ePos, LPCTSTR str); + BOOL SpeakLine(int line, CString &text, CArray &pos); + BOOL SpeakCheck(CCurPos sPos, CCurPos ePos, LPCTSTR str); void DrawBitmap(CDC *pDestDC, CRect &rect, CDC *pSrcDC, int width, int height, DWORD dwRop); void DrawLine(CDC *pDC, CRect &rect, COLORREF fc, COLORREF bc, BOOL bEraBack, struct DrawWork &prop, class CRLoginView *pView); diff --git a/RLogin/TextRamProc.cpp b/RLogin/TextRamProc.cpp index 4019cb3..d1a0c6d 100755 --- a/RLogin/TextRamProc.cpp +++ b/RLogin/TextRamProc.cpp @@ -4920,7 +4920,7 @@ void CTextRam::fc_OSCEXE(DWORD ch) } break; - case 801: // Speek String + case 801: // Speak String if ( (m_XtOptFlag & XTOP_SETUTF) != 0 ) m_IConv.RemoteToStr(m_SendCharSet[UTF8_SET], p, tmp); else @@ -4942,7 +4942,7 @@ void CTextRam::fc_OSCEXE(DWORD ch) } else wrk += *s; } - ((CMainFrame *)::AfxGetMainWnd())->Speek(wrk); + ((CMainFrame *)::AfxGetMainWnd())->Speak(wrk); break; } diff --git a/RLogin/resource.h b/RLogin/resource.h index ab28ff1..949d543 100755 --- a/RLogin/resource.h +++ b/RLogin/resource.h @@ -252,6 +252,9 @@ #define IDS_REGAPPSETMSG 642 #define IDS_REGAPPDELMSG 643 #define IDS_EMOJIMAGEMSG 644 +#define IDS_ANYPASTVIEWMSG 645 +#define IDS_VERSIONCHECKURL2 646 +#define IDS_SCRIPTDLGSTEP 647 #define IDE_ALLCLOSEREQ 700 #define IDE_DELETEKEYQES 701 #define IDE_DSABITSIZEERR 702 @@ -1129,7 +1132,7 @@ #define IDM_CMDHIS_MSG 5142 #define IDM_CMDHIS_SCRM 5143 #define IDM_HISTORYDLG 5144 -#define IDM_SPEEKALL 5145 +#define IDM_SPEAKALL 5145 #define IDM_FIRST_MDICHILD 0xF800 // Next default values for new objects @@ -1139,6 +1142,6 @@ #define _APS_NEXT_RESOURCE_VALUE 169 #define _APS_NEXT_COMMAND_VALUE 5146 #define _APS_NEXT_CONTROL_VALUE 2511 -#define _APS_NEXT_SYMED_VALUE 671 +#define _APS_NEXT_SYMED_VALUE 648 #endif #endif diff --git a/docs/history.html b/docs/history.html index ac9a98b..a40944b 100755 --- a/docs/history.html +++ b/docs/history.html @@ -6,13 +6,13 @@ 繝励Ο繧ー繝ゥ繝繝サ繝偵せ繝医Μ繝シ