Announcement

Collapse
No announcement yet.

Let any exe run in your DDT Dialog

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

  • Semen Matusovski
    replied
    Ralph --
    Just now I do approx., about what you asked.
    In my app something another situation, but methods, which I used could be useful to solve a discussion question.
    To demonstrate this technique I modified my hook sample (which doesn't exist in real app).

    Could be problems exactly with this code, but looking to living app, can say that all questions have a decision.

    If you will start under 9x, probably (I didn't test) you will need to add SetParent CaptWnd, 0 before exit (as I remember living app).

    So, DLL:

    Code:
       #Compile Dll "Hook.Dll"
       #Register None
       #Dim All
       #Include "Win32Api.Inc"
    
       $TrayWndNm = "Any unique name"
       %NotifyId = %WM_USER + 401
    
       Global hHook As Long, hInstDLL As Long
       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
             Case %DLL_PROCESS_DETACH: LibMain = 1
          End Select
       End Function
    
       Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Export As Long
          Static hDlg As Long, NotFirstTime As Long
          Function = CallNextHookEx(ByVal hHook, ByVal nCode, ByVal wParam, ByVal lParam)
          If hDlg = 0 Then hDlg = FindWindow("", $TrayWndNm)
          If IsWindow(hDlg) = %False Then
             FreeLibrary hInstDll
          ElseIf (nCode = %HCBT_ACTIVATE) And (wParam <> hDlg) Then
             If IsFalse(NotFirstTime) Then
                NotFirstTime = %True
                Local pt As POINTAPI, hRgn As Long, rcW As RECT, rcC As RECT
                GetWindowRect wParam, rcW
                GetClientRect wParam, rcC
                ClientToScreen wParam, pt
                pt.x = pt.x - rcW.nLeft
                pt.y = pt.y - rcW.nTop
                hRgn = CreateRectRgn(pt.x, pt.y, pt.x + rcC.nRight, pt.y + rcC.nBottom)
                SetWindowRgn wParam, hRgn, %True
                PostMessage hDlg, %NotifyId, wParam, 0
             End If
          End If
       End Function
    
       Function SetHookWindow Alias "SetHookWindow" (hWnd As Long) Export As Long
          hHook = SetWindowsHookEx (%WH_CBT, CodePtr(HookProc), ByVal hInstDLL, ByVal 0)
       End Function
    
       Function UnHookWindow Alias "UnHookWindow" Export As Long
          UnhookWindowsHookEx hHook
       End Function
    Exe

    Code:
       #Compile Exe
       #Dim All
       #Register None
       #Include "Win32Api.Inc"
    
       $TrayWndNm = "Any unique name"
       %NotifyId = %WM_USER + 401
    
       Declare Function SetHookWindow Lib "Hook.Dll" Alias "SetHookWindow" (hWnd As Long) As Long
       Declare Function UnHookWindow Lib "Hook.Dll" Alias "UnHookWindow" As Long
    
       CallBack Function DlgProc
          Static CaptWnd As Long
          Select Case CbMsg
             Case %WM_INITDIALOG
                SetHookWindow CbHndl
                Dim i As Long
                i = Shell ("notepad.exe", 1)
             Case %WM_SYSCOMMAND
                If CbWparam = %SC_CLOSE Then DestroyWindow CaptWnd
             Case %NotifyId
                CaptWnd = CbWparam
                UnHookWindow
                SetParent CaptWnd, CbHndl
                ShowWindow CbHndl, %SW_SHOW
                Function = 1: Exit Function
          End Select
       End Function
    
       Function PbMain
          Local hDlg As Long
          Dialog New 0, $TrayWndNm, , , 200, 200, _
             %WS_CAPTION Or %WS_SYSMENU Or %WS_THICKFRAME Or %WS_CLIPCHILDREN Or %WS_CLIPSIBLINGS Or _
             %WS_MINIMIZEBOX Or %WS_MAXIMIZEBOX, %WS_EX_TOPMOST To hdlg
          ShowWindow hDlg, %SW_MAXIMIZE
          Dialog Show Modal hDlg Call DlgProc
       End Function
    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Semen Matusovski
    replied
    Ralph --
    I don't know Italian language, but idea is obvious without translation.
    Authors want to use WH_CBT hook.
    I agree that it's very powerful hook, but performance ...
    Ok, anyway this is CBT hook' sample.
    Code:
       #Compile Exe
       #Dim All
       #Register None
       #Include "Win32Api.Inc"
    
       Global hHook As Long
    
       Function SBProc(ByVal lMsg As Long, ByVal wParam As Long, _
          ByVal lParam As Long) As Long
         If lMsg = %HCBT_ACTIVATE Then
            SetWindowPos wParam, 0, 100, 100, 0, 0, _
               %SWP_NOSIZE Or %SWP_NOZORDER Or %SWP_NOACTIVATE
            UnhookWindowsHookEx hHook
         End If
      End Function
       
       Function PbMain
          Dim hInst As Long
          hHook = SetWindowsHookEx(%WH_CBT, CodePtr(SBProc), GetModuleHandle(ByVal 0&), _
             GetCurrentThreadId)
          MsgBox "This message box has been positioned at (100,100)."
       End Function
    ------------------

    Leave a comment:


  • Ralph Berger
    replied
    Hi there,

    found this on Microsoft's KB. How about your Italien ?

    rgds
    Ralph

    Code:
    HOWTO: trasformare una top-level window in child window
    
    ID Articolo:       I14766
    Data creazione:    06-apr-1998
    Data revisione:    08-apr-1998
    
    
    Le informazioni in questo articolo si applicano a: Microsoft Win32 SDK
    
    
    SOMMARIO
    Questo articolo illustra come e` possibile trasformare una top-level window
    di un processo in una child window di un altro processo. Questa operazione
    puo` essere utile quando si vuole riprodurre l'effetto di un controllo per
    un'applicazione gia` realizzata e non modificabile.
    
    ULTERIORI INFORMAZIONI
    I passi per eseguire questa operazione sono:
    - cercare la finestra top-level che si vuole rendere child
    - rendere la finestra figlia di una finestra della propria applicazione
      tramite SetParent
    - modificare lo stile della finestra: togliere WS_OVERLAPPEDWINDOW e
      WS_BORDER (funzione SetWindowLong)
    - muovere la finestra per farla coincidere con le dimensioni della finestra
      parent
    - forzare il ridisegno della finestra (Invalidate) Segue un esempio che
      illustra come eseguire questa operazione in MFC con l'applicazione Blocco
      Note (Notepad):
    
      void CSetParentDlg::OnSetChild() {
        pWnd = CWnd::FindWindow(NULL, _T("Senza nome - Blocco Note"));
        if (pWnd != NULL)
            CWnd* pPrevParent = pWnd->SetParent(&m_Rect);
            ASSERT(pPrevParent);
            long Style = ::GetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE);
            SetWindowLong(pWnd->GetSafeHwnd(), GWL_STYLE, Style & ~WS_BORDER &
            ~WS_OVERLAPPEDWINDOW);
            pWnd->SetMenu(NULL);
            CRect r;
            m_Rect.GetClientRect(&r);
            pWnd->MoveWindow(&r, true);
            pWnd->BringWindowToTop();
            pWnd->Invalidate();
        else
            AfxMessageBox("Window not found");
    }
    
    Questo codice funziona in Windows NT. In Windows 95 la finestra viene resa
    figlia, ma la barra del titolo e i bordi della finestra rimangono perche`,
    secondo le informazioni in Q83366, alcuni stili di finestra, fra cui
    WS_CAPTION e WS_BORDER, non possono essere cambiati dopo che la finestra
    e` gia` stata creata. Per togliere la barra del titolo anche in Windows 95
    e` necessario intervenire tramite un hook in fase di creazione della
    finestra (vedi oltre).
    
    MIGLIORAMENTO DEL REPAINT
    La soluzione esposta evidenzia talvolta problemi di repaint. Questi problemi
    possono essere risolti usando gli stili di clipping in modo opportuno. Segue
    un esempio SDK:
    
    hNotePad = FindWindow("Notepad",NULL);
    SetWindowLong(hNotePad,GWL_STYLE,WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
    SetParent(hNotePad,hDlg);
    SetWindowPos(hNotePad,NULL,10,30,300,200,SWP_NOACTIVATE|SWP_SHOWWINDOW);
    
    UTILIZZO DI UN HOOK
    Per poter impostare a piacimento gli stili e` necessario poter intervenire
    in fase di creazione della finestra. Questo puo` essere fatto tramite un
    CBT hook. I passi da seguire sono i seguenti:
    - installare un hook di tipo CBT nella propria applicazione (funzione SetWindowsHookEx
      con argomento WH_CBT)
    - far partire l'applicazione di cui si vuol rendere figlia la top-level window
      nella hook procedure, monitorare i messaggi di tipo HCBT_CREATEWND
    - quando il messaggio viene ricevuto, modificare gli stili della finestra e
      renderla figlia disinstallare l'hook
    
    RIFERIMENTI
    
    Win32 Programmer's Reference, chapter 8: Hooks
    Q83366 "Value Returned by GetWindowLong(hWnd, GWL_STYLE)" in Microsoft
    Knowledge Base


    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Aisin --
    I took a hook, designed to log all started apps, and quickly modified it.
    To demonstrate that DLL is in new process I added in DLL Dialog New.
    Exactly this (Dialog New ; Dialog Show Modal) crashes Windows98
    (under Win2000 - no troubles). So delete them and use something else.

    In general to add modal dialog is wrong idea (it will be two modal loops) and my purpose was another.

    I wanted to demonstrate that it's very easy to introduce own DLL into shelled process.
    (BTW, there is a simple way to find top window in new process - wParam in hook procedure).

    What to do further... (I guess)
    My experiments, which I did some monthes ago, showed that appears a lot of troubles, if to try to declare external window as child of DDT.
    But what exactly possible
    1) to subclass this external window and to try to control it inside
    (for example, moving/resizing).
    2) it's easy to set connection beetween DDT and "child".

    ------------------


    [This message has been edited by Semen Matusovski (edited July 28, 2000).]

    Leave a comment:


  • Aisin Geuru Suen Yue
    Guest replied
    Hi Semen,

    I got your hook program crash on my Windows 98 SE!

    ???


    ------------------

    Leave a comment:


  • Patrice Terrier
    replied
    Hello

    Did you try the WinLIFT "Universal Browser" demo?

    The WinLIFT "Universal Browser" illustrates two powerfull technologies:

    * Integration of ActiveX controls in PowerBASIC applications.
    * WinLIFT "Skin Engine" to give a professionnal touch to your applications.

    --------------------------------------------------------------------------------

    The IE ActiveX control used for the demo is more than a Web browser, it is a Universal Browser:
    It will let you display, print and even program such different types of documents as:

    * HTML pages,
    * Word documents,
    * Excel spreadsheets,
    * Visio drawings,
    * PowerPoint presentations,
    * Shockwave movies,
    * and more...

    ------------------
    Patrice Terrier
    mailto[email protected][email protected]</A>

    [This message has been edited by Patrice Terrier (edited July 28, 2000).]

    Leave a comment:


  • Ralph Berger
    replied
    Fernando,

    thank you for the code snippet. You told me that your asm routine
    makes any window a child of another window. Trying your source i
    always get a GPF on Windows 98 or Dr. Watson error on NT.

    The snippet below gave you access to whole thread's memory. Could
    you pls explain how you want to alter a createstruct on a already
    opened window ? Never heard about a hack like this.
    I'm very curious.

    Ralph
    Code:
    $COMPILE EXE
    $REGISTER NONE
    $INCLUDE "WIN32API.INC"
    
    
    FUNCTION pluginStart(BYVAL cmdline AS STRING, PI AS PROCESS_INFORMATION  ) AS LONG
    
        LOCAL SI AS STARTUPINFO CreateProcess
        LOCAL rc AS LONG, Ec AS LONG
    
        SI.cb          = SIZEOF(SI)
        SI.dwFlags     = %STARTF_USESHOWWINDOW
        SI.wShowWindow = %SW_SHOWMINNOACTIVE
    
        rc = CreateProcess(BYVAL %Null, _
                           BYVAL STRPTR(cmdline), _
                           BYVAL 0&, _
                           BYVAL 0&, _                'ThreadAttribute
                           BYVAL 1&, _                'InheritHandle
                           %NORMAL_PRIORITY_CLASS, _  'CreationFlag
                           BYVAL %Null, _             'Environment
                           BYVAL %Null, _             'Current Directory
                           SI, _                      'StartUpInfo
                           PI)                        'ProcessInfo
    
        FUNCTION = rc
    
    END FUNCTION
    
    
    FUNCTION pluginWaitEnd( PI AS PROCESS_INFORMATION  ) AS LONG
    
       LOCAL lret AS LONG
       LOCAL ec   AS LONG
    
       lret = WaitForSingleObject(PI.hProcess, %INFINITE)
       ec   = 256
    
       lret = GetExitCodeProcess(PI.hProcess,Ec)
       lret = CloseHandle(PI.hProcess)
       FUNCTION = Ec
    
    END FUNCTION
    
    CALLBACK FUNCTION dlg_main
        LOCAL  szTitle     AS ASCIIZ * 256
        LOCAL  styleSearch AS LONG
        LOCAL  R   AS Rect
        LOCAL LPCREATESTRUCT AS CREATESTRUCT PTR
    
        STATIC PI AS PROCESS_INFORMATION
    
        SELECT CASE CBMSG
            CASE %WM_initdialog
    
                 pluginStart "C:\WinNt\explorer.exe", pi
                 WaitForInputIdle    pi.hProcess, %INFINITE
    '            readprocessMemory   pi.hProcess, lpBaseAddress, lpBuffer, LEN(bUFFER), lpNumberOfBytesRead
                 '''' your code
                 
                 
    '            WriteProcessMemory  pi.hProcess, .........
    
            CASE %WM_CLOSE
                 MSGBOX "byE"
                 pluginWaitEnd pi
    
        END SELECT
    
    END FUNCTION
    
    FUNCTION PBMAIN AS LONG
    
       LOCAL hDlg AS LONG
       DIALOG NEW 0, "PB captures Explorer",,, 400,200, %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME TO hdlg
       DIALOG SHOW MODAL hdlg CALL dlg_main
    
       MSGBOX "END"
    
    END FUNCTION


    ------------------

    Leave a comment:


  • Eric Pearson
    replied
    > My frontend should run the related app as plugin.
    > There are many non MS progs which doesn't support
    > ActiveX ore OLE. So i tried this way.

    The basic problem (as I see it) is that Windows requires that a window be "serviced" by a message loop that runs in the thread that created the window. So when you connect a window from one process to a window from another process (by making one the child of the other) if a message gets passed up the chain, it ends up being "seen" by a message loop in a different thread.

    > Closing it via the system menu or ALT F4 will work.

    Not on my NT4 system. No matter how I close the program, the Task Manager's "Processes" tab shows it still running after the window disappears.

    -- Eric

    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>



    [This message has been edited by Eric Pearson (edited July 26, 2000).]

    Leave a comment:


  • Ralph Berger
    replied
    Semen,

    thank's for the code.

    Ralph

    ------------------


    [This message has been edited by Ralph Berger (edited July 27, 2000).]

    Leave a comment:


  • Ralph Berger
    replied
    Eric,

    i'd converted NASA's HDF to win32. Trying now to write a frontend.
    The hirarchic file system can store any type of data. My frontend
    should run the related app as plugin. There are many non MS progs
    which doesn't support ActiveX ore OLE. So i tried this way.

    Used hardcoded path- and prg. names for the demo. That causesd the
    trouble starting the program. It's not terminating because the
    %WM_CLOSE message isn't forwarded to the child win. Closing it
    via the system menu or ALT F4 will work.

    I'm not very familiar with shell programming. Posted the snippet
    because i'm looking for a way to open the plugin as hidden window
    before "pluging". Any ideas ?

    rgds,
    Ralph



    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Ralph --
    I think, better to integrate a "gift".
    Compile Dll (before correct way to explorer, LCASE !)
    Code:
       #Compile Dll "HookS.Dll"
       #Register None
       #Dim All
       #Include "Win32Api.Inc"
    
       Global hDlg As Long, hHook As Long, hInstDLL As Long, nTest As Long
       Global TmpAsciiz As Asciiz * 256
       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
             Case %DLL_PROCESS_DETACH: LibMain = 1
          End Select
       End Function
    
       Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Export As Long
          Function = CallNextHookEx(ByVal hHook, ByVal nCode, ByVal wParam, ByVal lParam)
          If ncode = %HSHELL_WINDOWCREATED And nTest = 0 Then
             nTest = 1
             If hDlg = 0 Then
                GetModuleFileName(GetModuleHandle(ByVal 0), TmpAsciiz, SizeOf(TmpAsciiz)
                ' sample
                Select Case LCase$(TmpAsciiz)
                   Case "f:\winnt\explorer.exe"
                      Local hWnd As Long
                      hWnd = FindWindow(ByVal 0&, "My Hook")
                      PostMessage hWnd, %WM_USER + 999, 0, 0
                      Local hDlg1 As Long
                      Dialog New 0, "Gift (at first close me, then explorer)", , , 500, 400, %WS_SYSMENU To hDlg1
                      Dialog Show Modal hDlg1 'Call DlgProc
                   Case Else
                      FreeLibrary hInstDll
                End Select
             End If
          End If
       End Function
    
       Function SetHook Alias "SetHook" (hWnd As Long) Export As Long
          hDlg = hWnd
          hHook = SetWindowsHookEx (%WH_SHELL, CodePtr(HookProc), ByVal hInstDLL, ByVal 0)
       End Function
    
       Function UnHook Alias "UnHook" Export As Long
          UnhookWindowsHookEx hHook
       End Function
    and start Exe
    Code:
       #Compile Exe
       #Dim All
       #Register None
       #Include "Win32Api.Inc"
    
       Declare Function SetHook Lib "HookS.Dll" Alias "SetHook" (hWnd As Long) As Long
       Declare Function UnHook  Lib "HookS.Dll" Alias "UnHook" As Long
    
       CallBack Function DlgProc
          Local i As Long
          Select Case CbMsg
             Case %WM_INITDIALOG: SetHook CbHndl
                                  i = Shell ("Explorer.Exe", 1)
             Case %WM_SIZE: ShowWindow CbHndl, 0         
             Case %WM_USER + 999: Dialog End CbHndl, 0
             Case %WM_DESTROY   : Unhook
          End Select
       End Function
    
       Function PbMain()
          Local hDlg As Long
          Dialog New 0, "My Hook", 0, 0, 100, 20, %WS_SYSMENU Or %WS_CAPTION, %WS_EX_TOPMOST Or %WS_EX_TOOLWINDOW To hDlg
          Dialog Show Modal hDlg Call DlgProc
       End Function
    This code should explain, what I mean.
    (PS. What about JPG ?)



    [This message has been edited by Semen Matusovski (edited July 26, 2000).]

    Leave a comment:


  • Eric Pearson
    replied
    Ralph --

    Your program didn't work for me until I changed the string "Explorer" to "Exploring - C:\" so the program could find the window. I also had to change the sleep from 500 to 1000 ms.

    Also, when you close Explorer your program is left running. You can see it if you start up Task Manager (Ctrl-Alt-Del) and look at the Processes tab.

    Also, the path to Explorer varies from version to version of Windows. There is, of course, no C:\WINNT directory on a 95/98 system.

    What purpose did you have in mind for this technique? It might be more useful if you were to create a smaller window that is a child of the main DDT dialog, and make Explorer a child of the smaller window. That way you could add buttons and other controls around the Explorer subwindow.

    However, it is not generally a good idea to make a window from one process the child of a window from another process. Windows doesn't usually like it when you do that.

    Hmmm... I wonder why the Explorer pulldown menu disappears when it becomes the child of another window.

    -- Eric

    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>



    [This message has been edited by Eric Pearson (edited July 26, 2000).]

    Leave a comment:


  • Ralph Berger
    started a topic Let any exe run in your DDT Dialog

    Let any exe run in your DDT Dialog

    Hi there,

    below is a code snippet which embeds the Explorer in a DDT dailog.
    Pls let me know what you think about it.

    rgds
    Ralph

    Code:
    $COMPILE EXE
    $REGISTER NONE
    $INCLUDE "WIN32API.INC"
    
    FUNCTION cbEnum(BYVAL hWnd AS LONG, lpszTitle AS ASCIIZ PTR) AS LONG
    
        GetWindowText hWnd, @lpszTitle, 256
        IF INSTR(@lpszTitle, "Explorer") THEN
           @lpszTitle = STR$(hWnd)
           FUNCTION = %false
           EXIT FUNCTION
        END IF
        FUNCTION = %true
    
    END FUNCTION
    
    
    CALLBACK FUNCTION dlg_main
        LOCAL  szTitle     AS ASCIIZ * 256
        LOCAL  styleSearch AS LONG
        LOCAL  R   AS Rect
    
        STATIC hwndSearch  AS LONG
    
        SELECT CASE CBMSG
            CASE %WM_initdialog
    '             try with iexplorer
    '             SHELL "C:\Programme\Internet Explorer\Iexplore.exe"
    '             apisleep 2000
                 ''' hardcoded path pls modify
                 SHELL "C:\WinNt\explorer.exe"
                 ''' give explorer time to start
                 apisleep 500
                 ''' find the explorer window handle
                 EnumWindows CODEPTR(cbEnum), VARPTR( szTitle )
                 hwndSearch  = VAL(szTitle)
                 
                 ''' make it parent of our dialog
    '             styleSearch = getwindowlong ( hwndSearch, %GWL_STYLE )
    '             styleSearch = styleSearch OR %WS_CHILD
                 Setwindowlong hwndSearch, %GWL_STYLE, %WS_CHILD OR %WS_VISIBLE ''styleSearch
                 setparent     hwndSearch, CBHNDL
       
    ''' cosmetics
                 getclientrect CBHNDL, r
                 SetWindowPos  hwndSearch, %HWND_TOP, 0,0, r.nright-r.nleft, r.nbottom - r.ntop, %SWP_FRAMECHANGED
    
            CASE %WM_SIZE
                 IF CBWPARAM = %SIZE_MINIMIZED THEN EXIT FUNCTION
                 MoveWindow hwndSearch, 0, 0, LOWRD(CBLPARAM), HIWRD(CBLPARAM), %true
    
        END SELECT
    
    END FUNCTION
    
    
    FUNCTION PBMAIN AS LONG
    
       LOCAL hDlg AS LONG
       DIALOG NEW 0, "PB captures Explorer",,, 400,200, %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME TO hdlg
       DIALOG SHOW MODAL hdlg CALL dlg_main
    
       MSGBOX "END"
    
    END FUNCTION


    ------------------
Working...
X