现在的位置: 首页 > 综合 > 正文

MFC使用总结

2012年11月26日 ⁄ 综合 ⁄ 共 4276字 ⁄ 字号 评论关闭

1. DoDataExchange(CDataExchange* pDX)函数

这是MFC APPWizard自动生成的对话框类的成员函数,其功能是用于完成对话框控件和与之对应的成员变量的数据交换,函数的定义如下:

void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerDlg)
DDX_Control(pDX, IDC_LIST, m_list);
DDX_Control(pDX, IDC_EDIT_IPADDRESS, m_ip);
DDX_Text(pDX, IDC_EDIT_PORT, m_port);
DDV_MinMaxUInt(pDX, m_port, 0, 65535);
//}}AFX_DATA_MAP
}

DDX_Control(pDX, IDC_LIST, m_list); 用于实现控制类控件数据交换。DDX_Text(pDX, IDC_EDIT_PORT, m_port);用于一般用于完成编辑类如edit控件的数据交换。它管理着对话框、表格视或控件视对象中的编辑控件(ID)与int,UINT,long,DWORD,CString,float或double型数据成员之间的数据交换。DDX_Text的函数原形为:

void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, TYPE& value );

参数: pDX    指向CDataExchange对象的指针。框架提供了这个对象,用于建立数据交换的环境及方向。      nIDC 对话框、表格视或控件视中编辑控件的ID。
            value 对对话框、表格视或控件视对象的成员变量的引用,其类型取决于你使用了DDX_Text的哪一个重载版本。TYPE可以是int,UINT,long,DWORD,CString,float或double型。

DDV_MinMaxUInt(pDX, m_port, 0, 65535);函数是限定了成员变量m_port(整型)的取值范围,当超出范围时,系统会自动弹出警告。另外如果是字符串类型的成员变量,还可以设置其字符数的上界。

上面的一切都是用MFC 的Class Wizard自动生成,在源文件中则显示为灰色。

2.DoModal()函数

用于生成模态对话框。一般这样使用:

MyDlg mydlg;
mydlg.DoModal();

这里mydlg是 MyDlg 的一个对象,调用这个函数,即产生了一个MyDlg类型的对话框。

MSDN上解释如下:

Call this member function to invoke the modal dialog box and return the dialog-box result when done.

*Return Value
An int value that specifies the value of the nResult parameter that was passed to the CDialog::EndDialog member function, which is used to close the dialog box. The return value is –1 if the function could not create the dialog box, or IDABORT if some other error occurred, in which case the Output window will contain error information from GetLastError.

*Remarks
This member function handles all interaction with the user while the dialog box is active. This is what makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box is closed.
*If the user clicks one of the pushbuttons in the dialog box, such as OK or Cancel, a message-handler member function, such as OnOK or OnCancel, is called to attempt to close the dialog box. The default OnOK member function will validate and update the dialog-box data and close the dialog box with result IDOK, and the default OnCancel member function will close the dialog box with result IDCANCEL without validating or updating the dialog-box data. You can override these message-handler functions to alter their behavior.

3.UpdateData(TRUE)与UpdateData(FALSE)

UpdateData(TRUE):是把当前屏幕上控件显示的值赋给它所对应的成员变量。UpdateData(FALSE)则与之相反,把修改后的变量值传给它所对应的控件更新显示出来。

例如:你在你的窗体中有一个Edit控件,为这个控件关联了CString类型的变量m_strName;    你在控件中添入内容之后,必须调用UpdateData(true);才能把你添入的内容传给m_strName这个变量;而当你在程序中改变了m_strName变量的内容的时候,如果你想让那个Edit也显示更新后的m_strName,就必须调用UpdateData(false);    这样在你的Edit中才能显示更新完的变量的值!  

这里需要注意的是,使用UpdateData()函数时,当前界面上所有绑定了的变量(即通过MFC ClassWizard给控件添加了对应的变量)都会被UpdateData(TRUE)更新成对应控件中的内容;同样所有绑定了变量的控件中的内容也会UpdateData(FALSE)更新成对应变量中的内容。所以数据量不多的话,最好用SetDlgItemText()和GetDlgItemText()。

4.AfxMessageBox()与MessageBox()

AfxMessageBox()一般应用于窗体之中,没有窗体,或者是全局函数,不能使用该函数;   MessageBox()可以应用于没有窗体和有窗体的两种情况。

在有窗体的情况下,两者用法一样,只需要三个参数,一个是显示文本,一个是对话框名称Caption,一个是显示方式;如 MessageBox( "我的对话框", title, MB_OK); 不过后两个参数是可以省略不写的。在没有窗体或者全局函数中,他必须传入一个窗体句柄才可能执行,如果没有,用NULL代替也可,但是此时该消息框属于桌面,可能达不到我们所需要的目的,所以一般要传入一个窗口句柄。函数原形如下:

int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);例如::MessageBox(NULL, "我的对话框", title, MB_OK);

5.AfxEnableControlContainer()

顾名思义,AfxEnableControlContainer()函数是允许应用程序作为控件容器来使用,也就是说你可以在这个应用程序中使用ocx之类的控件。对于用MFC向导自动生成的单文档框架程序的CXXXAPP::InitInstance()函数中自动加了这一句 AfxEnableControlContainer();

6.几个DC

我的聊天程序中没用到这个东西,无意中在网上搜到的,也贴下来。

CPaintDC      无效区dc,相当于BeginPaint,   EndPaint  
CClientDC     客户区dc,相当于GetDC,   ReleaseDC  
CWindowDC     整窗口dc,   相当于GetWindowDC,   ReleaseDC  
CDC           任何dc,       相当于CreateDC,   DeleteDC        
  
CWindowDC   包括   由CClientDC+标题栏;  
CClientDC     标题栏以下部分;
CPaintDC   是CClientDC的真子集,且是无效的区域,重新绘制时要用到BeginPaint,EndPaint.
如果往一个对话框上绘整个客户区大小的图应该可以用CClientDC,如果小于整个客户区请用CPaintDC

7._T()和_TEXT()

在VC6中,_T()和_TEXT()是一样的,定义如下:
#define _T() __T()
#define _TEXT() __T() 为了兼容老版本。

8.给CListCtrl控件添加图表

m_image.Create(16,16,TRUE|ILC_COLOR24,3,1);//m_image是个CImageList对象
clientlist.SetImageList(&m_image,LVSIL_SMALL);
m_image.Add(hIcon);//
HICON hIcon;
hIcon=AfxGetApp()->LoadIcon(IDI_XXX);
插入记录时LV_ITEM lvitemAdd={0};
lvitemAdd.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

9.线程处理函数写在哪?

创建线程函数 AfxBeginThread(ProcThread,(LPVOID)m_Sock);写在需要创建线程的地方,可线程处理函数ProcThread(LPVOID pParam)写在哪呢?这个问题对初学者有点困惑吧?比如你的创建线程函数写在对话框一个按钮按下的处理函数OnButtonDown()中,那么ProcThread是不是要作为该对话框类的成员函数呢?还是写成全局?

正确答案是,要么把该线程处理函数ProcThread(LPVOID pParam)写成全局函数,要么写成该对话框类的成员函数,注意一定要把该成员函数定义为静态的

抱歉!评论已关闭.