Änderungen von Angaben in einem Formular ermöglichen

langer1801

Erfahrenes Mitglied
Hallo,
ich habe in meinem Projekt mehrere Formulare, in denen monats- und parameterbezogen Vorgaben gemacht werden. Diese Vorgaben muß ich nach Monatsende zum Teil bearbeiten, weil sie sich geändert haben. Wenn z.B. am 07.08. für Parameter 12 eine 1 steht, die Leistung aber 2 mal erfolgte, muß ich das im Formular ändern. Das Formular mit den Eintragungen selbst ist in einer von CScrollView abgeleiteten Klasse gezeichnet. Nun habe ich ein ähnliches Programm gesehen, in dem nach Anklicken des zu ändernden Parameters an dieser Stelle ein EditControl erscheint, aber nur, indem um den Parameter ein Rechteck gezeichnet wird und ein Cursor erscheint. Dieses EditControl scheint auch nicht zur Ansicht zu gehören, denn wenn das Blatt gescrollt wird, bleibt das EditControl an der alten Stelle, wird also nicht mit verschoben. Diese Variante könnte mir bei meinem Problem echt weiter helfen. Weiß jemand, wie das geht? Oder hat jemand eine andere Idee?

Mfg

langer
 
Funktioniert prinzipiell so:

  • Füge einen Message-Handler für den Mausklick (WM_LBUTTONDOWN) ein.
  • Mit der Funktion "GetMessagePos()" bekommst du die Cursorposition zum Zeitpunkt des Mausklicks. Damit musst du dann den Parameter identifizieren und das exakte umschließende Rechteck berechnen.
  • Auf diese Rechteck setzt du jetzt einfach ein CEdit-Control drauf.

Ein Editfeld, das stehenbleibt, während das Formular gescrollt wird, sieht meiner Meinung nach unprofessionell aus. Sobald das Editfeld den Fokus verliert (z.B. bei Klick auf die Scrollbar) würde ich das Editfeld löschen (einfachste Lösung).
 
Danke für die Antwort. Mit dem Ermitteln des Parameters ist das kein Problem mehr, das hab ich implementiert. Und mit dem CEdit-Control habe ich es jetzt so gelöst, daß ich einen Dialog eingefügt habe, der nur aus dem CEdit-Control besteht. Den Dialog selbst habe ich transparent gemacht, sodaß wirklich nur der Cursor erscheint. Bißchen experimentieren muß ich noch mit den Koordinaten, wo der Dialog erscheinen soll, das klappt noch nicht so. Meine Frage wäre aber, gibt es noch eine andere Möglichkeit, das CEdit in die Ansicht einzubauen? Oder wirklich nur über einen Dialog?
Und mit dem unprofessionellen Aussehen, wenn das Feld nicht mitgescrollt wird, das sehe ich eben so. Deshalb werde ich das wie vorgeschlagen löschen, wenn der Fokus weg ist.

langer
 
Noch 'ne Frage:
Ich hab in meiner View-Klasse zwei Message-Handler für die linke Maus-Taste, einmal OnLButtonDblClick (den habe ich schon vorher gebraucht) und nun noch den Message-Handler OnLButtonDown. Den hab ich jetzt eingefügt, um die Parameterabfrage zu starten. Nur, wenn ich die linke Maustaste betätige, springt das Programm immer erst in die Routine für OnLButtonDown, auch wenn ich einen Doppelklick ausführe. Das ist ja auch logisch, da ich eben die linke Maustaste betätige. Ich muß nun aber unterscheiden, ob es ein Mausklick oder ein Doppelklick war. Gibt es dafür eine Funktion?

Mfg

langer
 
Zur ersten Frage:
Also dafür extra einen Dialog zu anzulegen ist nicht nötig. Du kannst ein CEdit-Control doch direkt als Child des Scrollviews erzeugen.

Code:
// Anlegen einer Membervariablen in der Viewklasse
CEdit m_edit; 

// Erzeugen des Controls bei der Initialisierung des Views
m_edit.Create(WS_CHILD | WS_BORDER, CRect(0,0,0,0), this, 1);

// Wenn es gebraucht wird
m_edit.MoveWindow( ... );   // Größe und Position
m_edit.ShowWindow(SW_SHOW); // Anzeigen

// Wenn es nicht mehr angezeigt werden soll
m_edit.ShowWindow(SW_HIDE); //Verstecken

Zur zweiten Frage:
Ob's ein Doppelklick war weiß man ja erst nach dem 2.Klick. ;)
Das Prinzip muss daher darin bestehen, die Verarbeitung bei WM_LBUTTONDOWN solange zu verschieben, bis ein zweiter Klick entweder erfolgt ist oder garantiert nicht mehr kommt.
Vielleicht folgende Idee - Du startest bei WM_LBUTTONDOWN einen Timer mit einen Delay größer als die Doppelklickzeit (mit SetTimer) und löscht ihn bei WM_LBUTTONDBLKLICK wieder (mit KillTimer).
Wenn der Timer-Event erreicht wird, war's nur ein Einfachklick und du kannst dort den Timer löschen und die entsprechende Verarbeitung ausführen.
 
Danke für die Antwort. Den Tip mit dem CEdit werde ich so umsetzen. Mit Controls als Child in der Ansicht hatte ich vorher noch nie gearbeitet, deshalb hilft mir der Tip sehr viel, weil ich eben nicht wußte, wie ich das Control da reinkriege. Daß es so einfach ist...
Und das Abfragen des Doppelklicks über einen Timer-Event wird wohl auch die beste oder einzige Möglichkeit sein. Aber da schließe ich mich jokey2 an: Wie kriege ich die Delay-Zeit. Habe in der MSDN nur GetDelayTime gefunden, die Funktion bezieht sich aber auf die Tool-Tips.

Mfg

langer
 
Uups, da hab ichs wohl beim ersten Mal übersehen. Die Funktion heißt GetDoubleClickTime und gibt die Zeit in Millisekunden zurück.

langer
 
Mit der Methode, den Timer einzusetzen, klappt die Unterscheidung von einfachem und doppeltem Klick ohne Probleme.
Hier der Code-Schnipsel:
Code:
void CAbrView::OnLButtonDown(UINT nFlags, CPoint point)
{
	CAbrDoc* pDoc=GetDocument();
	pDoc->m_timer=SetTimer(1,::GetDoubleClickTime()+100,NULL);
}

void CAbrView::OnTimer(UINT nIDEvent)
{
	CAbrDoc* pDoc=GetDocument();
	KillTimer(pDoc->m_timer);    //Timer hat ausgelöst -> war einfacher Klick
            //Hier die Behandlungsroutine einfügen
	CScrollView::OnTimer(nIDEvent);
}

void CAbrView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CAbrDoc* pDoc=GetDocument();
	KillTimer(pDoc->m_timer);  //Timer vor Auslösen löschen -> war Doppelklick

        //Hier gehts weiter zur Behandlungsroutine Doppelklick
Schade eigentlich, daß Microsoft eine derartige Abfrage nicht implementiert hat. Kann mich noch an die guten alten AMIGA-Zeiten erinnern (Gott habe ihn selig ;) ), da konnte man das nach einem Mausklick abfragen und dann verzweigen.

Mfg

langer
 

Neue Beiträge

Zurück