bokee.net

电子/电气工程师博客

正文 更多文章

使用CFileDialog类-在动态对话框上动态创建控件

      使用CFileDialog类-在动态对话框上动态创建控件
                               王佰营 徐丽红
    在动态对话框上用Create函数很方便动态创建控件,但是动态对话框要显示,
必须调用DoModal()函数,数据的更新和交换都在该函数中处理,直到退出该函数
才返回IDOK或IDCANCEL值;我们无法处理动态控件的信息更新和交换。
    为了实现动态控件的信息交换,可以借助局部勾子函数介入DoModal()的消息
处理, 本例是截获鼠标单击并且在OK键上时, 在DoModal()函数处理OK键消息
之前,处理动态控件的有关信息,实现数据的交换。
     该程序的界面如下:
    
     以下是以文件打开对话框上动态创建静态文本框和编辑文本框为例,说明以
上思想,将整个实现做成CFileDialog类的继承类---CMyFileDialog,仅仅是个
示例,已在VC++6.0上调试通过。
 一、CMyFileDialog类定义文档
#if !defined(AFX_MYFILEDIALOG_H__4DD52B6C_63B3_486A_B66C_16A87D19304C__INCLUDED_)
#define AFX_MYFILEDIALOG_H__4DD52B6C_63B3_486A_B66C_16A87D19304C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyFileDialog.h : header file
//
#include <dlgs.h>
//#include "afxdd_.h"//DDX/DDV

#define IDE_EDIT_STRA      0x2000
#define IDE_EDIT_STRB      0x2001
#define IDE_BUT_BUTOPEN    0x2002
#define IDE_SAT_FORSTRA    0x2003

TCHAR  static chEdit[129];

/////////////////////////////////////////////////////////////////////////////
// CMyFileDialog dialog

 static HHOOK m_ghook;

class CMyFileDialog : public CFileDialog
{
 DECLARE_DYNAMIC(CMyFileDialog)

public:
 //bOpenFileDialog: TRUE for FileOpen, FALSE for FileSaveAs
 CMyFileDialog(BOOL bOpenFileDialog,
  LPCTSTR lpszDefExt = NULL,
  LPCTSTR lpszFileName = NULL,
  DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
  LPCTSTR lpszFilter = NULL,
  CWnd* pParentWnd = NULL);

  ~CMyFileDialog();

  BOOL OnInitDialog(void);
  int DoModal(void);
  CString GetEditA(void);

 static LRESULT CALLBACK MyMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
private:
 CEdit m_CeditA;
 CString m_strEditA;

 CEdit m_CeditB;
 CString m_strEditB;

 CStatic m_Static;

 TCHAR  * pchEdit;

 //int DoModal(void);
 // ClassWizard generated virtual function overrides


protected:
 //{{AFX_MSG(CMyFileDialog)
 //}}AFX_MSG
 afx_msg void OnButOpen();
 afx_msg BOOL OnGetEditStr(WPARAM wParam, LPARAM lParam); 
 DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYFILEDIALOG_H__4DD52B6C_63B3_486A_B66C_16A87D19304C__INCLUDED_)

 二、CMyFileDialog类实现文档
// MyFileDialog.cpp : implementation file
//

#include "stdafx.h"
#include "FileDialogEx.h"
#include "MyFileDialog.h"
#include <afxdllx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDE_EDIT_MY                  0x017B

CString  strTitle;
/////////////////////////////////////////////////////////////
// CMyFileDialog

IMPLEMENT_DYNAMIC(CMyFileDialog, CFileDialog)

CMyFileDialog::CMyFileDialog(BOOL bOpenFileDialog,
        LPCTSTR lpszDefExt,
        LPCTSTR lpszFileName,
        DWORD dwFlags,
        LPCTSTR lpszFilter,
        CWnd* pParentWnd) :
     CFileDialog(bOpenFileDialog,
        lpszDefExt,
        lpszFileName,
        dwFlags,
        lpszFilter,
        pParentWnd)
{
}


BEGIN_MESSAGE_MAP(CMyFileDialog, CFileDialog)
 //{{AFX_MSG_MAP(CMyFileDialog)
 //}}AFX_MSG_MAP
 END_MESSAGE_MAP()

CMyFileDialog:: ~CMyFileDialog()
{
 //卸载勾子函数
 if(m_ghook!=NULL)UnhookWindowsHookEx(m_ghook);
}

BOOL CMyFileDialog::OnInitDialog() // Override
{

 pchEdit = chEdit;

 const UINT iExtraSize = 150;
 const UINT nControls = 7;
 CWnd* pWndDlg=NULL;

 pWndDlg = GetParent();
 RECT Rect;
 pWndDlg->GetWindowRect(&Rect);

 pWndDlg->SetWindowPos( NULL,
       0,
       0,
       Rect.right - Rect.left,
       Rect.bottom - Rect.top + iExtraSize/2,
       SWP_NOMOVE);
 UINT Controls[nControls] = {stc3,stc2,edt1,cmb1,IDOK,IDCANCEL,lst1};
 for (int i=0 ; i<nControls ; i++)
 {
  CWnd *wndCtrl = pWndDlg->GetDlgItem(Controls[i]);
  wndCtrl->GetWindowRect(&Rect);
  pWndDlg->ScreenToClient(&Rect);
  if (Controls[i] != lst1)
  {
   wndCtrl->SetWindowPos( NULL,
         Rect.left,
         Rect.top + iExtraSize/2,
         0,
         0,
         SWP_NOSIZE);
  }
  else
  {
   wndCtrl->SetWindowPos( NULL,
         0,
         0,
         Rect.right - Rect.left,
         Rect.bottom - Rect.top + iExtraSize/2,
         SWP_NOMOVE);
  }
 }

 /////////////////////////////////////////////////////////////
 //创建编辑文本框控件
 pWndDlg = GetParent();
 pWndDlg->GetWindowRect(&Rect);
 CRect m_rect;
 m_CeditA.Create(WS_CHILD|WS_VISIBLE|ES_CENTER ,
     m_rect,
     pWndDlg,
     IDE_EDIT_STRA);
 m_CeditA.ModifyStyleEx( 0,
       WS_EX_CLIENTEDGE,
       SWP_DRAWFRAME);
 //通过COMB控件定位新加EDIT控件位置;
 CWnd *wndCtrl = pWndDlg->GetDlgItem(cmb1);
 wndCtrl->GetWindowRect(&Rect);
 pWndDlg->ScreenToClient(&Rect);
 m_CeditA.MoveWindow(Rect.left,
      Rect.bottom+10,
      Rect.right-Rect.left,
      Rect.bottom-Rect.top);
 m_CeditA.SetFont(GetFont(),true);
 m_CeditA.ReplaceSel(_T("这是新加的文本编辑框"));

 /////////////////////////////////////////////////////////////
 //创建静态文本控件
 pWndDlg = GetParent();
 pWndDlg->GetWindowRect(&Rect);
 char sb[]=_T("数据源名称");
 m_Static.Create(sb,
     WS_CHILD|WS_VISIBLE|SS_LEFT ,
     m_rect,
     pWndDlg,
     IDE_SAT_FORSTRA);
 //通过STATIC2控件定位新加静态文本控件位置;
 wndCtrl = pWndDlg->GetDlgItem(stc2);
 wndCtrl->GetWindowRect(&Rect);
 pWndDlg->ScreenToClient(&Rect);
 m_Static.MoveWindow(Rect.left,
      Rect.bottom+15,
      80,
      Rect.bottom-Rect.top);
 m_Static.SetFont(GetFont(),true);


 for(i=0;i<128;i++) chEdit[i]=’\0’;

 //安装勾子函数
 m_ghook = ::SetWindowsHookEx(WH_MOUSE,MyMouseProc,NULL,AfxGetThread()->m_nThreadID);

 // Remember to call the baseclass.
 return CFileDialog::OnInitDialog();
}


int CMyFileDialog::DoModal()
{
 strTitle=m_ofn.lpstrTitle;
 return CFileDialog::DoModal();
}

CString CMyFileDialog::GetEditA(void)
{
 return m_strEditA=pchEdit;
}

//勾子函数
LRESULT CALLBACK CMyFileDialog::MyMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 int iID;
 HWND hwnOK ;
 CWnd* pMyCwnd=NULL;
 CRect mRect,rcOK;
 POINT mPoint=((MOUSEHOOKSTRUCT*)lParam)->pt;
 HWND hwinFileDlg=NULL;
 hwinFileDlg=::FindWindow(NULL,strTitle);//dlg.m_ofn.lpstrTitle

 if(::IsWindow(hwinFileDlg))
 {
  ::GetWindowRect(hwinFileDlg,mRect);
 }

 CString s;
 if(wParam ==WM_LBUTTONDOWN)
 {

  hwinFileDlg=::GetActiveWindow();
  ::GetWindowRect(hwinFileDlg,mRect);

  iID=::GetDlgCtrlID(hwinFileDlg);
  hwnOK=::GetDlgItem(hwinFileDlg,IDOK);
  ::GetWindowRect(hwnOK,rcOK);
  iID=::GetDlgCtrlID(hwnOK);

  if(rcOK.PtInRect(mPoint))
  {
   ::GetDlgItemText(hwinFileDlg,IDE_EDIT_STRA,chEdit,128);
   ::SetDlgItemText(hwinFileDlg,IDE_EDIT_STRA,chEdit);
  }
 }
 // 让其它钩子函数也处理发生的事件
 return CallNextHookEx(m_ghook,nCode,wParam,lParam);;
}
    三、CMyFileDialog类应用文档
void CFileDialogExDlg::OnButTest()
{
 // TODO: Add your control notification handler code here
 char szFilter[] = _T("DBSE Files (*.mdb;*.mdb)|*.mdb;*.mdb|All Files (*.*)|*.*||");
 char lpstrCustomFilter[255]={"Previous Filter\0*.mdb\0"};
 CMyFileDialog dlg( TRUE,      
      NULL,     
      NULL,       
      OFN_HIDEREADONLY |OFN_ALLOWMULTISELECT| to be selected
      OFN_OVERWRITEPROMPT,  
      szFilter,     
      NULL);      

 char lpszInitDir[]={"c:\\temp"};
 dlg.m_ofn.lpstrInitialDir=lpszInitDir;
 char lpszTitle[]={"打开数据源文件"};
 dlg.m_ofn.lpstrTitle=lpszTitle;
 dlg.m_ofn.lpstrCustomFilter=lpstrCustomFilter;
 dlg.m_ofn.nMaxCustFilter=255;
 // open file dialog and get file name(s)
 if (dlg.DoModal()==IDOK)
 {
  AfxMessageBox(dlg.GetEditA());
 }
}

关键词: VC MFC CFileDialog 勾子函数 动态 控件

分享到:

上一篇:

下一篇:Windows常见窗口样式和控件风格

评论 (0条) 发表评论

抢沙发,第一个发表评论
验证码