| |
VB & Windows APISetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 16.02.05 15:03 |
| Hi,
ich glaube so langsam bin ich am Verzweifeln... Ich bastel gerade an einer Anwendung mit vielen, vielen Fenstern. Jedes dieser Fenster besitzt einen Button, mit dem das jeweilige Fenster mittels SetWindowPos systemweit als Topmost-Fenster angezeigt wird (also nicht verdeckt werden kann)...
Nun kann der Nutzer durch Klicken auf den Button in der Titelleiste die Topmost-Eigenschaft ein- oder ausschalten, was auch für das jeweilige Fenster ganz gut funktioniert... Aber: Die API scheint diese Eigenschaft nicht nur einem Fenster zu entziehen, sondern allen...
Hier mal ein Beispielcode. Ihr benötigt dazu lediglich 2 Forms, in der ersten gehört dieser Code rein:
Option Explicit
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal _
hWndInsertAfter As Long, ByVal x As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Sub Form_Load()
'Erst mal zweite Form laden:
Form2.Show
'Erste Form nach oben:
SetWindowPos Me.hWnd, -1, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
'Zweite Form nach oben:
SetWindowPos Form2.hWnd, -1, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
'Erste Form nicht mehr oben:
SetWindowPos Me.hWnd, -2, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End Sub Der Code macht folgendes:
* Form1 nach oben
* Form2 nach oben
* Form1 nicht mehr nach oben
Windows führt jetzt irgendwie noch den Schritt "Form2 nicht mehr oben" aus, obwohl ich den eigentlich nie wollte... Ich bin schon fast am verzweifeln, die anderen Formulare sollen doch oben bleiben... Wer hat von euch schon mal ähnliche Erfahrungen gemacht? Wer kennt eine Lösung? Ich freue mich schon auf eure zahlreichen Antworten
E7
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 16.02.05 16:06 |
| Hi,
Zitat: | | When a topmost window is made non-topmost, its owners and its owned windows… | |
ja, Eltern (parent) und Kinder (child). Meine Fenster existieren aber nebeneinander, und haben höchstens gemeinsame Vorfahren
Mittels .Show werden die Fenster ja rein theoretisch als Geschwister angezeigt, stehen also nicht direkt miteinander in Beziehung.
In meinem Programm gibt es ein Fenster, das zeigt alle Unterfenster auch einfach mittels .Show an - damit existieren alle Fenster nebeneinander, es können ja nicht einfach irgendwelche Kinder bevorzugt werden
Außerdem denke ich, .Show ist eine Funktion des anzuzeigenden Fensters, und so lange kein Parameter mitgeliefert wird, auch unabhängig von seinem aufrufenden Fenster... Bzw.: Was ist, wenn ich das Fenster von einem Modul aus anzeige?
E7
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 16.02.05 19:29 |
| aber irgendwie muss das doch möglich sein, dass wenn ein Fenster nicht mehr Ontop ist, die anderen dennoch oben bleiben? Die Taskleiste verschwindet schließlich auch nicht einfach...
Im Grunde kann ich ja sämtliche Forms durchgehen und für die betroffenen Forms wieder SetWindowPos aufrufen - aber so wirklich gut ist die Lösung nicht...
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: Guido Eisenbeis | Datum: 02.03.05 01:28 |
| Option Explicit
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal _
hWndInsertAfter As Long, ByVal x As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Sub Form_Load()
'Erst mal zweite Form laden:
Form2.Show
'Erste Form nach oben:
SetWindowPos Me.hWnd, -1, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
Me.Show ' <-- Anzeigen der Form abschließen/sicherstellen
'Zweite Form nach oben:
SetWindowPos Form2.hWnd, -1, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
' 'Erste Form nicht mehr oben:
' SetWindowPos Me.hWnd, -2, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE ' <-- _
weglassen
End Sub Guido | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 02.03.05 14:03 |
| Ähm... Wie verwende ich jett deinen Code? Bzw. warum soll ich die letzte Zeile weglassen? Das ist doch genau der Punkt, die Zeile brauch ich ja...
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: Guido Eisenbeis | Datum: 02.03.05 21:07 |
| Hast du's ausprobiert?
"HWND_NOTOPMOST Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window."
Auf Deutsch: Der Parameter "HWND_NOTOPMOST" hat keinen Effekt, wenn das Fenster schon ein "non-topmost window" ist. (Zumindest offensichtlich nicht den gewünschten!)
Guido | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: RapID23o5 | Datum: 10.03.05 15:40 |
| Wenn es so nicht geht dann versuch es doch mit der DeferWindowPos funktion damit setzt du für mehrere Fenster gleichzeitig ein Handle! Irg.wie StartDeferWindowPos dann die Defs und dann EndDeferWindowPos "!
Ohne Mampf, kein Kampf ! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 10.03.05 19:30 |
| Hi,
die Funktion sieht zwar ganz nett aus - aber im Endeffekt macht es keinen Unterschied, ob ich nun das ganze mit einer Schleife und SetWindowPos mache, oder mit DeferWindowPos - die Fenster werden zurückgesetzt, und anschließend muss ich diese wieder nach vorne bringen. Genau das ist es, was ich vermeiden will.
E7
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: RapID23o5 | Datum: 11.03.05 16:09 |
| ' - - - - - - - - - - - - - - - - - - - - - - -
' Erstelle 5 Formen
' Namen: Form1 - Form4, Topper
'
' Erstelle 6 CommandButtons auf Form1
' Namen: Command1 - Command6
'
' Füge Nachfolgenden code in den Privaten Deklarations Bereich der Form1
' Aussprobieren und spass haben ... ;)
' - - - - - - - - - - - - - - - - - - - - - - -
' Ich denke mal der restliche Code erklärt sich von selbst!
' - - - - - - - - - - - - - - - - - - - - - - -
Option Explicit
Private Declare Function SetWindowPos Lib "user32" (ByVal _
hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
ByVal y As Long, ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Sub SetTopLevelWindow(ByVal hWnd As Long, Optional topmost As Boolean = _
True)
Const HWND_NOTOPMOST = -2
Const HWND_TOPMOST = -1
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
SetWindowPos hWnd, IIf(topmost, HWND_TOPMOST, HWND_NOTOPMOST), 0, 0, 0, 0, _
SWP_NOMOVE + SWP_NOSIZE
SetWindowPos Me.hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE
End Sub
Private Sub Command1_Click()
SetTopLevelWindow Form2.hWnd
End Sub
Private Sub Command2_Click()
SetTopLevelWindow Form3.hWnd
End Sub
Private Sub Command3_Click()
SetTopLevelWindow Form4.hWnd
End Sub
Private Sub Command4_Click()
SetTopLevelWindow Form2.hWnd, False
End Sub
Private Sub Command5_Click()
SetTopLevelWindow Form3.hWnd, False
End Sub
Private Sub Command6_Click()
SetTopLevelWindow Form4.hWnd, False
End Sub
Private Sub Form_Initialize()
Command1.Caption = "Form2 Top"
Command2.Caption = "Form3 Top"
Command3.Caption = "Form4 Top"
Command4.Caption = "Form2 NotTop"
Command5.Caption = "Form3 NotTop"
Command6.Caption = "Form4 NotTop"
Command1.Move 240, 2000, 800, 500
Command2.Move 240, 2500, 800, 500
Command3.Move 240, 3000, 800, 500
Command4.Move 1040, 2000, 800, 500
Command5.Move 1040, 2500, 800, 500
Command6.Move 1040, 3000, 800, 500
End Sub
Private Sub Form_Load()
Form1.Move 1000, 1000, 2200, 5000
Form2.Move 1000, 1000, 50, 50
Form3.Move 1500, 1100, 50, 50
Form4.Move 2000, 1200, 50, 50
Topper.Move -1000, -1000, 0, 0
Form2.Show
Form3.Show
Form4.Show
Topper.Show
SetTopLevelWindow Form2.hWnd
SetTopLevelWindow Form3.hWnd
SetTopLevelWindow Form4.hWnd
SetTopLevelWindow Topper.hWnd
End Sub Ohne Mampf, kein Kampf ! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 11.03.05 17:58 |
| Hi,
mmhmhh... der Code funktioniert so weit ganz gut - sobald aber Form1 auch Topmost ist, zeigt sich wieder das misteriöse Verhalten...
Ich hab mal noch einen Commandbutton dazu:
Private Sub Command7_Click()
SetWindowPos Me.hWnd, -1, 0, 0, 0, 0, 3
End Sub Ich klicke auf diesen Button, und anschließend auf einen beliebigen anderen, der ein Fenster zurück in den Hintergrund setzt - und promt ist Form1 ebenfalls weg. Genau das ist das Problem, mein allererstes Fenster ist grundsätzlich oben...
Falls ihr das ganze mal selbst im Programm ausprobieren wollt: http://sourceforge.net/project/showfiles.php?group_id=131465... Die .zip und die .7z sind der Sourcecode (beide bis auf ihre Komprimierung identisch). Der Code findet sich in frmNote.imgControl_Click(index=1), zw. ELSE und ENDIF... Natürlich freu ich mich auch über andere Verbesserungen im Programm, ist schließlich OpenSource
Die letzte Zeile von SetTopLevelWindow() hab ich übrigens auskommentiert, da sich dieses Verhalten von selbst einstellt ist aber wurscht...
E7
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: BasTler | Datum: 14.04.05 13:34 |
| Hi E7,
kann dir bei deinem Prob's leider nicht helfen und weiß auch nicht so recht, wofür du das Ganze brauchst, aber das Design und die Anordnung der Elemente gefällt mir. Wollte ich nur mal sagen.
Gruß BasTler | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: BasTler | Datum: 14.04.05 13:53 |
| Hi E7,
nochmal ich, vielleicht kann ich dir doch etwas helfen, durch ein paar Tipps bzw. Hinweise auf andere API-Aufrufe die Fenster betreffen.
AnyPopup (User32) ermittelt, ob am Bildschirm ein Überlagerungsfenster sichtbar ist.
BeginDeferWindowPos (User32) verschiebt mehrere Fenster gleichzeitig und zeichnet den Bildschirm neu.
BringWindowToTop (User32) stellt das angegebene Fenster in den Vordergrund (Z-Position).
CBTProc (IMPORT) Rückruffunktion, die vom System aufgerufen wird, bevor ein Fenster aktiviert, erzeugt, freigegeben, zum Symbol verkleinert, zum Vollbild vergrößert, verschoben oder in seiner Größe verändert wird.
ChangeClipboardChain (User32) löscht das angegebene Fenster aus der Kette der Clipboard-Viewers.
ChildWindowFromPoint(User32) liefert einen Handle (Verweis) auf das Fenster zurück, über dem sich der Mauszeiger beim Auslösen einer Mausnachricht befand.
DeferWindowPos (User32) bestimmt die Positionskoordinaten für die zu verschiebenden Fenster.
DestroyWindow (User32) entfernt das angegebene Fenster.
EnableCommNotification (IMPORT) aktiviert oder deaktiviert die Übergabe von WM_COMMNOTIFY-Botschaften an das angegebene Fenster.
EnumThreadWindows (User32) ermittelt alle Fenster eines bestimmten Tasks.
GetActiveWindow (User32) liefert einen Handle (Verweis) auf das aktive Fenster, das dem Thread zugeordnet ist, der die Funktion aufruft.
GetCapture (User32) stellt einen Handle bereit, der das Fenster bezeichnet, das alle Mauseingaben auf sich zieht. Zu einem bestimmten Zeitpunkt hat nur ein einzelnes Fenster die Fähigkeit, Mauseingaben zu bearbeiten; es empfängt die Mauseingaben auch, wenn sich der Mauszeiger außerhalb seiner Grenzen befindet.
Wie erwähnt, wollte nur helfen, nicht verwirren.
Gruß BasTler | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: E7 | Datum: 14.04.05 18:07 |
| Hi,
die Liste ist zwar umfangreich - aber leider kann man die Fenster nur mittels SetWindowPos() dauerhaft ontop und wieder zurück setzen. Das Problem ist ja hier, dass SetWindowPos eben das macht, was sie tun soll - nur eben etwas übereifrig.
E7
???????????????????????????????????????????????????????????
e7o.de | jetzt (wirklich) neu! | |
Re: SetWindowPos: Bug? Fenster nicht oben! | | | Autor: RapID23o5 | Datum: 03.06.05 16:03 |
| Dieser Fehler ist übrig. ein bekannter BUG (Q192254) siehe 3.! Allerdings nur in VB in C und so sollte SetWindowPos richtig funktionieren. Ich denke das hat was mit dem VB-SingleThreadingModel zu tun . . .
SYMPTOMS
When using the SetWindowPos() API in Visual Basic to set the Topmost window flag, these known problems may occur:
1. When an application is running in the Visual Basic IDE, clicking on the Desktop or My Computer icon causes the Topmost window setting to be turned off. This does not occur when the application is a compiled EXE. Please see the REFERENCES section below for more information.
2. Setting the Topmost flag for a parent form does not set it for that form's children. This conflicts with the documented behavior of the SetWindowPos function.
3. When calling SetWindowPos with the NoTopmost flag for a Visual Basic form, all forms in the project are set to NoTopmost.
leider scheint es kein WorkAround hierfür zu geben... Naja.... Ich bleib dran ;) ma sehn
Ohne Mampf, kein Kampf ! | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevISDN 1.0
Überwachung aller eingehender Anrufe!
Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Weitere InfosTipp des Monats März 2024 Dieter OtterUTF-8 Konvertierung von Dateien und StringsVB6 selbst verfügt über keine Funktionen zur UTF-8 Konvertierung von Daten. Mit Hilfe des ADODB.Stream-Objekts lassen sich diese fehlenden Funktionen aber schnell nachrüsten. sevGraph (VB/VBA)
Grafische Auswertungen
Präsentieren Sie Ihre Daten mit wenig Aufwand in grafischer Form. sevGraph unterstützt hierbei Balken-, Linien- und Stapel-Diagramme (Stacked Bars), sowie 2D- und 3D-Tortendiagramme und arbeitet vollständig datenbankunabhängig! Weitere Infos
|