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