[ Pobierz całość w formacie PDF ] .Operacja przekazania ogniska wprowadzania zakończy się poprawnie, nawet jeśli inne metody (takie jak sprawdzenie poprawności danych) zgłoszą wystąpienie błędów.Jeśli stwierdzisz, że sprawdzane dane nie są poprawne, powinieneś wyświetlić stosowny komunikat i wywołać metodę Fail.Powoduje to zgłoszenie wyjątku, który przerwie działanie metody DoDataExchange i spowoduje umieszczenie ogniska wprowadzania w ostatnim oznaczonym elemencie kontrolnym.Oczywiście weryfikacja danych powinna być przeprowadzana tylko wtedy, gdy składowa m_bSaveAndValidate ma wartość TRUE.Podczas przekazywania danych z programu do okna dialogowego, zazwyczaj zakłada się, że dane są poprawne.Funkcje weryfikujące informacje wyglądają niemal tak samo, jak funkcje służące do przekazywania danych; różnią się jedynie argumentami.W nazwie funkcji użyj prefiksu DDV_.Jeśli chodzi o argumenty, to funkcje służące do weryfikacji danych pobierają wskaźnik do obiektu CDataExchange, wartość odpowiedniego typu oraz jeden lub dwa argumenty dodatkowe (Np.górną i dolną granicę dopuszczalnego zakresu wartości).W tym przypadku Twoje zadanie jest proste.Jeśli składowa m_bSaveAndVatidate będzie miała wartość TRUE, wykonaj dowolne czynności, za pomocą których będziesz mógł określić, czy przekazana wartość jest poprawna czy nie.Jeśli wartość jest poprawna zakończ działanie funkcji, w przeciwnym wypadku wywołaj metodę Fail.Poprzednia metoda transferu danych oznaczyła element kontrolny, którego dotyczą wykonywane operacje, więc ognisko wprowadzania zostanie umieszczone w odpowiednim miejscu.To właśnie dlatego transfer danych z wybranego elementu kontrolnego i ich weryfikacja powinny następować bezpośrednio po sobie.Na listingu 5.4 przedstawiona została kolejna wersja programu OTB (patrz listing 5.2).W programie tym wykorzystywana jest niestandardowa procedura weryfikująca poprawność danych (patrz listing 5.5).Kod weryfikujący sprawdza, czy po przecinku dziesiętnym nie podano więcej niż dwóch cyfr.Wywołuje on także standardową metodę DDV_MinMaxFloat sprawdzającą czy analizowana liczba jest poprawnie zapisaną liczbą zmiennoprzecinkową.No i dobrze, bo po co wywarzać otwarte drzwi?Zwróć uwagę na to, że funkcja sprawdzająca poprawność danych nie otrzymuje jawnie identyfikatora elementu kontrolnego, tak jak funkcja służąca do transferu danych.Dzieje się tak dlatego, że zazwyczaj funkcja weryfikująca interesuje się jedynie wartością elementu kontrolnego.Jeśli chcesz, możesz pobrać uchwyt do okna elementu kontrolnego, który jest zapisany w składowej m_hWndLastControl obiektu CDataExchange.Listing 5.4.Stosowanie własnych metod DDX i DDV// validView.cpp : implementation of the CValidView class//#include "stdafx.h"#include "valid.h"#include "validDoc.h"#include "validView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CValidViewIMPLEMENT_DYNCREATE(CValidView, CFormView)// Kreator Class Wizard nie umieści tego makra w mapie komunikatów// gdyż sądzi, że to okna dialogowe obsługują OnOK.Obsługują, to// prawda, jednakże my dysponujemy widokiem dialogu a nie oknem// dialogowymBEGIN_MESSAGE_MAP(CValidView, CFormView)//{{AFX_MSG_MAP(CValidView)ON_COMMAND(IDOK,OnOK)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CValidView construction/destructionCValidView::CValidView(): CFormView(CValidView::IDD){validating=FALSE;vid=0;//{{AFX_DATA_INIT(CValidView)m_age = 18;m_name = _T("");m_wager = 1.0f;//}}AFX_DATA_INIT// TODO: add construction code here}CValidView::~CValidView(){}void CValidView::DoDataExchange(CDataExchange* pDX){CFormView::DoDataExchange(pDX);validating=TRUE; // zapobiegniej rekursju// wywołania usunięte z komentarzy kreator Class Wizard i zmodyfikowanetry{if (!vid||vid==IDC_AGE) DDX_Text(pDX, IDC_AGE, m_age);if (!vid||vid==IDC_AGE) DDV_MinMaxInt(pDX, m_age, 18, 150);if (!vid||vid==IDC_NAME) DDX_Text(pDX, IDC_NAME, m_name);if (!vid||vid==IDC_NAME) DDV_MaxChars(pDX, m_name, 64);if (!vid||vid==IDC_WAGER) DDX_Text(pDX, IDC_WAGER, m_wager);if (!vid||vid==IDC_WAGER) DDV_MinMaxFloat(pDX, m_wager, 1.f, 100.f);//{{AFX_DATA_MAP(CValidView)//}}AFX_DATA_MAPvalidating=FALSE;}catch (.){validating=FALSE; // pamiętaj aby ustawić tą flagęthrow; // ponownie zgłoś wyjątek}}BOOL CValidView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CFormView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CValidView diagnostics#ifdef _DEBUGvoid CValidView::AssertValid() const{CFormView::AssertValid();}void CValidView::Dump(CDumpContext& dc) const{CFormView::Dump(dc);}CValidDoc* CValidView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CValidDoc)));return (CValidDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CValidView message handlersvoid CValidView::OnOK(){if (UpdateData(TRUE))MessageBox("Wager placed");}BOOL CValidView::OnCommand(WPARAM wParam, LPARAM lParam){if (HIWORD(wParam)==EN_KILLFOCUS&&!validating){vid=LOWORD(wParam);UpdateData(TRUE);// zresetuj warunki// Poniższą linię będziesz musiał wykonywać jesli// nie przechwytujesz wyjątków w metodzie DoDataExchange// validating=FALSE;vid=0;}return CFormView::OnCommand(wParam, lParam);}Listing 5.5.Niestandardowe metody DDX i DDV.#include#include "customdd.h"// Transfervoid DDX_EnableWindow(CDataExchange *pDX, int id, BOOL &flag)CWnd *ctl=pDX->m_pDlgWnd->GetDlgItem(id);if (pDX->m_bSaveAndValidate)flag=ctl->IsWindowEnabled();elsectl->EnableWindow(flag);// Weryfikacjavoid DDV_MinMaxCurrency(CDataExchange *pDX, float val, float min, float max){CWnd *editctl=CWnd::FromHandle(pDX->m_hWndLastControl);CString s;int n;if (pDX->m_bSaveAndValidate){// Zastosowanie operacji matematycznych do określenia czy coś// zostało jest złym rozwiązaniem ze względu na błędy zaokrągleń;// zamiast tego należy zastosować metody służące do obsługi// łańcuchów znakóweditctl->GetWindowText(s);n=s.Find('.');if (n!=-l && n+3FailO;> DDV_MinMaxFloat(pDX,val,min,max); // niech domyślna// funkcja zrobi resztęNa listingu 5.5 przedstawiona została także metoda wymiany danych, która zamienia wartość typu BOOL na stan zaznaczenia elementu kontrolnego.Standardowo, musiałbyś użyć kreatora Class Wizard i skojarzyć ze zmienną cały element kontrolny (np.: typu CButton).Wszystko to, tylko i wyłącznie w celu umożliwienia ustawiania stanu elementu kontrolnego.Zaprezentowana na listingu 5.5 funkcja operuje na normalnych zmiennych, dzięki czemu stan elementu kontrolnego można określać za pomocą prostej zmiennej typu BOOL.Pamiętaj tylko, że żadne modyfikacje nie będą uwzględniane aż do momentu wywołania metody UpdateData
[ Pobierz całość w formacie PDF ]
zanotowane.pldoc.pisz.plpdf.pisz.plhanula1950.keep.pl
|