动态创建控件支持事件响应并可保存与读取
2010-08-22 20:47:30 来源:WEB开发网上面的代码看着真头痛....其实仔细阅读也不是太难理解。它是真正负责在窗体上建立控件的代码。建立控件已经到此就完成了 ,你在例子代码中可以看到。函数会根据 addContorl 调用的第二个参数的不同在窗体上创建不同的控件,我们要做的不止这些,因为我说过,只有当动态控件能响应几乎所有事件的话,整个工程才算完整。所以接下来我们将要把控件对事件的响应完成掉。
动态控件的事件响应,两种最为常用(也许只是我) 一种是在PreTranslateMessage中判断消息的ID是否是控件ID,然后再判断事件消息来操作。一种就是使用自己的控件类,在类中添加好控件对消息的事件处理。有人会使用 ON_COMMAND_RANGE,但不总是太好也不能实现大多数消息功能。
因为在一开始,我们使用了系统向导来生成继承的控件类,所以,它是能够得到六个文件(三个.h三个.cpp),也就意味着,它是能够使用ctrl+w类向导来生成事件。你可以试一下? 呵,是的,就是这么简单,直接添加事件的响应就可以了,不如在按钮类里面来个单击事件?void CMyButton::OnClicked()
噢,真的能响应,似乎太简单了!? 也许,任何方法都是不止你所能看到的数量,而只是你我都未发现而已。
{
AfxMessageBox("你单击了我!(BN_CLICKED)");
}
到此,动态控件的添加与事件响应已经能够完成了,我还说过要将它能保存与读取,所以,下面的代码将完成它。把下面这些代码都写到global文件中://////////////////////////
//取得控件在窗体中的坐标与大小(根据控件 窗体相对屏幕的坐标)
//////////////////////////
template<class T,class B>
static CRect getRect(T& myControl,B& obj)
{
CRect _rect,_rect2,_rect3;
int _right,_bottom;//用于保存控件大小
//获取控件所在父窗体坐标
obj.GetClientRect(&_rect);
obj.ClientToScreen(&_rect);
//获取自身坐标
myControl.GetClientRect(&_rect2);
_right=_rect2.right;
_bottom=_rect2.bottom;
myControl.ClientToScreen(&_rect2);
_rect3.left=_rect2.left-_rect.left;//控件left值等于自身的left减去父窗体的left
_rect3.top=_rect2.top-_rect.top;//控件top值等于自身的top减去父窗体的top
_rect3.right=_rect3.left+_right;//这是控件的right值 等于left坐标+大小
_rect3.bottom=_rect3.top+_bottom;//这是控件的bottom值 等于top坐标+大小
return _rect3;
}
//////////////////////////
//重新计算控件坐标
//////////////////////////
template<class T>
static void getGUIData(T& obj)
{
CWnd* _wnd;
//重新计算控件坐标信息
for (int i=1;i<=globalData.count;i++) {
switch(globalData.myControl[i]->type) {
case MYBUTTON:
{
_wnd=CWnd::FromHandle(globalData.myControl[i]->myButton.m_hWnd);
}
break;
case MYEDIT:
{
_wnd=CWnd::FromHandle(globalData.myControl[i]->myEdit.m_hWnd);
}
break;
case MYLABEL:
{
_wnd=CWnd::FromHandle(globalData.myControl[i]->myLabel.m_hWnd);
}break;
default:;
}
globalData.myControl[i]->rect=getRect(*_wnd,*obj);
}
}
// **********************************************
//数据保存
// **********************************************
template<class T>
static void saveFile(T& object)
{
getGUIData(object);//重新计算控件坐标及大小
//共用变量
CString _str;
//清空文件
CFile _file(globalData.appAllPath,CFile::modeCreate);//清空文件先CFile::Remove
_file.Close();
//DeleteFile(globalData.appAllPath);//删除整个文件
//清除
//WritePrivateProfileString(APPINFO,NULL,NULL,globalData.appAllPath);
//保存数量
_str.Format("%d",globalData.count);
WritePrivateProfileString(APPINFO,"count",_str,globalData.appAllPath);
//保存控件信息
//清除
//WritePrivateProfileString(CONTROL,NULL,NULL,globalData.appAllPath);
CString ITEM,_temp;
for (int i=1;i<=globalData.count;i++)
{
_str.Format("%d",i);
ITEM=CONTROL+_str;//项名
//公共属性
WritePrivateProfileString(ITEM,"caption",globalData.myControl[i]->caption,globalData.appAllPath);
_temp.Format("%d",globalData.myControl[i]->rect.left);
WritePrivateProfileString(ITEM,"left",_temp,globalData.appAllPath);
_temp.Format("%d",globalData.myControl[i]->rect.top);
WritePrivateProfileString(ITEM,"top",_temp,globalData.appAllPath);
_temp.Format("%d",globalData.myControl[i]->rect.right);
WritePrivateProfileString(ITEM,"right",_temp,globalData.appAllPath);
_temp.Format("%d",globalData.myControl[i]->rect.bottom);
WritePrivateProfileString(ITEM,"bottom",_temp,globalData.appAllPath);
_temp.Format("%d",globalData.myControl[i]->type);
WritePrivateProfileString(ITEM,"type",_temp,globalData.appAllPath);
}
}
// **********************************************
//数据读取
// **********************************************
template<class T>
void readFile(T& object)
{
//清除资源
for (int j=1;j<=globalData.count;j++) {
delete globalData.myControl[j];
globalData.myControl[j]=new _myControl;
}
CString _str,ITEM;
char _buff[255];
globalData.count=GetPrivateProfileInt(APPINFO,"count",NULL,globalData.appAllPath);
for(int i=1;i<=globalData.count;i++)
{
_str.Format("%d",i);
ITEM=CONTROL+_str;//项名
GetPrivateProfileString(ITEM,"caption",NULL,_buff,256,globalData.appAllPath);
globalData.myControl[i]->caption.Format("%s",_buff);
globalData.myControl[i]->rect.left=GetPrivateProfileInt(ITEM,"left",NULL,globalData.appAllPath);
globalData.myControl[i]->rect.top=GetPrivateProfileInt(ITEM,"top",NULL,globalData.appAllPath);
globalData.myControl[i]->rect.right=GetPrivateProfileInt(ITEM,"right",NULL,globalData.appAllPath);
globalData.myControl[i]->rect.bottom=GetPrivateProfileInt(ITEM,"bottom",NULL,globalData.appAllPath);
globalData.myControl[i]->type=GetPrivateProfileInt(ITEM,"type",NULL,globalData.appAllPath);
//调用创建控件函数
addContorl(object,globalData.myControl[i]->type,i);
}
//获取屏幕分辩率
int nFullWidth=GetSystemMetrics(SM_CXSCREEN);
int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
}
更多精彩
赞助商链接