Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0086: Common Dialog beliebig auf dem Bildschirm positionieren

 von 

Beschreibung 

Der Common Dialog erscheint meist dort, wo er am meisten stört. Dabei läßt er sich mit einem Trick Pixelgenau postionieren. Dafür müssen die Fensternachrichten des eigenen Threads abgehört werden. Der Trick besteht darin, auf das Öffnen eines neuen Fensters zu warten und dieses mit der KlassenID des ComDlgs zu vergleichen. Bei Erfolg kann dann mit der API SetWindowsPos dieser an die gewünschte Stelle verschoben werden.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

GetClassNameA (GetClassName), SetWindowPos, SetWindowsHookExA (SetWindowsHookEx), UnhookWindowsHookEx

Download:

Download des Beispielprojektes [3,15 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 Project1.vbp -------------
' Die Komponente 'Microsoft Common Dialog Control 6.0 (SP3) (comdlg32.ocx)' wird benötigt.

'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Schaltfläche "Command2"
' Steuerelement: Standarddialog-Steuerelement "CommonDialog1"
' Steuerelement: Schaltfläche "Command1"

Option Explicit

Private Sub Command1_Click()
    'Absolute X & Y Position des Dialoges in Pixels festlegen
    Call InitDlgPos(App.ThreadID, 500, 500)
    
    'Dialog aufrufen
    CommonDialog1.ShowOpen
    
    'Hook zurücksetzen (wichtig, sonst Absturz !!!)
    Call ResetDlgPos
End Sub

Private Sub Command2_Click()
    Dim Break As Boolean
    On Error Goto Abbruch:
  
    'Absolute X & Y Position des Dialoges in Pixels festlegen
    Call InitDlgPos(App.ThreadID, 200, 200)
    
    'Dialog aufrufen
    CommonDialog1.CancelError = True
    CommonDialog1.ShowColor
    
    'Hook zurücksetzen (wichtig, sonst Absturz !!!)
    Call ResetDlgPos
    
    If Break Then Call MsgBox("Abbruch")
    Exit Sub
 
Abbruch:
   'Es wurde "Abbrechen" ausgewählt
   Break = True
   Resume Next
End Sub

Private Sub Form_Load()
    Command1.Caption = "Common Dialog aufrufen"
    Command2.Caption = "Dialog aufrufen mit CancelError"
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'--------- Anfang Modul "Module1" alias Module1.bas ---------
Option Explicit

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

Private Declare Function GetClassName Lib "user32" _
        Alias "GetClassNameA" (ByVal hWnd As Long, _
        ByVal lpClassName As String, ByVal nMaxCount _
        As Long) As Long

Public Declare Function UnhookWindowsHookEx Lib "user32" _
       (ByVal hHook As Long) As Long

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 Type CWPSTRUCT
    lParam As Long
    wParam As Long
    message As Long
    hWnd As Long
End Type

Private Const WH_CALLWNDPROC As Long = 4
Private dlgX As Long, dlgY As Long, pPos As Long

Public Sub InitDlgPos(ByVal ID As Long, X As Long, Y As Long)
    pPos = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf DlgPosProc, 0, ID)
    dlgX = X
    dlgY = Y
End Sub

Public Sub ResetDlgPos()
    Dim Result As Long
    Result = UnhookWindowsHookEx(pPos)
End Sub

Public Sub DlgPosProc(ByVal n&, ByVal wParam&, Inf As CWPSTRUCT)
    Dim Result As Long, Class As String * 6
    
    If Inf.message = 1 Then
        GetClassName Inf.hWnd, Class, 7
        If Left(Class, 6) = "#32770" Then
            SetWindowPos Inf.hWnd, 0, dlgX, dlgY, 0, 0, 1
        End If
    End If
End Sub
'---------- Ende Modul "Module1" alias Module1.bas ----------
'-------------- Ende Projektdatei Project1.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 1 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 George Löwer am 11.03.2008 um 09:02

Hi @ll,

also mit dem Farbdialog klappt das wunderbar, aber der Öffnen/ Speicherndialog wird immer dort geöffnet, wo er das letzte mal war.