Announcement

Collapse
No announcement yet.

Passing a string to a function inside a WinXP DLL

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

  • Michael Mattias
    replied
    >Got it to work with

    I don't know how that worked if that function was designed for use with RunDll32.Exe, since the procedure header does not match the doc for "rundll" functions.

    Oh, wait a minute ... it looks you never got it work correctly using rundll32.exe.

    The part about needing a Unicode filename is because that's the way the function author wrote it.

    Leave a comment:


  • Edwin Knoppert
    replied
    1) I tried the unicode as well but on the ..W function.
    The $nul should not be needed but maybe this is the clue?

    2) And yes, i almost tried it with ATL but i thought it was a stand alone app, ha!

    Leave a comment:


  • José Roca
    replied
    Originally posted by Edwin Knoppert View Post
    1)
    2) it seems that the library also has a com interface.

    This *should* work but doesn't:
    Code:
        Local o As Dispatch
        Local v As Variant
        Local v1 As Variant
    
        Set o = New Dispatch In "Preview.Preview"    
        
        v = "C:\.....BEEMW.jpg"
        v1 = 0
        
        Object Call o.ShowFile( v, v1 )
        
        'MsgBox  Str$( IsObject( o ) )

    It is a visual ActiveX control, so you have to provide a host.

    The following example demonstrates how to embed the Preview control (remember to change the path and name of the picture to load).

    Code:
    #COMPILE EXE
    #DIM ALL
    #DEBUG ERROR ON
    #INCLUDE "WIN32API.INC"
    
    %IDC_PREVIEW = 1001
    
    ' ========================================================================================
    ' ATL functions
    ' ========================================================================================
    DECLARE FUNCTION AtlAxWinInit LIB "ATL.DLL" ALIAS "AtlAxWinInit" () AS LONG
    DECLARE FUNCTION AtlAxGetControl LIB "ATL.DLL" ALIAS "AtlAxGetControl" (BYVAL hWnd AS DWORD, BYREF pp AS DWORD) AS DWORD
    
    ' ========================================================================================
    ' The IUnknown::AddRef method increments the reference count for an interface on an object. It
    ' should be called for every new copy of a pointer to an interface on a given object.
    ' ========================================================================================
    FUNCTION IUnknown_AddRef (BYVAL pthis AS DWORD PTR) AS DWORD
        LOCAL DWRESULT AS LONG
        IF ISFALSE pthis THEN EXIT FUNCTION
        CALL DWORD @@pthis[1] USING IUnknown_AddRef(pthis) TO DWRESULT
        FUNCTION = DWRESULT
    END FUNCTION
    
    ' ========================================================================================
    ' Puts the address of an object in a variant and marks it as containing a dispatch variable
    ' ========================================================================================
    SUB AtlMakeDispatch (BYVAL lpObj AS DWORD, BYREF vObj AS VARIANT) EXPORT
       LOCAL lpvObj AS VARIANTAPI PTR                 ' Pointer to a VARIANTAPI structure
       LET vObj = EMPTY                               ' Make sure is empty to avoid memory leaks
       lpvObj = VARPTR(vObj)                          ' Get the VARIANT address
       @lpvObj.vt = %VT_DISPATCH                      ' Mark it as containing a dispatch variable
       @lpvObj.vd.pdispVal = lpObj                    ' Set the dispatch pointer address
       IUnknown_AddRef lpObj                          ' Increment the reference counter
    END SUB
    
    ' ========================================================================================
    ' Main
    ' ========================================================================================
    FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
    
       LOCAL hWndMain AS dword
       LOCAL hCtl AS DWORD
       LOCAL hFont AS DWORD
       LOCAL wcex AS WndClassEx
       LOCAL szClassName AS ASCIIZ * 80
       LOCAL rc AS RECT
       LOCAL szCaption AS asciiz * 255
       LOCAL nLeft AS LONG
       LOCAL nTop AS LONG
       LOCAL nWidth AS LONG
       LOCAL nHeight AS LONG
    
       AtlAxWinInit   ' Initialize ATL
    
       hFont = GetStockObject(%ANSI_VAR_FONT)
    
       ' Register the window class
       szClassName        = "MyClassName"
       wcex.cbSize        = SIZEOF(wcex)
       wcex.style         = %CS_HREDRAW OR %CS_VREDRAW
       wcex.lpfnWndProc   = CODEPTR(WndProc)
       wcex.cbClsExtra    = 0
       wcex.cbWndExtra    = 0
       wcex.hInstance     = hInstance
       wcex.hCursor       = LoadCursor (%NULL, BYVAL %IDC_ARROW)
       wcex.hbrBackground = %COLOR_3DFACE + 1
       wcex.lpszMenuName  = %NULL
       wcex.lpszClassName = VARPTR(szClassName)
       wcex.hIcon         = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
       wcex.hIconSm       = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
       RegisterClassEx wcex
    
       ' Window caption
       szCaption = "Preview Demo"
    
       ' Retrieve the size of the working area
       SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0
    
       ' Calculate the position and size of the window
       nWidth  = (((rc.nRight - rc.nLeft)) + 2) * 0.95   ' 95% of the client screen width
       nHeight = (((rc.nBottom - rc.nTop)) + 2) * 0.95   ' 95% of the client screen height
       nLeft   = ((rc.nRight - rc.nLeft) \ 2) - nWidth \ 2
       nTop    = ((rc.nBottom - rc.nTop) \ 2) - (nHeight \ 2)
    
       ' Create a window using the registered class
       hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _           ' extended style
                                 szClassName, _                    ' window class name
                                 szCaption, _                      ' window caption
                                 %WS_OVERLAPPEDWINDOW OR _
                                 %WS_CLIPCHILDREN, _               ' window style
                                 nLeft, _                          ' initial x position
                                 nTop, _                           ' initial y position
                                 nWidth, _                         ' initial x size
                                 nHeight, _                        ' initial y size
                                 %NULL, _                          ' parent window handle
                                 0, _                              ' window menu handle
                                 hInstance, _                      ' program instance handle
                                 BYVAL %NULL)                      ' creation parameters
    
       ' Create the Preview control
       hCtl = CreateWindowEx(%NULL, _                                             ' extended styles
                             "AtlAxWin", _                                        ' class name
                             "Preview.Preview.1", _                               ' caption
                             %WS_CHILD OR %WS_VISIBLE OR %WS_CLIPSIBLINGS OR _    ' window styles
                             %WS_TABSTOP, _
                             0, 0, _                                              ' left, top
                             0, 0, _                                              ' width, height
                             hWndMain, %IDC_PREVIEW, _                            ' handle of parent, control ID
                             hInstance, BYVAL %NULL)                              ' handle of instance, creation parameters
    
       ' Get the interface pointer of the Preview control
       LOCAL pUnk AS DWORD
       AtlAxGetControl(hCtl, pUnk)
    
       ' Make a dispatch variant from it to be able to use PB automation
       LOCAL vVar AS VARIANT
       LOCAL oPreview AS DISPATCH
       AtlMakeDispatch(pUnk, vVar)
       SET oPreview = vVar
       vVar = EMPTY
    
       ' Load the file
       LOCAL vName AS VARIANT
       LOCAL vSelectCount AS VARIANT
       ' --> Change me!
       vName = "C:\Documents and Settings\Pepe\Mis documentos\Mis imágenes\Capture.jpg"
       vSelectCount = 0 AS LONG
       OBJECT CALL oPreview.ShowFile(vName, vSelectCount)
    
       ' Show the window
       ShowWindow hWndMain, nCmdShow
       UpdateWindow hWndMain
    
       ' Message handler loop
       LOCAL Msg AS tagMsg
       WHILE GetMessage(Msg, %NULL, 0, 0)
          IF ISFALSE IsDialogMessage(hWndMain, Msg) THEN
             TranslateMessage Msg
             DispatchMessage Msg
          END IF
       WEND
    
       FUNCTION = msg.wParam
    
    END FUNCTION
    ' ****************************************************************************************
    
    ' ****************************************************************************************
    ' Main Window procedure
    ' ****************************************************************************************
    FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
    
       LOCAL rc AS RECT
    
       SELECT CASE wMsg
    
          CASE %WM_COMMAND
             SELECT CASE LOWRD(wParam)
    
                CASE %IDCANCEL
                   IF HIWRD(wParam) = %BN_CLICKED THEN
                      SendMessage hWnd, %WM_CLOSE, wParam, lParam
                      FUNCTION = 0
                      EXIT FUNCTION
                   END IF
    
             END SELECT
    
          CASE %WM_SYSCOMMAND
             ' Capture this message and send a WM_CLOSE message
             IF (wParam AND &HFFF0) = %SC_CLOSE THEN
                SendMessage hWnd, %WM_CLOSE, wParam, lParam
                EXIT FUNCTION
             END IF
    
          CASE %WM_DESTROY
             PostQuitMessage 0
             EXIT FUNCTION
    
          CASE %WM_SIZE
             IF wParam <> %SIZE_MINIMIZED THEN
                GetClientRect hWnd, rc
                MoveWindow GetDlgItem(hWnd, %IDC_PREVIEW), rc.nLeft, rc.nTop, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, %TRUE
             END IF
    
       END SELECT
    
       FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
    
    END FUNCTION

    Leave a comment:


  • Ray Crumrine
    replied
    Got it to work with
    Code:
    DECLARE FUNCTION ImageView_Fullscreen LIB "shimgvw.dll" ALIAS "ImageView_Fullscreen" (BYVAL DWORD) AS LONG
    
    FUNCTION PBMAIN () AS LONG
    LOCAL file_name AS STRING
    LOCAL rval AS LONG
    
    file_name = UCODE$(COMMAND$) + $NUL
    rval = ImageView_Fullscreen(STRPTR(file_name))
    END FUNCTION
    Apparently requires a two byte string format

    Leave a comment:


  • Michael Mattias
    replied
    You mean you want to call your function from your own program?

    Functions which work with RUNDLL32 must have the following prototype which you could have found in your WinAPI reference:
    The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
    Code:
    void CALLBACK EntryPoint(
      HWND hwnd,        // handle to owner window
      HINSTANCE hinst,  // instance handle for the DLL
      LPTSTR lpCmdLine, // string the DLL will parse
      int nCmdShow      // show state
    );
    So you need a DECLARE for the way the function must be defined...
    Code:
    DECLARE FUNCTION ImageView_Fullscreen ALIAS "ImageView_FullScreen"  LIB "shimgvw.dll" ALIAS "ImageView_Fullscreen"  _
       (BYVAL hWnd AS LONG, _
        BYVAL hinst AS LONG,_
        sz  AS ASCIIZ, _
        BYVAL iCmdShow AS LONG) AS LONG
    Then you just set it up and call it...
    Code:
    FUNCTION PBMAIN() AS LONG
    
      LOCAL sz AS ASCIIZ * %MAX_PATH, iret as long
      LOCAL hWnd AS LONG, hInst AS LONG, icmdShow AS LONG
    
       hWnd        = GetDesktopWindow()
       hINst        = GetModuleHandle ("shimgvw.dll") * 
       iCmdShow  = %SW_SHOW
       sz             = "C:\folder\...\amd,sadsmand\nmdnamsnd.png"
    
       iRet = ImageView_Fullscreen (hWnd, hINst, sz, iCmdShow) 
    
    END FUNCTION
    The doc is not real clear if you need an instance handle for the DLL file or for the owning program. If above does not work try making hinst = GetModuleHandle(BYVAL %NULL) and try again.

    MCM

    Leave a comment:


  • Edwin Knoppert
    replied
    1) I used the ..A call (the alias) and the window came up but without a file.
    That's odd..

    2) it seems that the library also has a com interface.

    This *should* work but doesn't:
    Code:
        Local o As Dispatch
        Local v As Variant
        Local v1 As Variant
    
        Set o = New Dispatch In "Preview.Preview"    
        
        v = "C:\.....BEEMW.jpg"
        v1 = 0
        
        Object Call o.ShowFile( v, v1 )
        
        'MsgBox  Str$( IsObject( o ) )

    Leave a comment:


  • Ray Crumrine
    replied
    I suspect that would work as well but I was trying to avoid using the SHELL function / statement. I found some mentions of DDE. Maybe I am missing something.

    Leave a comment:


  • Edwin Knoppert
    replied
    And this?

    Code:
    Local n As Long
    Local command_str As String
    command_str = "C:\.............\image1.png"
    n = Shell( "rundll32.exe shimgvw.dll,ImageView_Fullscreen " & command_str, %SW_SHOWMAXIMIZED )

    Leave a comment:


  • Ray Crumrine
    replied
    using the "ByRef pFileName As Asciiz" from the first post I got a crash. using the BYVAL declaration from the 2nd post doesn't seem to do anything at all. The only way I have been able to make it work is by using the SHELL command but that doesn't seem like a very clean way to do it. Any suggestions?

    Code:
    DECLARE FUNCTION ImageView_Fullscreen LIB "shimgvw.dll" ALIAS "ImageView_Fullscreen" (BYVAL file_name AS STRING) AS LONG
    
    FUNCTION PBMAIN () AS LONG
    LOCAL AStr, file_name AS STRING
    LOCAL rval AS LONG
    
    'AStr = "rundll32.exe shimgvw.dll,ImageView_Fullscreen "
    
    file_name = COMMAND$
    
    'This works
    'shell AStr + file_name
    
    'This doesn't
    rval = ImageView_Fullscreen(file_name)
    END FUNCTION

    Leave a comment:


  • Edwin Knoppert
    replied
    DECLARE FUNCTION ImageView_Fullscreen LIB "shimgvw.dll" ALIAS "ImageView_Fullscreen" (BYVAL command_str AS STRING) AS LONG

    Leave a comment:


  • Kev Peel
    replied
    No, it's wrong. It's important to note that no native API calls use "As String" as a parameter* (if they do exist, I've never come across one in 12 years of Windows programming).

    *VB calls do not count, as they use translation from STRING to ASCII internally.

    This is the correct DECLARE you need to call the function:

    Code:
    Declare Function ImageView_Fullscreen Alias "ImageView_Fullscreen" Lib "shimgvw.dll" (ByRef pFileName As Asciiz) As Long
    You also do not need to include the path, since the DLL is already in the Windows (system) folder.

    Leave a comment:


  • Passing a string to a function inside a WinXP DLL

    I am trying to write a "wrapper" for the WinXP function
    "rundll32.exe shimgvw.dll,ImageView_Fullscreen %1"
    I have it in a batch file and it works fine but I have been unable to figure out how to pass the filename inside of the PB code. I have;
    Code:
    DECLARE FUNCTION ImageView_Fullscreen LIB "C:\WINDOWS\system32\shimgvw.dll" ALIAS "ImageView_Fullscreen" (command_str AS STRING) AS LONG
    
    FUNCTION PBMAIN () AS LONG
    LOCAL n AS LONG
    LOCAL command_str AS STRING
    
    command_str = COMMAND$
    
    n = ImageView_Fullscreen(command_str)
    END FUNCTION
    At one point I was able to bring up the WinXP image viewer but could not get the file name. I can't find any documentation on how to call this function. I don't think I have the declaration correct and I'm guessing I need to "dummy up" the file name from the command line in a particular way.
Working...
X