sudoku me_Sudoku,一个完整的MFC应用程序。 第4部分

sudoku me

介绍: (Introduction:)

在状态栏上显示信息。

Continuing from the third article about sudoku.  

继续关于数独的第三篇文章。

Open the project in visual studio.

在Visual Studio中打开项目。

Status bar – let’s display the timestamp there.  We need to get the timestamp from the document so we add one public function there (after the GetGame).  Open SudokuDoc.h and append a new line:

状态栏–让我们在此处显示时间戳。 我们需要从文档中获取时间戳,因此我们要在其中添加一个公共函数(在GetGame之后)。 打开SudokuDoc.h并添加新行:

    char* GetGame() { return m_arGame; };
    const CString& GetInfo() { return m_szInfo; };

The view is notified when information is changed so we can use the handler (OnUpdate) to also handle this information.  If one looks in the code in the CMainFrame class then one sees that the statusbar is a child of that window, nothing to do with the view – so we will delegate the actual display of information to the frame window itself.

信息更改时会通知视图,因此我们可以使用处理程序(OnUpdate)来处理此信息。 如果人们在CMainFrame类的代码中查找,那么就会看到状态栏是该窗口的子级,与视图无关。因此,我们将信息的实际显示委托给框架窗口本身。

In the SudokuView.cpp file modify it to be as follows (adding the #include “MainFrm.h” after the existing #include “SudokuView.h”)

在SudokuView.cpp文件中,对其进行如下修改(在现有的#include“ SudokuView.h”之后添加#include“ MainFrm.h”)

#include "SudokuView.h"
#include "MainFrm.h"

Next we modify the OnUpdate function, adding a new line directly after the case statement

接下来,我们修改OnUpdate函数,在case语句之后直接添加新行

    case CSudokuDoc::eLoadGame:
        //Update the status bar on the frame
        static_cast<CMainFrame*>(GetParentFrame())->DisplayStatusInfo(GetDocument()->GetInfo());

The GetParentFrame returns a generic CFrameWnd pointer, we cast this to our specific CMainFrame class which is a derived class from CFrameWnd.  Notice this has a new function – DisplayStatusInfo – which we must now add to the CMainFrame class.  Modify the MainFrm.h file so it is as follows:

GetParentFrame返回一个通用的CFrameWnd指针,我们将此指针转换为特定的CMainFrame类,该类是CFrameWnd的派生类。 注意,它有一个新函数DisplayStatusInfo,我们现在必须将其添加到CMainFrame类中。 修改MainFrm.h文件,如下所示:

public:
    afx_msg void OnClose();
    void DisplayStatusInfo(const CString& szInfo);

Now in the MainFrm.cpp file add at the end of the file the function body:

现在在MainFrm.cpp文件中,在文件末尾添加函数主体:

void CMainFrame::DisplayStatusInfo(const CString& szInfo)
{
}

The program should compile but the status bar needs a little work now.  In the OnCreate function of the CMainFrame there should be the following code:

该程序应该可以编译,但是状态栏现在需要一些工作。 在CMainFrame的OnCreate函数中,应该有以下代码:

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

This creates a default status bar.  We want a custom one which will display menu prompts as the default one does and also have two panes, one for the hint (later article) and one for the time stamp.

这将创建一个默认状态栏。 我们需要一个自定义的菜单,它会像默认菜单一样显示菜单提示,并且也有两个窗格,一个窗格用于提示(后面的文章),另一个窗格用于时间戳。

We also want some extra functionality so we will create a class derived from CStatusBar (NOT CStatusBarCtrl – careful when selecting the base class).  I have explained in step 3 how to create a CGridButton – we will do similar to create a CSudokuStatusBar.

我们还需要一些额外的功能,因此我们将创建一个派生自CStatusBar的类( 不是 CStatusBarCtrl-选择基类时要小心)。 我已经在步骤3中说明了如何创建CGridButton –我们将执行类似的操作来创建CSudokuStatusBar。

You should have the following:

您应该具有以下条件:

class CSudokuStatusBar : public CStatusBar
{
    DECLARE_DYNAMIC(CSudokuStatusBar)

public:
    CSudokuStatusBar();
    virtual ~CSudokuStatusBar();

protected:
    DECLARE_MESSAGE_MAP()
};

At the head of the file – SudokuStatusBar.cpp, before the IMPLEMENT_DYNAMIC add the following:

在文件的开头– SudokuStatusBar.cpp,在IMPLEMENT_DYNAMIC之前添加以下内容:

static UINT indicators[] =
{
    ID_SEPARATOR, 
    ID_SEPARATOR,
    ID_SEPARATOR
};
#define PANE_HINT 1
#define PANE_INFO 2

This is the basic collection of 3 panes we want in the status bar.

这是我们在状态栏中需要的3个窗格的基本集合。

Now add a WM_CREATE message handler and modify it to be this:

现在添加一个WM_CREATE消息处理程序并将其修改为:

int CSudokuStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CStatusBar::OnCreate(lpCreateStruct) == -1)
        return -1;

    if(!SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))
        return -1;

    SetPaneInfo(0, ID_SEPARATOR, SBPS_NOBORDERS | SBPS_STRETCH, 0);
    SetPaneInfo(PANE_HINT, ID_SEPARATOR, SBPS_NORMAL, 100);
    SetPaneInfo(PANE_INFO, ID_SEPARATOR, SBPS_NORMAL, 80);

    return 0;
}

We also need some more functionality to cope with the display.  Add the following to the header file for the custom statusbar.

我们还需要更多功能来适应显示。 将以下内容添加到自定义状态栏的头文件中。

public:
    void SetInfo(const CString& szInfo);

And the following into the cpp file for the statusbar

并将以下内容放入状态栏的cpp文件中

void CSudokuStatusBar::SetInfo(const CString& szInfo)
{
    SetPaneText(PANE_INFO, szInfo);
}

In the header file for the CMainFrame we need to add a #include “SudokuStatusBar” after the #pragma once and change the CStatusBar m_wndStatusBar into CSudokuStatusBar.

在CMainFrame的头文件中,我们需要在#pragma之后添加#include“ SudokuStatusBar”,并将CStatusBar m_wndStatusBar更改为CSudokuStatusBar。

protected:  // control bar embedded members
    CSudokuStatusBar  m_wndStatusBar;
    CToolBar    m_wndToolBar;

In the OnCreate of the CMainFrame we need to make a change:

在CMainFrame的OnCreate中,我们需要进行更改:

This:

这个:

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

Becomes

成为

    if (!m_wndStatusBar.Create(this))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

And the DisplayStatusInfo function needs to be:

并且DisplayStatusInfo函数需要为:

void CMainFrame::DisplayStatusInfo(const CString& szInfo)
{
    m_wndStatusBar.SetInfo(szInfo);
}

You can now compile and run the app, load the saved game and see the status bar.

您现在可以编译并运行该应用程序,加载保存的游戏并查看状态栏。

Why did we pass a const CString& in function such as the following?

为什么我们传递一个const CString&in函数,如下所示?

void CSudokuStatusBar::SetInfo(const CString& szInfo)

We need to pass the string information, passing it by reference (&) means that it is not constantly being copied into a new CString variable - efficiency.  

我们需要传递字符串信息,通过引用(&)传递它意味着它不会一直被复制到新的CString变量-效率中。

We have created our own statusbar to encapsulate the updating of the display elements.  Should we decide to add an extra pane to the status bar or to rearrange the layout in future then we don’t need to change a lot of code in other classes.  Note we even use a #define for the different pane indexes – to rearrange the layout is then just changing a #define value.

我们创建了自己的状态栏,以封装显示元素的更新。 如果我们决定在状态栏上添加一个额外的窗格,或者在将来重新安排布局,则无需在其他类中更改很多代码。 请注意,我们甚至为不同的窗格索引使用#define-重新排列布局只是在更改#define值。

结论: (Conclusion:)

Here we customised the default MFC status bar to provide visual feedback for the user.

在这里,我们自定义了默认的MFC状态栏,以为用户提供视觉反馈。

Click here for the source code for this article单击此处获取本文的源代码

Previous article in the series is here:  Sudoku in MFC: Part 3

该系列中的上一篇文章在这里: MFC中的Sudoku:第3部分

There we loaded and saved data to file on the hard disc.  We also investigated the interaction between the document and view based classes in the application architecture.

在那里,我们将数据加载并保存到硬盘上的文件中。 我们还研究了应用程序体系结构中文档和基于视图的类之间的交互。

Next article in the series is here:  Sudoku in MFC: Part 5

该系列的下一篇文章在这里: MFC中的Sudoku:第5部分

Here we will be providing keyboard support (in PreTranslateMessage) to navigate the grid in response to arrow keys, we will also be entering numbers into the grid cells from the keyboard.

在这里,我们将提供键盘支持(在PreTranslateMessage中),以响应箭头键在网格中导航,我们还将从键盘向网格单元中输入数字。

Two points to bear in mind.

需要牢记两点。

You may use the code but you are not allowed to distribute the resulting application either for free or for a reward (monetary or otherwise).  At least not without my express permission.

您可以使用代码,但不能免费或以奖励(货币或其他方式)分发结果应用程序。 至少没有我的明确许可。

I will perform some things to demonstrate a point – it is not to be taken as that meaning it is a ‘best’ practice, in fact an alternative might be simpler and suitable.  Some points in the code would even be called poor design and a possible source of errors.

我将做一些事情来说明一个观点–不能认为它是“最佳”实践,实际上,另一种选择可能更简单,更合适。 代码中的某些要点甚至被称为不良设计和可能的错误源。

翻译自: https://www.experts-exchange.com/articles/3823/Sudoku-a-complete-MFC-application-Part-4.html

sudoku me

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值