guard_page.cpp

 
Thread 1 "buffer_pool_man" received signal SIGTSTP, Stopped (user). futex_wait (private=0, expected=2, futex_word=0x5555556c0a90) at ../sysdeps/nptl/futex-internal.h:146 warning: 146 ../sysdeps/nptl/futex-internal.h: No such file or directory (gdb) thread apply all bt Thread 13 (Thread 0x7ffff6ffe6c0 (LWP 92375) "buffer_pool_man"): #0 __futex_abstimed_wait_common (cancel=false, private=<optimized out>, abstime=0x0, clockid=0, expected=3, futex_word=0x5555556cb5a4) at ./nptl/futex-internal.c:103 #1 __GI___futex_abstimed_wait64 (futex_word=futex_word@entry=0x5555556cb5a4, expected=expected@entry=3, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=<optimized out>) at ./nptl/futex-internal.c:128 #2 0x00007ffff78a333b in __pthread_rwlock_wrlock_full64 (abstime=0x0, clockid=0, rwlock=0x5555556cb598) at ./nptl/pthread_rwlock_common.c:730 #3 ___pthread_rwlock_wrlock (rwlock=0x5555556cb598) at ./nptl/pthread_rwlock_wrlock.c:26 #4 0x0000555555593573 in std::__glibcxx_rwlock_wrlock (__rwlock=0x5555556cb598) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:83 --Type <RET> for more, q to quit, c to continue without paging--c #5 0x00005555555954d5 in std::__shared_mutex_pthread::lock (this=0x5555556cb598) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:196 #6 0x0000555555594575 in std::shared_mutex::lock (this=0x5555556cb598) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:423 #7 0x0000555555590f1c in bustub::BufferPoolManager::CheckedWritePage (this=0x5555556c5a20, page_id=1, access_type=bustub::AccessType::Unknown) at /home/relic/cmu155452024/CMU15443-2024/src/buffer/buffer_pool_manager.cpp:222 #8 0x00005555555925b5 in bustub::BufferPoolManager::WritePage (this=0x5555556c5a20, page_id=1, access_type=bustub::AccessType::Unknown) at /home/relic/cmu155452024/CMU15443-2024/src/buffer/buffer_pool_manager.cpp:362 #9 0x000055555557043b in bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5::operator()() const (this=0x5555556c5f98) at /home/relic/cmu155452024/CMU15443-2024/test/buffer/buffer_pool_manager_test.cpp:335 #10 0x00005555555703dd in std::__invoke_impl<void, bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5>(std::__invoke_other, bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5&&) (__f=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61 #11 0x000055555557036d in std::__invoke<bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5>(bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5&&) (__fn=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96 #12 0x0000555555570345 in std::thread::_Invoker<std::tuple<bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x5555556c5f98) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292 #13 0x0000555555570315 in std::thread::_Invoker<std::tuple<bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5> >::operator()() (this=0x5555556c5f98) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299 #14 0x0000555555570229 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody()::$_5> > >::_M_run() (this=0x5555556c5f90) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244 #15 0x00007ffff7cecdb4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 #16 0x00007ffff789caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447 #17 0x00007ffff7929c6c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78 Thread 12 (Thread 0x7ffff77ff6c0 (LWP 92374) "buffer_pool_man"): #0 0x00007ffff7898d71 in __futex_abstimed_wait_common64 (private=-1, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555556c5d48) at ./nptl/futex-internal.c:57 #1 __futex_abstimed_wait_common (cancel=true, private=-1, abstime=0x0, clockid=0, expected=0, futex_word=0x5555556c5d48) at ./nptl/futex-internal.c:87 #2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x5555556c5d48, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139 #3 0x00007ffff789b7ed in __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x5555556c5cf8, cond=0x5555556c5d20) at ./nptl/pthread_cond_wait.c:503 #4 ___pthread_cond_wait (cond=0x5555556c5d20, mutex=0x5555556c5cf8) at ./nptl/pthread_cond_wait.c:627 #5 0x00005555555ae691 in std::condition_variable::wait<bustub::Channel<std::optional<bustub::DiskRequest> >::Get()::{lambda()#1}>(std::unique_lock<std::mutex>&, bustub::Channel<std::optional<bustub::DiskRequest> >::Get()::{lambda()#1}) (this=0x5555556c5d20, __lock=..., __p=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/condition_variable:105 #6 0x00005555555ac48c in bustub::Channel<std::optional<bustub::DiskRequest> >::Get (this=0x5555556c5cf8) at /home/relic/cmu155452024/CMU15443-2024/src/include/common/channel.h:48 #7 0x00005555555aba6e in bustub::DiskScheduler::StartWorkerThread (this=0x5555556c5cf0) at /home/relic/cmu155452024/CMU15443-2024/src/storage/disk/disk_scheduler.cpp:41 #8 0x00005555555ac0c8 in bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0::operator()() const (this=0x7fffe4000b78) at /home/relic/cmu155452024/CMU15443-2024/src/storage/disk/disk_scheduler.cpp:22 #9 0x00005555555ac09d in std::__invoke_impl<void, bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0>(std::__invoke_other, bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0&&) (__f=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61 #10 0x00005555555ac02d in std::__invoke<bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0>(bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0&&) (__fn=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96 #11 0x00005555555ac005 in std::thread::_Invoker<std::tuple<bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x7fffe4000b78) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292 #12 0x00005555555abfd5 in std::thread::_Invoker<std::tuple<bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0> >::operator()() (this=0x7fffe4000b78) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299 #13 0x00005555555abef9 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<bustub::DiskScheduler::DiskScheduler(bustub::DiskManager*)::$_0> > >::_M_run() (this=0x7fffe4000b70) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244 #14 0x00007ffff7cecdb4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 #15 0x00007ffff789caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447 #16 0x00007ffff7929c6c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78 Thread 1 (Thread 0x7ffff7ebf740 (LWP 92142) "buffer_pool_man"): #0 futex_wait (private=0, expected=2, futex_word=0x5555556c0a90) at ../sysdeps/nptl/futex-internal.h:146 #1 __GI___lll_lock_wait (futex=futex@entry=0x5555556c0a90, private=0) at ./nptl/lowlevellock.c:49 #2 0x00007ffff78a0101 in lll_mutex_lock_optimized (mutex=0x5555556c0a90) at ./nptl/pthread_mutex_lock.c:48 #3 ___pthread_mutex_lock (mutex=0x5555556c0a90) at ./nptl/pthread_mutex_lock.c:93 #4 0x000055555556eb63 in __gthread_mutex_lock (__mutex=0x5555556c0a90) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13/bits/gthr-default.h:749 #5 0x0000555555573da5 in std::mutex::lock (this=0x5555556c0a90) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_mutex.h:113 #6 0x00005555555939f3 in std::scoped_lock<std::mutex>::scoped_lock (this=0x7fffffffcf60, __m=...) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/mutex:779 #7 0x0000555555590d1a in bustub::BufferPoolManager::CheckedWritePage (this=0x5555556c5a20, page_id=2, access_type=bustub::AccessType::Unknown) at /home/relic/cmu155452024/CMU15443-2024/src/buffer/buffer_pool_manager.cpp:212 #8 0x00005555555925b5 in bustub::BufferPoolManager::WritePage (this=0x5555556c5a20, page_id=2, access_type=bustub::AccessType::Unknown) at /home/relic/cmu155452024/CMU15443-2024/src/buffer/buffer_pool_manager.cpp:362 #9 0x000055555556e4a2 in bustub::BufferPoolManagerTest_DeadlockTest_Test::TestBody (this=0x7fffec000ed0) at /home/relic/cmu155452024/CMU15443-2024/test/buffer/buffer_pool_manager_test.cpp:350 #10 0x000055555560703b in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void> (object=0x7fffec000ed0, method=&virtual testing::Test::TestBody(), location=0x55555564cb63 "the test body") at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2612 #11 0x00005555555ea90a in testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void> (object=0x7fffec000ed0, method=&virtual testing::Test::TestBody(), location=0x55555564cb63 "the test body") at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2648 #12 0x00005555555c7243 in testing::Test::Run (this=0x7fffec000ed0) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2687 #13 0x00005555555c7ef0 in testing::TestInfo::Run (this=0x5555556c0350) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2836 #14 0x00005555555c87dc in testing::TestSuite::Run (this=0x5555556bf9d0) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:3015 #15 0x00005555555db3e4 in testing::internal::UnitTestImpl::RunAllTests (this=0x5555556bf5b0) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:5920 #16 0x000055555560b5bb in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x5555556bf5b0, method=(bool (testing::internal::UnitTestImpl::*)(class testing::internal::UnitTestImpl * const)) 0x5555555daf80 <testing::internal::UnitTestImpl::RunAllTests()>, location=0x55555564d408 "auxiliary test code (environments or event listeners)") at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2612 #17 0x00005555555ed05a in testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x5555556bf5b0, method=(bool (testing::internal::UnitTestImpl::*)(class testing::internal::UnitTestImpl * const)) 0x5555555daf80 <testing::internal::UnitTestImpl::RunAllTests()>, location=0x55555564d408 "auxiliary test code (environments or event listeners)") at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:2648 #18 0x00005555555daf2b in testing::UnitTest::Run (this=0x5555556ace08 <testing::UnitTest::GetInstance()::instance>) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/src/gtest.cc:5484 #19 0x000055555560ecc1 in RUN_ALL_TESTS () at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googletest/include/gtest/gtest.h:2317 #20 0x000055555560ec9b in main (argc=1, argv=0x7fffffffdaf8) at /home/relic/cmu155452024/CMU15443-2024/third_party/googletest/googlemock/src/gmock_main.cc:71
最新发布
09-29
根据我提供的控件源码,写出一个更好的控件 #ifndef _CONSOLE_H_ #define _CONSOLE_H_ #define _CRT_SECURE_NO_WARNINGS #define NO_WARN_MBCS_MFC_DEPRECATION #include <SDKDDKVer.h> //#include <afxwin.h> #include <afxcmn.h> #include <concurrent_vector.h> #define CONSOLECOLOR_BLACK "\x1E\x1D" //字体 黑色 #define CONSOLECOLOR_RED "\x1E\x1F" //字体 红色 #define CONSOLECOLOR_GREEN "\x1E\x20" //字体 绿色 #define CONSOLECOLOR_YELLOW "\x1E\x21" //字体 黄色 #define CONSOLECOLOR_BLUE "\x1E\x22" //字体 蓝色 #define CONSOLECOLOR_PURPLE "\x1E\x23" //字体 紫色 #define CONSOLECOLOR_CYAN "\x1E\x24" //字体 青色 #define CONSOLECOLOR_DEF "\x1E\x25" //字体 默认色 class ScrollBar; struct LineInfo { DWORD m_dwStrLen;//行内容的长度 DWORD m_dwHead;//行首的sel游标 DWORD m_dwMaxSelWnd;//当前控件x轴尽头的sel DWORD m_dwTail;//行尾的sel int m_xPos;//行首的x开始坐标 int m_yPos;//行首的y开始坐标 DWORD m_dwMaxPixl;//此行内容占最大的像素 int* m_pDx; ~LineInfo() { if (m_pDx)delete[]m_pDx; } }; class Console: public CRichEditCtrl { public: Console(CWnd* _pParent); ~Console(); template<class ...Args> void Printf(const char* pformat, Args... args) { int len = std::snprintf(nullptr, 0, pformat, args...); if (len > 0) { char* szBuf = new char[len+1]; std::snprintf(szBuf, len+1, pformat, args...); split(szBuf); delete[]szBuf; } } private: void split(const char* _szText); void printf(const char* _szText); private: CDC* m_pDC; CRect m_rcWnd; BOOL m_bIsTrack; CFont m_Font;//默认字体,只是方便计算字体占屏幕长度使用的 int m_nFontSize;//默认字体大小(单位Twips) 如220Twip = 220/20 = 11磅 CHARFORMAT2 m_CF;//最终字体的数据 concurrency::concurrent_vector<LineInfo> m_vecLineInfo; ScrollBar* m_pHScroll; SCROLLINFO m_infoHScroll; DWORD m_pixCurMaxChars; ScrollBar* m_pVScroll; SCROLLINFO m_infoVScroll; int m_iLineHeight; int m_iStartPos_x; int m_iPrePos_x; bool m_bIsCapture; CHARRANGE m_StartSel; public: DECLARE_MESSAGE_MAP() afx_msg void OnEnSelchange(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnEnMsgfilter(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnMouseLeave(); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); }; extern Console* pConsole; #define console(_format, ...)pConsole->Printf(_format, ##__VA_ARGS__); #endif#include "Console.h" #include <io.h> #include <thread> #include "ScrollBar/ScrollBar.h" Console* pConsole = NULL; Console::Console(CWnd* _pParent) : m_nFontSize(10 * 10), m_bIsTrack(FALSE), m_pHScroll(NULL), m_pVScroll(NULL), m_pixCurMaxChars(0), m_iPrePos_x(0), m_iStartPos_x(0), m_bIsCapture(FALSE) { if (_pParent) { const char* szFontName = "lucida consoles"; //Arial _pParent->GetWindowRect(&m_rcWnd); m_rcWnd = {10, 0, m_rcWnd.Width()-15, m_rcWnd.Height()-15};//682 //| WS_HSCROLL | WS_VSCROLL if (CreateEx(NULL, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_WANTRETURN | ES_MULTILINE | ES_READONLY | ES_AUTOHSCROLL | ES_AUTOVSCROLL, m_rcWnd, _pParent, 0))// { m_pDC = GetDC(); SetBackgroundColor(false, RGB(30, 30, 30));//设置背景颜色 LimitText(32767);//系统默认设置是 32767 = 31.999kb 只能限制用户的输入 //创建新字体数据,此字体只是方便计算屏幕显示的长度用的。最终字体数据以 CHARFORMAT2 为准 //以十分之一磅为单位。例如,如果你想要一个12磅的字体,你应该传递120作为这个参数。 m_Font.CreatePointFont(m_nFontSize, szFontName);// 100/10 =10磅,相当于200Twip CreatePointFont用的单位是Point, 是磅的10倍,刚好是Twips的一半 SetFont(&m_Font);//设置字体 m_pDC->SelectObject(&m_Font);//dc选择当前字体 /* 1缇等于1/1440 英寸或1/567厘米 缇(Twips) (缇:计量单位,等于“磅”的 1/20,英寸的 1/1440。一厘米有 567 缇。 像素(Pixels):监视器或打印机分辨率的最小单位 右键单击桌面,选择属性,选择“设置”选卡,单击高级按钮。 里面出现DPI设置。一般为“正常尺寸(96 DPI)”。 DPI的意思就是 DPI(Dots per Inch)。因此我们可以得到如下换算公式 1 Pixel = 1440 TPI / 96 DPI = 15 Twips 1 Twip = 96 DPI / 1440 TPI = 0.0666667 Pixels 磅:指打印的字符的高度的度量单位, 1磅等于1/72英寸,或大约等于1厘米的 1/28。 英寸:2.54 厘米 一般情况下:1厘米=8505像素 20Twip = 1磅 = 20*0.0666667 = 1.333334 Pixels */ LRESULT FontStyle = 0; FontStyle = SendMessage(EM_GETLANGOPTIONS, 0, 0); if (FontStyle & IMF_DUALFONT) { FontStyle &= ~IMF_DUALFONT; //"<CRichEdit_Ctrl::CRichEdit_Ctrl>成功去掉IMF_DUALFONT"; } SendMessage(EM_SETLANGOPTIONS, 0, (LPARAM)FontStyle); /* PARAFORMAT2 pf; ZeroMemory(&pf, sizeof(PARAFORMAT2)); pf.cbSize = sizeof pf; pf.dwMask |= PFM_ALL; pf.bLineSpacingRule = 100; pf.dyLineSpacing = 400; pf.dySpaceAfter = 400; pf.dySpaceBefore = 400; pf.dxStartIndent = 100; pf.dxRightIndent = 100; SetParaFormat(pf); */ TEXTMETRIC tm; ::GetTextMetrics(m_pDC->GetSafeHdc(), &tm); m_iLineHeight = tm.tmHeight + (tm.tmDescent*2);//取得行高 //准确的字体数据 memset(&m_CF, 0, sizeof(m_CF)); //StrCpyA(m_CF.szFaceName, szFontName);//设置字体 //m_CF.cbSize = sizeof(CHARFORMAT2); m_CF.dwMask = CFM_EFFECTS | CFM_COLOR; m_CF.dwEffects = 0; m_CF.crTextColor = RGB(165, 165, 165);//设置颜色 //m_CF.yHeight = m_nFontSize;//除20得到磅 如 200/20 = 10磅 //默认的字符磅数 SetDefaultCharFormat(m_CF);//设置字体 SetEventMask(GetEventMask() | ENM_CHANGE | ENM_SELCHANGE | ENM_SCROLL | ENM_MOUSEEVENTS); //创建滚动动 m_pHScroll = new ScrollBar(); if (m_pHScroll->Create(SB_HORZ, CRect(m_rcWnd.left, m_rcWnd.Height(), m_rcWnd.right, m_rcWnd.Height()+15), _pParent)) { m_pHScroll->SetTarget(this); memset(&m_infoHScroll, 0, sizeof m_infoHScroll); m_infoHScroll.cbSize = sizeof m_infoHScroll; m_infoHScroll.fMask = SIF_ALL; m_infoHScroll.nPage = m_rcWnd.Width(); } m_pVScroll = new ScrollBar(); if (m_pVScroll->Create(SB_VERT, CRect(m_rcWnd.right, m_rcWnd.top, m_rcWnd.right+15, m_rcWnd.bottom), _pParent)) { m_pVScroll->SetTarget(this); memset(&m_infoVScroll, 0, sizeof m_infoVScroll); m_infoVScroll.cbSize = sizeof m_infoVScroll; m_infoVScroll.fMask = SIF_ALL; m_infoVScroll.nPage = m_rcWnd.Height(); } } } } Console::~Console() { m_Font.DeleteObject(); if (m_pHScroll)delete m_pHScroll; if (m_pVScroll)delete m_pVScroll; for (concurrency::concurrent_vector<LineInfo>::iterator iter = m_vecLineInfo.begin(); iter != m_vecLineInfo.end(); iter++) { if (iter->m_pDx) { delete[] iter->m_pDx; iter->m_pDx = NULL; } } } /* *0x1E RS (Record Separator) 记录分离符 属性代码 颜色 29 黑色 = 0x1D 31 红色 = 0x1F 32 绿色 = 0x20 33 黄色 = 0x21 34 蓝色 = 0x22 35 紫色 = 0x23 36 青色 = 0x24 */ void Console::printf(const char* _szText) { const char* szText = _szText; char byteColor = 0; //如果\n会替换成\r int indexLine = LineFromChar(-1);//取出当前行号 long lStart = 0; long lEnd = 0; GetSel(lStart, lEnd);//取得当前的光标位置 CString szStart; GetTextRange(lStart - 1, lEnd, szStart);//当前光标向后选择一位字符,并取出此字符 if (szStart == '\r' || szStart == "")//判断字符是否行头 { CPoint point = PosFromChar(lEnd); LineInfo info; memset(&info, 0, sizeof info); info.m_dwHead = lEnd; info.m_xPos = point.x; info.m_yPos = point.y; m_vecLineInfo.push_back(info);//保存行头的光标位置 } if (_szText[0] == '\x1E') { switch (_szText[1]) { case '\x1D': { m_CF.crTextColor = RGB(0, 0, 0); break; } case '\x1F': { m_CF.crTextColor = RGB(255, 0, 0); break; } case '\x20': { m_CF.crTextColor = RGB(0, 255, 0); break; } case '\x21': { m_CF.crTextColor = RGB(255, 255, 0); break; } case '\x22': { m_CF.crTextColor = RGB(0, 0, 255); break; } case '\x23': { m_CF.crTextColor = RGB(199, 0, 106); break; } case '\x24': { m_CF.crTextColor = RGB(0, 255, 255); break; } default: { m_CF.crTextColor = RGB(165, 165, 165); break; } } szText = _szText+2; SetSelectionCharFormat(m_CF); } ReplaceSel(szText); m_CF.crTextColor = RGB(165, 165, 165);//重置回原始颜色 SetSelectionCharFormat(m_CF); LineInfo* pInfo = &(m_vecLineInfo[indexLine]); //尝试取出控件尽头x轴末尾是否有字符存在 GetSel(lStart, lEnd);//取得当前的光标位置 GetTextRange(lEnd - 1, lEnd, szStart);//当前光标向后选择一位字符,并取出此字符 bool bIsEnter = false; if (szStart == '\r') { //已经完成换行操作 bIsEnter = true; pInfo->m_dwTail = lEnd - 1; GetTextRange(pInfo->m_dwHead, pInfo->m_dwTail, szStart);//取出本行内容 CPoint point = PosFromChar(pInfo->m_dwTail); pInfo->m_dwMaxPixl = point.x-1;//此行文本的最大像素 int len = szStart.GetLength(); int iFit = 0; CSize size = { 0, 0 }; if (pInfo->m_pDx) { delete [] pInfo->m_pDx; pInfo->m_pDx = NULL; } pInfo->m_pDx = new int[len]; pInfo->m_dwStrLen = len; ::GetTextExtentExPoint(m_pDC->GetSafeHdc(), szStart, len, point.x, &iFit, pInfo->m_pDx, &size);//计算出本行每个字符所占的像素,并把每个字符的像素存在m_pDx数组里面 pInfo->m_yPos = indexLine * m_iLineHeight; } else { pInfo->m_dwTail = lEnd; CPoint point = PosFromChar(pInfo->m_dwTail); pInfo->m_dwMaxPixl = point.x;//此行文本的最大像素 } //重置水平滚动条信息 if (pInfo->m_dwMaxPixl > (DWORD)m_rcWnd.Width() && pInfo->m_dwMaxPixl > m_pixCurMaxChars) { m_pixCurMaxChars = pInfo->m_dwMaxPixl; m_infoHScroll.nMax = m_pixCurMaxChars; m_pHScroll->SetScrollInfo(m_infoHScroll); } if (bIsEnter) { //已经完成换行操作 if (((indexLine + 1) * m_iLineHeight) > m_rcWnd.Height()) { m_infoVScroll.nMax = ((indexLine + 1) * m_iLineHeight); m_pVScroll->SetScrollInfo(m_infoVScroll); m_pVScroll->SetScrollPos(m_infoVScroll.nMax - m_rcWnd.Height());//向下滚动 } LineScroll(1); } } void Console::split(const char* _szText) { const char* szCurText = _szText; const char* szOldText = _szText; char* szPreText = NULL; int len = NULL; const char* szClrText = NULL; if (_szText[0] != '\x1E') { bool bIsFined = false; while ((szClrText = strchr(szCurText, '\x1E'))) { bIsFined = true; len = szClrText - szOldText; szPreText = new char[len + 1]; szPreText[len] = 0; memcpy(szPreText, szOldText, len); Console::printf(szPreText); delete[]szPreText; szCurText = szClrText + 1; szOldText = szClrText; } if (bIsFined) { if(szOldText)Console::printf(szOldText); } else { Console::printf(_szText); } } else { bool bIsFined = false; szCurText = _szText + 1; while ((szClrText = strchr(szCurText, '\x1E'))) { bIsFined = true; len = szClrText - szOldText; szPreText = new char[len + 1]; szPreText[len] = 0; memcpy(szPreText, szOldText, len); Console::printf(szPreText); delete[]szPreText; szCurText = szClrText + 1; szOldText = szClrText; } if (szOldText) { Console::printf(szOldText); } } } BEGIN_MESSAGE_MAP(Console, CRichEditCtrl) ON_NOTIFY_REFLECT(EN_SELCHANGE, &Console::OnEnSelchange) ON_NOTIFY_REFLECT(EN_MSGFILTER, &Console::OnEnMsgfilter) ON_WM_MOUSELEAVE() ON_WM_VSCROLL() END_MESSAGE_MAP() void Console::OnEnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { SELCHANGE* pSelChange = reinterpret_cast<SELCHANGE*>(pNMHDR); // TODO: 控件将不发送此通知,除非您重写 // CRichEditCtrl::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送 // 到该控件,同时将 ENM_SELCHANGE 标志“或”运算到 lParam 掩码中。 // TODO: 在此添加控件通知处理程序代码 int iLineIndex = -1; iLineIndex = LineFromChar(pSelChange->chrg.cpMax); if (iLineIndex != -1 && iLineIndex < (int)m_vecLineInfo.size()) { CHARRANGE LineStartSel; LineInfo* pInfo = &m_vecLineInfo[iLineIndex]; switch (pSelChange->seltyp) { case 0://鼠标点击在某处文本的某个sel中 { //开始存储此行的选择sel起始位置 m_StartSel = pSelChange->chrg; break; } case CBN_EDITCHANGE://鼠标左键按住拖动选择文本 { //通过m_StartSel算出本行的选择起始位置 CPoint point = PosFromChar(m_StartSel.cpMin);//算出sel处于控件内坐标 int x = point.x; point.y = pInfo->m_yPos;//替换上本行的y坐标 LineStartSel.cpMin = CharFromPos(point);//算出本行起始位置 LineStartSel.cpMax = LineStartSel.cpMin; point = PosFromChar(LineStartSel.cpMin); if (point.x < x - 5) { //outputdebug_default("行号:%d 检测到起始位置异常,和原位差太远", iLineIndex); LineStartSel.cpMin = 0; LineStartSel.cpMax = 0; if (point.x > m_rcWnd.Width()) { m_pHScroll->SetScrollPos(point.x - m_rcWnd.Width());//通知滚动条 } else { m_pHScroll->SetScrollPos(0); } } if (pSelChange->chrg.cpMax > LineStartSel.cpMax) { //outputdebug_default("行号:%d 从左向右选择文本: %d", iLineIndex, pSelChange->chrg.cpMax); CString str; GetTextRange(pInfo->m_dwHead, pSelChange->chrg.cpMax, str); int len = str.GetLength(); if (--len > -1 && len < (int)pInfo->m_dwStrLen) { //outputdebug_default("行号:%d, 当前光标所占像素: %d", iLineIndex, pInfo->m_pDx[len]); int pix = pInfo->m_pDx[len]; if (pix > m_rcWnd.Width()) { //outputdebug_default("行号:%d, 当前光标所占像素超出控件长度: %d", iLineIndex, pix); m_pHScroll->SetScrollPos(pix - m_rcWnd.Width());//通知滚动条 } } else { if (--len > -1 && pInfo->m_dwStrLen == 0) { //此行末尾没有/r回车符 CPoint point = PosFromChar(pSelChange->chrg.cpMax); if (point.x > m_rcWnd.Width()) { m_pHScroll->SetScrollPos(point.x - m_rcWnd.Width());//通知滚动条 } else { m_pHScroll->SetScrollPos(0); } } else { int i = 0; } } } else if (pSelChange->chrg.cpMax != pInfo->m_dwHead) { //outputdebug_default("行号:%d 从右向左选择文本: head:%d start:%d, min:%d max:%d", iLineIndex, pInfo->m_dwHead, LineStartSel.cpMax, pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); if (pSelChange->chrg.cpMin == pInfo->m_dwHead) { m_pHScroll->SetScrollPos(0); } } else { //outputdebug_default("x行号:%d 从右向左选择文本: head:%d start:%d, min:%d max:%d", iLineIndex, pInfo->m_dwHead, LineStartSel.cpMax, pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); if (pInfo->m_dwHead == pSelChange->chrg.cpMax)//本行头部和上一行行尾重复,定位回上一行 { if (--iLineIndex > -1) { pInfo = &m_vecLineInfo[iLineIndex]; CString str; GetTextRange(pInfo->m_dwHead, pSelChange->chrg.cpMax, str); int len = str.GetLength(); //outputdebug_default("行号:%d, 当前光标所占像素: %d len:%d", iLineIndex, pInfo->m_pDx[len-2], len); if (--len > -1 && len <= (int)pInfo->m_dwStrLen) { int pix = pInfo->m_pDx[len-1]; if (pix > m_rcWnd.Width()) { //outputdebug_default("行号:%d, 当前光标所占像素超出控件长度: %d", iLineIndex, pix); //m_pHScroll->SetScrollPos(pix - m_rcWnd.Width());//通知滚动条 } } } } } break; } } } //outputdebug_default("min:%d max:%d", pSelChange->chrg.cpMin, pSelChange->chrg.cpMax); *pResult = 0; } void Console::OnEnMsgfilter(NMHDR* pNMHDR, LRESULT* pResult) { MSGFILTER* pMsgFilter = reinterpret_cast<MSGFILTER*>(pNMHDR); // TODO: 控件将不发送此通知,除非您重写 // CRichEditCtrl::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送 // 到该控件,同时将 ENM_KEYEVENTS 或 ENM_MOUSEEVENTS 标志 //“或”运算到 lParam 掩码中。 // TODO: 在此添加控件通知处理程序代码 switch(pMsgFilter->msg) { case WM_MOUSEMOVE: { /* if (pMsgFilter->wParam == MK_LBUTTON) { int xPos = GET_X_LPARAM(pMsgFilter->lParam); int yPos = GET_Y_LPARAM(pMsgFilter->lParam); //outputdebug_default("x: %d, y:%d",xPos, yPos); if (m_bIsCapture) { if (xPos > m_iStartPos_x) { //outputdebug_default("正在从左向右选择文本."); } else { //outputdebug_default("正在从右向左选择文本."); } m_iPrePos_x = xPos; } }*/ if (!m_bIsTrack) { m_bIsTrack = TRUE; TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1;// 鼠标在按钮上停留超过 1ms ,才认为成功 _TrackMouseEvent(&tme); } break; } case WM_LBUTTONDOWN: { if (pMsgFilter->wParam == MK_LBUTTON) { int xPos = GET_X_LPARAM(pMsgFilter->lParam); int yPos = GET_Y_LPARAM(pMsgFilter->lParam); m_iPrePos_x = xPos; m_iStartPos_x = xPos; m_bIsCapture = TRUE; //outputdebug_default("x: %d, y:%d", xPos, yPos); } break; } case WM_LBUTTONUP: { if (pMsgFilter->wParam == MK_LBUTTON) { m_bIsCapture = FALSE; } break; } } *pResult = 0; } void Console::OnMouseLeave() { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bIsTrack = FALSE; ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); CRichEditCtrl::OnMouseLeave(); } void Console::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CRichEditCtrl::OnVScroll(nSBCode, nPos, pScrollBar); }
07-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值