LAPTOP-SNT8I5JK\Boounion
2025-01-09 3175d60b3b6e3f43ae62193743c4017db27005dc
1.增加底部日志窗口;
已添加4个文件
已修改9个文件
523 ■■■■■ 文件已修改
SourceCode/Bond/BoounionPLC/BoounionPLC.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/CMainContainer.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/CMainContainer.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/CPageLogcat.cpp 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/CPageLogcat.h 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/Common.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/LogEdit.cpp 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/LogEdit.h 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/Resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BoounionPLC/BoounionPLC.rc
Binary files differ
SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj
@@ -205,12 +205,14 @@
    <ClInclude Include="Component.h" />
    <ClInclude Include="Configuration.h" />
    <ClInclude Include="Context.h" />
    <ClInclude Include="CPageLogcat.h" />
    <ClInclude Include="DBManager\AlarmManager.h" />
    <ClInclude Include="DBManager\AxisManager.h" />
    <ClInclude Include="DBManager\SystemLogManager.h" />
    <ClInclude Include="DBManager\UserManager.h" />
    <ClInclude Include="Intent.h" />
    <ClInclude Include="Log.h" />
    <ClInclude Include="LogEdit.h" />
    <ClInclude Include="McBool.h" />
    <ClInclude Include="McInt.h" />
    <ClInclude Include="McItem.h" />
@@ -240,6 +242,7 @@
    <ClCompile Include="Component.cpp" />
    <ClCompile Include="Configuration.cpp" />
    <ClCompile Include="Context.cpp" />
    <ClCompile Include="CPageLogcat.cpp" />
    <ClCompile Include="DBManager\AlarmManager.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
    </ClCompile>
@@ -248,6 +251,7 @@
    <ClCompile Include="DBManager\UserManager.cpp" />
    <ClCompile Include="Intent.cpp" />
    <ClCompile Include="Log.cpp" />
    <ClCompile Include="LogEdit.cpp" />
    <ClCompile Include="McBool.cpp" />
    <ClCompile Include="McInt.cpp" />
    <ClCompile Include="McItem.cpp" />
SourceCode/Bond/BoounionPLC/BoounionPLC.vcxproj.filters
@@ -123,6 +123,12 @@
    <ClInclude Include="DBManager\UserManager.h">
      <Filter>DBManager</Filter>
    </ClInclude>
    <ClInclude Include="CPageLogcat.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="LogEdit.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="BoounionPLC.cpp">
@@ -218,6 +224,12 @@
    <ClCompile Include="DBManager\UserManager.cpp">
      <Filter>DBManager</Filter>
    </ClCompile>
    <ClCompile Include="CPageLogcat.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="LogEdit.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="BoounionPLC.rc">
SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
@@ -62,6 +62,7 @@
    m_crBkgnd = APP_MAIN_DLG_BACKGROUND;
    m_hbrBkgnd = nullptr;
    m_pActiveView = nullptr;
    m_pPageLogcat = nullptr;
}
void CBoounionPLCDlg::DoDataExchange(CDataExchange* pDX)
@@ -114,6 +115,7 @@
                    if (m_pActiveView->GetContext() != (void*)pPlc) {
                        m_pActiveView->SetWindowText(pPlc->getName().c_str());
                        m_pActiveView->SetContext(pPlc);
                        m_pActiveView->SendMessage(WM_NCPAINT, 0, 0);
                    }
                }
            }
@@ -193,6 +195,13 @@
    m_pMainContainer->ShowWindow(SW_SHOW);
    // æ—¥å¿—
    m_pPageLogcat = new CPageLogcat();
    m_pPageLogcat->Create(IDD_PAGE_LOGCAT, m_pMainContainer);
    m_pPageLogcat->ShowWindow(SW_SHOW);
    m_pMainContainer->SetBottomWnd(m_pPageLogcat, 220);
    // èœå•
    CMenu menu;
    menu.LoadMenu(IDR_MENU_APP);
SourceCode/Bond/BoounionPLC/BoounionPLCDlg.h
@@ -8,6 +8,7 @@
#include "CMainContainer.h"
#include "CBaseView.h"
#include "AlarmPopupDlg.h"
#include "CPageLogcat.h"
// CBoounionPLCDlg å¯¹è¯æ¡†
@@ -33,6 +34,7 @@
    CPagePlcList* m_pPagePlcList;
    CMainContainer* m_pMainContainer;
    CBaseView* m_pActiveView;
    CPageLogcat* m_pPageLogcat;
    CAlarmPopupDlg* m_pAlarmWnd;
SourceCode/Bond/BoounionPLC/CMainContainer.cpp
@@ -17,6 +17,8 @@
{
    m_crBkgnd = MAIN_CONTAINER_BACKGROUND;
    m_hbrBkgnd = nullptr;
    m_pBottomWnd = nullptr;
    m_nBottomWndHeight = 0;
}
CMainContainer::~CMainContainer()
@@ -38,6 +40,12 @@
// CMainContainer æ¶ˆæ¯å¤„理程序
void CMainContainer::SetBottomWnd(CWnd* pWnd, int nHeight)
{
    m_pBottomWnd = pWnd;
    m_nBottomWndHeight = nHeight;
}
BOOL CMainContainer::OnInitDialog()
{
@@ -84,8 +92,12 @@
void CMainContainer::Resize()
{
    CRect rcClient;
    CRect rcClient, rcChild;
    GetClientRect(&rcClient);
    rcChild = rcClient;
    if (m_pBottomWnd != nullptr && m_nBottomWndHeight > 0) {
        rcChild.bottom -= m_nBottomWndHeight;
    }
    // å…ˆå–得子窗口数量
    int count = 0;
@@ -97,7 +109,13 @@
    pClild = FindWindowEx(m_hWnd, NULL, NULL, NULL);
    while (pClild != nullptr) {
        pClild->MoveWindow(&rcClient);
        if (pClild != m_pBottomWnd) {
            pClild->MoveWindow(&rcChild);
        }
        else if (m_pBottomWnd != nullptr) {
            m_pBottomWnd->MoveWindow(0, rcChild.bottom, rcClient.Width(), rcClient.bottom - rcChild.bottom);
        }
        if (::GetProp(pClild->GetSafeHwnd(), "Home") == (HANDLE)1) {
            pClild->ShowWindow(count == 1 ? SW_SHOW : SW_HIDE);
        }
SourceCode/Bond/BoounionPLC/CMainContainer.h
@@ -14,11 +14,13 @@
public:
    void Resize();
    void SetBottomWnd(CWnd* pWnd, int nHeight);
private:
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    CWnd* m_pBottomWnd;
    int m_nBottomWndHeight;
// å¯¹è¯æ¡†æ•°æ®
SourceCode/Bond/BoounionPLC/CPageLogcat.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,304 @@
// CPageLogcat.cpp: å®žçŽ°æ–‡ä»¶
//
#include "stdafx.h"
#include "BoounionPLC.h"
#include "Common.h"
#include "CPageLogcat.h"
#include "afxdialogex.h"
#include <regex>
// CPageLogcat å¯¹è¯æ¡†
IMPLEMENT_DYNAMIC(CPageLogcat, CDialogEx)
CPageLogcat::CPageLogcat(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_PAGE_LOGCAT, pParent)
{
    m_crBkgnd = LOGCAT_BACKGROUND_COLOR;
    m_hbrBkgnd = nullptr;
    m_pObserver = nullptr;
    m_nLevel = 0;
    m_strIncludeText = _T("");
    m_bIncludeRegex = FALSE;
}
CPageLogcat::~CPageLogcat()
{
}
void CPageLogcat::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON_LEVEL, m_btnLevel);
    DDX_Control(pDX, IDC_BUTTON_INCLUDE, m_btnInclude);
    DDX_Control(pDX, IDC_EDIT_LOG, m_logEdit);
}
BEGIN_MESSAGE_MAP(CPageLogcat, CDialogEx)
    ON_WM_CTLCOLOR()
    ON_WM_DESTROY()
    ON_WM_SIZE()
    ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_LEVEL, &CPageLogcat::OnButtonLevelMenuClicked)
    ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_INCLUDE, &CPageLogcat::OnButtonIncludeMenuClicked)
    ON_EN_CHANGE(IDC_EDIT_INCLUDE, &CPageLogcat::OnEnChangeEditInclude)
    ON_BN_CLICKED(IDC_CHECK_REGEX, &CPageLogcat::OnBnClickedCheckRegex)
END_MESSAGE_MAP()
// CPageLogcat æ¶ˆæ¯å¤„理程序
void CPageLogcat::InitRxWindow()
{
    /* code */
    // è®¢é˜…数据
    IRxWindows* pRxWindows = RX_GetRxWindows();
    pRxWindows->enableLog(5);
    if (m_pObserver == NULL) {
        m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
            // onNext
            pAny->addRef();
            int code = pAny->getCode();
            if (RX_CODE_LOG == code && ::IsWindow(m_hWnd)) {
                const char* pszLogMsg;
                int level;
                if (pAny->getStringValue("text", pszLogMsg)
                    && pAny->getIntValue("exCode", level)) {
                    if (level >= m_nLevel) {
                        CString strText = pszLogMsg;
                        BOOL bInclude = TRUE;
                        if (!m_strIncludeText.IsEmpty()) {
                            if (!m_bIncludeRegex) {
                                bInclude = (strText.Find(m_strIncludeText) >= 0);
                            }
                            else {
                                bInclude = std::regex_search((LPTSTR)(LPCTSTR)strText,
                                    std::regex((LPTSTR)(LPCTSTR)m_strIncludeText));
                            }
                        }
                        if (bInclude) {
                            strText.Replace("\n", "\r\n");
                            AppendLog(level, (LPTSTR)(LPCTSTR)strText);
                        }
                    }
                }
            }
            pAny->release();
            }, [&]() -> void {
                // onComplete
            }, [&](IThrowable* pThrowable) -> void {
                // onErrorm
                pThrowable->printf();
            });
        theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
            ->subscribe(m_pObserver);
    }
}
BOOL CPageLogcat::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // ç¼“å­˜
    m_nLevel = theApp.m_model.m_configuration.getLogcatLevel();
    theApp.m_model.m_configuration.getLogcatIncludeText(m_strIncludeText);
    m_bIncludeRegex = theApp.m_model.m_configuration.isLogcatIncludeRegex();
    theApp.m_model.m_configuration.getCustomLogcatIncludeTexts(m_customIncludeTexts);
    // Level
    HMENU hMenu = LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCEA(IDR_MENU_LOGCAT_LEVEL));
    m_btnLevel.SetMenu(hMenu);
    m_btnLevel.SetCurrentMenuItem(m_nLevel);
    m_btnLevel.SetBkgndColor(BS_NORMAL, RGB(241, 242, 244));
    m_btnLevel.SetBkgndColor(BS_HOVER, RGB(220, 223, 228));
    m_btnLevel.SetBkgndColor(BS_PRESS, RGB(179, 185, 196));
    m_btnLevel.SetFrameColor(BS_NORMAL, RGB(133, 144, 162));
    m_btnLevel.SetFrameColor(BS_HOVER, RGB(56, 139, 255));
    m_btnLevel.SetFrameColor(BS_PRESS, RGB(56, 139, 255));
    m_btnLevel.SetFrameColor(BS_FOCUS, RGB(56, 139, 255));
    // åŒ…含字符串
    CString strIcon1;
    strIcon1.Format(_T("%s\\Res\\logcat_include.ico"), theApp.m_strAppDir);
    HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
        strIcon1, IMAGE_ICON, 24, 24,
        LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
    m_btnInclude.SetIcon(hIcon, hIcon, 24);
    {
        HMENU hMenu = LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCEA(IDR_MENU_INCLUDE));
        HMENU hSubMenu = GetSubMenu(hMenu, 0);
        DeleteMenu(hSubMenu, 0, MF_BYPOSITION);
        int i = 0;
        for (auto& item : m_customIncludeTexts) {
            i++;
            InsertMenu(hSubMenu, 0, MF_BYPOSITION, 0x1998+i, item.c_str());
            m_btnInclude.SetMenu(hMenu);
        }
    }
    SetDlgItemText(IDC_EDIT_INCLUDE, m_strIncludeText);
    CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
    pCheckBox->SetCheck(m_bIncludeRegex ? BST_CHECKED : BST_UNCHECKED);
    // å†…容
    m_logEdit.SetMaxLineCount(20);
    m_logEdit.SetLimitText(-1);
    InitRxWindow();
    return TRUE;  // return TRUE unless you set the focus to a control
                  // å¼‚常: OCX å±žæ€§é¡µåº”返回 FALSE
}
HBRUSH CPageLogcat::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
    if (nCtlColor == CTLCOLOR_STATIC) {
        pDC->SetBkColor(m_crBkgnd);
    }
    if (m_hbrBkgnd == nullptr) {
        m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
    }
    return m_hbrBkgnd;
}
void CPageLogcat::OnDestroy()
{
    CDialogEx::OnDestroy();
    {
        HMENU hMenu = m_btnLevel.GetMenu();
        if (hMenu != NULL) {
            ::DestroyMenu(hMenu);
        }
    }
    {
        HMENU hMenu = m_btnInclude.GetMenu();
        if (hMenu != NULL) {
            ::DestroyMenu(hMenu);
        }
    }
    if (m_hbrBkgnd != nullptr) {
        ::DeleteObject(m_hbrBkgnd);
    }
    ASSERT(m_pObserver != NULL);
    m_pObserver->unsubscribe();
    m_pObserver = NULL;
}
void CPageLogcat::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (GetDlgItem(IDC_EDIT_LOG) == nullptr) return;
    int x, y, temp;
    CRect rcClient, rcItem;
    CWnd* pItem;
    GetClientRect(&rcClient);
    x = 12;
    y = 0;
    pItem = GetDlgItem(IDC_LINE1);
    pItem->MoveWindow(x, y, rcClient.Width(), 2);
    pItem = GetDlgItem(IDC_BUTTON_LEVEL);
    pItem->GetWindowRect(&rcItem);
    ScreenToClient(&rcItem);
    pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
    x += 18;
    y = rcItem.bottom;
    y += 12;
    pItem = GetDlgItem(IDC_BUTTON_INCLUDE);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
    x += 2;
    pItem = GetDlgItem(IDC_EDIT_INCLUDE);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
    x += rcItem.Width();
    x += 12;
    temp = rcItem.Height();
    pItem = GetDlgItem(IDC_CHECK_REGEX);
    pItem->GetWindowRect(&rcItem);
    pItem->MoveWindow(x, 12 + (temp - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
    pItem = GetDlgItem(IDC_EDIT_LOG);
    pItem->MoveWindow(12, y, rcClient.Width() - 24, rcClient.Height() - 12 - y);
}
void CPageLogcat::AppendLog(int level, const char* pszText)
{
    if (!::IsWindow(m_logEdit.m_hWnd)) {
        return;
    }
    m_logEdit.AppendText(pszText);
}
void CPageLogcat::OnButtonLevelMenuClicked(NMHDR* pNMHDR, LRESULT* pResult)
{
    BLBUTTON_NMHDR* pblbNmhdr = reinterpret_cast<BLBUTTON_NMHDR*>(pNMHDR);
    m_nLevel = (int)pblbNmhdr->dwData;
    theApp.m_model.m_configuration.setLogcatLevel(m_nLevel);
    m_btnLevel.SetCurrentMenuItem(m_nLevel);
    *pResult = 0;
}
void CPageLogcat::OnButtonIncludeMenuClicked(NMHDR* pNMHDR, LRESULT* pResult)
{
    BLBUTTON_NMHDR* pblbNmhdr = reinterpret_cast<BLBUTTON_NMHDR*>(pNMHDR);
    int position = (int)pblbNmhdr->dwData;
    std::string& strInclude = m_customIncludeTexts.at(position);
    SetDlgItemText(IDC_EDIT_INCLUDE, strInclude.c_str());
    CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
    m_bIncludeRegex = FALSE;
    pCheckBox->SetCheck(BST_UNCHECKED);
    theApp.m_model.m_configuration.setLogcatIncludeRegex(m_bIncludeRegex);
    theApp.m_model.m_configuration.setLogcatIncludeText(m_strIncludeText);
    *pResult = 0;
}
void CPageLogcat::OnEnChangeEditInclude()
{
    GetDlgItemText(IDC_EDIT_INCLUDE, m_strIncludeText);
    theApp.m_model.m_configuration.setLogcatIncludeText(m_strIncludeText);
}
void CPageLogcat::OnBnClickedCheckRegex()
{
    CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
    m_bIncludeRegex = pCheckBox->GetCheck();
    theApp.m_model.m_configuration.setLogcatIncludeRegex(m_bIncludeRegex);
}
SourceCode/Bond/BoounionPLC/CPageLogcat.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
#pragma once
#include "BlButton.h"
#include "LogEdit.h"
#include <vector>
#include <string>
// CPageLogcat å¯¹è¯æ¡†
class CPageLogcat : public CDialogEx
{
    DECLARE_DYNAMIC(CPageLogcat)
public:
    CPageLogcat(CWnd* pParent = nullptr);   // æ ‡å‡†æž„造函数
    virtual ~CPageLogcat();
private:
    void InitRxWindow();
    void AppendLog(int level, const char* pszText);
private:
    COLORREF m_crBkgnd;
    HBRUSH m_hbrBkgnd;
    IObserver* m_pObserver;
    int m_nLevel;
    CString m_strIncludeText;
    BOOL m_bIncludeRegex;
    std::vector<std::string> m_customIncludeTexts;
private:
    CBlButton m_btnLevel;
    CBlButton m_btnInclude;
    CLogEdit m_logEdit;
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_PAGE_LOGCAT };
#endif
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV æ”¯æŒ
    DECLARE_MESSAGE_MAP()
public:
    virtual BOOL OnInitDialog();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnDestroy();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnButtonLevelMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnButtonIncludeMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnEnChangeEditInclude();
    afx_msg void OnBnClickedCheckRegex();
};
SourceCode/Bond/BoounionPLC/Common.h
@@ -19,6 +19,8 @@
#define MAIN_CONTAINER_BACKGROUND        RGB(252, 252, 255)
#define BASE_VIEW_BACKGROUND            RGB(252, 252, 255)
#define PLC_VIEW_BACKGROUND                RGB(252, 252, 255)
#define LOGCAT_BACKGROUND_COLOR            RGB(252, 252, 255)
/* è§£é™¤è­¦å‘Š æŒ‰é’® */
#define BTN_ALARM_OFF_FRAME_NORMAL        RGB(88, 88, 88)
SourceCode/Bond/BoounionPLC/LogEdit.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
#include "stdafx.h"
#include "LogEdit.h"
#define MENU_ITEM_SEL_ALL        0x666
#define MENU_ITEM_COPY            0x667
#define MENU_ITEM_CLEAR            0x668
CLogEdit::CLogEdit()
{
    m_nMaxLineCount = 0xffff;
}
CLogEdit::~CLogEdit()
{
}
BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
    ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
void CLogEdit::SetMaxLineCount(int line)
{
    m_nMaxLineCount = line;
}
void CLogEdit::OnContextMenu(CWnd* pWnd, CPoint point)
{
    HMENU hMenu = CreatePopupMenu();
    InsertMenu(hMenu, 0, MF_BYPOSITION, MENU_ITEM_SEL_ALL, "ȫѡ");
    InsertMenu(hMenu, 1, MF_BYPOSITION, MENU_ITEM_COPY, "复制");
    InsertMenu(hMenu, 2, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
    InsertMenu(hMenu, 3, MF_BYPOSITION, MENU_ITEM_CLEAR, "全部清除");
    int cmd = ::TrackPopupMenu(hMenu,
        TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
        point.x, point.y + 2, 0, m_hWnd, NULL);
    DestroyMenu(hMenu);
    if (cmd == MENU_ITEM_SEL_ALL) {
        SetFocus();
        this->SetSel(0, -1);
    }
    else if (cmd == MENU_ITEM_COPY) {
        this->Copy();
    }
    else if (cmd == MENU_ITEM_CLEAR) {
        SetWindowText(_T(""));
    }
}
void CLogEdit::AppendText(const char* pszText)
{
    // èŽ·å–é€‰æ‹©èŒƒå›´ä»¥ä¾¿æ¢å¤
    int nStart, nEnd;
    GetSel(nStart, nEnd);
    // è¶…过指定行数则删除最前面的行
    int nLineCount = GetLineCount();
    while (nLineCount > m_nMaxLineCount) {
        int nLin1End = LineIndex(1);
        nStart -= nLin1End;
        if (nStart < 0) nStart = 0;
        nEnd -= nLin1End;
        if (nEnd < 0) nEnd = 0;
        SetSel(0, nLin1End);
        ReplaceSel(_T(""));
        nLineCount = GetLineCount();
    }
    // è¿½åŠ åˆ°æœ€åŽ
    int length = GetWindowTextLength();
    SetSel(length, length);
    ReplaceSel(pszText);
    PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
    // æ¢å¤
    if (nStart == 0 && nEnd == 0) {
        nStart = GetWindowTextLength();
        nEnd = nStart;
    }
    SetSel(nStart, nEnd);
}
SourceCode/Bond/BoounionPLC/LogEdit.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
#pragma once
#include "afxwin.h"
class CLogEdit :
    public CEdit
{
public:
    CLogEdit();
    ~CLogEdit();
public:
    void SetMaxLineCount(int line);
    void AppendText(const char* pszText);
private:
    int m_nMaxLineCount;
    DECLARE_MESSAGE_MAP()
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
};
SourceCode/Bond/BoounionPLC/Resource.h
Binary files differ