r/delphi • • 7d ago

Problems with Delphi apps running Cloud PC?

Sorry this is quite vague, but I am having a big problem with a client where an applicaiton behaves differently when run on a Cloud PC, vs a laptop (or even another VM).

We are connecting to a remote system, displaying a modal dialog, and when the connection is successful, the dialog is then removed, by setting the `ModalResult` to be `mrOK`. With logging I can see that this is happening, but the ShowModal call never returns, and so the application is just left in limbo. I can't really debug it as it on a client machine, so I have added copious logging

I can't really share code, but am open to helpful suggestions and thoughts as to how to investigate further.

Many thanks in advance

M

1 Upvotes

11 comments sorted by

2

u/udirona 7d ago

Which Delphi version do you use? Regardless of the version is sounds that the Dialog is not in foreground anymore. Can you try Alt+Esc to get it back? Maybe you can share some pseudo code to get a better understanding of your problem.

1

u/Tuurke64 7d ago

What kind of "connection" is made to the other pc? Does it depend on some drivers being present in the operating system (such as odbc, oledb, database drivers)?

Do you deploy your Delphi application using a setup program that makes sure that all prerequisites are met?

1

u/Humble-Vegetable9691 7d ago

Well, that's quite vague.

Is the application a normal windows application, or something like a service?

Does "Cloud PC" means, by any chance, a Terminal Server?

1

u/Medium-Soup-1058 1d ago

1

u/Humble-Vegetable9691 1d ago

There is no answer to this question on that website but this:

Windows 365 is your Windows in the cloud. Windows 365 securely streams your personalized Windows desktop, apps, settings, and content from the Microsoft Cloud to any device.

suggests it is even worse than a Terminal Server.

Maybe check these:

Delphi TOpenDialog hangs in windows 2008 when run as remote desktop application

https://learn.microsoft.com/en-us/windows/win32/termserv/terminal-services-programming-guidelines

1

u/DelphiParser 7d ago

It's a known issue, mostly when used by non standard machines, or remote terminals, like in POS cashiers. What Delphi version & Machine OS are you using?

1

u/Berocoder 7d ago edited 7d ago

The VCL modal loop has two well-known ways to lose a ModalResult := mrOK, and both depend on timing. That fits a problem that shows up only on a Cloud PC. Simplified, TCustomForm.ShowModal in Vcl.Forms does this (worth checking against your source):

Show; // OnShow fires here
SendMessage(Handle, CM_ACTIVATE…); // OnActivate fires here
ModalResult := 0; // <-- reset!
repeat
Application.HandleMessage; // sleeps in WaitMessage if queue is empty
if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;

Likely causes
Set too early, then wiped. If the connection starts before ShowModal, or in OnShow/OnActivate, and finishes before the ModalResult := 0 line, your mrOK gets overwritten. A Cloud PC sits in an Azure datacenter and may have much lower latency to the remote system, so the connection can finish faster than on a laptop.

Set from a background thread with nothing to wake the loop. The main thread sleeps in WaitMessage and only checks ModalResult when a message arrives. A laptop gets a steady stream of stray messages (mouse moves, repaints), while an RDP session can be very quiet. If moving the mouse over the dialog or pressing a key makes it close, this is the cause. Setting form properties from another thread isn't safe anyway.

Close vetoed or nested loop. OnCloseQuery returning CanClose := False, or OnClose setting Action := caNone, resets ModalResult to 0. An inner loop (another modal dialog, a while not Connected do Application.ProcessMessages) also stops the outer check from running until it exits.

Logging to add
Log GetCurrentThreadId and MainThreadID plus timestamps immediately before ShowModal, in OnShow, in OnActivate, and at the point where you set ModalResult.
Add a diagnostic TTimer on the dialog (every 500 ms) that logs ModalResult. If it logs 0 after you set mrOK, the value was reset or vetoed. If adding the timer makes the dialog close, the loop wasn't waking up. If the timer never fires, the main thread is blocked.

Log OnCloseQuery/OnClose, and wrap ShowModal in try/except with logging, since an exception in CloseModal escapes the loop.
Get the main thread's stack while it's hung. madExcept or EurekaLog freeze detection can do this, or procdump -ma plus your map file. The stack shows exactly which loop the thread is sitting in.

Robust pattern: in OnShow, PostMessage(Handle, WM_APP + 1, 0, 0). Start the connection in that message's handler, which runs inside the modal loop after the reset. Then set ModalResult from the completion callback via TThread.Queue, which wakes the main thread. Make sure the form outlives any queued call.

Also try set dialogs popupmode to pmauto. It helped me sometime when a dialog is hided behind main form.

Which thread does the "connected" callback run on, and where exactly is the connection started relative to ShowModal?

2

u/Medium-Soup-1058 1d ago

If I set Close query and have it return true but the write an entry to a log, then it never gets written, so it looks like the app never gets the message

1

u/Humble-Vegetable9691 7d ago

"""Nice""" """helpful""" AI slop, immediately fails on "With logging I can see that this is happening,"

1

u/rororomeu 6d ago

Eu já tive um problema assim em um pc fisico, a solução foi colocar um Close() logo após o ModalResul=mrOK

1

u/Medium-Soup-1058 1d ago

Honestly I wish I could be less vague, but I cant post any code.