Besteht die Gefahr, daß deine Benutzer mit 1000-er Seperatoren
arbeiten?
Wenn ja, dann gibt es keine wirklich gute Lösung dafür. Allerdings
sollte man ihnen das IMHO sowieso abgewöhnen. Führt in der Praxis
immer wieder zu Ärger.
Zu deinem Problem.
Die MFC-spezial DDX Makros, mit denen man ein Edit Feld so
einschränken kann, daß eine Zahleneingabe erwartet wird, sind
so in der Praxis sowieso Müll. Lösch einfach mal die Zahl aus
so einem Edit Feld raus (zb. mit einem Backspace) und die MFC
mault rum, daß man bitte eine Zahl eingeben möge. Einen Endbenutzer
kann man damit in den Wahnsinn treiben.
Lösung: Auch Zahleneingaben immer als Texteingaben machen, und
die Umwandlung in eine Zahl dann selbst (zb. mit einem sscanf)
machen. Dann ist es auch einfach im String, den man vom Control
bekommt, alle ',' durch '.' zu ersetzen, sodaß sscanf das richtig
parsen kann. Der Vorteil: Der Benutzer kann dann wahlweise
sowohl ',' als auch '.' als Dezimaltrenner verwenden. Geht aber
klarerweise nur dann, wenn 1000-er Seperatoren nicht benutzt werden.
Wir haben uns dafür spezielle DDX Funktionen geschrieben.
Zb. sowas
1 | void C3dDDX_Text( CDataExchange* pDX, int nIdC, double& d, int Comma = 2 );
|
1 | void C3dDDX_Text( CDataExchange* pDX, int nIdC, double& d, int Comma /* = 2 */ )
|
2 | {
|
3 | CWnd* pWnd = pDX->m_pDlgWnd->GetDlgItem( nIdC );
|
4 | CString str;
|
5 |
|
6 | pDX->PrepareEditCtrl( nIdC );
|
7 |
|
8 | ASSERT( pWnd );
|
9 | if( pDX->m_bSaveAndValidate ) {
|
10 | pWnd->GetWindowText( str );
|
11 |
|
12 | int n = str.Find( _T( "," ) );
|
13 | if( -1 < n ) {
|
14 | str.SetAt( n, '.' );
|
15 | }
|
16 |
|
17 | d = 0;
|
18 | _stscanf( str, _T( "%lf" ), &d );
|
19 | }
|
20 |
|
21 | else {
|
22 | TCHAR szBuf[64];
|
23 | _stprintf( szBuf, _T( "%-8.*lf" ), Comma, d );
|
24 | pWnd->SetWindowText( szBuf );
|
25 | }
|
26 | }
|
Die haben dann auch noch den netten Nebeneffekt, dass man die
Anzahl der auszugebenden Nachkommastellen sauber definieren
kann.
Wenn der Dialog dann fertig ist, wird die DDX Zeile in DoDataExchange
gegen einen Aufruf so einer Funktion ersetzt:
1 | void CKalibrierfaktor::DoDataExchange(CDataExchange* pDX)
|
2 | {
|
3 | CDialog::DoDataExchange(pDX);
|
4 | //{{AFX_DATA_MAP(CKalibrierfaktor)
|
5 | C3dDDX_Text(pDX, IDC_txtFaktor, m_fWert, 3);
|
6 | //}}AFX_DATA_MAP
|
7 | }
|
Allerdings spielt dann der Dialogeditor nicht mehr mit. Daher
diesen Austausch erst ganz zum Schluss machen.