Announcement

Collapse
No announcement yet.

DLL call function in owning EXE

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #21
    Can I send Strings using SendMessage? I've seen some variants in VB before, like SendMessageByString.

    I tried declaring this in PB, but it reported a duplicate declaration - so I guess that idea is out unless I change my SendMessage declaration
    in the win32api.inc entirely..

    Comment


    • #22
      Well, how about creating the "string buffer" in VB (say, using a BYTE array), and pass the first element BYREF to the PB code (ie, a pointer to the array) and let the PB code manipulate the storage buffer directly (DIM..AT or with a pointer, etc).

      VB's VARPTR() function should help with this.

      Also, it looks like you are really trying to read/write a UDT, so the same techquie could be applied. Allocate the storage in VB, pass a pointer to the UDT to the PB code.


      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #23
        The easiest way to transfer string to VB is to make hidden textbox on VB form and to use SendWindowtext in PB.
        VB controls have hWnd property, which you can pass to PB.


        ------------------
        E-MAIL: [email protected]

        Comment


        • #24
          I think the real problem i'm having here is that this is a DLL performing a hook, so it has
          multiple instances. I just tested this.. I made a 'GLOBAL lPtr AS LONG' in the General Decs section.

          Then i added a parameter of 'lP AS LONG' to the first function my VB EXE calls, called "StartHook".
          And in the Hook's callback I added 'MSGBOX FORMAT$(lPtr)', so when the hook is triggered it displays the number
          that was in the second parameter in my 'StartHook' function.

          In my VB EXE, I added the extra parameter to the declare, and called it like: 'Call StartHook(Me.hWnd, 123123)'

          When i triggered the Hook's event - it displayed 0 in the MSGBOX.



          Semen, I have experimented with this method, but there is no way to set the WindowProc's return if I rely
          on VB to control WM_SETTEXT for the TextBox. I have to control the WindowProc return number so my DLL may respond
          to what the EXE has told it.

          - Nathan.

          Comment


          • #25
            i feel the type of hook i'm using is of some relevance now: http://www.powerbasic.com/support/pb...ad.php?t=21331
            it is some great code put together by semen matusovski.

            i'm trying to perform all this in the function that's referenced in place of the original function.
            this is the 'mytextout' function in the first example on the url above.

            thanks!!

            [updated]
            in my vb exe i tested the strptr returned to me by the pb dll using isbadstringptr.
            i called it like: msgbox isbadstringptr(lparam, 1), this would test if the app has read access to the pointer at a length of 1 byte.
            it returned 1, according to msdn - nonzero means the app does not have read access to that location.


            - nathan


            [this message has been edited by nathan evans (edited august 08, 2001).]

            Comment


            • #26
              Nathan --
              Try following (NT/2000) (POFFS, PB IDE ...)

              Vb Exe

              Form1:
              Code:
              Private Const UniqueName = "My Hook"
              Private Sub Form_Load()
                 Me.Caption = UniqueName
                 Hook Me.hWnd
                 SetHook Me.hWnd, Form2.hWnd
              End Sub
              
              Private Sub Form_Unload(Cancel As Integer)
                 End
              End Sub
              Form2 - empty (no code)
              Module1:
              Code:
              Option Explicit
              
              Declare Function SetHook Lib "hookd" (hWndM As Long, hWndT As Long) As Long
              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
              
              Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, _
                 ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
              
              Public Const GWL_WNDPROC = -4
              Public Const WM_DESTROY = &H2
              Public Const WM_USER = &H400
              Global lpPrevWndProc As Long
              
              Public Sub Hook(hWnd As Long)
                 lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
              End Sub
              
              Function WindowProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
                 Select Case wMsg
                    Case WM_USER + 401:
                       Form2.Caption = "[Hook]" + Form2.Caption
                    Case WM_DESTROY: SetWindowLong hWnd, GWL_WNDPROC, lpPrevWndProc
                 End Select
                 WindowProc = CallWindowProc(lpPrevWndProc, hWnd, wMsg, wParam, lParam)
              End Function
              Pb/Dll
              Code:
                 #Compile Dll "HookD.Dll"
                 #Register None
                 #Dim All
                 #Include "Win32Api.Inc"
              
                 $UniqueName = "My Hook"
                 Global hInstDLL As Long, MainDll As Long
              
                 Function SetHookProc(Op As Long) As Long
                    Static hProc As Long, tProc As String
                    Local hLib As Long
                    If hProc = 0 Then
                       hLib = GetModuleHandle("gdi32.dll")
                       hProc = GetProcAddress(hLib, "TextOutA")
                       tProc = Peek$(hProc, 7)
                       If IsFalse(VirtualProtect (ByVal hProc, 7, ByVal %PAGE_EXECUTE_READWRITE, ByRef hLib)) Then _
                          MsgBox "Error in VirtualProtect": hProc = 0: Exit Function
                       ' Under 9x VirtualProtect doesn't work in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).
                       ' For example, for system dlls.
                    End If
                    If Op = 1 Then Poke$ hProc, Chr$(&HB8) + Mkl$(CodePtr(MyTextOut)) + Chr$(&HFF, &HE0)
                    If Op = 2 Then Poke$ hProc, tProc
                    FlushInstructionCache GetCurrentProcess, ByVal hProc, ByVal 7
                 End Function
              
                 Function MyTextOut (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As Dword, ByVal nCount As Long) As Long
                    Static hDlg As Long, hWndT As Long
                    Local MyString As Asciiz * 1000
                    If hWndT = 0 Then hDlg = FindWindow("", $UniqueName): _
                       If hDlg Then hWndT = GetProp(hDlg, ByVal 2)
                    If hWndT Then
                       SetWindowText hWndT, ByVal lpString
                       SendMessage hDlg, %WM_USER + 401, 0, 0
                       GetWindowText hWndT, MyString, SizeOf(MyString)
                       SetHookProc 2
                       TextOut hdc, x, y, MyString, Len(MyString)
                       SetHookProc 1
                    End If
                 End Function
              
                 Function LibMain(ByVal hInstance As Long, ByVal fwdReason As Long, _
                    ByVal lpvReserved As Long) Export As Long
                    Select Case fwdReason
                       Case %DLL_PROCESS_ATTACH: hInstDLL = hInstance: LibMain = 1: SetHookProc 1
                       Case %DLL_PROCESS_DETACH: LibMain = 1: SetHookProc 2
                    End Select
                 End Function
              
                 Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Export As Long
                    Static hHook As Long, hDlg As Long
                    hDlg = FindWindow("", $UniqueName)
                    If hHook = 0 Then If hDlg Then hHook = GetProp(hDlg, ByVal 1)
                    If hHook Then Function = CallNextHookEx(ByVal hHook, ByVal nCode, ByVal wParam, ByVal lParam)
                    If IsFalse(MainDll) And (IsFalse(hDlg) Or IsFalse(hHook)) Then FreeLibrary hInstDll
                 End Function
              
                 Function SetHook Alias "SetHook" (hWndM As Long, hWndT As Long) Export As Long
                    Local hHook As Long
                    hHook = SetWindowsHookEx (%WH_CBT, CodePtr(HookProc), ByVal hInstDLL, ByVal 0)
                    SetProp hWndM, ByVal 1, ByVal hHook
                    SetProp hWndM, ByVal 2, ByVal hWndT
                    MainDll = 1
                 End Function
              Because VB IDE doesn't like hooks, I'd recommend to compile and to run Vb.Exe from explorer

              ------------------
              E-MAIL: [email protected]

              Comment


              • #27
                Thanks Semen. I overlooked the possibility of using SETTEXT and another SendMessage together!

                Many thanks to you all!

                - Nathan

                Comment


                • #28
                  Didn't read much about this topic yet but,
                  I saw the statement VB doesn't do exported functions.

                  Well www.desaware.com has a tool for that.
                  Click spyworks and scroll down.

                  Or: http://www.desaware.com/ExportedFunctionsL3.htm

                  Don't know how it works tough.


                  ------------------
                  hellobasic

                  Comment

                  Working...
                  X