PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MFC-Kalender in VC++ 6.0



der Papst
18-06-2007, 20:26
Ich schreibe in Informatik ein Projekt für die Schule.
Es soll eine Art Terminkalender werden.
Dafür will ich eine MFC-Oberfläche machen und natürlich den Terminkalender benutzen.
Wie ich jetzt aber bemerkt habe, ist dieses Teil ein einziger Bug.
Die Krönung des ganzen ist, dass dieser Kalender auch noch ein falsches Datum in die zugewiesene Variable schreibt, und zwar ist es um einen bestimmten Zeitraum zu groß, ich glaube das waren 3 Monate und 10 Tage.
Umgekehrt funktioniert die Zuweisung eines Datums.

Kennt jemand eine gute Alternative dafür?

jan61
18-06-2007, 22:38
MFC? VC++? Meinst Du nicht, dass Du in einem Forum namens "mrunix" die falschen Leute um Hilfe fragst? Ist nicht böse gemeint, aber Fragen zu den M$ Foundation Classes und M$ Visual C++ kriegst Du wohl eher in einem M$-orientierten Forum beantwortet.

Jan

peschmae
19-06-2007, 07:56
Naja, mrunix ist "das Forum für Entwickler" und eigentlich Plattformunabhängig, trotz dem Namen.

Allerdings glaube ich auch kaum dass sich hier Entwickler mit Erfahrungen in so grauenhaftem Zeugs wie der MFC finden lassen werden.

MfG Peschmä

anda_skoa
19-06-2007, 14:12
Mal abgesehen davon, dass MFC selbst unter Windows schon als extrem veraltet gilt.

Kann natürlich sein, dass Benutzer "der Papst" durch äußere Umstände dazu gezwungen ist. Es kommt leider immer wieder vor, dass Firmen oder Institutionen am Stand der 1990er Jahre sind und in Ausschreibungen so alte und komplizierte Frameworks vorschreiben.

Ciao,
_

der Papst
19-06-2007, 16:54
Ich mache den Ing. in Elektronik und unsere ganze Schule ist M$-Orientiert.
Zum stand meiner Schule - wohl eher in den frühen 80ern, denn die meisten werken da noch mit Borland Grafikmodus auf Dos-Ebene rum...

Zur Platform:
Ich habe früher unter Windows und MFC programmiert.
Seit einem halben Jahr bin ich fast nur noch auf Linux unterwegs, bin aber durch das Studium mehr oder weniger zu Windoof gezwungen.
Ich hatte bis jetzt leider noch keine Zeit, die Linux-APIs zu erlernen und habe ein kleines Projekt am Freitag abzugeben.
Hier her kam ich durch mein Stammforum - linuxforen.de - dass dieses hier als Partnerforum angegeben hat.

sommerfee
19-06-2007, 18:17
Dafür will ich eine MFC-Oberfläche machen und natürlich den Terminkalender benutzen.
Wie ich jetzt aber bemerkt habe, ist dieses Teil ein einziger Bug.

Was genau meinst du mit "Terminkalender"? Meinst du diese Monats-Übersicht, die man sich in einen Dialog packen kann und unter MFC auf den Namen "CMonthCalCtrl" hört?

Wenn ja: Ja, CMonthCalCtrl::GetCurSel() hat einen Bug und damit klappt auch DDX_MonthCalCtrl() nicht. Falls du letztere Routine verwendest (also den Kram mit DDX angebunden hast), sach' mal "Bescheid!", dann habe ich einen Workaround für dich.


Die Krönung des ganzen ist, dass dieser Kalender auch noch ein falsches Datum in die zugewiesene Variable schreibt, und zwar ist es um einen bestimmten Zeitraum zu groß, ich glaube das waren 3 Monate und 10 Tage.

Ja, ich erinnere mich gut, das hat mich damals auch ein paar Stunden gekostet... :mad:


Allerdings glaube ich auch kaum dass sich hier Entwickler mit Erfahrungen in so grauenhaftem Zeugs wie der MFC finden lassen werden.

Wette verloren :D

Liebe Grüße,
Axel

der Papst
19-06-2007, 20:35
Was genau meinst du mit "Terminkalender"? Meinst du diese Monats-Übersicht, die man sich in einen Dialog packen kann und unter MFC auf den Namen "CMonthCalCtrl" hört?

Wenn ja: Ja, CMonthCalCtrl::GetCurSel() hat einen Bug und damit klappt auch DDX_MonthCalCtrl() nicht. Falls du letztere Routine verwendest (also den Kram mit DDX angebunden hast), sach' mal "Bescheid!", dann habe ich einen Workaround für dich.



Ja, ich erinnere mich gut, das hat mich damals auch ein paar Stunden gekostet... :mad:



Wette verloren :D

Liebe Grüße,
AxelGenau das ist mein Problem!
Ich bedank mich schonmal jetzt für deine Hilfe!

sommerfee
20-06-2007, 08:33
Ich habe es einfach "zu Fuß" gemacht, also ein "CTime m_datetime;" in den Header eingefügt und am Ende der betroffenen DoDataExchange() Funktion in etwa folgendes:



CMonthCalCtrl* pctrlDate = (CMonthCalCtrl*)GetDlgItem( IDC_DATE );
ASSERT( pctrlDate != 0 );
if ( pDX->m_bSaveAndValidate )
{
SYSTEMTIME sysDate = {0}, sysTime = {0};

BOOL bResult = pctrlDate->GetCurSel( &sysDate );
ASSERT( bResult ); // Besser: Exception werfen

// hier ggf. sysTime setzen

m_datetime = CTime( sysDate.wYear, sysDate.wMonth, sysDate.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond );
}
else
{
pctrlDate->SetCurSel( m_datetime );
}


Dies läßt sich natürlich beliebig abändern, wichtig ist nur, daß man weder CMonthCalCtrl::GetCurSel(CTime& refDateTime) noch DDX_MonthCalCtrl() verwendet, weil die buggy sind. (DDX_MonthCalCtrl::GetCurSel(LPSYSTEMTIME pDateTime) ist hingegen ok.)

Liebe Grüße,
Axel

anda_skoa
20-06-2007, 19:18
Ich habe früher unter Windows und MFC programmiert.
Seit einem halben Jahr bin ich fast nur noch auf Linux unterwegs, bin aber durch das Studium mehr oder weniger zu Windoof gezwungen.
Ich hatte bis jetzt leider noch keine Zeit, die Linux-APIs zu erlernen und habe ein kleines Projekt am Freitag abzugeben.

Ich persönlich tendiere ja zu Qt, besonders wenns auch unter Windows laufen soll, aber für jemanden mit MFC Vorkenntnissen ist vielleicht wxWidgets einen Blick wert.

Soweit ich weiß hat das einen sehr ähnlichen API Stil, ist aber bei weiten nicht so alt und kaputt.

Ciao,
_

der Papst
21-06-2007, 15:27
Ich habe es einfach "zu Fuß" gemacht, also ein "CTime m_datetime;" in den Header eingefügt und am Ende der betroffenen DoDataExchange() Funktion in etwa folgendes:



CMonthCalCtrl* pctrlDate = (CMonthCalCtrl*)GetDlgItem( IDC_DATE );
ASSERT( pctrlDate != 0 );
if ( pDX->m_bSaveAndValidate )
{
SYSTEMTIME sysDate = {0}, sysTime = {0};

BOOL bResult = pctrlDate->GetCurSel( &sysDate );
ASSERT( bResult ); // Besser: Exception werfen

// hier ggf. sysTime setzen

m_datetime = CTime( sysDate.wYear, sysDate.wMonth, sysDate.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond );
}
else
{
pctrlDate->SetCurSel( m_datetime );
}


Dies läßt sich natürlich beliebig abändern, wichtig ist nur, daß man weder CMonthCalCtrl::GetCurSel(CTime& refDateTime) noch DDX_MonthCalCtrl() verwendet, weil die buggy sind. (DDX_MonthCalCtrl::GetCurSel(LPSYSTEMTIME pDateTime) ist hingegen ok.)

Liebe Grüße,
Axel

Vielen dank für deine Hilfe, aber das stößt schon an die Grenzen meines Wissens.
Könntest du mir eventuell noch erklären wie ich einfach an das Datum rankomme?


Ich persönlich tendiere ja zu Qt, besonders wenns auch unter Windows laufen soll, aber für jemanden mit MFC Vorkenntnissen ist vielleicht wxWidgets einen Blick wert.

Soweit ich weiß hat das einen sehr ähnlichen API Stil, ist aber bei weiten nicht so alt und kaputt.Meine "Erfahrung" mit MFC ist nichtmal nennenswert...
Und als KDE-Liebhaber wäre meine Wahl sowiso auf QT gefallen aber momentan habe ich sowiso keine Zeit etwas neues zu lernen

der Papst
21-06-2007, 20:45
Diese Lösung bekam ich auf Codeproject.com:

void CTodolisteDlg::OnSelectkalender(NMHDR* pNMHDR, LRESULT* pResult)
{
NMSELCHANGE *pNMSelChange = (NMSELCHANGE *)pNMHDR;

COleDateTime OleDateTime(pNMSelChange->stSelStart);

m_tag = OleDateTime.Format( "%A, %B %d, %Y" );

UpdateData(false);
}

sommerfee
21-06-2007, 21:46
Vielen dank für deine Hilfe, aber das stößt schon an die Grenzen meines Wissens.
Könntest du mir eventuell noch erklären wie ich einfach an das Datum rankomme?

Ein "CTime m_datetime;" in die Klasse packen und obrigen Code in die DoDataExchange()-Methode der Dialogklasse einbauen. Dann hast du automatisch nach dem Schließen des Dialoges das Datum in m_datetime, oder innerhalb einer Methode der Dialogklasse ebenfalls in m_datetime, allerdings dort erst nach einem UpdateData().

Wie du m_datetime weiter verarbeitest (etwa in eine Zeichenkette mit dem Format deiner Wahl), entnimmst du der Hilfe zur Klasse CTime.


Meine "Erfahrung" mit MFC ist nichtmal nennenswert...

Mein Tipp: In der MFC-Online-Hilfe gibt es ein sog. "Scribble Tutorial", da wird Schritt-für-Schritt erklärt, wie das "Scribble"-Beispiel entworfen und entwickelt wurde. Da wird auch die Sache mit dem "Data Exchange" (=DDX) bei den Dialogen erklärt. Ansonsten hilft sicherlich auch eine Suche nach "MFC DDX".

Nachtrag zu deiner Codeproject-Lösung:



COleDateTime OleDateTime(pNMSelChange->stSelStart);
m_tag = OleDateTime.Format( "%A, %B %d, %Y" );


Hier wird COleDateTime statt CTime verwendet. (Das geht natürlich auch bei "meiner" Lösung, wenn man will.) Und da man bei der OnSelectXxx()-Methode gleich die passende SYSTEMTIME-Struktur mitbekommt, sieht das so schön einfach aus, weil man sich das GetDlgItem und GetCurSel spart. ABER:

1. Man ist dann auf diese Methode festgelegt, woanders bekommt man die Zeit nicht (so einfach) heraus.

2. Architektonisch gesehen finde ich die Lösung nicht hübsch, sowas gehört nach DoDataExchange. Wenn es DDX gibt und die MFC das aktiv unterstützen, sollte man es IMHO auch nutzen.

3. Das geht nur in eine Richtung. Die von mir gepostete Lösung ist aber bidirektional, d.h. wenn man m_datetime vor dem Aufrufen des Dialoges mit DoModal setzt, steht der Kalender auch auf diesem Datum.

4. Ein Bug ist in der Codeproject-Lösung auch noch drin. Da fehlt das UpdateData( TRUE ) am Anfang, ansonsten werden mit dem UpdateData( FALSE ) am Ende gnadenlos alle anderen Änderungen am Dialog übergebügelt.

Liebe Grüße,
Axel

der Papst
23-06-2007, 11:03
1. Man ist dann auf diese Methode festgelegt, woanders bekommt man die Zeit nicht (so einfach) heraus.

2. Architektonisch gesehen finde ich die Lösung nicht hübsch, sowas gehört nach DoDataExchange. Wenn es DDX gibt und die MFC das aktiv unterstützen, sollte man es IMHO auch nutzen.

3. Das geht nur in eine Richtung. Die von mir gepostete Lösung ist aber bidirektional, d.h. wenn man m_datetime vor dem Aufrufen des Dialoges mit DoModal setzt, steht der Kalender auch auf diesem Datum.

4. Ein Bug ist in der Codeproject-Lösung auch noch drin. Da fehlt das UpdateData( TRUE ) am Anfang, ansonsten werden mit dem UpdateData( FALSE ) am Ende gnadenlos alle anderen Änderungen am Dialog übergebügelt.

Liebe Grüße,
AxelWie gesagt, das war mein letztes Projekt mit MFC da ich in Zukunft nur noch unter Linux entwickeln werde.

Die andere Richtung habe ich übrigens mit einer CTime-Membervariable realisiert, da besteht der Bug ja nur in eine Richtung