⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visualkb.cpp

📁 是一个用C++编写的图形编辑器!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <afxwin.h>
#include "VisualKB.h"


CMyApp myApp;

/////////////////////////////////////////////////////////////////////////
// CMainWindow message map and member functions

BEGIN_MESSAGE_MAP (CMainWindow, CWnd)
    ON_WM_CREATE ()
    ON_WM_PAINT ()
	ON_WM_SIZE ()
	ON_WM_DESTROY( )
    ON_WM_SETFOCUS ()
    ON_WM_KILLFOCUS ()
    ON_WM_SETCURSOR ()
    ON_WM_LBUTTONDOWN ()
	ON_WM_MOUSEMOVE ()
    ON_WM_KEYDOWN ()
	ON_WM_KEYUP ()
    ON_WM_CHAR ()
	ON_COMMAND(ID_FILE_EXIT, OnFileExit)
	ON_COMMAND(ID_EDIT_COPY,OnEditCopy)
	ON_COMMAND(ID_EDIT_PASTE,OnEditPaste)
	ON_COMMAND(ID_EDIT_DELETE,OnEditDelete)
	ON_COMMAND(ID_EDIT_CUT,OnEditCut)
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
	ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, OnUpdateEditDelete)
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
END_MESSAGE_MAP ()

/////////////////////////////////////////////////////////////////////////
// CMyApp member functions
BOOL CMyApp::InitInstance ()
{
    m_pMainWnd = new CMainWindow;
    m_pMainWnd->ShowWindow (m_nCmdShow);
    m_pMainWnd->UpdateWindow ();
    return TRUE;
}

CMainWindow::CMainWindow ()
{
 	// Load the arrow cursor and the I-beam cursor and save their handles.
	//
    m_hCursorArrow = AfxGetApp ()->LoadStandardCursor (IDC_ARROW);
    m_hCursorIBeam = AfxGetApp ()->LoadStandardCursor (IDC_IBEAM);//Standard text-insertion cursor

	//
	// Register a WNDCLASS.
	//
 	CString strWndClass = AfxRegisterWndClass (
        0,
        NULL,
        (HBRUSH)(COLOR_3DFACE+1),
        AfxGetApp ()->LoadStandardIcon (IDI_WINLOGO)
		);

	//
	// Create a window.
	//
    CreateEx (0, strWndClass, _T ("Visual Keyboard"),
        WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_THICKFRAME ,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL,NULL);
	CMenu menu;
	menu.LoadMenu(IDR_MAINFRAME);
	SetMenu(&menu);
	menu.Detach();
}

int CMainWindow::OnCreate (LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate (lpCreateStruct) == -1)
        return -1;
    
	//
	// Initialize member variables whose values are dependent upon screen metrics.
	//
    CClientDC dc (this);
  	font.CreatePointFont(240, "Courier New");
	dc.SelectObject(&font);
    TEXTMETRIC tm;
	//使用属性设备描述表接收当前字体的计量单位信息。
    dc.GetTextMetrics (&tm);//Retrieves the metrics for the current font using the attribute device context
    m_cxChar = tm.tmAveCharWidth;
    m_cyChar = tm.tmHeight;
    m_cyLine = tm.tmHeight + tm.tmExternalLeading;
	m_nLineCount = 1;
	m_nCurrentRow = 1;
	m_nCurrentCol = 0;
//	b_CaretHide=false;
	b_Selected=false;
    return 0;
}

void CMainWindow::PostNcDestroy ()
{
    delete this;
}

void CMainWindow::OnSize( UINT nType, int cx, int cy )
{
	CClientDC dc(this);
	dc.SelectObject(&font);

    GetClientRect(&m_rcTextBoxBorder);
    m_rcTextBox = m_rcTextBoxBorder;  
    m_rcTextBox.InflateRect (-2, -2);//inflates CRect by moving its sides away from its center. m_rcTextBox(18,18,462,38)
    

    m_ptTextOrigin.x = m_rcTextBox.left + max(2,::GetSystemMetrics(SM_CXBORDER));
    m_ptTextOrigin.y = m_rcTextBox.top + m_cyChar / 9;

  	m_ptCaretPos = m_ptTextOrigin;  //插入符位置
    m_nLineLimit =m_rcTextBox.Width() - m_cxChar;//一行最大距离

	m_EditBox.SetRect(0,0,0,0);
//	m_EditBox.SetRect(m_ptTextOrigin.x,m_ptTextOrigin.y,m_ptTextOrigin.x,m_cyLine);
	Adjust(m_strInputText);
	dc.ExtTextOut( m_ptTextOrigin.x, m_ptTextOrigin.y, ETO_OPAQUE , m_rcTextBox, "",NULL ); 
	dc.DrawText( (char*)m_strInputText, &m_rcTextBox, DT_LEFT | DT_WORDBREAK );	
}


void CMainWindow::OnPaint ()
{
    CPaintDC dc (this);
	dc.SelectObject(&font);
	dc.DrawEdge (m_rcTextBoxBorder, EDGE_SUNKEN, BF_RECT );//BF_LEFT
	dc.SetBkColor ((COLORREF)RGB(255,255,255));
	dc.ExtTextOut( m_ptTextOrigin.x, m_ptTextOrigin.y, ETO_OPAQUE , m_rcTextBox, "",NULL ); 
	Adjust(m_strInputText);
	dc.DrawText( (char*)m_strInputText, &m_rcTextBox, DT_LEFT | DT_WORDBREAK );	
}

//使用插入符的窗口应该在接收到输入焦点时创建插入符
void CMainWindow::OnSetFocus (CWnd* pWnd)//先于OnPaint调用
{
	//
	// Show the caret when the VisualKB window receives the input focus.
	//这个函数为系统插字符创建一个实心矩形,并声明对插字符的所有权。指定了插字符的宽度,高度
//	GetSystemMetrics(SM_CXBORDER)值为1
	int i=	::GetSystemMetrics (SM_CXBORDER);
    CreateSolidCaret (max (2, ::GetSystemMetrics (SM_CXBORDER)), m_cyChar);//用20或m_cxChar调式
    SetCaretPos (m_ptCaretPos);//这个函数设置插字符的位置。
    ShowCaret ();//这个函数在屏幕上当前插字符位置显示插字符。一旦被显示,则插字符就开始自动闪烁。
}

//在失去输入焦点时销毁插入符
void CMainWindow::OnKillFocus (CWnd* pWnd)
{
	//
	// Hide the caret when the VisualKB window loses the input focus.
	//
    HideCaret ();
	//Retrieves the client coordinates of the caret’s current position and returns them as a CPoint. 
    m_ptCaretPos = GetCaretPos ();
	//The DestroyCaret function destroys the caret's current shape, frees the caret from the window, and removes the caret from the screen. 
    ::DestroyCaret ();
}

BOOL CMainWindow::OnSetCursor (CWnd* pWnd, UINT nHitTest, UINT message)
{
	//在文本窗口光标变为I形 ,在其它地方变为箭头形
    if (nHitTest == HTCLIENT) {
        DWORD dwPos = ::GetMessagePos ();
        CPoint point (LOWORD (dwPos), HIWORD (dwPos));
        ScreenToClient (&point);
        ::SetCursor (m_rcTextBox.PtInRect (point) ?
            m_hCursorIBeam : m_hCursorArrow);
		return true;
    }
    return CWnd::OnSetCursor (pWnd, nHitTest, message);
}



void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
{
	HideCaret( );
	if(b_Selected){
		b_Selected=false;
		m_EditBox.SetRect(0,0,0,0);
		CClientDC dc(this);
		dc.SelectObject(&font);
		dc.SetBkColor ((COLORREF)RGB(255,255,255));
		dc.SetTextColor((COLORREF)RGB(0,0,0));
		dc.ExtTextOut( m_ptTextOrigin.x, m_ptTextOrigin.y, ETO_OPAQUE , m_rcTextBox, "",NULL );
		dc.DrawText( (char*)m_strInputText, &m_rcTextBox, DT_LEFT | DT_WORDBREAK );
	}
    if (m_rcTextBox.PtInRect (point)) {
		GetPositionFromPoint(point);//根据点point确定当前位置
		m_nPrevRow = m_nCurrentRow;
		m_nPrevCol = m_nCurrentCol;
		CPoint point1;
		point1= GetPointFromPosition();
		m_EditBox.left = point1.x;
		SetCaretPos(point1);
   }
	ShowCaret ();
}


void CMainWindow::OnMouseMove( UINT nFlags, CPoint point )//???
{
	if (nFlags == MK_LBUTTON ){
		m_ptCaretPos = GetCaretPos();
		HideCaret ();
		GetPositionFromPoint(point);
		CPoint point1;
		point1 = GetPointFromPosition();
		if( m_nCurrentCol > m_nPrevCol)
		{
			b_Selected=true;
			m_EditBox.right = point1.x;
			m_EditBox.top = m_ptTextOrigin.y + (m_nCurrentRow - 1) * m_cyChar;
			m_EditBox.bottom = m_EditBox.top + m_cyChar;
			cstring str;
			int nBeginPos;
			if(m_nCurrentRow == m_nPrevRow)//鼠标点击在同一行
			{
				if(m_nLineCount == 1)//只有一行
					str = m_strInputText.SubString(m_nPrevCol,m_nCurrentCol - m_nPrevCol);
				else{
					nBeginPos = m_strInputText.Find(m_nCurrentRow - 1,'\n');
					str = m_strInputText.SubString(nBeginPos + m_nPrevCol,m_nCurrentCol - m_nPrevCol);
				}
				CClientDC dc(this);
				dc.SelectObject(&font);

				dc.SetBkColor ((COLORREF)RGB(0,0,0));
				dc.SetTextColor((COLORREF)RGB(255,255,255));
				dc.DrawText( (char*)str, &m_EditBox, DT_LEFT );
			}
		}
		SetCaretPos(GetPointFromPosition());
		ShowCaret ();
	}
}




void CMainWindow::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags)
{
 	// Move the caret when the left, right, Home, or End key is pressed.
	//
	CClientDC dc(this);
	dc.SelectObject(&font);

    switch (nChar) {

    case VK_LEFT:
		if(m_nCurrentRow == 1){// in the first row
			if(m_nCurrentCol > 0)
				m_nCurrentCol--;
			else
	      		m_nCurrentRow = 1;
		}	
		else{
			if (m_nCurrentCol > 0) 
          		m_nCurrentCol--;
			else{
				m_nCurrentRow--;
				if(m_nCurrentRow == 1)
					m_nCurrentCol = m_strInputText.Find(m_nCurrentRow,'\n') - 1;
				else
					m_nCurrentCol = m_strInputText.Find(m_nCurrentRow,'\n') - m_strInputText.Find(m_nCurrentRow - 1,'\n') - 1;
			}
		}
		SetCaretPos (GetPointFromPosition());
        break;

    case VK_RIGHT:
		int nBeginPos,nEndPos;
		if(m_nCurrentRow == m_nLineCount){//in the last row
			
			if(m_nLineCount == 1)
				nBeginPos = 0;
			else
				nBeginPos = m_strInputText.Find(m_nCurrentRow - 1,'\n');
			cstring str=m_strInputText.SubString(nBeginPos,m_strInputText.Length()-nBeginPos);
			if(m_nCurrentCol < str.Length()){
				m_nCurrentCol++;
				SetCaretPos (GetPointFromPosition());	   //再根据行、列修正点
			}
		}
		else{//不在最后一行
			if(m_nCurrentRow == 1)//在第一行
			{
				nBeginPos = 0;
				nEndPos = m_strInputText.Find(m_nCurrentRow ,'\n');
			}
			else {
				nBeginPos = m_strInputText.Find(m_nCurrentRow - 1,'\n');
				nEndPos = m_strInputText.Find(m_nCurrentRow ,'\n');
			}
			cstring str=m_strInputText.SubString(nBeginPos,nEndPos - nBeginPos -1);
			if(m_nCurrentCol < str.Length())
				m_nCurrentCol++;
			else{
				m_nCurrentRow++;
				m_nCurrentCol = 0;
			}
			SetCaretPos (GetPointFromPosition());
		}
        break;
	case VK_DELETE:
		if(m_nLineCount == 1){
			if (m_nCurrentCol < m_strInputText.Length())
				m_strInputText.Delete(m_nCurrentCol);
		}
		else{//不止一行
			int nBeginPos = 0;
			if(m_nCurrentRow > 1){//不在第一行
				nBeginPos= m_strInputText.Find(m_nCurrentRow - 1,'\n');
				m_strInputText.Delete( nBeginPos + m_nCurrentCol + 1);
			}
			else{
				m_strInputText.Delete(  m_nCurrentCol);
				m_nCurrentCol = 0;
			}
			//	m_nCurrentCol = 0;
			//	m_nCurrentRow++;
			//	m_strInputText.Delete(m_strInputText.Find(m_nCurrentRow - 1,'\n') + m_nCurrentCol);
			
		}
		HideCaret ();
		dc.ExtTextOut( m_ptTextOrigin.x, m_ptTextOrigin.y, ETO_OPAQUE , m_rcTextBox, "",NULL );
		Adjust(m_strInputText);
		dc.DrawText( (char*)m_strInputText, &m_rcTextBox, DT_LEFT | DT_WORDBREAK );
		SetCaretPos (GetPointFromPosition());
		ShowCaret ();
        break;

	case VK_DOWN:
		if(m_nCurrentRow < m_nLineCount){
			CPoint point=GetPointFromPosition();//从当前行、列得到点

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -