sudoku me
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes. I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.
这将是一系列系列文章的第一篇,该系列文章演示使用MFC类开发基于Windows的完整应用程序。 我将尽力使每篇文章都专注于一个(或几个)可能要完成的任务。
We will need options to save and load a game (that is not yet finished). A database to allow you to play random games would be nice. With the database storage it would be nice to be able to import and export multiple games for sharing. How about the option to undo the last action – wait why just the last action? Why not a listing of the last changes made and be able to undo lots of changes. To help you play we will be implementing visual assists – different levels of assistance no less.
我们将需要一些选项来保存和加载游戏(尚未完成)。 一个允许您玩随机游戏的数据库会很好。 有了数据库存储,能够导入和导出多个游戏进行共享会很好。 撤消上一个动作的选项怎么样–等待为什么只有上一个动作? 为什么不列出最近所做的更改,并能够撤消许多更改。 为了帮助您演奏,我们将实施视觉辅助–各种级别的辅助都将如此。
Using Visual Studio – We will be using Visual Studio 2005 for this project and the uploaded files and description of steps here will be based on that. Database storage will be with Microsoft Access 2000. Please note that for those of you with the express editions of Visual Studio the MFC classes are NOT natively supported.
使用Visual Studio –我们将为该项目使用Visual Studio 2005,并且将基于此内容上载文件和此处的步骤说明。 数据库存储将随Microsoft Access 2000一起提供。请注意,对于使用Visual Studio的快速版本的您,MFC类本身不受支持。
In this first article we will be making modifications using the new project wizard to generate the skeleton application required, then using the resource editor to get the functionality we desire.
在第一篇文章中,我们将使用新的项目向导进行修改,以生成所需的框架应用程序,然后使用资源编辑器来获得所需的功能。
Sudoku is played on a grid so a form sort of display would be required. Having both a menu and toolbar buttons for the options makes it easier for the user to perform actions. A dialog based app could be a possibility but that doesn’t have the document/view architecture (re save/load) and it also doesn’t support a menu or toolbar nicely – that means we would have to code some functionality ourselves. This leaves us the SDI (or MDI) style. SDI (single document interface) makes sense – after all we can run it a number of times if we did want to play a number of games simultaneously! The form like display – well we can use a CFormView to make it look like a dialog.
数独在网格上播放,因此需要某种形式的显示。 同时具有菜单和工具栏按钮的选项,使用户可以更轻松地执行操作。 基于对话框的应用程序可能是可行的,但是它没有文档/视图架构(重新保存/加载),并且它也不能很好地支持菜单或工具栏-这意味着我们必须自己编写一些功能。 这样就剩下了SDI(或MDI)样式。 SDI(单个文档界面)很有意义–如果我们确实想同时玩很多游戏,那么毕竟我们可以运行多次! 像显示这样的表单–好吧,我们可以使用CFormView使其看起来像对话框。
Start Visual Studio and from the File menu choose New then Project. Now from the Project Types we need a Visual C++, MFC type of project (tree view at left) then from the pane at the right choose MFC Application. At the base of the form enter a name (Sudoku for example) and choose a location for the project. Click the OK button.
启动Visual Studio,然后从“文件”菜单中选择“新建”,然后选择“项目”。 现在,从“项目类型”中,我们需要一个Visual C ++,MFC类型的项目(左侧的树视图),然后从右侧的窗格中选择“ MFC应用程序”。 在表单的底部输入名称(例如数独),然后选择项目的位置。 单击确定按钮。
You are now presented with the MFC Application Wizard with an overview of the options selected by default. Here is what we want to change.
现在,您将看到MFC应用程序向导,其中包括默认情况下所选选项的概述。 这就是我们要改变的地方。
Application Type – select Single document (default is Multiple documents), leave the Use Unicode libraries option checked (actually I don’t want UNICODE, I’ll show how this ‘mistake’ is corrected in a later article).Document Template Strings – for the File Extension enter sdk (or other file extension if you prefer, it ought to be one not in common usage)
文档模板字符串–对于文件扩展名,请输入sdk(如果需要,也可以输入其他文件扩展名,应该不常用)
Database Support – leave that as none! (We will be doing that ourselves later) User Interface Features – Uncheck the following Thick Frame, Maximize box. (Thick frame allows resizing with the mouse/keyboard) Advanced Features – Uncheck the following Printing and print , ActiveX controls (not going to use any). Generated classes – select in the Generated Classes list CSudokuView, now from the combobox called Base Class we need to select CFormView.Now click the Finish button. Confirm with yes the message about no printing with CFormView (odd – we didn’t select printing as a requirement, apparently a tiny bug in Visual Studio) and we should now be back into Visual Studio and ready to go. We can even press the F5 key and the application should compile and run, doesn’t do a lot (sudoku like) at this point though does it?
现在单击完成按钮。 是,请确认是否使用CFormView进行不打印的消息(奇怪-我们没有选择打印作为要求,显然是Visual Studio中的一个小错误),现在我们应该回到Visual Studio并可以使用了。 我们甚至可以按F5键,应用程序应该编译并运行,尽管它在这一点上没有做很多(数独之类的事情)吗?
The entry boxes for the digits in sudoku grid. What control can we use for that? An edit control sounds useful but an edit control supports lots of things, We are going to choose a button instead. Buttons are designed to support owner drawing – something we will want for our hinting. Edit controls also have some built in functionality (copy, cut, paste) that we do not require and the owner drawing is also more complex.
数独网格中数字的输入框。 我们可以为此使用什么控件? 一个编辑控件听起来很有用,但一个编辑控件支持很多东西,我们将改为选择一个按钮。 按钮旨在支持所有者绘图,这是我们希望用作提示的内容。 编辑控件还具有一些我们不需要的内置功能(复制,剪切,粘贴),并且所有者图形也更加复杂。
In Visual Studio open the resource view, expand the tree items Sudoku, Sudoku.rc, Dialog, select IDD_SUDOKU_FORM and double click (or press enter key) and we see the form in design mode. If we look at the bottom right of the status bar we should see something like 0,0 and 320 x 200. The 0,0 means the top, left co-ordinates (in the design editor – this is not an onscreen setting for when the app is running) and the 320 x 200 are a width and height in dialog units (again not pixels for on screen). There is functionality to convert between pixels and dialog units and vice versa but it is something we do not require to use in the resource editor.
在Visual Studio中,打开资源视图,展开树项Sudoku,Sudoku.rc,对话框,选择IDD_SUDOKU_FORM并双击(或按Enter键),我们将在设计模式下看到该表单。 如果我们查看状态栏的右下角,我们应该会看到类似0,0和320 x 200的图形。0,0表示左上角的坐标(在设计编辑器中–这不是屏幕显示时间应用程序正在运行),而320 x 200是以对话框单位表示的宽度和高度(同样不是屏幕上的像素)。 可以在像素和对话框单位之间进行转换,反之亦然,但这是我们不需要在资源编辑器中使用的功能。
Using the mouse we resize the form until it is 495 x 400. The piece of text “TODO: Place form controls on this dialog” is not needed so select it with a mouse click. (This is actually a static control, I see 24,42 and 280 x 8 as is location and size parameters). Now delete the text control with the delete key. From the toolbox select button with a mouse click then on the form with a mouse click insert a button control, it will display Button1 as text. Modify the size and location so this button is something like 11,12 and 49 x 38. We are not too bothered about being exact – making things look nice will be done soon.
我们使用鼠标来调整窗体的大小,直到495 x400。不需要文本“ TODO:在此对话框上放置窗体控件”,因此单击鼠标即可选择它。 (这实际上是一个静态控件,我看到24,42和280 x 8以及location和size参数)。 现在,使用Delete键删除文本控件。 用鼠标单击从工具箱选择按钮,然后用鼠标单击在表单上插入一个按钮控件,它将Button1显示为文本。 修改大小和位置,以便此按钮的大小类似于11,12和49 x38。我们不必为精确而烦恼-很快就会使外观看起来更好。
This stage is very important. Do not add any other controls from the toolbox until you have generated all 81 buttons, not even add then delete (I will explain why later). Now click on the toolbar copy then paste buttons. The second button will overlay the first – so drag it a bit to the right of the first button (I have 61, 14). Repeat this step to add a third button. (Note the arrow keys can be used to move controls around on the resource editor. Pressing the shift key along with an arrow button allows resizing.) We should have something like the following:
这个阶段非常重要。 在您生成所有81个按钮之前,请不要从工具箱中添加任何其他控件,甚至不要先添加再删除(我稍后将解释原因)。 现在单击工具栏上的复制,然后粘贴按钮。 第二个按钮将覆盖第一个按钮-因此将其拖动到第一个按钮的右侧(我有61、14)。 重复此步骤以添加第三个按钮。 (请注意,箭头键可用于在资源编辑器上移动控件。按下Shift键和箭头键可以调整大小。)我们应该具有以下内容:
Now select all three buttons (keep shift key depressed as we drag the mouse over all three buttons) and repeat the copy / paste / move to make a crude row of nine buttons. Now select all nine buttons and repeat until we have nine rows, each of nine buttons. Now from the toolbox select picture control and add this to the form. Position and resize it to give 8, 8 and 477 x 387 (sometimes one has to try different sizes to get nice looking border spacing). This is not just to make things pretty – this has a function in the code. Select the rectangle and display the properties – The Type should be as Frame and change the ID to IDC_STATIC_BOUNDARY (from IDC_STATIC – this is a generic resource ID which can be used many times on one dialog, normally an ID is unique – only one control on the dialog can have that ID).
现在,选择所有三个按钮(在我们将鼠标拖动到所有三个按钮上时,按住Shift键),然后重复复制/粘贴/移动以制作一个粗略的九个按钮行。 现在选择所有九个按钮,然后重复直到我们有九行,每九个按钮。 现在,从工具箱中选择图片控件并将其添加到表单中。 定位并调整其大小,使其分别为8、8和477 x 387(有时必须尝试使用其他大小才能获得美观的边框间距)。 这不仅仅是使事情变得漂亮–它在代码中具有一个功能。 选择矩形并显示属性-类型应为Frame并将ID更改为IDC_STATIC_BOUNDARY(来自IDC_STATIC-这是一个通用资源ID,可以在一个对话框上多次使用,通常一个ID是唯一的-仅在一个控件上该对话框可以具有该ID)。
The dialog part of the interface is now completed. Other UI (user interface) components are still in their defaults. Some of these we require, some not and we also require some new options in menus and toolbars.
界面的对话框部分现已完成。 其他UI(用户界面)组件仍为默认设置。 其中一些是我们需要的,有些不是,我们还需要菜单和工具栏上的一些新选项。
From the resource editor view open the menu branch of the tree and double click on IDR_MAINFRAME to display the menu in the resource editor. It appears in a similar fashion to what we see when the app would be run.
在资源编辑器视图中,打开树的菜单分支,然后双击IDR_MAINFRAME以在资源编辑器中显示菜单。 它的显示方式类似于我们在运行该应用程序时所看到的方式。
Click on File and we see: New, open, Save, Save As, Recent File and Exit. The underline is a visual hint for a key shortcut eg. Ctrl key + N will act as if the ‘New’ option was pressed. We want to add a play option – this will bring a random sudoku puzzle from the database for us to solve. At the bottom (below the Exit option) there is a pale grey ‘Type Here’ – Type in Play Random then press return. Now with the mouse click on this new menu item, keep the left mouse button depressed and drag it between the ‘New’ and ‘Open’ menu points. (That is how we can reorder menu points to our liking.) Right click the mouse on the ‘Play’ menu point and choose properties. In the caption field add an & sign before the capital R – on the menu you should now see the R of random underlined, now after the m enter \t then Ctrl+ R and press return. You should see the menu with the mnemonic (Ctrl+ R) right adjusted in the display. In the field labelled Prompt enter a hint eg. Play a random game from the database. This text should appear in the status bar when this menu item is selected.
单击文件,我们看到:新建,打开,保存,另存为,最近的文件并退出。 下划线是按键快捷方式的视觉提示,例如。 Ctrl + N的作用就像是按下“新建”选项一样。 我们要添加一个播放选项–这将带来一个来自数据库的随机数独难题,供我们解决。 在底部(“退出”选项下方)有一个浅灰色的“在这里键入”-键入“播放随机”,然后按回车键。 现在,用鼠标单击此新菜单项,按住鼠标左键并将其拖动到“新建”和“打开”菜单点之间。 (这是我们可以按照喜好重新排列菜单点的方式。)在“播放”菜单点上单击鼠标右键,然后选择属性。 在标题字段中,在大写字母R之前添加一个&符号–在菜单上,您现在应该看到随机带下划线的R,现在m之后,请输入\ t然后按Ctrl + R并按回车键。 您应该会在菜单中看到带有调整后的助记符(Ctrl + R)的菜单。 在“提示”字段中输入提示,例如。 从数据库玩一个随机的游戏。 选择此菜单项后,该文本应显示在状态栏中。
For completeness if you right click the mouse on Play you should see a context menu with one option being to insert a separator, we don’t require one – but that is how one can group items on a menu.
为了完整起见,如果在“播放”上单击鼠标右键,您应该会看到一个上下文菜单,其中一个选项是插入分隔符,我们不需要一个-但这就是将菜单项进行分组的方式。
Now click the menu item at the top labelled Edit – select and use the delete key to remove the separator and Cut, Copy and Paste options. Leave the menu point Undo – we want that later.
现在,单击顶部标签为“编辑”的菜单项-选择并使用Delete键删除分隔符以及“剪切,复制和粘贴”选项。 离开菜单点“撤消”-我们稍后再说。
We are missing options for Lock, Solve, Delete and Maintenance. (I’ll explain those when they are needed). So add them to the Edit menu after the Undo and use a separator to group them separate from the Undo option. Use a mnemonic Ctrl+ L (with & for the underline) for the Lock option, the Solve just add the underline to the S but don’t enter anything for a mnemonic. Now add a separator then options called Delete and finally Database Maintenance. Add something to the prompts for each of these new options eg. ‘Lock a game’, ‘Solve a game’, ‘Delete a game’, ‘Organise games in the database’.
我们缺少锁定,解决,删除和维护的选项。 (我将在需要时进行解释)。 因此,将它们添加到“撤消”之后的“编辑”菜单中,并使用分隔符将它们与“撤消”选项分开。 对锁定选项使用助记符Ctrl + L(带有&的下划线),“求解”仅将下划线添加到S,但不为助记符输入任何内容。 现在添加一个分隔符,然后添加名为Delete的选项,最后添加Database Maintenance。 为这些新选项的每个提示添加一些内容,例如。 “锁定游戏”,“解决游戏”,“删除游戏”,“在数据库中组织游戏”。
From the resource view open the Accelerator and double click the IDR_MAINFRAME. This is where the keyboard shortcuts can be organised. (We have added hints to the menu points, that is not the same as the actual keyboard support – don’t confuse the two.)
在资源视图中,打开加速器,然后双击IDR_MAINFRAME。 在这里可以组织键盘快捷键。 (我们在菜单点上添加了提示,这与实际的键盘支持不同,请不要混淆两者。)
Copy, Cut and paste are not supported – so select the IDC_EDIT_COPY, IDC_EDIT_CUT and IDC_EDIT_PASTE options and delete them. (Note three ID’s but six entries – one ID can have more than one key combination as a shortcut.) The ID_NEXT_PANE and ID_PREV_PANE can go as well.
不支持复制,剪切和粘贴-因此,请选择IDC_EDIT_COPY,IDC_EDIT_CUT和IDC_EDIT_PASTE选项并将其删除。 (请注意,三个ID但六个条目–
Click on the line at the bottom (below ID_FILE_SAVE) – this is how to add a new key shortcut. From the combo select ID_FILE_PLAYRANDOM, leave the modifier column (Ctrl) entry alone and enter an R in the Key column. Remember our menu specifies Ctrl+ R for playing a random game. We also need a shortcut for Lock (Ctrl+ L, ID_EDIT_LOCK) menu options.
单击底部的行(ID_FILE_SAVE下方)–这是添加新的快捷键的方法。 从组合菜单中选择ID_FILE_PLAYRANDOM,仅保留修饰符列(Ctrl)项,然后在“键”列中输入R。 请记住,我们的菜单指定Ctrl + R用于玩随机游戏。 我们还需要一个用于Lock(Ctrl + L,ID_EDIT_LOCK)菜单选项的快捷方式。
Now we go to resource view then open the Toolbar and double click on IDR_MAINFRAME to view the toolbar. Click the ‘cut’ symbol and drag off the row then release the mouse button – the cut has been removed. Do the same for ‘Copy’, ‘Paste’ and 'Print'. Now you should have buttons for new, open and save and about (question mark). There is also a blank box to the far right of the row – this is for new buttons. We would like to add options for a random game, lock and solve as well as an undo option. Click this blank button and start drawing in it – there is a toolbar that gives you lines, shapes and other options. I suggest you play with that yourself. To organise you can drag and drop buttons on the bar, a drag a little to the right will introduce a spacer. Here are some suggestions for the buttons I have done myself.
现在我们进入资源视图,然后打开工具栏,然后双击IDR_MAINFRAME来查看工具栏。 单击“剪切”符号并拖出该行,然后释放鼠标按钮-剪切已被删除。 对“复制”,“粘贴”和“打印”执行相同的操作。 现在,您应该具有用于新建,打开和保存以及关于(问号)的按钮。 该行的最右边还有一个空白框–用于新按钮。 我们想为随机游戏添加选项,锁定和解决以及撤消选项。 单击此空白按钮并开始在其中绘图–有一个工具栏,可为您提供线条,形状和其他选项。 我建议你自己玩。 要进行组织,您可以拖放工具栏上的按钮,向右拖动一点将引入一个空格。 这是我自己做的按钮的一些建议。
Now click on a button (eg. The die – second from left) then look at the properties. Change the ID to ID_FILE_PLAYRANDOM. You should see the Prompt comes with that we entered with the menu item. Assign the other new buttons ID_EDIT_UNDO, ID_EDIT_LOCK and the exclamation mark to ID_EDIT_SOLVE. Now perform a Save All to save our changes.
现在单击一个按钮(例如,模具-左数第二),然后查看属性。 将ID更改为ID_FILE_PLAYRANDOM。 您应该看到我们随菜单项一起输入的提示。 将其他新按钮ID_EDIT_UNDO,ID_EDIT_LOCK和感叹号分配给ID_EDIT_SOLVE。 现在执行全部保存以保存我们的更改。
From the Edit menu of the resource editor there should be a point ‘ID= Resource Symbols’, click on this – this gives a listing of all resource ID’s in the app, we can delete unused ones here (should there be any by eg. adding a button to a dialog form then later deleting it).
在资源编辑器的“编辑”菜单上,应该有一个“ ID =资源符号”点,单击此位置–这会列出应用程序中所有资源ID的列表,我们可以在此处删除未使用的资源ID(例如,如果有ID,请使用。在对话框表单中添加按钮,然后稍后将其删除)。
Finally from resource view open the Version then double click on VS_VERSION_INFO. Here is information displayed in the windows explorer when one looks at the properties of a file. We’ll leave everything here as is at present.
最后,从资源视图中打开“版本”,然后双击VS_VERSION_INFO。 这是当人们查看文件属性时在Windows资源管理器中显示的信息。 目前,我们将一切都保留在这里。
A quick compile and run (F5 key) should show the app – note our new menu items and buttons are greyed out – this is the expected behaviour as we have no code for them yet.
快速编译并运行(F5键)应显示该应用程序-注意我们的新菜单项和按钮为灰色-这是预期的行为,因为我们尚无相应的代码。
We have decided how the application should look and behave
我们已经决定了应用程序的外观和行为
before we even started using Visual Studio - planning is very important and a major key to success. 在我们甚至开始使用Visual Studio之前,规划就非常重要,也是成功的关键。We have used the project wizard to create the basic classes and resources for an application.
我们已使用项目向导为应用程序创建基本类和资源。
We have used the resource editor to modify some of those resources that were automatically generated for us.
我们已经使用资源编辑器来修改一些为我们自动生成的资源。
Next article in the series is here: Sudoku in MFC: Part 2
该系列的下一篇文章在这里: MFC中的Sudoku:第2部分
In that we will be looking at dynamically positioning controls on a window from code. We will also be using the windows registry for storing information about the application.
这样,我们将研究通过代码在窗口上动态定位控件。 我们还将使用Windows注册表来存储有关应用程序的信息。
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/3707/Sudoku-a-complete-MFC-application-Part-1.html
sudoku me