CMapEditorCtrl






4.45/5 (8投票s)
2003年12月7日
3分钟阅读

66602

1960
这个类为CMapEditor提供MFC控件功能,并支持等距视图
引言
我编写了这个类,为之前在CodeProject上发布的类CMapEditor
(https://codeproject.org.cn/cpp/CMapEditor.asp)提供完整的MFC控件功能。这是我编写的第一个自定义控件,请多多包涵;) 基本思路很简单:控件获取一系列位图和一个CMapEditor
类型,并向CMapEditor
值显示相应的图像。该控件支持鸟瞰标准编辑器模式和等距视图模式。我提供了一个基本的演示应用程序来演示这些概念。我目前正在完善一个等距编辑器,该编辑器将很快可用。在本文中,我将说明使用CMapEditorCtrl
所涉及的步骤,我将提供有关每个方法的信息,并且我将讨论该控件的一些已知问题。
使用CMapEditorCtrl
创建控件
您可以通过对话框资源编辑器(如演示应用程序中所示)或使用Create(...)
函数来初始化控件,如下所示
CMapEditorCtrl *g_pMapCtrl; g_pMapCtrl = new CMapEditorCtrl(); g_pMapCtrl->Create(MAPEDCTRLCLASS,NULL,WS_VISIBLE|WS_CHILD, CRect(4,4,820,620),this,1000);
我们现在已经成功创建了控件,现在我们必须对其进行初始化。
初始化控件
MECTRLINITSTRUCT isInit; //The structure isInit.iCellHeight = 20; //Cell height, in pixels isInit.iCellWidth = 20; //Cell width, in pixels isInit.iIsoHeight = 16; //Half the height of the isometric images isInit.iIsoWidth = 32; //Half the width of the isometric images isInit.iMapHeight = 30; //Number of rows in 2D editor isInit.iMapWidth = 40; //Number of columns in 2D editor isInit.pMapEditor = g_pMapEditor; //Pointer to a CMapEditor isInit.CtrlProc = ControlProc; //Callback function g_pMapCtrl->Initialize(&isInit); //Initialize the control
还需要将位图分配给控件。此示例代码演示了如何使用for循环将内存中的HBITMAPS
数组循环,并将它们分配给控件。
for(int i=0;i<m_nBitmaps;i++) { CBitmap *pBitmap = CBitmap::FromHandle(m_hBitmap[i][ISO]); BITMAP bmInfo; pBitmap->GetBitmap(&bmInfo); g_pMapCtrl->AssignBitmap(i+1,m_hBitmap[i][TWOD],m_hBitmap[i][ISO], bmInfo.bmHeight - 32); }
该控件现在可以使用了。以下部分介绍了使CMapEditorCtrl
发挥最佳性能的一些必要步骤。
回调函数
回调函数的工作方式就像一个WindowProc
方法。传递给此函数的参数定义为ARG_CTRLPROC
。第一个参数是一个整数,iMsg,它对应于消息代码。这可以是由用户定义的(以便可以在控件上执行任何类型的操作),也可以是预定义的值,例如MC_MOUSEMOVE
或MC_LBCLICKED
。用户定义的消息可以使用CMapEditorCtrl::SetValues(...)
。在文章的后面可以找到iMsg的可能值的完整列表。
CMapEditorCtrl::SetValues( . . . )
每次需要更改将修改CMapEditor的参数时,都必须调用此方法,当用户与控件交互时。语法非常简单,但要更好地理解这一点,请参考CMapEditor::SetMapValue 。
SetValues( int iValue, //The cells will be changed to this value int iLevel //This level will be affected int iMode //0 corresponds to normal //1 corresponds to CMapEditor::Fill(...) //Use other values for user-defined functionalites, this will be //passed to the callback function as iMsg. bool bCanDrag //For use with a user-defined iMode, TRUE, //if dragging is allowed //in the control );
该控件现在完全可用。
基本功能
- 单击 - 根据iMode执行操作,到选定的单元格,或结束拖动操作。
- 双击 - 开始拖动操作。
- 右键单击- 居中选定的单元格
- Ctrl + 右键单击 - 居中选定的单元格并切换视图模式
类成员
方法
//Assigns bitmaps h2DBitmap and hIsoBitmap to value iBitmap //(iHeight is extra height in isometric bitmap) bool AssignBitmap(int iBitmap,HBITMAP h2DBitmap,HBITMAP hIsoBitmap, int iHeight = 0);
//Centers the cell specified by ptPos void CenterCell(CPoint ptPos);
//Draws the control void DrawItem(CRect rUpdate = CRect(-1,-1,-1,-1));
//Sets wether a level is drawn or not void DrawLevel(int iLevel,bool bDraw = true);
//Retrieves control information void GetInfo(MECTRLINFO* mciInfo);
//Returns the x or y coordinate of the currently selected cell int GetPos(int nCoord);
//Highlights the cell specified by ptPos void HighlightCell(CPoint ptPos);
//Initializes the Map Control bool Initialize(MECTRLINITSTRUCT* isInitStruct);
//Sets the values void SetValues(int iValue, int iLevel, int iMode, bool bCanDrag);
//Sets the view mode void SetViewMode(int nViewMode,bool bUpdate = true);
结构体
typedef struct _SETSTRUCT { //Structure used to change the mode values for the map unsigned short int iValue; unsigned short int iLevel; unsigned short int iMode; bool bCanDrag; }SETSTRUCT;
typedef struct _MECTRLINITSTRUCT { //Structure used to initialize the map control CMapEditor* pMapEditor; //Pointer to a CMapEditor object short int iCellWidth; //Width of the 2D cells short int iCellHeight; //Height of the 2D cells short int iIsoWidth; //Half the width of the isometric tiles short int iIsoHeight; //Half the standard height of the isometric tiles short int iMapWidth; //Number of 2D cells displayed across the control short int iMapHeight; //Number of 2D cells displayed down the control void (*CtrlProc)(ARG_CTRLPROC); //Callback function }MECTRLINITSTRUCT;
typedef struct _MECTRLINFO { //Structure containing relevant information about the CMapEditorCtrl CPoint ptPos; //Currently selected cell CPoint ptScroll; //Current scroll coordinates int iMode; //Current mode int iLevel; //Current level int iValue; //Current value }MECTRLINFO;
定义
//Values for iMsg MC_MOUSEMOVE //Mouse moved MC_LBCLICKED //Left mouse button clicked MC_RBCLICKED //Right mouse button clicked MC_SCROLL //Scrolled MC_SETVIEWMODE //Changed view mode MC_CENTERCELL //Cell centered
//Values for nViewMode TWOD //Normal 2D editor mode ISO //Isometric editor mode
//Value for nCoord GP_X //X coordinate GP_Y //Y coordinate
问题
编写此控件非常有趣,我希望我分享了一些对MFC社区有用的东西。但是,我意识到存在一些问题,并且我在这里声明,有点像向专家寻求建议。如果打开了许多其他应用程序,则该控件可能会遇到一些性能问题。这主要是由设备上下文绘图引起的,如果控件很大,则绘图会很慢。
该控件已使用64x32的图块进行了测试。尚未尝试使用其他图像大小进行测试(我太懒了;)
如果其他CPian花时间看看CMapEditorCtrl
并在报告此处的任何错误,或发布任何建议,我将不胜荣幸,我将尝试满足。此外,我想知道是否有人计划使用此类,只是出于好奇;此代码是完全开源的。