请问谁可以告诉我你的MFC程序有什么问题? [英] Please who can tell me what is wrong with yhis my MFC program?

查看:58
本文介绍了请问谁可以告诉我你的MFC程序有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是该应用程序无法识别SHIFT t(即)CAPITAL T.





当我尝试时奇怪的是在我的mfc应用程序中输入大写字母T没有任何反应。如果我使用Caps Lock它可以工作,但Shift t不起作用。最初我认为我的键盘出现故障,但当我发现Shift t在我的系统中的每个其他应用程序中都有效时,我开始想知道为什么。



我尝试调试应用程序,通过查找错误,调试显示我的应用程序的视图类/对象在按下shift t键时没有收到任何OnChar(WM_CHAR)消息。这不是世界上最伟大的奇迹。请问可能是什么原因以及可以解决的问题。如果你想知道,我的应用程序会响应所有其他角色和角色组合吗?





好​​的,这里有关于该应用程序的有用信息。

1.我的文档对象(以及其他)私有数据成员:TableFigure * m_pEditTableBox(通过调用可加入:TableFigure * GetEditTable();

2. TableFigure m_pEditTableBox,拥有(以及其他)私有数据成员:Table * m_pTable(可通过调用来访问:void Table * GetTable();

3.Table * m_pTable(以及其他)数据成员:TCell * m_ptcell(可通过调用来访问

TCell * GetEditCell();

4. TCell * m_ptcell等数据成员:TableTextFigure * m_pEditText(可通过调用TableTextFigure * GetEditTableText访问) ();

5. TableTextFigure继承TextFigure;



The problem is that the app doesn't recognise SHIFT t (i.e) CAPITAL T.


Strangely enough when I try to type a capital T in my mfc app nothing happens. If I use Caps Lock it works, but Shift t doesn't work. Initially I thought my keyboard had become faulty, but when I discovered that Shift t works in every other app in my system I started to wonder why.

I try to debug the app, by to find the error, debugging shows that my app's view class/object doesnt receive any OnChar (WM_CHAR) message when shift t keys are depressed. Isn't this the greatest wonder in the world. Please what can be the cause and what can be the solution. In case you are wondering, my app responds to every other characters and character combination?


Okay here are useful information about the app.
1. My document object has (among others) a private data member : TableFigure *m_pEditTableBox ( acceesible by calling : TableFigure * GetEditTable();
2. TableFigure m_pEditTableBox, has (among others),a private data member: Table *m_pTable (accessible by calling: void Table *GetTable();
3.Table *m_pTable has (among others) a data member: TCell *m_ptcell (accessible by calling
TCell *GetEditCell();
4. TCell *m_ptcell has among others, a data member: TableTextFigure *m_pEditText ( accessible by calling TableTextFigure *GetEditTableText();
5. TableTextFigure inherits TextFigure;

#pragma once
#include "..\\Caret.h"
#include "..\\Color.h"
#include "..\\MyFont.h"
#include "Figure.h"

typedef CArray<int> IntArray;
enum KeyboardState {KS_INSERT, KS_OVERWRITE};
enum TextDirection {LEFT_TO_RIGHT,TOP_TO_BOTTOM,BOTTOM_TO_TOP};
enum TextAlignment {TOP_LEFT,TOP_CENTRE,TOP_RIGHT,MIDDLE_LEFT,MIDDLE_CENTRE,MIDDLE_RIGHT,BOTTOM_LEFT,BOTTOM_CENTRE,BOTTOM_RIGHT};

class TextFigure: public Figure
{
  public:
    TextFigure();
    TextFigure(const Color& color, const CPoint& ptMouse,
               const MyFont& font, CDC* pDC);

    TextFigure(const TextFigure& text);
	Figure* Copy() const;

    void Serialize(CArchive& archive);

    BOOL Click(const CPoint& ptMouse);
    BOOL DoubleClick(const CPoint& ptMouse);
    BOOL Inside(const CRect& rcInside) const;

    void MoveOrModify(const CSize& szDistance);
    void Move(const CSize& szDistance);

    virtual BOOL KeyDown(UINT uChar, CDC* pDC);
    virtual void CharDown(UINT uChar, CDC* pDC,KeyboardState eKeyboardState);
    void SetPreviousText(CDC* pDC);

    void Draw(CDC* pDC) const;
    CRect GetArea() const;

	BOOL PointInFigure(const CPoint &ptMouse) const;
	
    MyFont* GetFont() {return &m_font;}
    virtual void SetFont(const MyFont& font, CDC* pDC);
	int GetTextLength() { return m_stText.GetLength();}
	CString GetText() { return m_stText;}
	CString *GetActualText() { return &m_stText;}
	void SetText(CString stText){ m_stText = stText;}
	int *GetEditIndex() { return &m_iEditIndex;}
	//void SetEditIndex(int iIndex){ m_iEditIndex = iIndex;}
	void UpdateCaretArray(CDC *pDC) {GenerateCaretArray(pDC);}
	CPoint GetTextPoint() { return m_ptText;}
	CPoint *GetMyTextPoint() { return &m_ptText;}
	CPoint GetTextInfo(TEXTMETRIC *ptm);
	void MouseDown(const CPoint& ptMouse);
	BOOL PointInText(const CPoint &ptMouse);

	void SetTextDirection(TextDirection eDirection){ m_eTextDirection = eDirection;}
	TextDirection GetTextDirection() { return m_eTextDirection;}
	void SetTextAlignment(TextAlignment eAlignment){ m_eTextAlignment = eAlignment;}
	TextAlignment GetTextAlignment() { return m_eTextAlignment;}

  protected:
    void GenerateCaretArray(CDC* pDC);

  public:
    CRect GetCaretArea(KeyboardState eKeyboardState);
    HCURSOR GetCursor() const;

  private:
    enum {CREATE_TEXT, MOVE_TEXT, EDIT_TEXT, NONE_TEXT} m_eDragMode;

 protected:
    CPoint m_ptText;
    CSize m_szText;

    CString m_stText, m_stPreviousText;
    int m_iAverageWidth;

    MyFont m_font;
    int m_iEditIndex;
    IntArray m_caretArray;

	TextDirection m_eTextDirection;
	TextAlignment m_eTextAlignment;
};





相关文字图代码为:





Relevant Textfigure codes are:

BOOL TextFigure::KeyDown(UINT uChar, CDC* pDC)
{
  int iLength = m_stText.GetLength();

  switch (uChar)
  {
    case VK_HOME:
      if (m_iEditIndex > 0)
      {
        m_iEditIndex = 0;
      }
      break;

    case VK_END:
      if (m_iEditIndex < iLength)
      {
        m_iEditIndex = iLength;
      }
      break;

    case VK_LEFT:
      if (m_iEditIndex > 0)
      {
        --m_iEditIndex;
      }
      break;

    case VK_RIGHT:
      if (m_iEditIndex < m_stText.GetLength())
      {
        ++m_iEditIndex;
      }
      break;

    case VK_DELETE:
      if (m_iEditIndex < m_stText.GetLength())
      {
        m_stText.Delete(m_iEditIndex);
        GenerateCaretArray(pDC);
        return TRUE;
      }
      break;

    case VK_BACK:
      if (m_iEditIndex > 0)
      {
        --m_iEditIndex;
        m_stText.Delete(m_iEditIndex);
        GenerateCaretArray(pDC);
        return TRUE;
      }
      break;
  }

  return FALSE;
}


void TextFigure::CharDown(UINT uChar, CDC* pDC, KeyboardState eKeyboardState)
{

  if (m_iEditIndex == m_stText.GetLength())
  {
    m_stText.AppendChar((TCHAR) uChar);
  }

  else
  {
    switch (eKeyboardState)
    {
      case KS_INSERT:
        m_stText.Insert(m_iEditIndex, (TCHAR) uChar);
        break;

      case KS_OVERWRITE:
        m_stText.SetAt(m_iEditIndex, (TCHAR) uChar);
        break;
    }
  }

  ++m_iEditIndex;
  GenerateCaretArray(pDC);
}

void TextFigure::GenerateCaretArray(CDC* pDC)
{
  CFont cFont;
  cFont.CreateFontIndirect(m_font.PointsToMeters());
  CFont* pPrevFont = pDC->SelectObject(&cFont);

  TEXTMETRIC textMetric;
  pDC->GetTextMetrics(&textMetric);
  m_iAverageWidth = textMetric.tmAveCharWidth;

  if (!m_stText.IsEmpty())
  {
    m_szText = pDC->GetTextExtent(m_stText);
  }

  else
  {
    m_szText.SetSize(textMetric.tmAveCharWidth, textMetric.tmHeight);
  }
  //m_szText.SetSize(0, textMetric.tmHeight);  this is the original code
  
  int iWidth = 0, iSize = m_stText.GetLength();
  m_caretArray.SetSize(iSize + 1);

  for (int iIndex = 0; iIndex < iSize; ++iIndex)
  {
    CSize szChar = pDC->GetTextExtent
                        (m_stText.Mid(iIndex, 1));
    m_caretArray[iIndex] = iWidth;
    iWidth += szChar.cx;
  }

  m_caretArray[iSize] = m_szText.cx;
  pDC->SelectObject(pPrevFont);
}

CRect TextFigure::GetCaretArea(KeyboardState eKeyboardState)
{
	CDrawView *pView = CDrawView::GetView();
	CClientDC dc(pView);
	pView->OnPrepareDC(&dc);

	CFont cFont;
	cFont.CreateFontIndirect(m_font.PointsToMeters());
	CFont* pPrevFont = dc.SelectObject(&cFont);

	TEXTMETRIC tm;
	dc.GetTextMetrics(&tm);
	dc.SelectObject(pPrevFont);
	
	switch(m_eTextDirection)
	{
	case LEFT_TO_RIGHT:
		{
		  CPoint ptCaret(m_ptText.x + m_caretArray[m_iEditIndex],m_ptText.y);

		  switch (eKeyboardState)
		  {
			case KS_INSERT:
			  {
				CSize szCaret(1, m_szText.cy);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;

			  case KS_OVERWRITE:
			  {
				CSize szCaret(m_iAverageWidth, m_szText.cy);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;
		  }
		}
		break;
	case BOTTOM_TO_TOP:
		{
		  CPoint ptCaret(m_ptText.x ,m_ptText.y + m_caretArray[m_iEditIndex]);

		  switch (eKeyboardState)
		  {
			case KS_INSERT:
			  {
				CSize szCaret(m_szText.cy,1);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;

			  case KS_OVERWRITE:
			  {
				CSize szCaret(m_szText.cy,m_iAverageWidth);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;
		  }
		}
		break;
	case TOP_TO_BOTTOM:
		{
		  CPoint ptCaret(m_ptText.x - tm.tmHeight,m_ptText.y - m_caretArray[m_iEditIndex]);

		  switch (eKeyboardState)
		  {
			case KS_INSERT:
			  {
				CSize szCaret(m_szText.cy,1);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;

			  case KS_OVERWRITE:
			  {
				CSize szCaret(m_szText.cy,m_iAverageWidth);
				return CRect(ptCaret, ptCaret + szCaret);
			  }
			  break;
		  }
		}
		break;
  }

  return CRect();
}





相关的TableTextFigure代码是:(覆盖TextFigure的抽奖



Relevant TableTextFigure codes are:(overrrides TextFigure's draw

#pragma once
#include"..//MyFont.h"
#include"..//Color.h"
#include "TextFigure.h"

class TableTextFigure : public TextFigure
{
 public:
	TableTextFigure();
    TableTextFigure(const Color& color, const CPoint& ptMouse,const MyFont& font, CDC* pDC);

    TableTextFigure(const TableTextFigure &text);
	//TableTextFigure operator =(const TableTextFigure &text);
	Figure* Copy() const;

    void Serialize(CArchive& archive);

    BOOL Click(const CPoint& ptMouse);
    BOOL DoubleClick(const CPoint& ptMouse);
    BOOL Inside(const CRect& rcInside) const;

    void MoveOrModify(const CSize& szDistance);
    void Move(const CSize& szDistance);
	
	void Draw(CDC* pDC) const;
    CRect GetArea() const;
	BOOL PointInFigure(const CPoint &ptMouse) const;

	void SetTextPoint(CPoint &ptText) { m_ptText = ptText;}
	BOOL PointInText(const CPoint &ptMouse) const;
	void SetFont(const MyFont& font, CDC* pDC);
	void SetMyFont(const MyFont& font, CDC* pDC);
	
};

void TableTextFigure::Draw(CDC* pDC) const
{
  CFont cFont;
  cFont.CreateFontIndirect(m_font.PointsToMeters());
  CFont* pPrevFont = pDC->SelectObject(&cFont);

  TEXTMETRIC tm;
  pDC->GetTextMetrics(&tm);

  if (IsMarked() && !pDC->IsPrinting())
  {
     pDC->SetTextColor(WHITE);
     pDC->SetBkColor(BLUE);
	 switch(m_eTextDirection)
	 {
	 case LEFT_TO_RIGHT:
		pDC->TextOut(m_ptText.x, m_ptText.y + m_szText.cy,m_stText);
		break;
	/*case RIGHT_TO_LEFT:
		{
			CString stText;
			CSize szText;
			CPoint ptText = m_ptText;
			int iSize = m_stText.GetLength();
			for(int i = 0; i < iSize; i++)
			{
				stText = m_stText[i];
				szText = pDC->GetTextExtent(stText);
				ptText.x -= szText.cx;
				pDC->TextOut(ptText.x, ptText.y + m_szText.cy,stText);
			}
		}
		break;*/
	 case BOTTOM_TO_TOP:
		 pDC->TextOut(m_ptText.x, m_ptText.y  + tm.tmHeight + tm.tmExternalLeading - m_szText.cy,m_stText);
		break;
	 case TOP_TO_BOTTOM:
		 pDC->TextOut(m_ptText.x, m_ptText.y - tm.tmHeight - tm.tmExternalLeading + m_szText.cy,m_stText);
		break;
	 }
  }
  else
  {
	  pDC->SetTextColor((COLORREF) GetColor());
	  pDC->SetBkColor(WHITE);
	  switch(m_eTextDirection)
	 {
	 case LEFT_TO_RIGHT:
		pDC->TextOut(m_ptText.x, m_ptText.y + m_szText.cy,m_stText);
		break;
	/*case RIGHT_TO_LEFT:
		{
			CString stText;
			CSize szText;
			CPoint ptText = m_ptText;
			int iSize = m_stText.GetLength();
			for(int i = 0; i < iSize; i++)
			{
				stText = m_stText[i];
				szText = pDC->GetTextExtent(stText);
				ptText.x -= szText.cx;
				pDC->TextOut(ptText.x, ptText.y + m_szText.cy,stText);
			}
		}
		break;*/
	 case BOTTOM_TO_TOP:
		 pDC->TextOut(m_ptText.x, m_ptText.y  + tm.tmHeight + tm.tmExternalLeading - m_szText.cy,m_stText);
		break;
	 case TOP_TO_BOTTOM:
		 pDC->TextOut(m_ptText.x, m_ptText.y  - tm.tmHeight - tm.tmExternalLeading + m_szText.cy,m_stText);
		break;
	 }
  }

  pDC->SelectObject(pPrevFont);





相关的View函数是:



The relevant View functions are:

// OnKeyDown is called when the user presses a key at the keyboard.

void CDrawView::OnKeyDown(UINT uChar, UINT /* uRepCnt */, UINT /* uFlags */)
{
  CClientDC dc(this);
  OnPrepareDC(&dc);

  switch (uChar)
  {
    // On home, we scroll to the top left corner.

    case VK_HOME:
      if (!m_pDrawDoc->KeyDown(VK_HOME, &dc))
      {
        OnVScroll(SB_TOP, 0, NULL);
        OnHScroll(SB_LEFT, 0, NULL);
      }
      break;

    // On end, we scroll to bottom right corner.

    case VK_END:
      if (!m_pDrawDoc->KeyDown(VK_END, &dc))
      {
        OnVScroll(SB_BOTTOM, 0, NULL);
        OnHScroll(SB_RIGHT, 0, NULL);
      }
      break;

    // The up and down arrow keys scroll one row.

    case VK_UP:
      OnVScroll(SB_LINEUP, 0, NULL);
      break;

    case VK_DOWN:
      OnVScroll(SB_LINEDOWN, 0, NULL);
      break;

    // In case the left or right arrow key was not used to edit a text, we
    // scroll one line.

    case VK_LEFT:
      if (!m_pDrawDoc->KeyDown(VK_LEFT, &dc))
      {
        OnHScroll(SB_LINELEFT, 0, NULL);
      }
      break;

    case VK_RIGHT:
      if (!m_pDrawDoc->KeyDown(VK_RIGHT, &dc))
      {
        OnHScroll(SB_LINERIGHT, 0, NULL);
      }
      break;

    // In case of the page up or page down key, we just scroll the bars.

    case VK_PRIOR:
      OnVScroll(SB_PAGEUP, 0, NULL);
      break;

    case VK_NEXT:
      OnVScroll(SB_PAGEDOWN, 0, NULL);
      break;

    // In case of the insert, delete, backspace, return, or escape key,
    // we call KeyDown in the document class.

    case VK_INSERT:
    case VK_DELETE:
    case VK_BACK:
    case VK_RETURN:
    case VK_ESCAPE:
      m_pDrawDoc->KeyDown(uChar, &dc);
      break;
  }
}

// OnChar is called when the user presses a printable character (ASCII table
// value 32 – 122). It calls CharDown in the document class.

void CDrawView::OnChar(UINT uChar, UINT /* uRepCnt */, UINT /* uFlags */)
{
  CClientDC dc(this);
  OnPrepareDC(&dc);

  m_pDrawDoc->CharDown(uChar, &dc);
}





相关的文件功能是:



The relevant Document functions are:

BOOL CDrawDoc::KeyDown(UINT uChar, CDC* pDC)
{
 if (uChar == VK_INSERT)
  {
    if (m_eKeyboardState == KS_INSERT)
    {
      m_eKeyboardState = KS_OVERWRITE;
    }
    else
    {
      m_eKeyboardState = KS_INSERT;
    }

    if(m_eApplicationState == EDIT_TABLETEXT)
    {
      CRect rcCaret = m_pEditTextBox->GetCaretArea(m_eKeyboardState);
      m_caret.SetAndShowCaret(rcCaret);
    }

    return TRUE;
  }IT_TEXTBOX)
    {
      CRect rcCaret = m_pEditTextBox->GetCaretArea(m_eKeyboardState);
      m_caret.SetAndShowCaret(rcCaret);
    }

	 if(m_eApplicationState == EDIT_TABLETEXT)
    {
      CRect rcCaret = m_pEditTextBox->GetCaretArea(m_eKeyboardState);
      m_caret.SetAndShowCaret(rcCaret);
    }

    return TRUE;
  }IT_TEXTBOX)
    {
      CRect rcCaret = m_pEditTextBox->GetCaretArea(m_eKeyboardState);
      m_caret.SetAndShowCaret(rcCaret);
    }

	 if(m_eApplicationState == EDIT_TABLETEXT)
    {
      CRect rcCaret = m_pEditTextBox->GetCaretArea(m_eKeyboardState);
      m_caret.SetAndShowCaret(rcCaret);
    }

    return TRUE;
  }


  if (m_eApplicationState ==  EDIT_TABLETEXT)
   {
    switch (uChar)
    {
      case VK_LEFT:
      case VK_RIGHT:
      case VK_HOME:
      case VK_END:
      case VK_DELETE:
      case VK_BACK:
	  case VK_RETURN:
	     {
          // If there is an editing character, we edit the text and set the
          // modified flag if the KeyDown method returns true.

          CRect rcOldText = m_pEditTableBox->GetArea();
          BOOL bModified = m_pEditTableBox->KeyDown(uChar, pDC);

          if (bModified)
          {
              SetModifiedFlag();
          }

          // We update the text and the caret.

          CRect rcNewText = m_pEditTableBox->GetArea();
          UpdateAllViews(NULL, (LPARAM) &rcOldText);
          UpdateAllViews(NULL, (LPARAM) &rcNewText);
		 
		  CRect rcCaret = m_pEditTableBox->GetCaretArea(m_eKeyboardState);
          m_caret.SetAndShowCaret(rcCaret);
         
        }
        break;

	 case VK_ESCAPE:
        {
          CRect rcText = m_pEditTableBox->GetArea();
          m_pEditTableBox->Mark(FALSE);

          UpdateAllViews(NULL, (LPARAM) &rcText);
          m_caret.HideCaret();

          m_pEditTableBox = NULL;
          m_eApplicationState = IDLE;
		  m_eNextActionState = MODIFY_FIGURE;
        }
        break;
     
      }

      return TRUE;
    
  }
  
  // If the application is in modifying mode and at least one figure is
  // marked, we simulate the menu option Delete.

  int iMarked = m_figurePtrList.CountIf(IsMarked);
  if ((uChar == VK_DELETE) && (iMarked > 0))
  {
    OnDelete();
    return TRUE;
  }

  // In case of a key different from those handled so far, we just return
  // false.

  return FALSE;
}

void CDrawDoc::CharDown(UINT uChar, CDC* pDC)
{
 
   if ((m_eApplicationState == EDIT_TABLETEXT) && isprint(uChar))
  {
	  m_caret.HideCaret();
	  if(m_pEditTableBox->GetTable()->GetEditCell()->GetCaretFlag())
	  {
		  return;
	  }
	 
	  try
	  {
		m_pEditTableBox->CharDown(uChar, pDC, m_eKeyboardState);
	  }
	  catch(BOOL bSkip)
	  {
		  m_pEditTableBox->GetTable()->GetEditCell()->SetCaretFlag(bSkip);
		  return;
	  }

	  CRect rcText = m_pEditTableBox->GetArea();
     
	  CRect rcCaret = m_pEditTableBox->GetCaretArea(m_eKeyboardState);
	  m_caret.SetAndShowCaret(rcCaret);
      
	  UpdateAllViews(NULL, (LPARAM) &rcText);
	  
	  SetModifiedFlag();
   }
}





The prototype of relevant TableFigure,Table, TCell,TableText classes are all the same:All each does to call get the relvant data member functions whicha are all public function: A sample prototype for TCell is shown below:





The prototype of relevant TableFigure,Table, TCell,TableText classes are all the same:All each does to call get the relvant data member functions whicha are all public function: A sample prototype for TCell is shown below:

void TCell::CharDown(UINT uChar, CDC *pDC, KeyboardState m_eKeyboardState)
BOOL TCell::KeyDown(UINT uChar, CDC* pDC)





So what really happens in the code is that, The view class calls the document class; the document class class calls its CharDown function and its CharDown function call the CharDown function of the Tablefigure object which goes on to eventually call the CharDown figure of the TableTextFigure.





So, what could be wrong



So what really happens in the code is that, The view class calls the document class; the document class class calls its CharDown function and its CharDown function call the CharDown function of the Tablefigure object which goes on to eventually call the CharDown figure of the TableTextFigure.


So, what could be wrong

推荐答案

WM_CHAR does not handle shift - you would need to handle WM_KEYDOWN to spot shift and / or control.

WM_KEYDOWN handles the raw keys, WM_CHAR handles the processed keys.



If you look here: http://msdn.microsoft.com/en-gb/library/windows/desktop/gg153546(v=vs.85).aspx[^] it explains it:

WM_CHAR does not handle shift - you would need to handle WM_KEYDOWN to spot shift and / or control.
WM_KEYDOWN handles the raw keys, WM_CHAR handles the processed keys.

If you look here: http://msdn.microsoft.com/en-gb/library/windows/desktop/gg153546(v=vs.85).aspx[^] it explains it:
For example, suppose the user presses the SHIFT key followed by the A key. Assuming a standard keyboard layout, you would get the following sequence of messages:
WM_KEYDOWN: SHIFT
WM_KEYDOWN: A
WM_CHAR: 'A'


这篇关于请问谁可以告诉我你的MFC程序有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆