Visual KB「MFC Windowsプログラム設計例」
11521 ワード
//filename:VisualKB.h
#define MAX_STRING 12
class CMyApp:public CWinApp{
public:
virtual BOOL InitInstance();
};
class CMainWindow:public CWnd
{
protected:
int m_cxChar; //Average character width
int m_cyChar; //Character height
int m_cyLine; //Vertical line spacing in message box
int m_nTextPos; //Index of current character for tabbed output
int m_nTabStops[7]; //Tab stop locations for tabbed output
int m_nTextLimit; //Maximum width of text in text box
int m_nMsgPos; //Current position in m_strMessages array
HCURSOR m_hCursorArrow; //Handle of arrow cursor
HCURSOR m_hCursorIBeam; //Handle of I-Beam cursor
CPoint m_ptTextOrigin; //Origin for drawing input text
CPoint m_ptHeaderOrigin; //Origin for drawing header text
CPoint m_ptUpperMsgOrigin; //Origin of first line in message box
CPoint m_ptLowerMsgOrigin; //Origin of first line in message box
CPoint m_ptCaretPos; //Current caret position
CRect m_rcTextBox; //Coordinates of text box
CRect m_rcTextBoxBorder; //Coordinates of text box border
CRect m_rcMsgBoxBorder; //Coordinates of message box border
CRect m_rcScroll; //Coordinates of scroll rectangle
CString m_strInputText; //Input text
CString m_stringMessages[MAX_STRING]; //Array Of message strings
public:
CMainWindow();
protected:
int GetNearestPos(CPoint point);
void PositionCaret(CDC * pDC=NULL);
void DrawInputText(CDC * pDC);
void ShowMessage(LPCTSTR pszMessage,UINT nChar,UINT nRepCnt,
UINT nFlags);
void DrawMessageHeader(CDC * pDC);
void DrawMessage(CDC * pDC);
void DrawMessages(CDC * pDC);
protected:
virtual void PostNcDestroy();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint ();
afx_msg void OnSetFocus(CWnd* pWnd); //old wnd
afx_msg void OnKillFocus(CWnd* pWnd); //new wnd
afx_msg BOOL OnSetCursor(CWnd *pWnd,UINT nHitTest,UINT message);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags);
DECLARE_MESSAGE_MAP()
};
//filename:VisualKB.cpp
#include <afxwin.h>
#include "VisualKB.h"
CMyApp myApp;
//CMyApp member functions
BOOL CMyApp ::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd ->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/////////////////////////////////////////////////////////
//CMainWindow message map and number functiosn
BEGIN_MESSAGE_MAP(CMainWindow,CWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_SETCURSOR()
ON_WM_LBUTTONDOWN()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_SYSKEYDOWN()
ON_WM_SYSKEYUP()
ON_WM_CHAR()
ON_WM_SYSCHAR()
END_MESSAGE_MAP()
CMainWindow::CMainWindow()
{
m_nTextPos = 0;
m_nMsgPos = 0;
m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
m_hCursorIBeam = AfxGetApp()->LoadStandardCursor(IDC_IBEAM);
//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,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL
);
}
int CMainWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CWnd::OnCreate(lpCreateStruct)==-1)
{
return -1;
}
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
m_cxChar = tm.tmAveCharWidth;
m_cyChar = tm.tmHeight;
m_cyLine = tm.tmHeight + tm.tmExternalLeading;
m_rcTextBoxBorder.SetRect(16,16,(m_cxChar*64)+16,
((m_cyChar*3)/2)+16
);
m_rcTextBox = m_rcTextBoxBorder;
m_rcTextBox.InflateRect(-2,-2);
m_rcMsgBoxBorder.SetRect(16, (m_cyChar*4)+16,
(m_cxChar * 64)+16,(m_cyLine * MAX_STRING)+(m_cyChar * 6)+16
);
m_rcScroll.SetRect(m_cxChar + 16,(m_cyChar * 4)+16,
(m_cxChar * 64)+16, (m_cyLine * MAX_STRING )
+ (m_cyChar * 6) + 16
);
m_ptTextOrigin.x = m_cxChar + 16;
m_ptTextOrigin.y = (m_cyChar /4 )+16;
m_ptCaretPos = m_ptTextOrigin;
m_nTextLimit = (m_cxChar * 63)+16;
m_ptHeaderOrigin.x = m_cxChar + 16;
m_ptHeaderOrigin.y = (m_cyChar * 3)+16;
m_ptUpperMsgOrigin.x = m_cxChar + 16;
m_ptUpperMsgOrigin.y = m_cyChar * 5 + 16;
m_ptLowerMsgOrigin.x = m_cxChar + 16;
m_ptLowerMsgOrigin.y = (m_cyChar * 5)
+ m_cyLine * (MAX_STRING -1)+16;
m_nTabStops[0] = (m_cxChar * 24) + 16;
m_nTabStops[1] = (m_cxChar * 30) + 16;
m_nTabStops[2] = (m_cxChar * 36) + 16;
m_nTabStops[3] = (m_cxChar * 42) + 16;
m_nTabStops[4] = (m_cxChar * 46) + 16;
m_nTabStops[5] = (m_cxChar * 50) + 16;
m_nTabStops[6] = (m_cxChar * 54) + 16;
CRect rect(0,0,m_rcMsgBoxBorder.right + 16,
m_rcMsgBoxBorder.bottom + 16);
CalcWindowRect(&rect);
SetWindowPos(NULL,0,0,rect.Width() ,rect.Height(),
SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
return 0;
}
void CMainWindow::PostNcDestroy()
{
delete this;
}
void CMainWindow::OnPaint()
{
CPaintDC dc(this);
dc.DrawEdge(m_rcTextBoxBorder,EDGE_SUNKEN,BF_RECT);
dc.DrawEdge(m_rcMsgBoxBorder,EDGE_SUNKEN,BF_RECT);
DrawInputText(&dc);
DrawMessageHeader(&dc);
DrawMessage(&dc);
}
void CMainWindow::OnSetFocus(CWnd* pWnd){
CreateSolidCaret(max(2,::GetSystemMetrics(SM_CXBORDER)),
m_cyChar);
SetCaretPos(m_ptCaretPos);
ShowCaret();
}
void CMainWindow::OnKillFocus(CWnd* pWnd){
HideCaret();
m_ptCaretPos = GetCaretPos();
::DestroyCaret();
}
BOOL CMainWindow::OnSetCursor(CWnd *pWnd,UINT nHitTest,UINT message)
{
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)
{
if(m_rcTextBox.PtInRect(point))
{
m_nTextPos = GetNearestPos(point);
PositionCaret();
}
}
void CMainWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_KEYDOWN"),nChar,nRepCnt,nFlags);
switch (nChar)
{
case VK_LEFT:
if(m_nTextPos !=0){
m_nTextPos --;
PositionCaret();
}
break;
case VK_RIGHT:
if(m_nTextPos != m_strInputText.GetLength())
{
m_nTextPos++;
PositionCaret();
}
break;
case VK_HOME:
m_nTextPos = 0;
PositionCaret();
break;
case VK_END:
m_nTextPos = m_strInputText.GetLength();
PositionCaret();
break;
}
}
void CMainWindow::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_CHAR"),nChar,nRepCnt,nFlags);
CClientDC dc(this);
switch (nChar)
{
case VK_ESCAPE:
case VK_RETURN:
m_strInputText.Empty();
m_nTextPos = 0;
break;
case VK_BACK:
if(m_nTextPos != 0)
{
m_strInputText = m_strInputText.Left(m_nTextPos-1)
+m_strInputText.Right(m_strInputText.GetLength()
- m_nTextPos);
m_nTextPos--;
}
break;
default:
if((nChar>=0) && (nChar <= 31))
return;
if(m_nTextPos == m_strInputText.GetLength())
{
m_strInputText += nChar;
m_nTextPos ++;
}
else
m_strInputText.SetAt(m_nTextPos++,nChar);
CSize size = dc.GetTextExtent(m_strInputText,
m_strInputText.GetLength());
if((m_ptTextOrigin.x + size.cx) > m_nTextLimit)
{
m_strInputText = nChar;
m_nTextPos = 1;
}
break;
}
HideCaret();
DrawInputText(&dc);
PositionCaret(&dc);
ShowCaret();
}
void CMainWindow::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_KEYUP"),nChar,nRepCnt,nFlags);
CWnd::OnKeyUp(nChar,nRepCnt,nFlags);
}
void CMainWindow::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_SYSKEYDOWN"),nChar,nRepCnt,nFlags);
CWnd::OnSysKeyDown(nChar,nRepCnt,nFlags);
}
void CMainWindow::OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_SYSCHAR"),nChar,nRepCnt,nFlags);
CWnd::OnSysChar(nChar,nRepCnt,nFlags);
}
void CMainWindow::OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
ShowMessage(_T("WM_SYSKEYUP"),nChar,nRepCnt,nFlags);
CWnd::OnSysKeyUp(nChar,nRepCnt,nFlags);
}
void CMainWindow :: PositionCaret(CDC * pDC/* =NULL */)
{
BOOL bRelease = FALSE;
if(pDC == NULL){
pDC = GetDC();
bRelease = true;
}
CPoint point = m_ptTextOrigin;
CString string = m_strInputText.Left(m_nTextPos);
point.x += (pDC ->GetTextExtent(string,string.GetLength())).cx;
SetCaretPos(point);
if(bRelease) ReleaseDC(pDC);
}
int CMainWindow::GetNearestPos(CPoint point)
{
if(point.x <= m_ptTextOrigin.x) return 0;
CClientDC dc(this);
int nLen = m_strInputText.GetLength();
if(point.x >= (m_ptTextOrigin.x+dc.GetTextExtent(m_strInputText,nLen).cx)) return nLen;
int i=0;
int nPrevChar = m_ptTextOrigin.x;
int nNextChar = m_ptTextOrigin.x;
while(nNextChar < point.x){
i++;
nPrevChar = nNextChar;
nNextChar = m_ptTextOrigin.x +
dc.GetTextExtent(m_strInputText.Left(i),i).cx;
}
return point.x - nPrevChar < nNextChar - point.x ? i-1 : i ;
}
void CMainWindow::DrawInputText(CDC * pDC)
{
pDC ->ExtTextOut(m_ptTextOrigin.x,m_ptTextOrigin.y,
ETO_OPAQUE,m_rcTextBox,m_strInputText,NULL);
}
void CMainWindow::ShowMessage(LPCTSTR pszMessage,UINT nChar,UINT nRepCnt, UINT nFlags)
{
CString string;
string.Format(_T("%s\t %u\t %u\t %u\t %u\t %u\t %u\t %u"),
pszMessage,nChar,nRepCnt,nFlags & 0xFF,
(nFlags >> 8 ) & 0x01,
(nFlags >> 13) & 0x01,
(nFlags >> 14) & 0x01,
(nFlags >> 15) & 0x01
);
ScrollWindow(0,-m_cyLine,&m_rcScroll);
ValidateRect(m_rcScroll);
CClientDC dc(this);
dc.SetBkColor((COLORREF)::GetSysColor(COLOR_3DFACE));
m_stringMessages[m_nMsgPos] = string;
dc.TabbedTextOut(m_ptLowerMsgOrigin.x,m_ptLowerMsgOrigin.y,
m_stringMessages[m_nMsgPos],m_stringMessages[m_nMsgPos].GetLength(),
sizeof(m_nTabStops),m_nTabStops , m_ptLowerMsgOrigin.x);
if(++m_nMsgPos == MAX_STRING) m_nMsgPos = 0;
}
void CMainWindow ::DrawMessageHeader(CDC * pDC)
{
static CString string = _T("Message\tChar\tRep\tScan\tExt\tCan\tPrv\tTran");
pDC->SetBkColor((COLORREF)::GetSysColor(COLOR_3DFACE));
pDC->TabbedTextOut(m_ptHeaderOrigin.x,m_ptHeaderOrigin.y,
string,string.GetLength(),sizeof(m_nTabStops),m_nTabStops,m_ptHeaderOrigin.x);
}
void CMainWindow::DrawMessage(CDC * pDC)
{
int nPos = m_nMsgPos;
pDC->SetBkColor((COLORREF)::GetSysColor(COLOR_3DFACE));
for(int i=0;i<MAX_STRING;i++){
pDC->TabbedTextOut(m_ptUpperMsgOrigin.x,
m_ptUpperMsgOrigin.y + m_cyLine*i,
m_stringMessages[nPos],
m_stringMessages[nPos].GetLength(),
sizeof(m_nTabStops),m_nTabStops,m_ptUpperMsgOrigin.x);
if(++nPos == MAX_STRING) nPos = 0;
}
}