VB 5/6-Tipp 0164: Command-Button in der Titelleiste erstellen lassen
von ActiveVB
Beschreibung
Wem die Anzahl der Schaltflächen in der Titelleiste nicht genügen, kann nach Belieben dort neue platzieren. Dies funktioniert in dem der Button zwangsweise von der Titelleiste 'adoptiert' wird.
Update am XX.XX.XXXX von Rudi und spiren: Die Events werden nun auch unter 2k und XP Systemen erkannt (man muss das Ereignis "mouseup" oder "mousedown" verwenden). Außerdem wurde der Code gekürzt.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: GetParent, GetWindowRect, SetParent, SetWindowLongA (SetWindowLong), SetWindowPos, SetWindowsHookExA (SetWindowsHookEx), UnhookWindowsHookEx | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '------------- Anfang Projektdatei Projekt1.vbp ------------- '--------- Anfang Formular "Form1" alias Form1.frm --------- ' Steuerelement: Schaltfläche "Command3" ' Steuerelement: Schaltfläche "Command2" ' Steuerelement: Schaltfläche "Command1" Option Explicit Private Sub Form_Load() Call Init End Sub Private Sub Form_Unload(Cancel As Integer) Call Terminate End Sub Public Sub Command1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) Call MsgBox("Command1_MouseUp()") End Sub Public Sub Command2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) Call MsgBox("Command2_MouseUp()") End Sub Public Sub Command3_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) Call MsgBox("Command3_MouseUp()") End Sub '---------- Ende Formular "Form1" alias Form1.frm ---------- '--------- Anfang Modul "Module1" alias Module1.bas --------- Option Explicit Public Declare Function SetWindowLong Lib "user32" Alias _ "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex _ As Long, ByVal dwNewLong As Long) As Long Public Declare Function GetWindowRect Lib "user32" (ByVal _ hwnd As Long, lpRect As Rect) As Long Public Declare Function GetParent Lib "user32" (ByVal _ hwnd As Long) As Long Public Declare Function SetParent Lib "user32" (ByVal _ hWndChild As Long, ByVal hWndNewParent As Long) _ As Long Public 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 Public Declare Function SetWindowsHookEx Lib "user32" Alias _ "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, _ ByVal hmod As Long, ByVal dwThreadId As Long) As Long Public Declare Function UnhookWindowsHookEx Lib "user32" _ (ByVal hHook As Long) As Long Public Type Rect Left As Long Top As Long Right As Long Bottom As Long End Type Public Type CWPSTRUCT lParam As Long wParam As Long Message As Long hwnd As Long End Type Private Const WM_MOVE As Long = &H3& Private Const WM_SETCURSOR As Long = &H20& Private Const WM_NCPAINT As Long = &H85& Private Const WM_COMMAND As Long = &H111& Private Const SWP_FRAMECHANGED As Long = &H20& Private Const GWL_EXSTYLE As Long = -20& Private WHook As Long Public Sub Init() WHook = SetWindowsHookEx(4, AddressOf HookProc, 0, App.ThreadID) Call SetWindowLong(Form1.Command1.hwnd, GWL_EXSTYLE, &H80) Call SetParent(Form1.Command1.hwnd, GetParent(Form1.hwnd)) Call SetWindowLong(Form1.Command2.hwnd, GWL_EXSTYLE, &H80) Call SetParent(Form1.Command2.hwnd, GetParent(Form1.hwnd)) Call SetWindowLong(Form1.Command3.hwnd, GWL_EXSTYLE, &H80) Call SetParent(Form1.Command3.hwnd, GetParent(Form1.hwnd)) End Sub Public Sub Terminate() Call UnhookWindowsHookEx(WHook) Call SetParent(Form1.Command1.hwnd, Form1.hwnd) Call SetParent(Form1.Command2.hwnd, Form1.hwnd) Call SetParent(Form1.Command3.hwnd, Form1.hwnd) End Sub Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, _ Inf As CWPSTRUCT) As Long Dim R As Rect Static LastParam As Long If Inf.hwnd = Form1.hwnd Then If Inf.Message = WM_NCPAINT Or Inf.Message = WM_MOVE Then Call GetWindowRect(Form1.hwnd, R) Call SetWindowPos(Form1.Command1.hwnd, 0, R.Right - 111, _ R.Top + 6, 17, 14, SWP_FRAMECHANGED) Call SetWindowPos(Form1.Command2.hwnd, 0, R.Right - 93, _ R.Top + 6, 17, 14, SWP_FRAMECHANGED) Call SetWindowPos(Form1.Command3.hwnd, 0, R.Right - 75, _ R.Top + 6, 17, 14, SWP_FRAMECHANGED) End If End If End Function '---------- Ende Modul "Module1" alias Module1.bas ---------- '-------------- Ende Projektdatei Projekt1.vbp --------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | |||||||
VB5 | |||||||
VB6 |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 18 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von ben am 28.10.2007 um 14:16
weiß einer denn code bitte melden
Kommentar von Maggo am 31.07.2006 um 21:37
Hey aufgepasst ihr solltet das projekt nicht über den stopp-button schließen, da sonst visualbasic das programm nicht beenden kann un hängen bleibt!
Kommentar von Homeier am 31.05.2005 um 08:07
Hallo Leute,
hat einer diesen Code schon für VB.Net aktualisiert?
Vielleicht kann man mir den mal zukommen lassen.
Danke.
Homeier
Kommentar von Marte am 04.05.2005 um 08:33
Hallo!
Hat schon mal jemand probiert, einen zusätzlichen Button in die Titelleiste eines MDI-Formulars zu bringen? Bei mir funktioniert es.Ich habe, da man auf dem MDI keine Buttons platzieren kann, den Button auf der ersten Form die aufgerufen wird plaziert. Es klappt auch wunderbar, nur das der Button im Taskmanager als eigene Anwendung angezeigt wird, d.h. es hat nachher im Taskmanager eine Anwendung "I" (I ist die Beschriftung des Buttons) und wenn man dem Button einen ToolTip zuweist,dann wird sogar der zu einer eigenen Anwendung.Hatte auch scho mal jemand das Problem bzw. hat einen Tipp wie ich das ändern kann??
Marte
Kommentar von Gigolo am 14.10.2004 um 11:04
Hallo!!
Bei wird die Funktion die hinter den Buttons steht nicht ausgeführt.......
Ich hoffe Sie können mir einen Tip geben, wie ich dieses Problem lösen kann......
Vielen Dank schon im Voraus
MfG Gigolo
Kommentar von Rick am 08.07.2004 um 13:48
Hallo Patrick,
Wegen Deiner Frage vom 22.02.2004 um 19:30 Uhr.
Hast Du das Event Command1_Click in der Form Public gemacht? Standardmäßig sind die Events der Formulare nämlich Private.
Dabei gilt z.B.
Sub Command1_Click()
und
Private Sub Command1_Click()
sind das Gleiche!
Es muss heissen
Public Sub Command1_Click()
Aufpassen: VB6 schmiert unter umständen ab, wenn die App normal beendet wird.
mfg Rick
Kommentar von Patrick Hegemann am 23.02.2004 um 15:05
Hallo,
ich habe eine frage und zwar:
wie kann ich machen, das wenn ich auf die Buttons Klicke das Etwas Passiert?
ich Bitte um Hilfe
mfg
Patrick Hegemann
Kommentar von Patrick Hegemann am 22.02.2004 um 19:30
Hallo,
bei mir zeigt er folgenden Fehler an wenn ich das Programm Öffne:
Fehler beim Kompilieren:
Methode oder Mitgliedsdaten nicht gefunden
wegen der Zeile im Modul:
Call Form1.Command1_Click
Bitte helft mir
mfg
Patrick Hegemann
Kommentar von Rudi am 27.05.2003 um 14:27
das MouseUp-Event funktioniert auch ohne den Hook-Part mit dem Click-Event (VB5, NT4).
da kann man sich also den teil vom großen If bis zum ElseIf im HookProc sparen.
Kommentar von Jerry am 02.04.2003 um 14:29
Wichtig ist der Aufruf von "sub terminate()" am Ende.
Zur Laufzeit wird dies automatisch über "Form_Unload" erledigt. - Im Designmodus muss man dies vor Rückkehr in den Designmodus evt. von Hand erledigen (Projekt mit Pause unterbrechen; "call Terminate" im Direktfenster aufrufen; Projekt beenden)
Kommentar von spiren am 19.06.2002 um 13:08
Mhh der Tip is aber nicht ganz ungefährlich, wenn man das Projekt startet und dann auf pause klickt, dann schmiert einen vb ab.
Kommentar von spiren am 19.06.2002 um 13:03
Mhh bei mir geht es, ich muss nur das event Command1_MouseUp nehmen und schon geht es hab win2k.
Kommentar von Ivan am 26.04.2002 um 13:28
Habe Win 2000.
Wenn ich die Schaltflächen klicke passiert gar nichst.. :-(( Bitte um Hilfe
Kommentar von propan am 26.12.2001 um 15:32
ich habe vor kurzem Win2000Pro (also NT 5) installiert.
die buttons werden immernoch angezeigt,
empfangen aber keine events mehr. gibt es eine möglichkeit die buttons auch unter diesem betriebssystem
funktionsfähig zu machen?
Kommentar von Eisbaer 24 am 11.09.2001 um 09:05
Funktionieren tut das ganze ja, nur leider hat es einen wirklich doofen Nebeneffekt.
Wenn ich ein anderes Formular modal anzeigen lassen, dann erscheinen die Commandbuttons der Titelleiste auch auf diesem Formular, weil sie nähmlich als separates Formular gelten. (Die Commandbuttons werden nicht sofort angezeigt, nur wenn man das modal angezeigte Formular ein paar Mal über das "gehookte" Formular bewegt. ) Wie kann ich das verhindern ?
Kommentar von Martin Straube am 17.07.2001 um 21:04
Hallo Teddy...
soweit ich weiß funktioniert das SubClassen ( so sieht das für mich aus ) von "fremden" Anwendungen in Visual Basic nicht...
man kann nur seine "eigenen" Fenster SubClassen.
Wng
Martin Straube
Kommentar von Xinorcimo am 10.01.2001 um 13:23
WHook = SetWindowsHookEx(4, AddressOf HookProc, 0, App.ThreadID)
funtioniert bei VB4 nicht. Die AdressOf-Funktion ist in der Version 4 noch nicht integriert.
Kommentar von Ted Teddy am 05.01.2001 um 13:39
Eine Frage an die Profis: (bei der ich verzweifle)
Kann ich diese Buttons auch in andere fremde Fenster bringen, deren Hwnd ich besitze? Ich habs schon mit "ersetzten" probiert, bekomm es aber nicht hin... HILFE! ;)