Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0164: Command-Button in der Titelleiste erstellen lassen

 von 

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:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

GetParent, GetWindowRect, SetParent, SetWindowLongA (SetWindowLong), SetWindowPos, SetWindowsHookExA (SetWindowsHookEx), UnhookWindowsHookEx

Download:

Download des Beispielprojektes [3,05 KB]

'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-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

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! ;)