Results 1 to 4 of 4

Thread: Opening documents from Windows Explorer

  1. #1

    Thread Starter
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Opening documents from Windows Explorer

    Hi all,

    I have a bit of a problem with the following scenario:

    I'm trying to get my MDI application to open documents from Windows Explorer.
    This isn't actually any problems but when ever I double click on a document a new instance of the application is started.

    So what I'm trying to do is to let the old instance (if any) open the new document.
    This is how I'm trying to do this:
    The start-up object is set to Sub Main().
    The first thing the Main sub does is to check if App.PrevInstance is True.
    If not it loads the frmMDI form that saves its hWnd to the registry (and other startup stuff in the Load event).
    If there is a previous instance loaded Sub Main reads the hWnd value from the registry.
    Then it calls the Command function to get the file name (if any).
    The file name is saved to a string called sFile.
    After that it sends a user defined message (WM_USER + &HFC) to the previous instance with wParam set to the length of the string (sFile) and lParam to the actual string value.

    I've subclassed the frmMDI form and it gets the message allright.
    But when I try to retrieve the original string it fails.
    I use CopyMemory in my WinProc to copy wParam back into a string but I only get garbage.

    Here's the code I use:
    Code:
    'In module1:
    Private Declare Function SendMessageString _
     Lib "user32" Alias "SendMessageA" ( _
     ByVal hwnd As Long, _
     ByVal wMsg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As String) As Long
    
    Public Const = UM_OPENFILE = &H4FC&
    
    Public Sub Main()
        Dim sFile As String
        Dim hWnd As Long
    
        If App.PrevInstance Then
            sFile = Command
            If Len(sFile) Then
                hWnd = CLng(GetSetting(App.EXEName, "Instance", "hWnd", "0")
                If hWnd Then
                    SendMessageString hWnd, UM_OPENFILE, LenB(sFile), sFile
                    End
                End If
            End If
        End If
        frmMDI.Show
    End Sub
    
    '**********************************
    'in frmMDI
    Private Sub MDIForm_Load()
        SaveSetting App.EXEName, "Instance", "hWnd", Me.hwnd
        HookForm Me.hwnd 'set up the sub-classing
        'other init stuff goes here
    End Sub
    
    '**********************************
    'in Module2 (sub-classing module)
    Private Declare Sub CopyMemory _
     Lib "kernel32" Alias "RtlMoveMemory" ( _
     Destination As Any, _
     Source As Any, _
     ByVal Length As Long)
    
    Private Declare Function SetWindowLong _
     Lib "user32" Alias "SetWindowLongA" ( _
     ByVal hwnd As Long, _
     ByVal nIndex As Long, _
     ByVal dwNewLong As Long) As Long
    
    Private Declare Function CallWindowProc _
     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
    
    Private Const GWL_WNDPROC = (-4)
    Private Const WM_DESTROY = &H2&
    
    Private lngHwnd As Long
    Private lngPrevWndProc As Long
    
    Public Sub HookForm(frmHandle As Long)
        lngHwnd = frmHandle
        lngPrevWndProc = SetWindowLong(lngHwnd, GWL_WNDPROC, AddressOf WinProc)
    End Sub
    
    Public Sub UnhookForm()
        SetWindowLong lngHwnd, GWL_WNDPROC, lngPrevWndProc
    End Sub
    
    Public Function WinProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Dim sFile As String
        
        Select Case uMsg
            Case UM_OPENFILE
                If wParam > 0 Then
                    sFile = String$(wParam, vbNullChar)
                    CopyMemory ByVal sFile, ByVal lParam, wParam
                End If
            Case WM_DESTROY
                'the window has been closed
                UnhookForm
        End Select
        WinProc = CallWindowProc(lngPrevWndProc, hw, uMsg, wParam, lParam)
        If Len(sFile) Then
             MsgBox sFile 'here I actually want to call my open file procedure
        End If
    End Function
    Why doesn't the above work??????

    The message is sent and retrieved by my WinProc above but I just can't get the string out correctly.

    Best regards

  2. #2
    Fanatic Member crispin's Avatar
    Join Date
    Aug 2000
    Location
    2 clicks west of a Quirkafleeg...Cornwall, England
    Posts
    754
    Hmmm.....Just off the top of my head....the garbage you are getting back, it's not a pointer to the string (and not the string itself) is it? (I know that would be two pointers in a row - but it's worth a go eh...and it sometimes happens in C++)
    Crispin
    VB6 ENT SP5
    VB.NET
    W2K ADV SVR SP3
    WWW.BLOCKSOFT.CO.UK

    [Microsoft Basic: 1976-2001, RIP]

  3. #3

    Thread Starter
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    Well, VBs implementation of a string is a pointer to a pointer. But as you can see by my code I send the string ByVal which means a pointer or address to where the string is saved.
    That's what is expected in both SendMessage (which I called SendMessageString to use safe typing) and in CopyMemory.

    But thanks anyway...

  4. #4

    Thread Starter
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    I've got the answer!
    http://www.vbforums.com/showthread.p...044#post460044

    Best regards

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width