以AFx开头的函数:
是application framework首字母.(x是比较流行的结尾字符,如activex等),微软开发mfc时候的af小组,当时开发的全局函数.一般以afx开头
DoModal()函数:
果函数成功则返回IDOK或IDCANCEL;否则返回0或-1。此成员函数用来显示一个模态对话框。
MFC程序的入口:
以对话框程序为例,APP文件里的实例化函数InitInstance()是程序的入口,InitInstance()中会创建对话框实例,调用DoModal()函数,显示对话框。一般来说,MFC机制为我们实现好了界面的创建。为了程序的可读性和可移植性,一般不要在APP文件以及Dialog文件中实现我们自己编写的功能。
一般尽量形成APP文件做程序入口,而后进入Dialog绘出对话框,在对话框的初始化函数中调用我们自己实现的函数,这样程序就会显得有层次,进而提高代码的可读性和可移植性。
日志:
写工程程序的时候,注意到日志是一个不可或缺的文件。程序的执行的各个中间结果要保存在日志文件中,这样有利于我们后来对程序的维护和调试。
例如:
TLog g_log("alter","main","1.0.0.0#20130710"); //定义T]log对象g_log,
g_log.setFlushFlag(1); //刷新
g_log.setMaxLines(100*10000);//最大行数一百万
g_log.setWithMillisecond(true); //输出毫秒
g_log.open(); //以上四行先设置相关参数,再打开日志文件
g_log.print(LogLevel_Info, "Dbconnect for MS SQLServer DB_Library\n");//输出信息到日志中,用法同C标准输出函数printf()
g_log.close();//关闭日志
读文件相关:
//宏定义INIFILE指向配置文件
#define INIFILE "./cfg/alterCfg.ini"
//定义字符数组acSourceName用于保存SourceName
char acSourceName[64]={0};
//函数调用如下:
::GetPrivateProfileString("DATABASE", "SourceName", "127.0.0.1", acSourceName, sizeof(acSourceName), INIFILE);
//说明:将INIFILE文件中【DATABASE】下以SourceName开头的数据读入到string对象acSourceName中,若为空,则传递默认的127.0.0.1 给acSourceName。
另外,也可以通过这种方式来调用:
bool DBServer::InitDataBase(const string &iniFileName, string &errMsg)
{
errMsg = string("");
//打开配置文件
bool flag = m_configFile.Open(iniFileName.c_str());
//加载配置文件相关信息
int dbtype = m_configFile.ReadInt("Database", "Type", DB_TYPE_SQLSERVER);
string sourcename = m_configFile.ReadString("Database","SourceName", "");
……
//关闭配置文件
m_configFile.Close();
}
INIFLIE中的内容如下:
[DATABASE]
# SQLSERVER = 0,SYBASE = 1,ORACLE =2, BDE= 3
Type = 0
SourceName = 255.255.255.1
User = test
Password = hello
DatabaseName = real
Charset=
编程中,静态变量一般以m_开头。
检测到程序的有异常退出时,以不同的值return,这样后续可以知道是什么异常。
静态成员函数与无实例函数使用问题:
1,在类封装中,将函数定义为静态成员函数的好处不单是类的所有实例都可以使用,而且可以通过类名来使用静态成员函数。这样的机制使得在调用这个函数的时候并不需要将类进行实例化。
2,静态成员函数中若调用本类的成员函数,也只能调用静态成员函数,在静态成员函数中调用本类的非静态成员函数是不行的:因为静态成员函数通过类名来调用,从而没有this指针,故不能调用非静态成员函数。
3,若在调用相关函数的时候不想进行类的实例化,则将其定义为静态成员函数,但是若在其中用到而来本类的其他相关成员函数时,则会产生问题。
4、本来也可通过将所有函数所设置成静态成员函数来解决这个问题,但是把所有成员函数设置静态成员函数并不符合我们的意愿。这里我们有一个另外的解决方法:使用静态指针变量,这样做后我们不需对类进行实例化(至少是我们自己不用做这个工作)就可以使用其非静态成员函数。实例如下:
//mainserver.h
class MainServer
{
public:
static MainServer *getRef() //若不为空,则返回m_self;不然新建一个对象;
{
if (m_self) return m_self;
m_self = new MainServer();
return m_self;
};
int StartAllServer ();
int StopAllServer();
MainServer();
~MainServer();
private:
static MainServer *m_self; //定义一个静态的MainServer对象指针m_self
};
//定义了m_self之后,以后再调用MainServer成员函数的时候就可以通过m_self来实现了,而没必要实例化一个对象出来了
//mainserver.cpp
MainServer* MainServer::m_self = NULL; //初始化静态成员m_self指针
//调用class MainServer中的非静态成员函数StarteAllServer()
if( MainServer::getRef()->StartAllServer()!=0 )
{
PostMessage(WM_ICONERASEBKGND,SC_CLOSE,0L);
}
//好了,这样就可以避免我们自己去实例化了
列表框的使用:
先在对话框中拖出一个列表框,其ID为为IDC_LIST,使用类向导为其创建一个control对象m_list
在对话框的OnInitDialog()里面对list进行初始化:
styles=GetWindowLong(m_list.m_hWnd,GWL_STYLE);
SetWindowLong(m_list.m_hWnd,GWL_STYLE,styles | LVS_REPORT);
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_list.InsertColumn(1,"设备名称", LVCFMT_LEFT, 80, 0);
m_list.InsertColumn(2,"回路号", LVCFMT_LEFT, 80, 0);
m_list.InsertColumn(3,"次控号", LVCFMT_LEFT, 80, 0);
完了之后就可以插入数据了:
index = m_listpower.InsertItem(0,m_devname);
m_listpower.SetItem(index,1,LVIF_TEXT,m_devladdr, 0, 0, 0,0);
m_listpower.SetItem(index,2,LVIF_TEXT,m_spaceaddr, 0, 0, 0,0);
下拉框的使用:
先在对话框中拖出一个下拉框出来,其ID为IDC_DEVTYPE,
在对话框的OnInitDialog()里面对其进行初始化:
((CComboBox*)GetDlgItem(IDC_DEVTYPE))->AddString("TYPE1");
((CComboBox*)GetDlgItem(IDC_DEVTYPE))->AddString("TYPE2");
((CComboBox*)GetDlgItem(IDC_DEVTYPE))->AddString("TYPE3");
((CComboBox*)GetDlgItem(IDC_DEVTYPE))->AddString("TYPE4");
这样,下拉框中就会有4个选项,分别为TYPE1、TYPE2、TYPE和TYPE4
获取下拉框的信息:(通过以下方式便可将下拉框中的信息获取到strType中)
CString strType;
GetDlgItem(IDC_DEVTYPE)->GetWindowText(strType);
同理:也可以通过上述方式获取编辑框中的数据:
GetDlgItem(IDC_EDIT)->GetWindowText(strTmp); //IDC_EDIT为编辑框ID,
日期时间选取器的使用:
在对话框中,如果要选取日期,我们可以通过日期时间选取器来获得:
将日期时间选取器拖至对话框中,设置其ID为IDC_DATE,为其创建控制变量CDateTimeCtrl m_date;
在选取时间后,我们可以这样在程序中获取时间日期:
CString y,m,d;
CTime date;
CString set_date;
m_date.GetTime(date);
y.Format("%d",date.GetYear());
m.Format("%2d",date.GetMonth());
d.Format("%2d",date.GetDay());
set_date = date.Format("%Y-%m-%d %H:%M:%S");
set_date =y+"-"+m+"-"+d+" 00:00:00";
我们可以在程序中这样获得当前的时间:
CString m_time;
CTime time=CTime::GetCurrentTime();
SYSTEMTIME st;
GetLocalTime(&st);
m_time=m_sqloper.DataFormat(st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
想要获得两个时间差:
可以用下面的方式:
GetTickCount,函数。GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD。
long time1=GetTickCount();
long time2=GetTickCount();
int seconds=(time2 - time1)/1000;
seconds即为两者的时间差(s)