非模式对话框使用手记

来源:互联网 发布:李涛疯狂淘宝扒皮 编辑:程序博客网 时间:2024/05/16 08:10
1、非模式对话框的打开:
 // 弹出无模式对话框
   CDevPproperty *pDlg= new CDevPproperty;
   pDlg->Create(IDD_DEV_PROPERTY,GetDesktopWindow());
   
   // 填充设备属性,用SetDlgItemInt()时就不用再定义一个CString来将数据转换成字符串了
   pDlg->SetDlgItemInt(IDC_EDT_DEV_ID,i,TRUE);
   // 为了实现向组合框发送选项,而又不想定义变量,所以这里用了消息传递   
   pWnd=pDlg->GetDlgItem(IDC_CMB_DEV_STATUS);
   pWnd->SetFocus();   // 设置对话框中的焦点
   pWnd->SendMessage(CB_SETCURSEL,CDeviceInfo[i].status,0);
   // 显示窗口
   pDlg->ShowWindow(SW_SHOW);
2、关闭非模式对话框:
 DestroyWindow();
 delete this;
 
3、在非模式对话框中向主对话框发送消息:
 // 获取全局句柄,然后调用Invalidate()来更新窗口
 AfxGetMainWnd()->Invalidate();
4、主窗口中向非模式对话框发送消息
   // 填充设备属性,用SetDlgItemInt()时就不用再定义一个CString来将数据转换成字符串了
   pDlg->SetDlgItemInt(IDC_EDT_DEV_ID,i,TRUE);
   // 为了实现向组合框发送选项,而又不想定义变量,所以这里用了消息传递   
   pWnd=pDlg->GetDlgItem(IDC_CMB_DEV_STATUS);
   pWnd->SetFocus();   // 设置对话框中的焦点
   pWnd->SendMessage(CB_SETCURSEL,CDeviceInfo[i].status,0);
   
5、将非模式对话框显示在父窗口后面,并且可以切换
一种解决办法是:
建立非模式对话框时Create的第二个参数用GetDesktopWindow(),
m_pDlg->Create(IDD_,GetDesktopWindow());
如果需要恢复Toolbar的属性:
m_pDlg->SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
现在有出现了一个问题:系统的任务栏上出现了非模式对话框的图标,好像该对话框和父窗口是两个应用。解决的办法是:
1 定义对象 CWnd *m_pWnd,该对象的父窗口为GetDesktopWindow,设置该对象ShowWindow(SW_HIDE);
2 将非模式对话框的父窗口设置为m_pWnd。

6、非模式对话框与主对话框是一个消息循环
7、如何取得非模式对话框的父窗口指针
取父窗口指针用GetParent()

class CWnd* hWnd = FindWindow(NULL,"窗口标题");
8、基于文档/视图的主窗口均是CMainFrame对象,需要在CView内响应的消息应该这样发送:
CMainFrame *pwnd = (CMainFrame *)GetParent();
pwnd->GetActiveView()->SendMessage(...)
9、怎样才能在线程中实现对话框的顶层显示。
不知为什么设置成WS_EX_TOPMOST并不能实现,可能我们还没有真正理解它该怎样使用。但我用另外的方法实现了:
SetWindowPos (&wndTopMost, 0, 0, 0, 0,SWP_NOMOVE | SWP_NOSIZE)。
10、建立非模态对话框时,它总是在主窗口的最上面,如何才能使它的主窗口显示在上面.
答:1)你有没有试过AfxGetMainWnd()->SetForegroundWindow(),在建立你的非模态对话框之后?
2)当你建立对话框时,向导建立的构造函数有一个指针指出该对话框的父窗口,如果你输入一个窗口,那么该对话框将总是显示在该窗口的上面,如果你输入一个NULL 那么该对话框就可以在主程序窗口的上面或者下面了.不过这时要仔细考虑用户界面,如果非模态对话框在主窗口消失,会不会让你的用户产生误会?是否将非模态对话框显示在任务条上.
11、MSDN中非模式对话框的代码
CMyDialog* pDialog;
void CMyWnd::OnSomeAction()
{
   //pDialog initialized to NULL in the constructor of CMyWnd class
   pDialog = new CMyDialog();
   //Check if new succeeded and we got a valid pointer to a dialog object
   if(pDialog != NULL)
   {
      BOOL ret = pDialog->Create(IDD_MYDIALOG,this);
      if(!ret)   //Create failed.
         AfxMessageBox("Error creating Dialog");
      pDialog->ShowWindow(SW_SHOW);
   }
   else
      AfxMessageBox("Error Creating Dialog Object");
}
14、
由于非模式对话框是在堆中动态分配的,所以每次弹出时,其中的一些变量如果弹出多个的话会有些冲突,比如我在显示每个设备的电量时,由于要用图形显示出来,所以要保存好原来的位置,然后再从第一个位置开始循环画点,这个时候就会发现,弹出的多个对话框中的值是相同的,因此必须要区分开来,我用了两种办法,一是用数组,可以是二维,也可以是一维的,这样呢,用其中的id号作标识。另一个方法是将这些全局变量声明在类内,作为类的变量存在,这样就不会互相干扰了。看代码
在非模式对话框头文件中加入变量:其中m_pt[]是为了保存所有的点的位置,而m_pt_num保存的是点的数目,m_index保存的是一个循环的索引
 CPoint m_pt[X_GRID_NUM];
 int m_pt_num;
 int m_index;
在非模式对话框程序中加入:
 CBrush drawBrush;
 drawBrush.CreateSolidBrush(RGB(255,255,0));   // 初始化画刷,为黄色
 
 pDC->SelectObject(&drawBrush);       // 选择画刷
 pDC->Ellipse(CRect(-3,-3,3,3));  // 画圆,RFD类型为圆圈
 Sleep(100);
 len = (rc.right-20)/X_GRID_NUM;
 m_pt_num = (m_pt_num+1) % X_GRID_NUM;
 
 m_pt[m_pt_num].x=len*m_pt_num;
 m_pt[m_pt_num].y=-CDeviceInfo[id].power/2;
 
 for(m_index=1; m_index<=m_pt_num; m_index++)
 {
  pDC->Ellipse(CRect(m_pt[m_index].x-1,m_pt[m_index].y-1,m_pt[m_index].x+2,m_pt[m_index].y+2));
 
   pDC->MoveTo(m_pt[m_index-1]);
   pDC->LineTo(m_pt[m_index]); 
 }
原创粉丝点击