Upload
edgar-reeves
View
287
Download
0
Embed Size (px)
DESCRIPTION
Modaless 對話盒的設計 Modaless 對話盒的使用方式 – 相較於 modal 對話盒而言, modaless 對話盒較為複 雜。要建立一個 modaless 對話盒我們必須呼叫 CDialog 的預設建構式建構對話盒物件,然後呼叫 CDialog::Create 函式產生對話盒視窗,而非 DoModal 函式。 – 對於一個 modaless 對話盒,你必須確切地掌握:何 時建構對話盒物件?何時產生對話盒視窗?何時摧 毀對話盒?何時處理使用者的輸入資料?
Citation preview
Visual C++ Windows Programming
第十章 Modaless 對話盒
大綱• Modaless 對話盒的設計• 對話盒應用程式的使用
Modaless 對話盒的設計• Modaless 對話盒的使用方式
– 相較於 modal 對話盒而言, modaless 對話盒較為複雜。要建立一個 modaless 對話盒我們必須呼叫 CDialog 的預設建構式建構對話盒物件,然後呼叫 CDialog::Create 函式產生對話盒視窗,而非 DoModal 函式。
– 對於一個 modaless 對話盒,你必須確切地掌握:何時建構對話盒物件?何時產生對話盒視窗?何時摧毀對話盒?何時處理使用者的輸入資料?
Modaless 對話盒的設計 ( 續 )
• 使用者自訂訊息– 傳送 Windows 訊息的方式有 CWnd::SendMessage 函式或者 CWnd::PostMessage 兩種。 SendMessage 會立刻呼叫訊息處理函式,而 PostMessage 函式只會把訊息放在 Windows 的 Message Queue 中。因此大多數的狀況,我們要送出使用者訊息的時候,採用 PostMessage 函式。
對話盒應用程式的使用• Doc/View 的迷思
– 建立一個 Doc/View 架構的應用程式是相當大的工程,但它的確為我們解決了不少資料處理的問題。– 對於一般並不處理資料儲存的應用程式而言,使用 Doc/
View 架構顯然小題大作,因此我們只需要將這類應用程式建立成對話盒應用程式就可以了。– 一般而言,對話盒應用程式相較於 Doc/View 架構的視窗應用程式,通常是比較小的程式,例如 CD 播放程式, FTP Client 等等。兩者的差別在於對話盒應用程式是獨立的一個程式,一般的對話盒通常只是某一個程式的一部分,僅在被呼叫時,才被產生。
http://cobra.ee.ntu.edu.tw/~bypeng/VC2003-3/programs/numres.zip
*Dlg.cpp// exam10Dlg.cpp : implementation file//
#include "stdafx.h"#include "exam10.h"#include "exam10Dlg.h"
#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif
/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog{public:
CAboutDlg();
// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA
*Dlg.cpp ( 續 )// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL
// Implementationprotected:
//{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){
//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX){
CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP
}
*Dlg.cpp ( 續 )BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)// No message handlers
//}}AFX_MSG_MAPEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////// CExam10Dlg dialog
CExam10Dlg::CExam10Dlg(CWnd* pParent /*=NULL*/): CDialog(CExam10Dlg::IDD, pParent)
{//{{AFX_DATA_INIT(CExam10Dlg)//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CExam10Dlg::DoDataExchange(CDataExchange* pDX){
CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CExam10Dlg)DDX_Control(pDX, IDC_S2, m_second2);DDX_Control(pDX, IDC_S1, m_second1);DDX_Control(pDX, IDC_M2, m_minute2);
*Dlg.cpp ( 續 )DDX_Control(pDX, IDC_M1, m_minute1);DDX_Control(pDX, IDC_H2, m_hour2);DDX_Control(pDX, IDC_H1, m_hour1);DDX_Control(pDX, IDC_COLON2, m_colon2);DDX_Control(pDX, IDC_COLON1, m_colon1);//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CExam10Dlg, CDialog)//{{AFX_MSG_MAP(CExam10Dlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_TIMER()ON_WM_DESTROY()//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////// CExam10Dlg message handlers
BOOL CExam10Dlg::OnInitDialog(){
CDialog::OnInitDialog();
*Dlg.cpp ( 續 )// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){
CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){
pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}}
// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
*Dlg.cpp ( 續 ) if(!SetTimer(IDC_TIMER, 1000, NULL)) { MessageBox("Timer Setup Failure."); DestroyWindow(); }
return TRUE; // return TRUE unless you set the focus to a control}
void CExam10Dlg::OnSysCommand(UINT nID, LPARAM lParam){
if ((nID & 0xFFF0) == IDM_ABOUTBOX){
CAboutDlg dlgAbout;dlgAbout.DoModal();
}else{
CDialog::OnSysCommand(nID, lParam);}
}
// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.
*Dlg.cpp ( 續 )void CExam10Dlg::OnPaint() {
if (IsIconic()){
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icondc.DrawIcon(x, y, m_hIcon);
}else{
CDialog::OnPaint();}
}
*Dlg.cpp ( 續 )// The system calls this to obtain the cursor to display while the user drags// the minimized window.HCURSOR CExam10Dlg::OnQueryDragIcon(){
return (HCURSOR) m_hIcon;}
void CExam10Dlg::OnTimer(UINT nIDEvent) {
// TODO: Add your message handler code here and/or call default CTime Current = CTime::GetCurrentTime();
long hour, minute, second; hour = Current.GetHour(); minute = Current.GetMinute(); second = Current.GetSecond();
m_hour1.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + hour / 10)); m_hour2.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + hour % 10)); m_colon1.SetIcon(AfxGetApp()->LoadIcon(IDI_COLON)); m_minute1.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + minute / 10)); m_minute2.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + minute % 10)); m_colon2.SetIcon(AfxGetApp()->LoadIcon(IDI_COLON)); m_second1.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + second / 10)); m_second2.SetIcon(AfxGetApp()->LoadIcon(IDI_NUM0 + second % 10));
*Dlg.cpp ( 續 )CDialog::OnTimer(nIDEvent);
}
void CExam10Dlg::OnDestroy() {
CDialog::OnDestroy();
// TODO: Add your message handler code here KillTimer(IDC_TIMER);}