2011-01-31 78 views

回答

7

除了上述问题的答案,也看到我的回答这个问题:Does anyone know about issues between Citrix and Delphi 2007 applications? (And perhaps other development languages?)

编辑:在我的博客,我对应用程序兼容性问题caterogy,它们是表现不好的应用程序的真实故事在RDS /思杰。可能是有用的检查出来:http://www.remkoweijnen.nl/blog/topics/application-compatibility/

其他类,可能是令人感兴趣的是http://www.remkoweijnen.nl/blog/topics/citrix/http://www.remkoweijnen.nl/blog/topics/terminalserver/虽然不是所有的,可以申请你的问题。

2日编辑:您可以使用来自微软的标准用户分析器工具来检查,如果您的应用程序适用于由一个普通用户的身份运行(MS侧重于UAC,但在一个典型的RDS或Citrix服务器只有低特权用户)。 http://technet.microsoft.com/en-us/library/cc765948(WS.10).aspx

10

Double buffering就是这样一种东西。

通常双缓冲是一件好事,我一直都在使用它。请参阅我的组件(1)(2)(3)。它们都是双缓冲的,因此完全没有闪烁(并且易于实现),但是如果远程运行它,则必须发送位图而不是GDI命令,所以它可能相当慢(并且不经济)。

+1

需要多长时间才能将整个自定义组件作为SO答案进行挑选?我刚刚提出了所有这三项 - 很好的工作! – 2011-02-01 00:05:20

+0

@大卫M:一般不到一个小时。我做了很多次。谢谢! – 2011-02-01 00:06:26

19

安德烈亚斯在指针式双缓冲中是正确的。这是我意识到的最重要的考虑因素。

作为一个温和的反面,我不喜欢双缓冲,因为它很难让它正确。许多组件不成功。我正在考虑VCL下拉列表框,这些列表框在Windows Basic下不能正确绘制。还有其他人!

但是有些控件确实需要双缓冲来避免闪烁,所以你会怎么做?当用户本地连接时,您希望获得双缓冲的好处,但您不希望在远程时使用网络带宽征税。

所以,这里是我做的:

procedure WMWTSSessionChange(var Message: TMessage); message WM_WTSSESSION_CHANGE; 

procedure TBaseForm.WMWTSSessionChange(var Message: TMessage); 
begin 
    case Message.WParam of 
    WTS_CONSOLE_DISCONNECT,WTS_REMOTE_DISCONNECT, 
    WTS_SESSION_LOCK,WTS_SESSION_LOGOFF: 
    SessionDisconnected; 
    WTS_CONSOLE_CONNECT,WTS_REMOTE_CONNECT, 
    WTS_SESSION_UNLOCK,WTS_SESSION_LOGON: 
    SessionConnected; 
    end; 
    inherited; 
end; 

function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): BOOL; stdcall; external 'Wtsapi32.dll'; 
function WTSUnRegisterSessionNotification(hWnd: HWND): BOOL; stdcall; external 'Wtsapi32.dll'; 

const 
    NOTIFY_FOR_THIS_SESSION = 0; 
    NOTIFY_FOR_ALL_SESSIONS = 1; 

procedure TBaseForm.CreateWnd; 
begin 
    inherited; 
    WTSRegisterSessionNotification(WindowHandle, NOTIFY_FOR_THIS_SESSION); 
end; 

procedure TBaseForm.DestroyWnd; 
begin 
    WTSUnRegisterSessionNotification(WindowHandle); 
    inherited; 
end; 

在我的应用形式从TBaseForm下降,因此继承了这种行为。 SessionConnectedSessionDisconnected方法是virtual,因此各个表单可以采取特定的操作。

特别是,我所有的形式呼吁UpdateDoubleBuffered

function InRemoteSession: Boolean; 
begin 
    Result := Windows.GetSystemMetrics(SM_REMOTESESSION)<>0; 
end; 

class procedure TBaseForm.UpdateDoubleBuffered(Control: TWinControl); 
var 
    DoubleBuffered: Boolean; 
begin 
    if InRemoteSession then begin 
    //see The Old New Thing, Taxes: Remote Desktop Connection and painting 
    DoubleBuffered := False; 
    end else begin 
    DoubleBuffered := (Control is TCustomListView) 
        or (Control is TCustomStatusBar); 
    //TCustomListView flickers when updating without double buffering 
    //TCustomStatusBar has drawing infidelities without double buffering in my app 
    end; 
    Control.DoubleBuffered := DoubleBuffered; 
end; 

procedure TBaseForm.UpdateDoubleBuffered; 
var 
    Control: TControl; 
begin 
    for Control in ControlEnumerator(TWinControl) do begin 
    UpdateDoubleBuffered(TWinControl(Control)); 
    end; 
end; 

ControlEnumerator是行走部件的孩子一个枚举。

旧的新事物的参考是一篇名为Taxes: Remote Desktop Connection and painting的文章,这是我对这段代码大部分的启发。

我确定还有其他与远程桌面相关的问题,但双缓冲肯定是其中一个更重要的问题。

+3

+1这个详细的答案。 – 2011-01-31 19:55:04

+0

虚拟方法的使用者应该检查会话消息是否适用于消费者的会话。他们如何做到这一点,而不知道SessionId(你没有通过它)? – Remko 2011-02-01 12:50:02

+0

@Remko我错过了我的代码中的一个重要部分,现在我已将其作为编辑添加到答案中。当我注册通知时,我使用`NOTIFY_FOR_THIS_SESSION`。我忘记了代码的那部分内容,当然,在你要求通知之前收听你不会收到的消息是没有意义的!感谢您发现这一点。 – 2011-02-01 13:01:45

4

Alpha透明表单不能很好地支持IME(由客户端或服务器根据其版本)。

如果你有一个干净的现代用户界面,你也可能需要把它变成“丑陋”的模式,以便所有的东西都可以使用,你也必须担心颜色,大多数远程桌面以16位颜色或甚至256色进行操作。保证可读。
本着同样的精神,提防消除锯齿的文本,这是任何现代UI必须的,但可能会导致低色RDP不可读模糊的字符。

有可与通知气泡和其他基于shell的影响等问题,所以你可能会想自己处理他们,在定期的形式,而不是依赖于Windows API的功能。从图形上讲,双缓冲可以是一把双刃剑,在某些情况下(低调图形),关闭它可能是有益的,但如果您有更高级的渲染(渐变,透明位图,缩放位图,花哨字体,消除锯齿线等),您可以通过双缓冲获得更好的外观和速度,因为稍微的延迟可能比闪烁的交互式绘图更好。
此外,一些位图可以比其他位图快得多,RDP中常用的快速压缩有利于水平梯度f.i上的垂直梯度。

如果您的应用程序永远不需要在普通用户帐户下运行,则还会有另一个问题与文件权限有关。特殊文件夹(如temp)和注册表键可以有不同的(动态)位置和限制。但是,如果您的应用程序已经在受限用户帐户下运行,则应该已经涵盖了所有内容。

4

如果这是一个由数百或数千用户运行的企业级应用程序或Web应用程序,请特别注意颜色深度,渐变和恶意动画。特别是最后一个。一个16x16的旋转“同步”图标不会吃太多的带宽,但更大的东西可能会产生大量的流量。 当颜色水平下降时,渐变看起来很糟糕,并且压缩不好。 当网络/系统管理员需要挤出更多网络时,颜色级别下降。您可能无法控制它。 这些问题也适用于Citrix应用程序,这些应用程序通常在没有完整桌面的情况下运行。 有一个额外的考虑是,用户不会看到系统托盘通知区域。

3

随着思杰,我们遇到了打印机问题。有时,连接将使用客户机在其计算机上定义的打印机,有时打印机来自其他用户的会话,而有时默认打印机位于我们用户无法访问的完全不同的位置。

0

我遇到很多问题,闪烁的东西太多以至于无法通过远程桌面使用。这是因为我每秒钟多次更新诸如Captions或Status面板之类的东西。我改变了我的所有更新UI代码来检查,如果标题实际上已经改变了:

if Str<>WeirdControl.Property1 then 
     WeirdControl.Property1 := Str; // minimize number of invalidates in case the control doesn't have it. 

随着在其他的答案中提到的其他事情,这让我的应用程序在远程桌面的情况下再使用。

相关问题