I have written this class to provide full MFC Control functionality to a previous class I had published on CodeProject,
CMapEditor (http://www.codeproject.com/cpp/CMapEditor.asp). This is the first custom control i have written, so please be easy on me ;) The basics are simple: the control takes a series of bitmaps and a
CMapEditor type, and displays the corresponding images to the
CMapEditor values. The control supports both bird-eye-view standard editor mode, and isometric view mode. I have provided a basic demo application that demonstrates these concepts. I am currently polishing an isometric editor which will be shortly available. In this article, i will illustrates the steps involved in using the
CMapEditorCtrl, i will provide information for every method, and I will discuss some know issues with the control.
Creating the control
You can initialize the control either from the Dialog Resource Editor (as shown in the Demo application), either with the
Create(...) function, as shown here:
g_pMapCtrl = new CMapEditorCtrl();
We have now successfully created the control, now we must initialize it.
Initalizing the control
isInit.iCellHeight = 20;
isInit.iCellWidth = 20;
isInit.iIsoHeight = 16;
isInit.iIsoWidth = 32;
isInit.iMapHeight = 30;
isInit.iMapWidth = 40;
isInit.pMapEditor = g_pMapEditor;
isInit.CtrlProc = ControlProc;
It is also necessary to assign the bitmaps to the control. This sample code demonstrates how to use a for to cycle an array of
HBITMAPS in memory and assign them to the control.
CBitmap *pBitmap = CBitmap::FromHandle(m_hBitmap[i][ISO]);
bmInfo.bmHeight - 32);
The control is now ready for use. The following section describes some of the steps necessary to make
CMapEditorCtrl work at best.
The callback function
The callback function works just as a
WindowProc method. The arguments passed to this function are defined as
ARG_CTRLPROC. The first argument is an integer, iMsg, which corresponds to the message code. This can be either a user defined (so that any kind of operation can be performed on the control), or a predefined value, such as
MC_LBCLICKED. User-defined messages can be used by using
CMapEditorCtrl::SetValues(...). A complete list of possible values for iMsg can be found further down in the article.
CMapEditorCtrl::SetValues( . . . )
This method must be called every time that it is necessary to change the parameters that will modify the CMapEditor when the user interacts with the control. The syntax is pretty straightforward, but to understand this at best refer to CMapEditor::SetMapValue .
The control is now completely functional.
- Single click - performs an operation based on iMode, to the selected cell, or ends a drag operation.
- Double click - begins a drag operation.
- Right click- centers the selected cell
- Ctrl + Right click - centers the selected cell and switches view mode
bool AssignBitmap(int iBitmap,HBITMAP h2DBitmap,HBITMAP hIsoBitmap,
int iHeight = 0);
void CenterCell(CPoint ptPos);
void DrawItem(CRect rUpdate = CRect(-1,-1,-1,-1));
void DrawLevel(int iLevel,bool bDraw = true);
void GetInfo(MECTRLINFO* mciInfo);
int GetPos(int nCoord);
void HighlightCell(CPoint ptPos);
bool Initialize(MECTRLINITSTRUCT* isInitStruct);
void SetValues(int iValue, int iLevel, int iMode, bool bCanDrag);
void SetViewMode(int nViewMode,bool bUpdate = true);
typedef struct _SETSTRUCT
unsigned short int iValue;
unsigned short int iLevel;
unsigned short int iMode;
typedef struct _MECTRLINITSTRUCT
short int iCellWidth;
short int iCellHeight;
short int iIsoWidth;
short int iIsoHeight;
short int iMapWidth;
short int iMapHeight;
typedef struct _MECTRLINFO
Programming this control was extremely fun, and I hope I have shared something useful to the MFC community. There are, however, some issues which I am aware of, and I state here, somewhat as to ask advice to experts. The control may experience some performance problems, usually if many other apps are open. This is primarily caused by the device context painting, which is slow if the control is big.
The control has been tested with tiles that were 64x32. Testing with other image sizes has not been tried (lazy me ;)
I'd be honored if any other CPian will take the time to take a look at
CMapEditorCtrl and report here any bug, or post any suggestion, which I will try to satisfy. Also, I'd like to know if anybody is planning on using this class, just out of curiosity; this code is completely open-source.