Hat sich erledigt.
Unter http://support.microsoft.com/kb/507791/de habe ich die Lösung
gefunden:
Private Sub Text1_MouseDown(Button As Integer, Shift As Integer,_
X As Single, Y As Single)
If Button = vbRightButton Then
Text1.Enabled = False
Text1.Enabled = True
Text1.SetFocus
PopUpMenu MeinMenu
End If
End Sub
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
> Wie subclasse ich eine TextBox und wie erhalte
> ich die Nachricht WM_CONTEXTMENU, die ich
> dann nicht an die alte Fensterprozedur weiterleite,
> sondern mein eigenes Menü anzeige.
So kannst Du WM_CONTEXTMENU durch Subclassing
abfangen.
' /// Code in Standardmodul *.bas
Option Explicit
Private Const GWL_WNDPROC As Long = -4
Private Const WM_CONTEXTMENU As Long = &H7B
Private lpOrgWndProcedure As Long
Private Declare Function apiSetWindowLong _
Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) _
As Long
Private Declare Function apiCallWindowProc _
Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) _
As Long
' /// Unterdrücken des Standard-Kontextmenüs von z.B. Textboxen
Public Sub SuppressContextMenu(hwnd As Long, Button As Integer)
If CBool(Button And vbRightButton) Then
' Umleiten der Fensternachrichten an Function
' WndProcNoCMenu(), wird dort eine Nachricht
' WM_CONTEXTMENU erkannt, dann wird sie
' unterdrückt, alle anderen Nachrichten werden
' von der Function WndProcNoCMenu an die
' originale Fensterprozedur weitergegeben.
lpOrgWndProcedure = _
apiSetWindowLong _
(hwnd, _
GWL_WNDPROC, _
AddressOf WndProcNoCMenu)
End If
End Sub
Private Function WndProcNoCMenu(ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) _
As Long
' \\\ Rückrufprozedur für Sub SuppressContextMenu()
If Msg = WM_CONTEXTMENU Then
' Nachricht WM_CONTEXTMENU unterdrücken
apiSetWindowLong hwnd, GWL_WNDPROC, lpOrgWndProcedure
WndProcNoCMenu = True
Else
' alle anderen Nachrichten an Originalfensterprozedur
' weitergeben
WndProcNoCMenu = _
apiCallWindowProc _
(lpOrgWndProcedure, _
hwnd, Msg, wParam, lParam)
End If
End Function
' /// Code im Formmodul für eine Textbox:
Private Sub Text1_MouseDown _
(Button As Integer, _
Shift As Integer, _
X As Single, _
Y As Single)
If Shift = vbCtrlMask Then
SuppressContextMenu Text1.hwnd, Button
End If
End Sub
' \\\ _________________
Im Beispiel wird bei rechtem Mausklick auf die Textbox
das Standard-Kontextmenü angezeigt. Wird dabei
gleichzeitig die Strg-Taste gedrückt gehalten, so wird
das Standard-Kontextmenü nicht angezeigt.
Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)
Bezweifel ich. Drück mal die Kontextmenütaste auf Deiner Tastatur.
Thorsten Dörfler
Siehe:
<URL:http://dotnet.mvps.org/vb/samples/controls/#TextBoxContextMenu>
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
>> Ich habe ein Menu mit drei Untermenus für eine TextBox eingerichtet,
>> das
>> beim Drücken der rechten Maustaste als PopUpmenu aufklappen soll.
>> Beim ersten Klick der rechten Taste klappt aber das standardmäßige
>> PopUpMenu
>> (Undo,Cut,Copy etc.) auf, beim nächsten Klick erst das von mir
>> eingerichtete.
> Siehe:
>
> <URL:http://dotnet.mvps.org/vb/samples/controls/#TextBoxContextMenu>
Die schlechte Variante mit Aktivieren und Deaktivieren der TextBox und
Setzen des Fokus betrifft nicht nur die eher triviale Auswahl in einer
TextBox, sondern kann auch erheblich unangenehmere (und evtl. nicht auf
den ersten Blick erkennbare) Seiteneffekte haben - wenn nämlich die
TextBox-Ereignisse GotFocus und LostFocus oder auch Validate für
irgendwelche Zwecke genutzt werden sollen.
Viele Grüße
Harald M. Genauck
"VISUAL STUDIO one" - http://www.visualstudio1.de (Chefredakteur)
"ABOUT Visual Basic" - http://www.aboutvb.de (Herausgeber)
Versteckte dummy Picturebox pctKontext
SendMessage pctKontext.hWnd, &H204, 0&, 0&
Private Sub pctKontext_MouseUp(...)
On Error Resume Next
Text1.SetFocus 'damit Markierung sichtbar bleibt
PopupMenu Text1, vbPopupMenuRightButton
end sub
In Text1_KeyDown kannst du noch die Kontextmenütaste abfangen.
Grüße,
Jens
"Wolfgang Badura" <Wolfgan...@aon.at> schrieb im Newsbeitrag
news:488ce90a$0$2137$91ce...@newsreader02.highway.telekom.at...
Timo (kräftig genervt von solchen Frickel"lösungen")
Timo
> Noch eine Möglichkeit:
>
> Versteckte dummy Picturebox pctKontext
>
> SendMessage pctKontext.hWnd, &H204, 0&, 0&
>
> Private Sub pctKontext_MouseUp(...)
>
> On Error Resume Next
> Text1.SetFocus 'damit Markierung sichtbar bleibt
> PopupMenu Text1, vbPopupMenuRightButton
>
> end sub
>
> In Text1_KeyDown kannst du noch die Kontextmenütaste abfangen.
Nur der Vollständigkeit halber - das Original dieser Idee ist in aller
Ausführlichkeit dort zu finden:
http://www.aboutvb.de/khw/artikel/khwuserpopupmenu.htm
Ansonsten möchte ich heutzutage auch das Subclassen von WM_CONTEXTMENU
empfehlen.
> Ansonsten möchte ich heutzutage auch das Subclassen von WM_CONTEXTMENU
> empfehlen.
Woher dieser Wandel? ;-)
Thorsten Dörfler
> Woher dieser Wandel? ;-)
Ich kann mich leider nicht mehr daran erinnern, was ich vor ein paar
Jahren gedacht habe, als ich zu dieser Erkenntnis gekommen bin...
:-(
Ist doch klar: Vorher dachtest Du, alles sei klasse. Dann kam ein gewisser
Herr und zeigte uns, daß Politik nicht optimal sondern suboptimal ist. Ab
da warst Du dann mit dem subklassen einverstanden...
--
----------------------------------------------------------------------
Thorsten Albers albers(a)uni-freiburg.de
----------------------------------------------------------------------
>> Bezweifel ich. Drück mal die Kontextmenütaste auf Deiner Tastatur.
> Ich glaube ich stehe am Draht: welche ist die Kontextmenutaste?
Auf einer seit 13 Jahren üblichen Standardtastatur befindet sich diese
zwischen der rechten Windows und Strg Taste.
Umsch. + F10 hat die gleiche Funktion.
> Habe ich mangels Wissen noch nie betätigt. ;-((
Mausschubser. ;-)
> Kann es sein, daß sie auf meiner Tastatur (noch) nicht verfügbar ist?
Bezweifel ich. Eine so alte Tastatur dürfte schwer an einem hinreichend
aktuellem Rechner anzuschließen sein. Der letzte Hobel ohne Windows +
Kontextmenütaste hatte bei mir einen DIN-Stecker. :-)
Thorsten Dörfler
Na ja, DIN auf PS2 kostet irgendetwas bei 2, 3 Euro. Ich habe hier sogar
eine der damals sog. Windows 95-Tastaturen mit DIN-Anschluß!
> Sofort kann ich das nicht ausprobieren, aber am nächsten Wochenende werde
> ich das tun.
Hallo Peter!
Ich habe Deinen Code ausprobiert. Für die rechte Maustaste funktioniert er
tadellos!
Aber Thorsten Doerfler hat mir einen Floh ins Ohr gesetzt: Eine lupenreine
Lösung sollte auch funtionieren, wenn man die Kontexttaste drückt,
da hat er schon recht. Das tut Dein Code nicht.
Aber nachdem ich bis hierher die Kontext-Taste gar nicht gekannt habe!
Welch umfassende Lösung gibt es, oder ist die nicht funktionierende
Kontexttaste ein lokales Problem meines PCs?
Im Posting von Harald M. Genauck werden die Aufrufe der Api´s auch als das
Subclassing, wie es Timo sicher meinte, verstanden.
Wolfgang
> Auf einer seit 13 Jahren üblichen Standardtastatur befindet sich diese
> zwischen der rechten Windows und Strg Taste.
Hallo Thorsten!
Die Taste ist auf meiner Tastatur natürlich vorhanden, aber ich habe sie
wirklich noch nie benützt! Bin anscheinend zu konservativ oder nicht
flexibel genug.
Du hast natürlich recht: bei Microsofts "Lösung" erscheint, wenn man sie
drückt, das Standardkontext PopUp.
Beim Code von Peter Götz ist das aber auch nicht anders. Ist das wirklich
"Subclassing", wie Timo Kunze es gemeint hat?
Hmmm.
Welche saubere Lösung gibt es nun wirklich, die auch beim Drücken der
Kontexttaste mein PopUp anzeigt?
Vielleicht kannst Du mich nochmals unterstützen!
Danke, Wolfgang
> Im Posting von Harald M. Genauck werden die Aufrufe der Api´s auch
> als das Subclassing, wie es Timo sicher meinte, verstanden.
Subclassing erscheint mir als die einzige Möglichkeit, das sauber
hinzubekommen. Denn Windows sendet die Nachricht WM_CONTEXTMENU, wenn
das Kontextmenü angezeigt werden soll - unabhängig davon, auf welchem
Wege der Anwender diesen Wunsch ursprünglich geäußert hat.
Ich kann mir beispielsweise vorstellen, dass es Spracheingabesysteme
geben könnte, die einen eigenen Sprachbefehl dafür haben (ich kenne
mich mit solchen Systemen allerdings nicht näher aus). Alle nur
denkbaren Variationen, wie der Anwender seinen Wunsch, ein Kontextmenü
zu Gesicht zu bekommen, ausdrücken könnte, in einer Anwendung zu
berücksichtigen, ist wohl unmöglich.
Daher sollte bzw. muss nur die Inputseite des Betriebssystems diese
Varationen kennen und einen eindeutigen Befehl an die Anwendung
absetzen - was eben über die Nachricht WM_CONTEXTMENU tatsächlich
geschieht. Der Anwendung obliegt es daher, auf diese Nachricht zu
reagieren, wenn sie ein eigenes Kontextmenü anzeigen möchte.
Zwar hat nicht jedes Control ein bereits "eingebautes" Kontextmenü wie
die TextBox, aber das ist auch egal. Will man ein eingebautes
Kontextmenü ersetzen, muss das Original eben unterdrückt werden (beim
Subclassing wird eben die Nachricht verworfen), und eben das eigene
Kontextmenü angezeigt werden. Man kann aber unter Umständen auch das
eingebaute Kontextmenü verändern, etwa eigene Menüpunkte einschieben
oder vorhandene entfernen. Gibt es kein eingebautes Kontextmenü, wird
eben schlichtweg das eigene angezeigt.
Thorsten Doerfler schrieb:
> ...
> Auf einer seit 13 Jahren üblichen Standardtastatur befindet sich diese
> zwischen der rechten Windows und Strg Taste.
>
> Umsch. + F10 hat die gleiche Funktion.
Aber nur(?) beim Explorer. Wenn ich Shift+F10 drücke, wird in meiner
Anwendung die Alt+D Funktion (Menü-Punkt oder CommandButton) ausgeführt.
Das KeyUp-Ereignis liefert bei
Context-Taste: KeyCode=93, Shift=0
Shift+F10 : KeyCode=121, Shift=1 (vbShiftMask)
Was tun mit Shift+F10?
Lothar Geyer
ich habe da gerade mal noch etwas gespielt und bin auf was seltsames
draufgekommen (wenn das auch nichts mit dem originalen Problem zu tun hat).
Ich generiere ein Popup-Menü mit der Anweisung
RetIdx = TrackPopupMenuEx(hMenu, _
TPM_LEFTALIGN Or TPM_RETURNCMD Or TPM_RIGHTBUTTON, _
pt.X, pt.Y, pWindowHandle, ByVal 0&)
DestroyMenu hMenu
und werte dann RetIdx aus, falls > 0. Das funktioniert auch ohne
Probleme. Wenn ich nun in dem PopupMenü (also während es angezeigt wird)
die Space-Taste drücke, erscheint das System-Menü der Anwendung, also
das, dass beim Klick auf das Icon links oben in der MDI-Form erstellt
wird. RetIdx hat den Wert 0.
Wie kann das kommen? Wie kann ich das unterdrücken? Denn beim Explorer
kommt das z.B. nicht.
Lothar Geyer
Nein, nicht nur dort.
> Wenn ich Shift+F10 drücke, wird in meiner
> Anwendung die Alt+D Funktion (Menü-Punkt oder CommandButton) ausgeführt.
Dann reagiert Deine Anwendung nicht (richtig) auf WM_CONTEXTMENU. Wenn
die Anwendung/das Fenster kein Kontextmenü bereitstellt, wird normal
der Menümodus aktiviert. Das dürfte dann auch Dein Systemmenü beim
Betätigen der Leertaste erklären.
Thorsten Dörfler
--
Microsoft MVP Visual Basic
vb-hellfire visual basic faq | vb-hellfire - einfach anders
http://vb-faq.de/ | http://www.vb-hellfire.de/
Thorsten Doerfler schrieb:
> Lothar Geyer schrieb:
>>> Auf einer seit 13 Jahren üblichen Standardtastatur befindet sich diese
>>> zwischen der rechten Windows und Strg Taste.
>>>
>>> Umsch. + F10 hat die gleiche Funktion.
>> Aber nur(?) beim Explorer.
>
> Nein, nicht nur dort.
deshalb das Fragezeichen ;-)
>> Wenn ich Shift+F10 drücke, wird in meiner
>> Anwendung die Alt+D Funktion (Menü-Punkt oder CommandButton) ausgeführt.
>
> Dann reagiert Deine Anwendung nicht (richtig) auf WM_CONTEXTMENU. Wenn
> die Anwendung/das Fenster kein Kontextmenü bereitstellt, wird normal
> der Menümodus aktiviert. Das dürfte dann auch Dein Systemmenü beim
> Betätigen der Leertaste erklären.
Ich muss gestehen, dass mir die Kontext-Taste auch noch nicht
aufgefallen ist. Und mein Popup-Menü starte ich bisher im
_MouseUp-Event, wenn es die rechte Maustaste war. WM_CONTEXTMENU kannte
ich bisher auch nicht. (In der Doku zu meiner Anwendung steht aber auch,
dass es nur über die rechte Maustaste geht.)
Trotzdem: was heißt "ein Kontext-Menü bereitstellt"? Muss ich ein
Kontext-Menü irgendwo anmelden?
Ich verwende (in dieser Anwendung) Kontext-Menüs hauptsächlich dafür,
dass der Benutzer die Ansicht z.B. einer Tabelle temporär ändern (z.B.
eine zusätzliche Spalte einblenden) kann oder in einer Kalender-Ansicht
die Termine eines anderen Benutzers gezeigt werden.
Lothar Geyer
Gebrauchen tue ich sie auch so gut wie gar nicht.
> Trotzdem: was heißt "ein Kontext-Menü bereitstellt"? Muss ich ein
> Kontext-Menü irgendwo anmelden?
Nein, Du musst, bei Behandlung von WM_CONTEXTMENU, wohl nur dafür
sorgen, dass die Nachricht nicht weiter "nach oben", an das Parent-
Fenster gereicht wird.
Bei Verzicht auf Subclassing und manueller Bereitstellung eines
Kontextmenüs über MouseUp bzw. KeyDown, konnte ich das von Dir
beschriebene Verhalten bei Verwendung der PopupMenu-Methode des
Formulars nicht nachvollziehen. Es mag also an TrackPopupMenuEx
liegen. Du könntest versuchen das Formular vor dem Anzeigen des
Kontextmenü zu deaktivieren und wieder aktivieren oder alternativ
mittels SendMessage WM_CANCELMODE an dieses senden.
Warum überhaupt TrackPopupMenuEx?
Thorsten Doerfler schrieb:
> Warum überhaupt TrackPopupMenuEx?
keine Ahnung, irgendwo abgeschrieben :-)
Gibt's was besseres? Was hat es für Nachteile?
Lothar Geyer
> Hallo Peter!
> Ich habe Deinen Code ausprobiert. Für die rechte
> Maustaste funktioniert er tadellos!
> Aber Thorsten Doerfler hat mir einen Floh ins Ohr
> gesetzt: Eine lupenreine Lösung sollte auch funtionieren,
> wenn man die Kontexttaste drückt, da hat er schon recht.
Ja, hat er.
> Das tut Dein Code nicht.
Natürlich nicht, weil das SubClassing nur
beim Drücken der rechten Maustaste ausgeführt
wird.
Hast Du Dir meinen Code auch mal angesehen
und vor allem auch verstanden?
> Aber nachdem ich bis hierher die Kontext-Taste
> gar nicht gekannt habe!
> Welch umfassende Lösung gibt es, oder ist die
> nicht funktionierende Kontexttaste ein lokales
> Problem meines PCs?
Nein, das ist kein lokales Problem Deines PCs
sondern liegt einfach daran, dass Du dafür die
Fensternachricht WM_CONTEXTMENU auch dann
via SubClassing abfangen musst, wenn die
Contextmenu-Taste auf der Tastatur gedrückt wird.
Für den Code aus meinem vorigen Posting würde
das bedeuten, dass Du ihn noch so ergänzen
müsstest
Private Sub Text1_KeyDown _
(KeyCode As Integer, _
Shift As Integer)
If KeyCode = 93 Then
SuppressContextMenu Text1.hwnd, vbRightButton
End If
End Sub
Damit wird das SubClassing für die Textbox "Text1" auch
aktiviert, wenn die ContextMenü-Taste (KeyCode = 93)
gedrückt wird.
> Im Posting von Harald M. Genauck werden die Aufrufe
> der Api´s auch als das Subclassing, wie es Timo sicher
> meinte, verstanden.
Ich denke mal, Du hast (noch) nicht wirklich verstanden,
was SubClassing bedeutet. Eben genau das, was ich
Dir in meinem ersten Beispielcode gezeigt habe.
Schau Dir diesen Code (insbesondere den im Standardmodul)
nochmal genau an um zu verstehen, wie darin die
Fensternachricht WM_CONTEXTMENU an das durch hWnd
gekennzeichnete Fenster (z.B. die Textbox) abgefangen und
ignoriert wird, wogegen alle anderen Fensternachrichten
unverändert an die originale Fensterprozedur weitergeleitet
werden.
> Du hast natürlich recht: bei Microsofts "Lösung" erscheint,
> wenn man sie drückt, das Standardkontext PopUp.
> Beim Code von Peter Götz ist das aber auch nicht anders.
Weil bei meinem Beispielcode das SubClassing nur
beim Drücken der Maustaste (Text1_MouseDown)
aktiviert wird.
> Ist das wirklich "Subclassing", wie Timo Kunze
> es gemeint hat?
Ja, das ist SubClassing: Umleiten von Fensternachrichten
an eine eigene Prozedur, in welcher diese Fensternachrichten
selektiert werden können und je nach Bedarf unterdrückt,
manipuliert oder einfach unverändert an die originale
Windows-Fensterprozedur weitergereicht werden.
> Hmmm.
> Welche saubere Lösung gibt es nun wirklich,
> die auch beim Drücken der Kontexttaste mein
> PopUp anzeigt?
Das SubClassing auch im KeyDown-Ereignis der
Textbox, so wie ich es Dir in meinem anderen Posting
gezeigt habe, aktivieren.
Ich bin etwas erleichtert, daß die Kontexttaste auch andere kaum bis gar
nicht verwenden.
Auch das WM_CONTEXTMENU ist noch nicht Allgemeingut.
An dieser Stelle möchte mich für die Hilfestellung aller und die daran
anschließende hochkarätige Diskussion über ein
anscheinend harmloses Problem bedanken.
Ich habe die Abfrage auf die Kontexttaste ergänzt, und nun ist alles so wie
es sollte.
Mit Gruß aus Wien Wolfgang
Ich war schon etwas erleichtert, daß die Kontexttaste offenbar selten
verwendet wird.
Auch das WM_CONTEXTMENU scheint noch nicht Allgemeingut.
An dieser Stelle möchte mich für die Hilfestellung aller und die daran
anschließende hochkarätige Diskussion über ein
anscheinend harmloses Problem bedanken. Was würde ich tun, wenn es diese
selbstlose Unterstützung nicht gäbe!
Ich habe die von Dir formulierte Abfrage auf die Kontexttaste ergänzt, und
nun ist alles so wie es sein sollte.
Mit besten Grüßen aus Wien Wolfgang
Timo (der wo eine Weile nicht da war und sich deshalb nicht eher
gemeldet hat)
> Nein! Nicht zusätzlich in KeyDown! Stattdessen gehört
> das Subclassing in MouseDown entfernt und nach
> Form_Load verschoben. Ansonsten erschlägt
> man nicht alle Fälle.
Das ist bei meinem ursprünglichen Beispiel auch
ganz bewusst so.
Das SubClassing wird in MouseDown aktiviert,
wenn gleichzeitig die Strg-Taste gedrückt ist und
es wird nicht aktiviert, wenn die Strg-Taste nicht
gedrückt ist.
Bei gedrückter Strg-Taste kann dann in Mouse_Up
ein eigenes ContextMenü mit eigenen Inhalten
aktiviert werden.
Wolfgangs Problem scheint mir auch weniger die
Frage wann das SubClassing aktiviert wird, sondern
erst mal überhaupt zu verstehen, wie SubClassing
funktioniert.
> An dieser Stelle möchte mich für die Hilfestellung
> aller und die daran anschließende hochkarätige
> Diskussion über ein anscheinend harmloses
> Problem bedanken.
> Ich habe die Abfrage auf die Kontexttaste ergänzt,
> und nun ist alles so wie es sollte.
Die Abfrage auf den KeyCode 93 im KeyDown-
Ereignis war nicht als allgmeingültige Lösung gedacht,
sondern bezog sich ganz speziell auf mein erstes
Beispiel. Bei diesem wird ganz bewusst nur in
MouseDown mit gedrückter Maustaste das Subclassing
aktiviert um dann im anschliessenden Mouse_Up
ein eigenes ContextMenü anzeigen zu können.
Bei nicht gedrückter Strg-Taste wird beim rechten
Mausklick das normale ContextMenü der Textbox
angezeigt. So wird es möglich, je nach Erfordernis
mal das eine (ohne Strg) und mal ein anderes (mit Strg)
ContextMenü anzuzeigen.
Wenn einfach nur das ContextMenü der Textbox unter-
drückt werden soll, ohne eine weitere Auswahl via Strg-
Taste (oder auch ein anderes Kriterium) zu haben, dann
kannst Du das SubClassing schon beim Programmstart
in Form_Load oder Form_Activate einschalten.
Timo
> Okay, verstehe. Aber ich halte diese Lösung für etwas
> umständlich. Man könnte genausogut WM_CONTEXTMENU
> immer abfangen und nur dann an CallWindowProc
> weiterreichen, wenn die Strg-Taste nicht gedrückt ist
> und andernfalls sein eigenes Menü anzeigen. Das hätte
> den Vorteil, dass man sein eigenes Menü nicht zu einem
> dafür ungeeigneten Zeitpunkt (MouseUp) anzeigt,
> sondern wirklich dann wenn man es sollte (WM_CONTEXTMENU).
Das normale, textboxeigene Contextmenü wird auch erst
mit dem Loslassen der Maustaste angezeigt, warum also
sollte Mouse_Up der falsche Zeitpunkt sein.
Ich nutze das so z.B. in meinem Beispiel
www.gssg.de -> VisualBasic -> VBclassic
-> Datenbank -> ADO DemoMU 2002
Mit der rechten Maustaste erhält man über den Textboxen
ohne Strg-Taste das normale Kontextmenü und mit gedrückter
Strg-Taste bekommt man bei den Textboxen und beim
Grid ein Kontextmenü zur Einstellung von Schriftattributen-
und Schriftfarben.
> Man könnte genausogut WM_CONTEXTMENU immer
> abfangen ...
An der Stelle bleibt dann anzumerken, dass "standig aktiviertes"
SubClassing (Form_Load, etc.) nicht unbedingt zuträglich ist
hinsichtlich sicheren Debuggings - gerade bei SubClassing-
"Newbies".
Peters Ansatz, das Subclassing nur so kurz wie möglich
zu aktivieren, ist unter dem Aspekt IMO ganz sinnvoll.
Und den Fall Umsch-F10 kann man direkt per KeyCode
(121+Shift) abfangen - hier reicht dann ein Keycode = 0,
um das Aufpoppen zu unterdrücken (für die Context-
Taste 93 reicht das nicht - hier muss dann halt wie von
Peter vorgeschlagen analog zur Mouse-Routine verfahren
werden.
Damit bleibt nur noch der Fall der von externen Apps
eventuell geposteten Context-Requests nicht
abgedeckt - das kann ja dann jeder abwägen, ob
ein stabile(re)s IDE-Projekt die fehlende (je nach
Kunde wahrscheinlich selten geforderte) Funktionalität
wert ist.
Olaf
Genauso gut kann man das Subclassing auch beim Debuggen abschalten bzw.
erst gar nicht einschalten - z.B. per bedingter Kompilierung.
> Genauso gut kann man das Subclassing auch beim Debuggen
> abschalten bzw. erst gar nicht einschalten - z.B. per bedingter
> Kompilierung.
Man wird beim Debugging dann halt nicht unbedingt das
sehen, was man sehen will.
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."
>> Genauso gut kann man das Subclassing auch beim Debuggen
>> abschalten bzw. erst gar nicht einschalten - z.B. per bedingter
>> Kompilierung.
> Man wird beim Debugging dann halt nicht unbedingt das
> sehen, was man sehen will.
Die Funktionalität der Menüpunkte eines eigenen Kontextmenüs lässt sich
sicher auch anders debuggen - man könnte dieses beispielsweise durch
eine spezielle Tastenkombination anzeigen lassen, die nur beim Debuggen
gültig ist.
Für die reguläre Anzeige des Kontextmenüs selbst braucht es ja wohl nur
wenig an Debuggerei.
Zum einen ist das eine sehr isolierte Funktionalität, die sich auch gut
kapseln und in einem kleinen eigenen Testprojekt testen lässt -
funktioniert sie dort, gibt es eigentlich kaum einen Grund, warum sie
nicht auch in der eigentlichen Anwendung funktionieren sollte. Alle
anderen Abhängigkeiten des Kontextmenüs selbst (Menüpunkte Visible,
Enabled, Checked, Text usw.) lassen sich auch ohne Subclassing testen -
siehe oben.
Zum anderen kann man ja für diesen Fall das Subclassing ausnahmsweise
mal eingeschaltet und Vorsicht walten lassen und die Anwendung regulär
beenden, und man muss ja nicht unbedingt den kritischen API-Bereich
komplett durchsteppen. Außerdem sollte es, falls da wirklich mal was
schiefgeht, ausnahmsweise verschmerzbar sein, falls die IDE abstürzen
sollte.
> Die Funktionalität der Menüpunkte eines eigenen Kontextmenüs lässt sich
> sicher auch anders debuggen - man könnte dieses beispielsweise durch
> eine spezielle Tastenkombination anzeigen lassen, die nur beim Debuggen
> gültig ist.
Natürlich könnte man das, aber meine Methode lässt das
Debuggen ohne irgendwelche Klimmzüge einfach zu und
die gestellte Aufgabe, dass ohne Strg-Taste das normale
und mit Strg-Taste das spezielle Kontextmenü gezeigt
wird, lässt sich so auch auf einfachste und sehr übersichtliche
Weise lösen.
Warum also irgendwelchen Klimmzüge, wenn diese gar
nicht nötig sind?
> Für die reguläre Anzeige des Kontextmenüs selbst braucht
> es ja wohl nur wenig an Debuggerei.
Es braucht aber immer Debugging und wenn dabei irgendein
Subclassing scharf ist, dann lässt der nächste Absturz nicht
lange auf sich warten.
>
> Zum einen ist das eine sehr isolierte Funktionalität, die sich
> auch gut kapseln und in einem kleinen eigenen Testprojekt
> testen lässt - funktioniert sie dort, gibt es eigentlich kaum
> einen Grund, warum sie nicht auch in der eigentlichen
> Anwendung funktionieren sollte.
Dass grundsätzlich immer die Fehler auftreten, die man am
wenigsten erwartet, weisst Du doch sicher auch aus eigener
Erfahrung. Ich habe mir es immer zur Gewohnheit gemacht,
wenn schon SubClassing notwendig war, es immer so
kurz wie möglich zu halten.
> Alle anderen Abhängigkeiten des Kontextmenüs selbst
> (Menüpunkte Visible, Enabled, Checked, Text usw.)
> lassen sich auch ohne Subclassing testen -
> siehe oben.
Ja natürlich lassen sie sich ohne SubClassing testen, bei
meiner Methode aber eben auch mit SubClassing.
>
> Zum anderen kann man ja für diesen Fall das Subclassing
> ausnahmsweise mal eingeschaltet und Vorsicht walten
> lassen
Na komm schon.
Wann ist Dir zum letzten Mal was abgestürzt, wo Du gerade
ganz besondere Vorsicht walten lassen hast?
> und die Anwendung regulär beenden, und man muss ja
> nicht unbedingt den kritischen API-Bereich komplett
> durchsteppen. Außerdem sollte es, falls da wirklich mal was
> schiefgeht, ausnahmsweise verschmerzbar sein,
> falls die IDE abstürzen sollte.
Nur halt wieder die Frage, warum soll ich einen solchen
Absturz riskieren, wenns auch ohne geht?
> Notfalls debuggt man den Spaß eben mit Visual Studio
> 2003/2005/2008, das ist nicht so instabil wie VB6.
Na dann öffne mal ein MIDI-Device mit dem Multimedia-
Api unter Vista und dann halte Deine Anwendung an.
BlueScreen lässt grüssen.
> ... ... ...
> Ja natürlich lassen sie sich ohne SubClassing testen, bei
> meiner Methode aber eben auch mit SubClassing.
Ich sehe bei Deiner Methode immer noch nicht, wie das Senden von
WM_CONTEXTMENU durch alternative Eingaben bzw. Eingabegeräte
aufgefangen wird, die nicht als Maus- oder Tastaturtreiber fungieren.
Wobei ich mir allerdings nicht sicher bin, ob es solche Geräte
überhaupt gibt.
> > Ja natürlich lassen sie sich ohne SubClassing testen, bei
> > meiner Methode aber eben auch mit SubClassing.
>
> Ich sehe bei Deiner Methode immer noch nicht, wie
> das Senden von WM_CONTEXTMENU durch alternative
> Eingaben bzw. Eingabegeräte aufgefangen wird, die
> nicht als Maus- oder Tastaturtreiber fungieren.
> Wobei ich mir allerdings nicht sicher bin, ob es solche
> Geräte überhaupt gibt.
Was für Geräte?
Was für Tastaturtreiber?
Was für alternative Eingaben?
Ich verstehe im Moment nur "Bahnhof".
Ich prüfe in MouseDown, ob die Strg-Taste gedrückt ist.
Wenn nein, dann aktiviere ich kein SubClassing,
wenn ja, dann aktiviere ich das SubClassing, welches
WM_CONTEXTMENU unterdrückt und öffne in
MouseUp ein eigenes Kontextmenü mit spez. Inhalten.
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
Das frage ich mich auch. Schließlich kann man auch bei Eintreffen von
'WM_CONTEXTMENU' feststellen, ob die Strg-Taste gedrückt ist, um dann
entweder das System das Menü anzeigen zu lassen oder ein eigenes Menü
anzuzeigen. Außer dem erwähnten "Debugproblem" fällt mir eigentlich kein
Grund ein, das nicht so zu tun. Man würde damit damit auch dem Problem
vorbeugen, daß von anderen Anwendungen gesendete
'WM_CONTEXTMENU'-Nachrichten nicht entsprechend behandelt werden.
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://dotnet.mvps.org/dotnet/faqs/>
Hallo Timo!
Ich dachte schon am Ende des Tunnels angelangt zu sein.
Für mich ist es verständlich, bei einer Aktion wie zB. rechter Mausklick
etwas gegen das Standard Kontextmenu zu tun.
Aber ich weiß nicht recht, wie ich Deinen Tip
> sondern wenn du sie erzeugst, also in Form_Load.
verstehen soll?
Also in Form_Load erzeuge ich nicht explizit Controls.
Wie soll ich das dort also tun?
Danke und mit Groß ausWien,
Wolfgang
> Wie soll ich das dort also tun?
Ich habe mal ein Beispiel erstellt:
http://www.timosoft-software.de/stuff/SuppressContextMenu.zip
Nicht über die Menge des Codes erschrecken. Ich verwende für das
SubClassing mein gut erprobtes und komfortables Framework. Das
SubClassing ginge auch mit erheblich weniger Code.
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
Wenn ich im ggst. Programm das Subclassing bei MouseUp mache, dann kommt
1. beim ersten Rechtsklick+Ctrl zuerst wieder das textboxeigene Kontextmenu
und erst beim 2.Klick mein eigenes.
2. Wenn nach dem 1. Rechtsklick als nächstes Linksgeklickt wird erscheint
mein eigenes Kontextmenu!
3. Ab dann ist alles wie es soll. Aber
4. wenn ich dann das Form unloade mit
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
Dim bRetVal As Boolean
bRetVal = InternetCloseHandle(hInternetOpen)
bRetVal = InternetCloseHandle(hInternetConnect)
bRetVal = InternetCloseHandle(hRequest)
End
End Sub
ist VB6 weg und ich muß das vbp neu laden!
Das ist übrigens auch so, wenn die Ctrl-Taste im Code gänzlich
unberücksichtigt bleibt.
Bei MouseDown sind alle 4 Punkte ok und Unload funktioniert ohne Absturz.
Wolfgang
> Ich dachte schon am Ende des Tunnels angelangt zu sein.
> Für mich ist es verständlich, bei einer Aktion wie zB.
> rechter Mausklick etwas gegen das Standard
> Kontextmenu zu tun.
Was SubClassing wirklich bedeutet, ist Dir offenbar immer
noch nicht wirklich klar geworden.
Für Deinen Fall "Kontextmenü" heisst das, dass Window
an das Fensterhandle Deiner Textbox eine Nachricht
WM_CONTEXTMENU sendet, wenn die Textbox ihr
Kontextmenü sichtbar machen soll. Der Auslöser hierfür
kann ein rechter Mausklick, aber auch ganz was anderes,
wie z.B. die MenüTaste auf der Tastatur, sein.
SubClassing bedeutet nun, dass man via APi-Funktion
SetWindowLong() alle Nachrichten an das betroffene
Fenster (auch eine Textbox ist ein Fenster) an eine eigene
Prozedur umleitet (in meinem Beispiel ist das die
Function WndProcNoCMenu). In dieser Prozedur kann
man nun alle an das betr. Fenster (Textbox) gerichteten
Windowsnachrichten mitlesen und entscheiden, ob man
diese Nachrichten einfach per Api-Funktion CallWindowProc
an die originale Fensterprozedur (das ist eine Prozedur
ausserhalb Deines VB-Codes, welche das Verhalten
des jeweiligen Fensters steuert) weiterreicht, oder ob
man z.B. zum Unterdrücken eines Contextmenüs im
Falle der Nachricht WM_CONTEXTMENU diese
Nachricht nicht an die originale Fensterprozedur
weitergibt, sondern die eigene Prozedur (WndProcNoCMenu)
einfach mit dem Rückgabewert True (-1) verlässt und
so Windows vorgaukelt, die Nachricht WM_CONTEXTMENU
sei von der org. Fensterprozedur der betr. Textbox
verarbeitet worden. In diesem Fall ist Windows zufrieden
und die Textbox selbst hat gar nicht bemerkt, dass sie
ein Kontextmenü anzeigen sollte.
> Aber ich weiß nicht recht, wie ich Deinen Tip
>
> > sondern wenn du sie erzeugst, also in Form_Load.
>
> verstehen soll?
Du kannst natürlich die Windowsnachrichten an Deine
Textbox schon in Form_Load via Api-Funktion SetWindowLong()
an eine eigene Prozedur umleiten. Das Problem dabei ist
allerdings, dass Du dann Dein Programm in der IDE nicht
mehr gefahrlos anhalten kannst. Deine Prozedur, an welche
Du die Windowsnachrichten umgeleitet hast empfängt ständig
eine Vielzahl von Nachrichten, die, wenn sie nicht beim
tatsächlichen Fenster (Textbox) ankommen resp. nicht
beantwortet werden, dazu führen können, dass Windows
wg. dieses Fehlverhaltens Deine Anwendung einfach
abschiesst. Wenn Du in der IDE Dein Programm anhältst,
dann bedeutet das in jedem Fall, dass evtl. an Deine Textbox
gerichtete Nachrichten weder bei der Textbox ankommen
noch von Deiner eigenen Prozedur durch einen entsprechenden
Rückgabewert beantwortet werden. Also macht Windows
kurzen Prozess und wirft Dein Programm in den Müll.
Bei meiner Methode ist das SubClassing nur immer
einen kurzen Moment aktiv und es kann somit auch
in der IDE beim Debugging nicht zu einem unerwarteten
Absturz kommen.
> Also in Form_Load erzeuge ich nicht explizit Controls.
Natürlich nicht,
die Controls hast Du doch schon vorher im Designmodus
auf die Form gezogen.
> Wie soll ich das dort also tun?
Du musst Dich entscheiden, ob Du das SubClassing
ständig aktiviert haben willst, mit der Gefahr eines
Absturzes beim Debuggen, oder ob Du SubClassing
eben wirklich nur für den Moment aktivierst, in dem
Du es wirklich brauchst. Ich ziehe die zweite Methode vor,
weil sie mit sehr wenig Aufwand zu realisieren ist und
eben die Gefahr eines Absturzes beim Debugging
vermeidet.
> Wenn ich im ggst. Programm das Subclassing bei MouseUp
> mache, dann kommt 1. beim ersten Rechtsklick+Ctrl zuerst
> wieder das textboxeigene Kontextmenu und erst beim 2.Klick
> mein eigenes.
Na ja logisch.
Du sollst das SubClassing ja auch nicht in MousUp aktivieren,
wo es eben schon zu späte ist, sondern zum Zeitpunkt MouseDown.
Wichtig wäre, dass Du erst mal versuchst zu verstehen,
was SubClassing wirklich macht. Es hat wenig Sinn, blind
herumzuprobieren, was, wie Du ja schon bemerkt hast, sehr
schnell zu Abstürzen in der IDE führt.
Nun wird es kaum der Regelfall sein, dass eine fremde
Anwendung Fensternachrichten an eine Textbox oder
was auch immer in meiner Anwendung sendet.
Schau Dir einfach mal das Beispiel unter
www.gssg.de -> Visual Basic -> VBclassic
-> Datenbank -> ADO DemoMU 2002
an. Darin wird die von mir beschriebene Methode verwendet.
Damit können für die Textboxen und das Grid wahlweise
zwei unterschiedliche Kontextmenüs, in Abhängigkeit von
der Strg-Taste, angezeigt werden und ein Anhalten des
Programms in der IDE bleibt ohne unerwünschte Folgen.
> Du musst Dich entscheiden, ob Du das SubClassing
> ständig aktiviert haben willst, mit der Gefahr eines
> Absturzes beim Debuggen, oder ob Du SubClassing
> eben wirklich nur für den Moment aktivierst, in dem
> Du es wirklich brauchst. Ich ziehe die zweite Methode vor,
> weil sie mit sehr wenig Aufwand zu realisieren ist und
> eben die Gefahr eines Absturzes beim Debugging
> vermeidet.
...dafür aber eben nicht alle WM_CONTEXTMENU-Nachrichten abfangen kann,
die die TextBox empfängt.
Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
> Man sollte sich mal im Windows SDK belesen welche
> Nachricht welche Rückgabewerte erfordert.
Glaube mir mal einfach, dass ich da schon öfters
mal nachgelesen habe. Ein Einsteiger, der überhaupt
nicht weiss, was SubClassing ist, sollte erst mal etwas
kleiner beginnen.
> Im Falle von WM_CONTEXTMENU ist es egal was man
> zurückgibt ("No return value"), aber dein obiger Satz klingt
> so als müsse man immer dann -1 (den COM/VB6-Boolean
> -Typ kennt dieser Teil von Windows übrigens gar nicht)
Da solltest Du Dir mal den Rückgabewert meiner
Prozedur ansehen. Das ist ein Long, also wird
-1 zurückgegeben.
> zurückgeben, wenn man die Nachricht selbst
> behandelt. Das ist aber falsch.
Im konkreten Fall meines Beispiels ist es nicht
falsch, wie sich ja leicht ausprobieren lässt.
> > Du musst Dich entscheiden, ob Du das SubClassing
> > ständig aktiviert haben willst, mit der Gefahr eines
> > Absturzes beim Debuggen, oder ob Du SubClassing
> > eben wirklich nur für den Moment aktivierst, in dem
> > Du es wirklich brauchst. Ich ziehe die zweite Methode vor,
> > weil sie mit sehr wenig Aufwand zu realisieren ist und
> > eben die Gefahr eines Absturzes beim Debugging
> > vermeidet.
> ...dafür aber eben nicht alle WM_CONTEXTMENU-Nachrichten
> abfangen kann, die die TextBox empfängt.
Das hat doch auch niemand behauptet. Ich denke aber
dennoch, dass ein Einsteiger nicht sonderlich gut
beraten ist, wenn er mit scharfem SubClassing in der
IDE arbeitet, solange er noch nicht mal weiss, was
SubClassing ist. Wenn er einfach nur irgendwelchen Code
kopiert, dessen Funktionalität er nicht im Geringsten
versteht, wird er es vermutlich auch nie lernen.
> Das beantwortet unsere Frage nicht. Warum zeigst
> du dein eigenes Menü erst in MouseUp an und nicht
> bei der Behandlung von WM_CONTEXTMENU wo es
> passender wäre?
Weil damit ganz einfach sichergestellt ist, dass die
eigene Fensterprozedur schnellstmöglich verlassen
wird und erst gar nicht die Gefahr besteht, dass irgend-
welcher Code ausgeführt wird, der evtl. einen Fehler
auslösen könnte. Und natürlich ist MouseUp sehr
wohl der geeignete Moment, ein eigenes Kontext-
menü anzuzeigen. Wann sollte es denn sonst
gezeigt werden. Das normale Kontextmenü kommt
ja auch beim Loslassen der Maustaste.
Ich denke aber, wir beenden diese inzwischen doch
reichlich fruchtlos gewordene Diskussion.
> Da solltest Du Dir mal den Rückgabewert meiner
> Prozedur ansehen. Das ist ein Long, also wird
> -1 zurückgegeben.
Das ist richtig. Ich halte es zwar für schlechten Stil einer
Long-Variable einen COM-Boolean zuzuweisen, aber das ist eine Frage des
Geschmacks.
> Im konkreten Fall meines Beispiels ist es nicht
> falsch, wie sich ja leicht ausprobieren lässt.
Schrieb ich ja auch, dass es im konkreten Fall egal ist.
> Wenn er einfach nur irgendwelchen Code
> kopiert, dessen Funktionalität er nicht im Geringsten
> versteht, wird er es vermutlich auch nie lernen.
Dem stimme ich natürlich zu.
> Wann sollte es denn sonst
> gezeigt werden. Das normale Kontextmenü kommt
> ja auch beim Loslassen der Maustaste.
Jein. Du kannst nicht wissen was zwischen WM_CONTEXTMENU und WM_MOUSEUP
Windows-intern alles passiert. Windows geht davon aus, dass Kontextmenüs
bei Erhalt von WM_CONTEXTMENU angezeigt werden. Wenn man sie erst bei
Erhalt von WM_MOUSEUP anzeigt, kann man sich nie sicher sein, dass es
keine Probleme gibt.
Außerdem kommt das Menü auch beim Loslassen der Kontextmenütaste oder
beim Loslassen von Shift+F10 oder beim Erhalt einer
WM_CONTEXTMENU-Nachricht von einer fremden Anwendung. Für all diese
Fälle braucht man bei deinem Ansatz eine Speziallösung bzw. kann sie
überhaupt nicht behandeln. Zeigt man das Kontextmenü bei Erhalt von
WM_CONTEXTMENU an, hat man 1 zentralen Punkt zum Anzeigen des Menüs und
erschlägt nebenbei alle Fälle (außer man subclassed nur temporär).
Timo (der wo das Nichtvorhandensein eines ContextMenu-Events in VB6 für
eine der dämlichsten Designentscheidungen Microsofts hält, da sie die
Entwickler zu Krüppellösungen geradezu drängt)
> Wichtig wäre, dass Du erst mal versuchst zu verstehen,
> was SubClassing wirklich macht. Es hat wenig Sinn, blind
> herumzuprobieren, was, wie Du ja schon bemerkt hast, sehr
> schnell zu Abstürzen in der IDE führt.
Siehe mein fast zeitgleiches Posting weiter oben!
Wolfgang
Nun, so tief bin ich in die Tiefen von Windows wirklich noch nicht
vorgedrungen.
> .........
> SubClassing bedeutet nun, dass man via APi-Funktion
> SetWindowLong() alle Nachrichten an das betroffene
> Fenster (auch eine Textbox ist ein Fenster) an eine eigene
> Prozedur umleitet (in meinem Beispiel ist das die
> Function WndProcNoCMenu).
> ........
Aber irgendwie stimmt es doch, daß erst bei einer Aktion (also einer
Nachricht an das Fenster)
der Code WndProcNoCMenu aktiv wird, damit auch erst dann etwas gegen das
systemeigene Kontextmenu geschieht?
Im Form_Load eingebaut, wie Timo schrieb, werden am Beginn des Programmes
die Weichen dafür gestellt.
Das habe ich eigentlich gemeint.
Ich dachte zuerst, daß das so etwas wie Unter-Klassen-Bibliotheken sind, die
meinem Programm
hinzuzufügen sind.
Aber es ist mir nun klar geworden was unter Subclassing zu verstehen ist.
Besten Dank.
Wolfgang
> Timo (der wo das Nichtvorhandensein eines ContextMenu-Events in VB6 für
> eine der dämlichsten Designentscheidungen Microsofts hält, da sie die
> Entwickler zu Krüppellösungen geradezu drängt)
So würde ich das auch sehen.
Ein Ansatz wäre auch, überhaupt kein systemeigenes Kontextmenu der Textbox
bereitzustellen, wie zB. im ListView.
Aber veilleicht sage ich hier wieder was falsches.
Jedenfalls ist mir dort noch kein systemeigenes Menu aufgefallen.
Wolfgang
>> Timo (der wo das Nichtvorhandensein eines ContextMenu-Events in VB6
>> für eine der dämlichsten Designentscheidungen Microsofts hält, da
>> sie die Entwickler zu Krüppellösungen geradezu drängt)
> So würde ich das auch sehen.
> Ein Ansatz wäre auch, überhaupt kein systemeigenes Kontextmenu der
> Textbox bereitzustellen, wie zB. im ListView.
> Aber veilleicht sage ich hier wieder was falsches.
> Jedenfalls ist mir dort noch kein systemeigenes Menu aufgefallen.
Die TextBox ist wohl das einzige unter den (zumindest gängigeren)
Windows-Controls, das ein fest eingebautes Kontextmenü hat.
Aber selbst wenn die TextBox kein eingebautes Kontextmenü hätte,
würdest Du nicht ums SubClassen herumkommen - das meinte Timo mit
seiner "Reklamation", der ich voll und ganz zustimme.
> Aber irgendwie stimmt es doch, daß erst bei
> einer Aktion (also einer Nachricht an das Fenster)
> der Code WndProcNoCMenu aktiv wird, damit
> auch erst dann etwas gegen das systemeigene
> Kontextmenu geschieht?
Ja und das ganz bewusst, damit eben nicht alle
Nachrichten (das können hunderte sein) überprüft
werden müssen.
> Im Form_Load eingebaut, wie Timo schrieb, werden
> am Beginn des Programmes die Weichen dafür
> gestellt.
Ja, das ist richtig und hat zur Folge, dass eben alle
Fensternachrichten ständig erst mal umgeleitet werden
und überprüft werden muss, ob es sich dabei um
WM_CONTEXTMENU handelt oder um eine der vielen
anderen Nachrichten, die ständig an ein Fenster geschickt
werden. Überfahren mit der Maus, Verdecken und Freilegen
durch andere Fenster und tausend andere Dinge mehr
lösen solche Fensternachrichten aus und müssen bei
einem permanenten SubClassing dann eben auch
entsprechend behandelt werden. U.a. führt das eben auch
dazu, dass man das Programm in der IDE auf keinen
Fall anhalten darf, da die Wahrscheinlichkeit, dass
"lebensnotwendige" Fensternachrichten nicht mehr
richtig verarbeitet werden können, sehr hoch ist und
Windows zur Notwehr greift und Deine VB-IDE abschiesst.
Es muss eben immer sichergestellt sein, dass alle Fenster-
nachrichten fehlerfrei verarbeitet werden, was bei aktivertem
SubClassing nicht mehr möglich ist, wenn das Programm
in der IDE angehalten wurde.
Diese Gefahr wird eben ausgeschaltet, wenn man das
SubClassing ganz gezielt nur kurzfristig für eine ganz
bestimmte Aktion aktiviert.
Das verstehe ich nun wieder nicht!
Der ganze Thread handelte doch von dem Problem, daß das systemeigene
Kontextmenu der Textbox meinem eigenen Popup im Wege war.
Wenn, wie in einem Listview, gar kein systemeigenes vorhanden ist, so kann
beim Rechtsklick ja mein eigenes problemlos angezeigt werden.
Warum sollte ich nun subclassen?
Aber da habe ich sicher wieder etwas übersehen oder vielleicht doch noch
nicht ganz verstanden.
Wolfgang
>> Aber selbst wenn die TextBox kein eingebautes Kontextmenü hätte,
>> würdest Du nicht ums SubClassen herumkommen - das meinte Timo mit
>> seiner "Reklamation", der ich voll und ganz zustimme.
> Das verstehe ich nun wieder nicht!
> Der ganze Thread handelte doch von dem Problem, daß das systemeigene
> Kontextmenu der Textbox meinem eigenen Popup im Wege war.
> Wenn, wie in einem Listview, gar kein systemeigenes vorhanden ist, so
> kann beim Rechtsklick ja mein eigenes problemlos angezeigt werden.
Die Kontextmenütaste und die Tastenkombination Umschalt+F10 nicht
vergessen...
> Warum sollte ich nun subclassen?
> Aber da habe ich sicher wieder etwas übersehen oder vielleicht doch
> noch nicht ganz verstanden.
Wirklich regulär ist nur subclassen. Denn dann ist es egal, wodurch die
Anforderung, ein Kontextmenü anzuzeigen, tatsächlich ausgelöst worden
ist - egal, ob über Rechtsklick oder Tasten(kombinationen) oder
irgendwelche Eingabehilfsmittel. Du hast dann lediglich einen einzigen
Punkt, den Deine Anwendung zu berücksichtigen braucht.
Danke für diesen Hinweis!
Oft genug habe ich schon festgestellt, daß jede Irregularität ganz woanders
zu unerwarteten
Problemen führen kann.
Timos Code http://www.timosoft-software.de/stuff/SuppressContextMenu.zip
habe ich nun auch eingebaut.
Alles ist nun wirklich so, wie es soll.
Und es funktioniert auch. ;-))
Danke, Wolfgang