I have Created a Delphi control with ActiveX Library and hosted it in WPF app using COM type library. I can see the Label and Delphi side background template colors loaded successfully in WPF but it's not showing controls such as button, Datepicker, Checkbox. Only label text and background are rendered properly. Can anyone help if I am missing anything?
This is my sample Delphi UI
After Hosting to WPF it is only loading as below
I am using HwndHost , below code is for WPF hosting
public class DelphiControlHost : HwndHost
{
[DllImport("user32.dll")]
static extern IntPtr CreateWindowEx(int dwExStyle, string lpszClassName, string lpszWindowName, int style, int x, int y, int width, int height, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
static extern bool DestroyWindow(IntPtr hWnd);
int height;
int width;
IntPtr child;
public DelphiControlHost(double initialWidth, double initialHeight, IntPtr hostedControl)
{
width = (int)initialWidth;
height = (int)initialHeight;
child = hostedControl;
}
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
var host = CreateWindowEx(0, "static", null, 0x40000000 | 0x10000000, 0, 0, height, width,
hwndParent.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
SetParent(child, host);
ShowWindow(child, 5);
return new HandleRef(this, host);
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
DestroyWindow(hwnd.Handle);
}
}
MainWindow.xaml.cs file
public partial class MainWindow : Window
{
[DllImport("msvcr110.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int _fpreset();
private ProFileUXCOMImpl service;
public MainWindow()
{
_fpreset();
InitializeComponent();
MainWindow_OnActivated(null,null);
}
private void MainWindow_OnActivated(object sender, EventArgs e)
{
if (service != null)
return;
service = new ProFileUXCOMImpl();
// var control = service.GetMainFrame(DelphiHostElement.ActualWidth, DelphiHostElement.ActualHeight);
var control = service.GetMainFrame(600, 300);
DelphiHostElement.Child = new DelphiControlHost(DelphiHostElement.ActualWidth, DelphiHostElement.ActualHeight, control);
}
private void MainCanvas_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
service?.WindowResized();
}
}
Below Code Snippet for Delphi Side
unit ProFileUXCOMU;
interface
uses
SysUtils, ComObj, ComServ, ProFileUXCOM_TLB, Winapi.ActiveX, StdVcl,Vcl.Forms, Winapi.Windows,
MainFormU, MainFrameU;
type
ProFileUXCOMImpl = class(TComObject, IProFileUXCOM)
private
MainFrame: TMainFrame;
MainHandle: Cardinal;
MainPointer: Pointer;
MainForm: TMainForm;
protected
function GetMainFrame(width: Double; height: Double): Pointer; stdcall;
procedure WindowResized(width: Double; height: Double); safecall; procedure IProFileUXCOM.WindowResized = IProFileUXCOM_WindowResized;
procedure IProFileUXCOM_WindowResized; safecall;
end;
implementation
function ProFileUXCOMImpl.GetMainFrame(width: Double; height: Double): Pointer; stdcall;
begin
MainForm := TMainForm.Create(Application);
MainForm.ClientWidth := Trunc(width);
MainForm.ClientHeight := Trunc(height);
MainHandle := MainForm.Frame.Handle;
MainPointer := System.Pointer(MainHandle);
Result := MainPointer;
end;
procedure ProFileUXCOMImpl.WindowResized(width: Double; height: Double); safecall;
begin
MainForm.ClientWidth := Trunc(width);
MainForm.ClientHeight := Trunc(height);
end;
procedure ProFileUXCOMImpl.IProFileUXCOM_WindowResized;
begin
end;
initialization
TComObjectFactory.Create(ComServer, ProFileUXCOMImpl, CLASS_ProFileUXCOMImpl, 'ProFileUXCOMImpl', '', ciMultiInstance, tmApartment);
end.