Code conversion (Delphi)

Hi all,

I want to run this code in Xojo. What it does:
It executes a Shellexecute with a record as parameter
Notepad.exe is executed, the handle is looked up and the (Delphi) application Window is used as parent. Result is that the Notepad.exe process runs inside your window.

I don’t know how to convert the Record parm type to Xojo. Anyone?

[code]procedure TForm1.Button1Click(Sender: TObject);
var
Rec: TShellExecuteInfo;
const
AVerb = ‘open’;
AParams = ‘’;
AFileName = ‘Notepad.exe’;
ADir = ‘’;
begin
FillChar(Rec, SizeOf(Rec), #0);

Rec.cbSize := SizeOf(Rec);
Rec.fMask := SEE_MASK_NOCLOSEPROCESS;
Rec.lpVerb := PChar( AVerb );
Rec.lpFile := PChar( AfileName );
Rec.lpParameters := PChar( AParams );
Rec.lpDirectory := PChar( Adir );
Rec.nShow := SW_HIDE;

ShellExecuteEx(@Rec);
WaitForInputIdle(Rec.hProcess, 5000);

fNotepadHandle := Windows.FindWindow( ‘Notepad’, nil );
Windows.SetParent( fNotepadHandle, Handle );

Resize;
ShowWindow(fNotepadHandle, SW_SHOW);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
if IsWindow(fNotepadHandle) then begin
SetWindowPos(fNotepadHandle, 0, 0, 0, ClientWidth, ClientHeight,
SWP_ASYNCWINDOWPOS);
end;
end;[/code]

What does this mean?
Result is that the Notepad.exe process runs inside your window.

Record is most likely a Structure in Xojo.

Define a SHELLEXECUTEINFO structure as described here .
The union DUMMYUNIONNAME of the structure must be declared as a single UInt32.
Declare the ShellExecuteEx() function described here and:

[code]Soft Declare Function ShellExecuteEx lib “shell32” (byref ShellParam As SHELLEXECUTEINFO) As Boolean

Dim rec as SHELLEXECUTEINFO
// fill the rec variable as required
if ShellExecuteEx(rec) then
end if
[/code]

seems it’s time to make a “WindowOSLib” just like we have a “MacOSLib” !

WFS hasn’t been updated in a while, but may still be useful for some things.

[quote=267244:@Marco Hof]What does this mean?
Result is that the Notepad.exe process runs inside your window.[/quote]
Notepad.exe runs in your window instead of its own, and ‘your window’ as in Xojo.

Thanks for the replies. I will try this weekend.

Really? Embedded like a textarea? Very interesting. Never knew that was possible.
Is that possible with all Apps? And is that Windows only or OS X as well?

Kinda sorta almost works:

//Window.Open
Declare Function ShellExecuteW Lib "Shell32" (HWND As Integer, op As WString, file As WString, params As WString, directory As WString, cmd As Integer) As Integer
  
Const SW_HIDE = 0
If ShellExecuteW(Self.Handle, "open", "notepad.exe", "", App.ExecutableFile.Parent.AbsolutePath, SW_HIDE) <= 32 Then
  MsgBox("Failed to launch")
  Return
End If
  
Declare Function FindWindowW Lib "User32" (ClassName As WString, WindowName As WString) As Integer
Dim HWND As Integer = FindWindowW("Notepad", Nil)
  
If HWND <> 0 Then
    Declare Function SetParent Lib "User32" (Child As Integer, NewParent As Integer) As Integer
    Call SetParent(HWND, Self.Handle)

    Declare Function SetWindowLongW Lib "User32" (HWND As Integer, Index As Integer, NewLong As Integer) As Integer
    Const GWL_STYLE = -16
    Call SetWindowLongW(HWND, GWL_STYLE, 0)
    
    Declare Function SetWindowPos Lib "User32" (HWND As Integer, hWndInstertAfter As Integer, x As Integer, y As Integer, cx As Integer, cy As Integer, flags As Integer) As Boolean
    Const SWP_FRAMECHANGED = &h0020
    Const SWP_ASYNCWINDOWPOS = &h4000
    Call SetWindowPos(HWND, 0, 0, 0, Self.Width, Self.Height, SWP_ASYNCWINDOWPOS Or SWP_FRAMECHANGED)
    
    Declare Function ShowWindow Lib "User32" (HWND As Integer, Command As Integer) As Boolean
    Const SW_SHOW = 5
    Call ShowWindow(HWND, SW_SHOW)
    
  Else
    MsgBox("Failed to find the window")
  End If

Would not the same technique allow what is discussed here : https://forum.xojo.com/32474-realbasic-olecontainer-microsoft-word

Yes Michael,

I was triggered by that question and came up with some old Delphi code. But Andrew’s code works! Strange thing is, not the first time, only when notepad.exe is in memory twice. Look at the screenshot. It is a genuine Xojo Window with Notepad inside.

I will try this with Word.

[quote=267278:@Andrew Lambert]Kinda sorta almost works:
[/quote]
It does work, albeit that Notepad isn’t active. You have to activate it with a mouseclick and open a new document. The window isn’t locked by the way, if I resize the windows, it doesn’t stick, Maybe that is a parameter in the SetWindowPos.

Rather, Notepad.exe runs and you steal its window. When the Xojo window closes, Notepad.exe is left running without any UI.

[quote=267268:@Marco Hof]Really? Embedded like a textarea? Very interesting. Never knew that was possible.
Is that possible with all Apps? And is that Windows only or OS X as well?[/quote]

Embedding one window within another is a basic feature of most window managers; a button is just a window of type “button” embedded in a larger window of some other type. But you’re asking for trouble if you steal windows from other processes, particularly windows that aren’t expecting it (like a top level window).

The window we’re stealing from Notepad.exe is just a top level window with a standard Edit Control window embedded within it. It would be safer to create your own Edit Control window and then embed it in your Xojo window (or just use a plain Xojo TextArea, which on Windows is implemented as a Rich Edit Control window.)

Heck, you can embed a Xojo window (or control) in non-Xojo apps the same way. Make sure exactly one fresh notepad.exe is running, then use this modified version of the above code (e.g. in a pushbutton on blank window in a new project):

  Declare Function FindWindowW Lib "User32" (ClassName As WString, WindowName As WString) As Integer
  Dim HWND As Integer = FindWindowW("Notepad", Nil)
  
  If HWND <> 0 Then
    Declare Function SetParent Lib "User32" (Child As Integer, NewParent As Integer) As Integer
    Call SetParent(Self.Handle, HWND) ' reverse the order
    
    Declare Function SetWindowPos Lib "User32" (HWND As Integer, hWndInstertAfter As Integer, x As Integer, y As Integer, cx As Integer, cy As Integer, flags As Integer) As Boolean
    Const SWP_FRAMECHANGED = &h0020
    Const SWP_ASYNCWINDOWPOS = &h4000
    Call SetWindowPos(Self.Handle, 0, 0, 0, Self.Width, Self.Height, SWP_ASYNCWINDOWPOS Or SWP_FRAMECHANGED) ' change the first argument
  End If

Upon running this code the Xojo window will be unceremoniously dumped onto Notepad’s main window.

And just like notepad.exe, the Xojo app doesn’t exit when its stolen window is closed.

You have to call SetWindowPos to resize the window, or to move it relative to its parent window.