Find our new blog here: Cybele Software Blog
![]() |
| Visit our new corporate blog! |
Tech Tips & Notes
Find our new blog here: Cybele Software Blog
![]() |
| Visit our new corporate blog! |
We are glad to inform you of our latest Development News:
TN Bridge Host Integration Pack on the new Embarcadero’s Delphi XE
TN Bridge Host Integration Pack is now compatible with the new Embarcadero’s Delphi XE development environment. So now, TN Bridge Host Integration Pack supports Embarcadero’s Delphi 5 through XE, any ActiveX compatible Development Environment and .NET framework and programming languages.
z/Scope for iPad/Android
We are currently extending z/Scope to enable Terminal Emulation access from iPad, tablet devices and smart phones running Apple iOS and Google Android’s OS. We would like to know about your current needs and what features you consider a must for a mobile OS Terminal Emulator. You can send us your comments and suggestions and we’d be happy to evaluate any special need or request you may have.
Web RDP client reaching its final release
Our new Web RDP client it is now getting close to its official release. We are thrilled about the amazing performance it is showing due to the full WebSockets implementation and Video Driver support, among other improvements. We are also planning full Chrome, Firefox and Internet Explorer compatibility and many other enhacements. Stay tunned!
Introduction
{"status:":1,"desktopWidth":1280,"desktopHeight":800,"cursor":"default","cursorX":241,"cursorY":525,
"windows": [ { "hwnd":"196724","zidx":1,"desktop":"Default","left":0,"top":0,"width":1280,"height":800},
{ "hwnd":"8521744","zidx":2,"desktop":"Default","left":364,"top":59,"width":806,"height":667},
{ "hwnd":"8129930","zidx":3,"desktop":"Default","left":-8,"top":-8,"width":1296,"height":776},
{ "hwnd":"1247020","zidx":4,"desktop":"Default","left":244,"top":28,"width":1023,"height":728},
{ "hwnd":"8785068","zidx":5,"desktop":"Default","left":-8,"top":-8,"width":1296,"height":776,"imgs": [ { "x":8,"y":8,"w":1280,"h":123,"img": "data:image/jpeg;base64,/9j/4......" }]},
{ "hwnd":"6033806","zidx":6,"desktop":"Default","left":-1,"top":479,"width":426,"height":22,"imgs": [ { "x":1,"y":0,"w":425,"h":22,"img": "data:image/jpeg;base64,/9j/4AAQ......" }]},
{ "hwnd":"196708","zidx":7,"desktop":"Default","left":0,"top":760,"width":1280,"height":40,"imgs": [ { "x":53,"y":0,"w":1227,"h":40,"img": "data:image/jpeg;base64,/9j/4AA......" }]},
{ "hwnd":"131186","zidx":8,"desktop":"Default","left":0,"top":760,"width":54,"height":40,"imgs": [ { "x":0,"y":0,"w":54,"h":40,"img": "data:image/jpeg;base64,/9j/4AAQSkZJ......" }]}]]}
function reload() {
scale = getScale();
var url = baseUrl + "json?id=" + sessionStatus.id;
clearTimeout(jsonTimeout);
jsonTimeout = setTimeout(onJsonTimeout,jsonTimeoutValue);
$.getJSON(url, function (obj) {
try {
$.each(obj.windows, function (i, win) {
processWindow(win);
})
for (var i = deskDiv.children.length - 1; i >= 0; i--) {
var found = false;
var canvas = deskDiv.children[i];
$.each(obj.windows, function (i, win) {
var canvasid = "canvas" + win.hwnd;
if (canvas.id == canvasid) {
found = true;
}
})
if (!found) {
canvas.style.display = "none";
canvas.innerHTML = '';
deskDiv.removeChild(canvas);
}
}
}
catch (err) {
if (sessionStatus.active) {
setTimeout(reload, 1);
}
}
});
}
function createCanvas(win) {
var canvas = document.createElement("canvas");
canvas.visibility = 'visible';
canvas.display = 'block';
canvas.style.position = 'absolute';
canvas.style.left = (win.left-sessionStatus.viewLeft)+'px';
canvas.style.top = (win.top-sessionStatus.viewTop)+'px';
canvas.style.zIndex = win.zidx;
canvas.width = deskDiv.offsetWidth;
canvas.height = deskDiv.offsetHeight;
canvas.id = "canvas" + win.hwnd;
deskDiv.appendChild(canvas);
return canvas;
}
function processWindow(win) {
var canvasid = "canvas" + win.hwnd;
var canvas = document.getElementById(canvasid);
if (!canvas) {
canvas = createCanvas(win);
}
deskDiv.style.marginLeft = getDeltaX() + 'px';
deskDiv.style.marginTop = getDeltaY() + 'px';
if ((win.width == 0) || (win.height == 0)) {
canvas.style.visibility = "hidden";
canvas.style.zIndex = -1;
} else {
canvas.style.left = (win.left-sessionStatus.viewLeft) + 'px';
canvas.style.top = (win.top-sessionStatus.viewTop) + 'px';
canvas.style.clip = 'rect(0px,' + win.width + 'px,' + win.height + 'px,0px)';
canvas.style.visibility = "visible";
canvas.style.zIndex = win.zidx;
}
if (win.imgs != null) {
var context = canvas.getContext('2d');
if (!context || !context.drawImage) {
alert("no hay canvas");
return;
};
$.each(win.imgs, function (i, imgpart) {
var img = new Image();
img.id = "imgcanvas";
img.style.display = "none";
img.onload = function () {
context.drawImage(img, imgpart.x , imgpart.y, img.width, img.height);
}
img.src = imgpart.img;
})
}
};
Cybele Software, Inc. introduces ThinVNC, a new remote desktop solution that boosts and enhances remote technical support and administration tasks, allowing users to remotely access a desktop using just a web browser.
ThinVNC was built from the ground up taking full advantage of AJAX, JSON and HTML5 technologies. By implementing a number of techniques not available in traditional AT&T RFB protocol, it achieves a remarkable performance, rivaling any traditional VNC.
ThinVNC exploits HTML5 canvas to display a remote PC desktop, not requiring any additional plugin, add-on or installation of any kind on the client side. Regardless of the computer or mobile operating system, ThinVNC provides native, secure data transmission using HTTP and SSL.
Users can use the ThinVNC Presentation Manager to invite people to attend online demonstrations or trainings. Running on the web browser, ThinVNC removes the need of a “viewer” download making the attendance of non-tech people smooth and free of any setup issue.
On corporate environments, ThinVNC can be set up as a gateway to proxy other ThinVNC instances. By publishing only one IP, users can remotely get access to desktops on the LAN just by entering the internal IP/PC name in the welcome screen.
ThinVNC Server works on Windows 2000/XP/2003/Vista/Win 7/Windows Server 8. On the client side, ThinVNC is compatible with any Operating System and an HTML5 compliant browser such as Mozilla Firefox, Chrome, Internet Explorer, Opera, Safari, etc.
- Full ThinVNC SDK 2.0 can be downloaded, being available on a royalty fee basis. Contact us for pricing and licensing information.
TWin = class(TObject)
private
Wnd : Hwnd;
Rect : TRect;
Pid : Cardinal;
public
constructor Create(AWnd:HWND;ARect:TRect;APid:Cardinal);
end;
function EnumWindowsProc(Wnd: HWnd; const obj:TList<TWin>): Bool; export; stdcall;
var ProcessId : Cardinal;
R,R1 : TRect;
Win : TWin;
begin
Result:=True;
GetWindowThreadProcessId(Wnd,ProcessId);
if IsWindowVisible(Wnd) and not IsIconic(wnd)then begin
GetWindowRect(Wnd,R);
IntersectRect(R1,R,Screen.DesktopRect);
if not IsRectEmpty(R1) then begin
win := TWin.Create(Wnd,R,ProcessId);
obj.Add(win);
end;
end;
end;
procedure GetProcessWindowList(WinList:TList<TWin>);
begin
WinList.Clear;
EnumWindows(@EnumWindowsProc, Longint(WinList));
end;
TWindowMirror = class
private
FIndex : Integer;
FRgn : HRGN;
FHandle : THandle;
FBoundsRect : TRect;
FProcessId : Integer;
FImage : TBitmap;
FDiffStreamList : TList<TImagePart>;
...
...
end;
procedure TMirrorManager.RefreshMirrorList(out OneMoved:Boolean);
procedure GetProcessWindowList(WinList:TList<TWin>);
begin
WinList.Clear;
EnumWindows(@EnumWindowsProc, Longint(WinList));
end;
var
wl : TList<TWin>;
n : Integer;
wm : TWindowMirror;
begin
OneMoved:=False;
wl := TList<TWin>.Create;
try
// Enumerates top windows
GetProcessWindowList(wl);
try
for n := wl.Count - 1 downto 0 do begin
// Looks for a cached window
wm:=GetWindowMirror(FMirrorList,wl[n].Wnd);
if assigned(wm) then begin
if IsIconic(wl[n].Wnd) then
wm.SetBoundsRect(Rect(0,0,0,0))
else wm.SetBoundsRect(wl[n].Rect);
// Returns true when at least one window moved
OneMoved:=OneMoved or (DateTimeToTimeStamp(Now-wm.FMoved).time<MOVE_TIME);
end else begin
// Do not create a TWindowMirror for invisible windows
if IsIconic(wl[n].Wnd) then Continue;
wm:=TWindowMirror.Create(Self,wl[n].Wnd,wl[n].Rect, wl[n].pid);
FMirrorList.Add(wm);
end;
// Saves the zIndex
wm.FIndex:=wl.Count-n;
// Generates clipping regions
wm.GenRegions(wl,n);
end;
finally
ClearList(wl);
end;
// Sorts the mirror list by zIndex
FMirrorList.Sort;
finally
wl.free;
end;
end;
function TWindowMirror.Capture(ANewImage:TBitmap): Boolean;
function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC;
XSrc, YSrc: Integer; Rop: DWORD): BOOL;
begin
// Capture only visible regions
SelectClipRgn(DestDC,FRgn);
result:=Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC,
XSrc, YSrc, Rop);
SelectClipRgn(DestDC,0);
end;
var
DC : HDC;
RasterOp,ExStyle: DWORD;
begin
RasterOp := SRCCOPY;
ExStyle:=GetWindowLong(FHandle, GWL_EXSTYLE);
if (ExStyle and WS_EX_LAYERED) = WS_EX_LAYERED then
RasterOp := SRCCOPY or CAPTUREBLT;
DC := GetDCEx(FHandle,0,DCX_WINDOW or DCX_NORESETATTRS or DCX_CACHE);
try
Result:=BitBlt(ANewImage.Canvas.Handle,0,0,
Width(FBoundsRect),Height(FBoundsRect),DC,0,0, RasterOp)
finally
ReleaseDC(FHandle,DC);
end;
end;
function TWindowMirror.CaptureDifferences(reset:boolean=false): Boolean;
....
begin
...
result:=Capture(TmpImage);
if result then begin
...
ra:=ExtractClippingRegions(Rect(0,0,TmpImage.Width,TmpImage.Height));
for n := 0 to Length(ra) - 1 do begin
ra2:=GetDiffRects(FImage,TmpImage,ra[n]);
for m := 0 to Length(ra2) - 1 do begin
Jpg := TJpegImage.Create;
...
CopyBmpToJpg(Jpg,TmpImage,ra2[m]);
FDiffStreamList.Add(TImagePart.Create(rbmp,'jpeg'));
Jpg.SaveToStream(FDiffStreamList[FDiffStreamList.Count-1].FStream);
...
Bitblt(FImage.Canvas.Handle,
ra2[m].Left,ra2[m].Top,Width(ra2[m]),Height(ra2[m]),
TmpImage.Canvas.handle, rbmp.Left,ra2[m].Top,SRCCOPY);
end;
end;
...
end;
Find our new blog here:
© Copyright 2010-2022 | Cybele Software's Dev Team | Theme by ONPRE