七 对话框

来源:互联网 发布:淘宝店个人转让流程 编辑:程序博客网 时间:2024/04/29 15:37

1.模态与非模态对话框

模态对话框创建

CTestDlg dlg;

dlg.DoModal();

 

非模态对话框的创建

CTestDlg *pDlg =new CTestDlg();

pDlg->Create(IDD_DIALOG1,this);

pDlg->ShowWindow(SW_SHOW);

这里第一个参数是对话框资源的ID和或话框模板的名称。

第二个参数是对话框的父窗口。

 

这里需要注意以下几点

1.  Create创建非模态对话框要用ShowWindow才会显示出来。

2.  这里用指针是因为要在堆上分配内存,在堆上分配内存是整个程序的生命周期一致的。这样做又会遇到一个问题,当这个函数体结速时,生命周期结束了,指针变量被销毁了。所指向的内存丢失了。

解决方法有两种:

一.     将指针变量声明为类的成员变量。在类的析构函数里,用delete函数释方指向的那块内存。

二.     CTestDlg中重载PostNcDestory函数,释放this指针指向的内存,delete this;

3.  如果用的是局部变量,在函数结束时会销毁局部变量。CTestDlg 被销毁了当然不会显示出来。还有一种解决方法是声明为类的成员变量。这样生命周期跟类一致。

4.  为什以模态对话框的可以用局部变量呢?这是因为模态对话框的实现机制,在弹出对话框后,创建模态对话框的函数被中止了,模态对话框关闭后,才继续执行创建函数体其它部份。

5.  对于非模态对话框,如果有ID值为IDOKIDCANCEL的按钮就必须重写OnOKOnCancel函数,在重写的函数中调用DestoryWindow函数销毁销口。因为基类虚函数OnOk按钮最终调用的EndDialog函数只会隐藏非模态窗口,但会销毁模态窗口。

2.动态创建按钮

知识点:按钮这类消息属于通告消息。

 

m_btn.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,123);

这里需要注意一下如果没有指定WS_VISIBLE随后一定要ShowWindow按钮才会显示出来。

但这样会有一个出现问题,因为用一个按钮动态的创建了另一个按钮后新创建的窗口就会与按钮相关联,已经绑定在一起了,再次创建就会出现问题。如何解决呢?

static BOOL  m_bIsCreated=FALSE;//只在第一次分配内存时赋值了,以后都不会重新赋值。

   if(m_bIsCreated==FALSE)

   {

      m_btn.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,123);

      m_bIsCreated=TRUE;

   }

  

   else

   {

      m_btn.DestroyWindow();

      m_bIsCreated=FALSE;

   }

Cwnd类里有一个成员变量m_hWnd保存了与窗口对象相关联的窗口句柄。

if(!m_btn.m_hWnd)

   {

      m_btn.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,CRect(0,0,100,100),this,123);

   }

  

else

   {

      m_btn.DestroyWindow();

   }

3.静态文本控件

为了使一个静态文本控件能够响应鼠标单击消息,那么需要进行两个特殊的步骤:

第一步,改变它的ID;

第二步,在它的属性对话框中选中Notify选项。(允许向其父窗口发送通告消息)

4.编辑框控件

2个编辑框内容求合显示在第三个编辑框内问题。

第一种方式:

int num1,num2,num3;

char ch1[10],ch2[10],ch3[10];

GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);

GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);

num1=atoi(ch1);

num2=atoi(ch2);

num3=num1+num2;

itoa(num3,ch3,10);

//这里的第三个参数是表示要转换的进制,这里代表是10进制。

GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);

第二种方式:

       int num1,num2,num3;

   char ch1[10],ch2[10],ch3[10];

   GetDlgItemText(IDC_EDIT1,ch1,10);

   GetDlgItemText(IDC_EDIT2,ch2,10);

   num1=atoi(ch1);

   num2=atoi(ch2);

   num3=num1+num2;

   itoa(num3,ch3,10);

   SetDlgItemText(IDC_EDIT3,ch3);

第三种方式:

   int num1,num2,num3;

   num1=GetDlgItemInt(IDC_EDIT1);

   num2=GetDlgItemInt(IDC_EDIT2);

   num3=num1+num2;

   SetDlgItemInt(IDC_EDIT3,num3);

第四种方式:

首选在ClassWizard中将控件与类成员变量关联。

会自动在源文件增加三处代码。首先在AFX_DATE之间增加三个成员变量。

在构造函数中对这三个变量进行初始化。

DoDataExchange函数内部实现了对话框控件与类成员变量的关联。

//{{AFX_DATA_MAP(CTestDlg)

   DDX_Text(pDX, IDC_EDIT1, m_num1);

   DDX_Text(pDX, IDC_EDIT2, m_num2);

   DDX_Text(pDX, IDC_EDIT3, m_num3);

   //}}AFX_DATA_MAP

   OnAdd中代码

   UpdateData();获取数据

   m_num3=m_num1+m_num2;

   UpdateData(FALSE);初始化数据(m_num3去更对话框里内容 )

这里要注意 必须调用DoDataExchange函数来完成数据交换,但在程序中从不直接调用DoDateExchange函数。要调用Cwnd类的成员函数UpdateData函数  来调用DoDateExchange

UpdateData有参数为TRUEFALSE如果为TRUE则从对话框获取数据,如果为FALSE则初始化对话框内容

 

知识点:DDX  Dialog Data Exchange数据交换

        DDV  Dialog Date Validation数据较验

 

第五种:类似第四种还可以在ClassWizard中关联控件变量。

 

第六种:

       int num1,num2,num3;

   char ch1[10],ch2[10],ch3[10];

   ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);

   ::SendMessage(GetDlgItem(IDC_EDIT2)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch2);

   num1=atoi(ch1);

   num2=atoi(ch2);

   num3=num1+num2;

   itoa(num3,ch3,10);

   ::SendMessage(GetDlgItem(IDC_EDIT3)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch3);

 

第七种:

不同于第六种,这里用Cwnd的成员函数数发送消息SendDlgItemMessage()

int num1,num2,num3;

char ch1[10],ch2[10],ch3[10];

SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);

SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LPARAM)ch2);

num1=atoi(ch1);

num2=atoi(ch2);

num3=num1+num2;

itoa(num3,ch3,10);

SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,0,LPARAM(ch3));

 

选取编辑框中复选的内容

GetDlgItem(IDC_EDIT3)->SetFocus();

SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,1,3);

选中IDC_EDIT313位置字符串。

知识点:EM_SETSEL该消息用来设置复选框中内容

EM   Edit Control Message编辑框控件消息。

对应的是EM_GETSEL

这里有一个特殊情况,当wParam0,lParam-1时对控件所有内容进行设置复选。

 

以下7种方试的总结。

GetDlgItem()->Get(Set)WindowText();

GetDlItemText()/SetDlgItemText();

GetDlgItemInt()/SetDlgItemInt();

将控件和整型变量相关联

将控件和控件变量相关联

SendMessage();

SendDlgItemMessage();

 

5对话框伸缩功能的实现

static CRect rectLarge;

   static CRect smallLarge;

   if(rectLarge.IsRectNull())

   {

      CRect rectSeperator;

      GetWindowRect(&rectLarge);

      GetDlgItem(IDC_SEPERATOR)->GetWindowRect(&rectSeperator);

      smallLarge.top=rectLarge.top;

      smallLarge.left=rectLarge.left;

      smallLarge.right=rectLarge.right;

      smallLarge.bottom=rectSeperator.top;

   }

   CString str;

   if(GetDlgItemText(IDC_BUTTON1,str),str=="收缩<<")

   {

      SetDlgItemText(IDC_BUTTON1,"扩展>>");

      SetWindowPos(NULL,0,0,smallLarge.Width(),smallLarge.Height(),SWP_NOMOVE|SWP_NOZORDER);

   }

   else

   {

      SetDlgItemText(IDC_BUTTON1,"收缩<<");

      SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),SWP_NOMOVE|SWP_NOZORDER);

   }

 

IsRectEmpty

检测矩形区域是否为空。如果矩形的宽度和高度为0或是一个负值,则说明此矩为空,返回非零值;否则,返回0.

IsRectNull

如果矩形的左上和右下角四个坐标值都是0,则函数返回一个非零值;否则,返回0.

Cwnd类成员函数

BOOL SetWindowPos(

  HWND hWndInsertAfter,  // placement-order handle

  int X,                 // horizontal position

  int Y,                 // vertical position

  int cx,                // width

  int cy,                // height

  UINT uFlags            // window-positioning options

);

6.输入焦点的传递

WNDPROC prevProc;

LRESULT CALLBACK NewEditProc(

                     HWND hwnd,   

                     UINT uMsg,     

                     WPARAM wParam, 

                     LPARAM lParam  

                     )

{

   if(uMsg==WM_CHAR && wParam==0x0d)

   {

      SetFocus(GetWindow(hwnd,GW_HWNDNEXT));//这个是按Z次顺排列。

或者SetFocus(GetNextWindow(hwnd,GW_HWNDNEXT);

      return 1;

   }

   else

   {

      return prevProc(hwnd,uMsg,wParam,lParam);

   }

}

在原有的窗口过程函数上添加。

       prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,(LONG)NewEditProc);

 

依次或将光标指向下一个窗口在MFC的默认回事消息响应函数中

       GetFocus()->GetNextWindow()->SetFocus();

7.默认按钮的进一步说明

依次或将光标指向下一个窗口在MFC的默认回事消息响应函数中

       GetFocus()->GetNextWindow()->SetFocus();