ChrisChuah 0 Posted October 31, 2023 Hi Is there a ActiveX or native component for VNC Client or Remote Desktop client so that the application can connect to the VNC server running on Ubuntu 22 and above. The VNC ActiveX component that i have been using since Delphi 6 is not able to properly show the Ubuntu desktop version 22. But it is able to display properly for Ubuntu 20. Please advise regards chris Share this post Link to post
Rollo62 581 Posted October 31, 2023 Like this ? https://github.com/teppicom/RealThinClient-SDK Share this post Link to post
Anders Melander 2008 Posted October 31, 2023 18 minutes ago, Rollo62 said: Like this ? https://github.com/teppicom/RealThinClient-SDK I think you mean this one: https://github.com/CloudDelphi/RTC-Portal-VCL But that is neither VNC nor RDP, which is what the OP asked for. For RDP there is an ActiveX but I don't know what it does. I've never used it. https://learn.microsoft.com/en-us/windows/win32/termserv/remote-desktop-activex-control 1 Share this post Link to post
ChrisChuah 0 Posted November 1, 2023 Hi What is the difference between https://github.com/teppicom/RealThinClient-SDK and https://github.com/CloudDelphi/RTC-Portal-VCL? Actually i need a VNC client component to connect to the VNC Server which is running on Ubuntu 22. Somehow the VNC Server on Ubuntu 22 is different from VNC Server on Ubuntu 20 regards chris Share this post Link to post
Fr0sT.Brutal 902 Posted November 1, 2023 AFAIU mRemoteNG uses some kind of component or a lib for VNC so probably there is one. Try to check that lib. But you'll likely have to write Delphi wrapper by yourself Share this post Link to post
Anders Melander 2008 Posted November 1, 2023 3 hours ago, ChrisChuah said: What is the difference between https://github.com/teppicom/RealThinClient-SDK and https://github.com/CloudDelphi/RTC-Portal-VCL? Different layers. I haven't used either but AFAIK RTC Portal is a layer on top of RTC SDK. Note though that it's a completely proprietary protocol. You need something that implements the RFB protocol (which is what VNC uses). Share this post Link to post
Fr0sT.Brutal 902 Posted November 1, 2023 Alas, mRemoteNG uses this https://github.com/humphd/VncSharp which is not a ready-to-use library but native implementation of protocol. Share this post Link to post
ChrisChuah 0 Posted November 2, 2023 so meaning there is no component that i can use readily to plug into a Delphi form so that i can connect to a VNC server isnt it? still have to do more work on it. oh mine.. then will need more time to research on these few github sources Share this post Link to post
Fr0sT.Brutal 902 Posted November 2, 2023 5 hours ago, ChrisChuah said: so meaning there is no component that i can use readily to plug into a Delphi form so that i can connect to a VNC server isnt it? Have you tried Googling yet? https://www.google.com/search?q=vnc+delphi&ie=utf-8&oe=utf-8&client=firefox-b-ab Share this post Link to post
aehimself 404 Posted November 3, 2023 On 10/31/2023 at 1:52 PM, Anders Melander said: For RDP there is an ActiveX but I don't know what it does. I've never used it. https://learn.microsoft.com/en-us/windows/win32/termserv/remote-desktop-activex-control It indeed exists, and works as advertised. I grabbed installation instructions from somewhere a long time ago: - Component -> Import Component -> Import ActiveX Control -> Select Terminal Services (mstscax.dll) - Palette page: MsTSC, unit dir name: Delphi Lib folder, Search path: empty. Check Generate component wrappers - Install to New package - Enter the same name (MsTSCLib_TLB.dproj) under Delphi Lib folder - Try to build package just to fail - Change Property type of ConnectWithEndpoint to "OleVariant", build package again - Right-click on MsTSCLib_TLB.bpl in Project manager and select "Install" After this different versions of the control will appear on the palette and everything can be set (RD gateway, compression, audio redirection, key capture, etc.) via properties what mstsc.exe allows. Kinda handy stuff. Share this post Link to post
ChrisChuah 0 Posted November 8, 2023 Hi Last time, since Delphi 6, i managed to download an VNCX.dll from internet and i was able to embed it into my Delphi 6 application. Now, i tried to import this same component into Delphi 11, Delphi 11 managed to convert into the TLB files and was able to compile it and add to the Palette. When i create a new Windows VCL app and add that VNC ActiveX component into the form, Delphi 11 will crash. Is there a way to find out why Delphi 11 crashed? regards chris Share this post Link to post
ChrisChuah 0 Posted November 8, 2023 hi Also the activeX comes in 32 bit and 64 bit version when i do a regsvr32 vnc.dll and regsvr32 vnc64.dll, Delphi only shows the 32 bit activeX when importing. how can delphi able to use the 64bit dll? please advise Share this post Link to post
Lars Fosdal 1857 Posted November 8, 2023 2 hours ago, ChrisChuah said: how can delphi able to use the 64bit dll? Is the Delphi app 64-bit? Share this post Link to post
ChrisChuah 0 Posted November 9, 2023 Delphi can compile app into 64bit isnt it? If so, can my Delphi 64bit app run the 32bit dll or does it require the 64bit dll? Share this post Link to post
DelphiUdIT 243 Posted November 9, 2023 (edited) 5 hours ago, ChrisChuah said: Delphi can compile app into 64bit isnt it? If so, can my Delphi 64bit app run the 32bit dll or does it require the 64bit dll? 64 bit app can run only 64 bit dll, and 32 bit app can run only 32 bit dll. But you can "connect" to 32 or 64 bit Com Object if it is out-of-process, from any process (both 32 and 64 bit). Edited November 9, 2023 by DelphiUdIT Share this post Link to post
ChrisChuah 0 Posted November 15, 2023 Thank you. I managed to connect to the 64 bit dll file although the Delphi IDE registered the 32 bit dll as activeX component. until now, i am still learning how to go about doing things in delphi regards chris Share this post Link to post
martins_044 0 Posted Tuesday at 06:32 PM On 03/11/2023 at 14:34, aehimself said: Ele realmente existe e funciona como anunciado. Peguei instruções de instalação em algum lugar há muito tempo: - Componente -> Importar Componente -> Importar Controle ActiveX -> Selecionar Serviços de Terminal (mstscax.dll) - Página da paleta: MsTSC, nome do diretório da unidade: pasta Delphi Lib, caminho de pesquisa: vazio. Marque a opção Gerar wrappers de componentes - Instalar em um novo pacote - Digite o mesmo nome (MsTSCLib_TLB.dproj) na pasta Delphi Lib - Tente compilar o pacote, mas não consiga - Altere o tipo de propriedade de ConnectWithEndpoint para "OleVariant", compile o pacote novamente - Clique com o botão direito do mouse em MsTSCLib_TLB.bpl no Gerenciador de Projetos e selecione "Instalar" Depois disso, diferentes versões do controle aparecerão na paleta e tudo poderá ser definido (gateway RD, compactação, redirecionamento de áudio, captura de teclas, etc.) por meio de propriedades permitidas pelo mstsc.exe. Coisa meio útil. I've been trying to implement this method for about two weeks, using MsTSCLib_TLB.pas. My problem may be my expectations of what could be done, as I would like an application like Remote Desktop Manager (RDM). I'm managing to make the connection and everything, but I'm stuck on these two validation tabs, maybe it's something in Windows, the big issue is that I've tried using several things and different ways, but I can't make something fluid and automatic, just by clicking and connecting. Share this post Link to post
aehimself 404 Posted Tuesday at 07:32 PM The first window warns about "invalidity" of certificate and approval of access for a specific function (drive mapping maybe?). You will not be able to bypass this (you can ignore the certificate so the warning only comes back once the cert is renewed). The second one you can bypass by specifying the username and password. This is how my tabbed remote access application sets up MsTscAx controls for RDP connections: If Self.Credential <> nil Then Begin If Not Self.Credential.DomainName.IsEmpty Then _rdp.Domain := Self.Credential.DomainName; If Not Self.Credential.UserName.IsEmpty Then _rdp.UserName := Self.Credential.UserName; If Not Self.Credential.Password.IsEmpty Then _rdp.AdvancedSettings7.ClearTextPassword := Self.Credential.Password; End; I suggest you check all the .AdvancedSettingsxxx options. There are plenty of tasty settings there to fulfill your needs. Share this post Link to post
martins_044 0 Posted Wednesday at 01:44 PM 18 hours ago, aehimself said: The first window warns about "invalidity" of certificate and approval of access for a specific function (drive mapping maybe?). You will not be able to bypass this (you can ignore the certificate so the warning only comes back once the cert is renewed). The second one you can bypass by specifying the username and password. This is how my tabbed remote access application sets up MsTscAx controls for RDP connections: If Self.Credential <> nil Then Begin If Not Self.Credential.DomainName.IsEmpty Then _rdp.Domain := Self.Credential.DomainName; If Not Self.Credential.UserName.IsEmpty Then _rdp.UserName := Self.Credential.UserName; If Not Self.Credential.Password.IsEmpty Then _rdp.AdvancedSettings7.ClearTextPassword := Self.Credential.Password; End; I suggest you check all the .AdvancedSettingsxxx options. There are plenty of tasty settings there to fulfill your needs. Can you help me? (Don't mind the writing and indentation of the code, it's really bad, this language is new to me) unit tbConnectRDP; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ExtCtrls, MSTSCLib_TLB, ActiveX, ComObj, Vcl.OleServer, Vcl.OleCtrls, Generics.Collections; type TConnectRDP = class(TForm) treeListServer: TTreeView; listServerSplitter: TSplitter; pageControlViewServer: TPageControl; procedure ConectarRDP( const IP, Usuario, Senha: string ); procedure treeListServerDblClick(Sender: TObject); procedure addServersListTree; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FRDPConnections: TObjectList<TMsRdpClient10>; procedure RDPDisconnected(Sender: TObject; discReason: Integer); procedure pageControlViewServerDrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean); procedure pageControlViewServerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); public { Public declarations } end; var ConnectRDP: TConnectRDP; implementation {$R *.dfm} uses tbMenu; procedure TConnectRDP.FormCreate(Sender: TObject); begin CoInitialize(nil); FRDPConnections := TObjectList<TMsRdpClient10>.Create(True); // True para liberar objetos ao destruir addServersListTree; pageControlViewServer.OwnerDraw := True; pageControlViewServer.OnDrawTab := pageControlViewServerDrawTab; pageControlViewServer.OnMouseDown := pageControlViewServerMouseDown; end; procedure TConnectRDP.FormDestroy(Sender: TObject); begin FRDPConnections.Free; CoUninitialize; end; procedure TConnectRDP.addServersListTree; var Grupo: TTreeNode; begin // Limpa a TreeView antes de adicionar treeListServer.Items.Clear; // Adiciona um grupo chamado "Produção" Grupo := treeListServer.Items.Add(nil, 'Produção'); treeListServer.Items.AddChild(Grupo, '10.1.1.96'); treeListServer.Items.AddChild(Grupo, '10.1.1.200'); treeListServer.Items.AddChild(Grupo, '10.1.1.233'); // Adiciona outro grupo chamado "Testes" Grupo := treeListServer.Items.Add(nil, 'Testes'); treeListServer.Items.AddChild(Grupo, '192.168.100.10'); // Expande os grupos para facilitar visualização // treeListServer.FullExpand; end; procedure TConnectRDP.treeListServerDblClick(Sender: TObject); var ServerIP, Username, Password: string; begin if not Assigned(treeListServer.Selected) then Exit; if treeListServer.Selected.Parent = nil then Exit; // evita grupo ServerIP := treeListServer.Selected.Text; Username := 'Administrador'; Password := '!tsncs4606'; ConectarRDP(ServerIP, Username, Password); end; { procedure TConnectRDP.ConectarRDP(const IP, Usuario, Senha: string); var Node: TTreeNode; NovaAba: TTabSheet; RDPClientLocal: TMsRdpClient10; begin Node := treeListServer.Selected; if (Node = nil) or (Node.Parent = nil) then Exit; NovaAba := TTabSheet.Create(pageControlViewServer); NovaAba.PageControl := pageControlViewServer; NovaAba.Caption := Node.Text; RDPClientLocal := TMsRdpClient10.Create(NovaAba); RDPClientLocal.Parent := NovaAba; RDPClientLocal.Align := alClient; RDPClientLocal.Visible := True; RDPClientLocal.OnDisconnected := RDPDisconnected; RDPClientLocal.UserName := Usuario; RDPClientLocal.Domain := ''; RDPClientLocal.AdvancedSettings9.ClearTextPassword := Senha; RDPClientLocal.AdvancedSettings9.AuthenticationLevel := 0; RDPClientLocal.AdvancedSettings9.EnableCredSspSupport := True; RDPClientLocal.AdvancedSettings9.RedirectClipboard := False; RDPClientLocal.Server := IP; // FRDPConnections.Add(RDPClientLocal); try RDPClientLocal.Connect; except on E: Exception do ShowMessage('Erro ao conectar: ' + E.Message); end; end; } procedure TConnectRDP.RDPDisconnected(Sender: TObject; discReason: Integer); begin ShowMessage('Desconectado. Motivo: ' + IntToStr(discReason)); end; procedure TConnectRDP.ConectarRDP(const IP, Usuario, Senha: string); var Node: TTreeNode; NovaAba: TTabSheet; RDPClientLocal: TMsRdpClient10; NonScriptable: IMsRdpClientNonScriptable5; begin Node := treeListServer.Selected; if (Node = nil) or (Node.Parent = nil) then Exit; NovaAba := TTabSheet.Create(pageControlViewServer); NovaAba.PageControl := pageControlViewServer; NovaAba.Caption := Node.Text; RDPClientLocal := TMsRdpClient10.Create(NovaAba); RDPClientLocal.Parent := NovaAba; RDPClientLocal.Align := alClient; RDPClientLocal.Visible := True; RDPClientLocal.OnDisconnected := RDPDisconnected; // Configuração de automação total RDPClientLocal.UserName := Usuario; RDPClientLocal.Domain := ''; RDPClientLocal.AdvancedSettings9.ClearTextPassword := Senha; RDPClientLocal.AdvancedSettings9.AuthenticationLevel := 0; // Ignora certificado RDPClientLocal.AdvancedSettings9.EnableCredSspSupport := True; // Configurações avançadas de prompt e credenciais via NonScriptable if Supports( RDPClientLocal, IMsRdpClientNonScriptable5, NonScriptable) then begin NonScriptable.Set_AllowPromptingForCredentials(False); NonScriptable.Set_PromptForCredentials(False); NonScriptable.Set_PromptForCredsOnClient(False); NonScriptable.Set_AllowCredentialSaving(True); end; // Redirecionamento (opcional) RDPClientLocal.AdvancedSettings9.RedirectDrives := False; RDPClientLocal.AdvancedSettings9.RedirectPrinters := False; RDPClientLocal.AdvancedSettings9.RedirectClipboard := false; RDPClientLocal.Server := IP; try RDPClientLocal.Connect; except on E: Exception do ShowMessage('Erro ao conectar: ' + E.Message); end; end; procedure TConnectRDP.pageControlViewServerDrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean); var TabCaption: string; CloseRect: TRect; begin TabCaption := pageControlViewServer.Pages[TabIndex].Caption; // Desenha o texto da aba Control.Canvas.TextRect( Rect, Rect.Left + 10, Rect.Top + 4, TabCaption ); // Desenha o "X" no canto direito da aba CloseRect := Rect; CloseRect.Left := CloseRect.Right - 25; CloseRect.Right := CloseRect.Right - 25; CloseRect.Top := CloseRect.Top + 4; CloseRect.Bottom := CloseRect.Bottom - 4; Control.Canvas.TextRect(CloseRect, CloseRect.Left, CloseRect.Top, 'X'); end; procedure TConnectRDP.pageControlViewServerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i: Integer; TabRect: TRect; CloseRect: TRect; begin for i := 0 to pageControlViewServer.PageCount - 1 do begin TabRect := pageControlViewServer.TabRect(i); CloseRect := TabRect; CloseRect.Left := CloseRect.Right - 18; CloseRect.Right := CloseRect.Right - 4; if PtInRect(CloseRect, Point(X, Y)) then begin pageControlViewServer.Pages.Free; Break; end; end; end; end. Share this post Link to post
aehimself 404 Posted Wednesday at 06:39 PM When experimenting with a new component I suggest a "barebone" example first. One control on the form, setting up and connecting in FormCreate. I'm not going to recreate your form layout and filter out the essentials I'm sorry... I already showed how I'm doing it and it works fine. Also keep in mind that by importing the MsTscAx control you are effectively using the current version available in your Windows setup: it can / might / surely will differ between versions, editions and even patch levels. Share this post Link to post
sh17 26 Posted 2 hours ago spawn451/Remote-Desktop-Streamer-Delphi: A lightweight remote desktop streaming and control solution built entirely in Delphi Share this post Link to post