Update: Apologies for the formatting mistakes on this post, and any eyestrain caused by them!
Update: Apologies for the formatting mistakes on this post, and any eyestrain caused by them!
First let me say what a horror installation.
Second Delphi has nothing to do with this problem.
What's going up:
I use a new Samsung Galaxy S4 for developing Android Applications from Delphi. I use a MacMini with running VMWare Fusion 6.01 and a installation of Windows 8.
Connecting the Samsung Device on the MacMini and connect the Device to the Mac OSX and watching with Hardware Growler the Device connects wonderful. But connect the Device with the VMWare Fusion Dialog to Windows the Device is connect/disconnect/connect/disconnect how ever a never ending story.
After hours of search i found the solution and i like to share to the community how to solve this problem.
Please read first all steps, to see the hurdles and then do it
#0 check on you samsung device developer mode is enabled if not here nice video (not from me!). Also in Developer Options enable USB Debugging !
#1 deinstall on your windows machine all Samsung drivers or existing Samsung Kies Application if installed
#2 reboot windows machine (image)
#3 after reboot plug you Samsung device to the mac and root the samsung to windows machine (yes do this we need a log entry)
#4 after some connect/disconnect loops disconnect the device
#5 shut down windows image and quit vmware
#6 navigate on the mac in finder to the vmware image
#7 secondary click or right mouse click on this file and select "Show Package Contents"
#8 search vmware.log file
#9 open this file in a text editor
#10 search for word "samsung"
#11 you find a line like
013-10-31T18:24:16.553+01:00| vmx| I120: USB: Found device [name:SAMSUNG_Android vid:04e8 pid:6860 path:10/1/1/3 speed:high family:vendor,comm serialnum:9c9679c7 arbRuntimeKey:d version:2]
#12 the intresting values are : vid:04e8 pid:6860 (your numbers can be other, depends from model and usa/europe/asia model how ever)
#13 close log file
#14 in the same folder you find a file yourImageName.vmx
#15 open this file in text editor
#16 add this line: usb.quirks.device0 = "0x4e8:0x6860 skip-reset"
you see there are the same number like the interesting value in step #12. but important the first number is the vid value the second the pid. add for each value the chars "0x"
#17 save file and close finder
#18 start vmware and your image
#19 DO NOT PLUG IN YOUR DEVICE NOW
#20 for deploying apps from Delphi you need a USB ADB Debugging Driver from Samsung. The Driver on the samsung web site is old an did not run an windows 7 and 8. do not install this driver !!! you find in the internet many drivers with virus and/or trojan malware. so be carful. i found the last original and code signed driver from samsung incl 32/64 bit and windows 8 functionality on this site:
http://www.droidacid.com/samsung-usb-drivers-for-mobile-phones-and-android-adb-drivers/
#21 download and install the driver
#22 reboot windows (!)
#23 now plug in your samsung device
#24 wait for finishing installing on windows driver detection
#25 watch on your phone screen. a message is coming to allow windows access the device
#26 if message not coming after a minute, disconnect and connect again the device (was on my configuration)
#27 now start delphi, create a new android application, refresh device node under the android node and you see you device
now i know, why i prefer iOS Devices
have fun
Release 14 is now available to all existing XE Plus Pack users. Release 14 also brings support for Delphi XE5.
The reason why the XE5 release was delayed was that the addition on iOS 7 support and a couple of changes to internal IDE component names (which made no sense to change) broke two of my experts. Needless to say, I was waiting for Update 1 to be released before making the XE5 version available.
NOTE: The XE5 release works with or without update 1 and with or without iOS 7 support.
This expert is a repository wizard to help made Debug Visualizers without needing to go into much detail about their implementation. It allows you to concentrate on creating custom visualizers which is perhaps one of the most unappreciated IDE features.
Those paying attention will know that this wizard is based off the Blaise Pascal Magazine article written back in the days of Delphi 2010. The code was upgraded and the templates improved and now available from Delphi XE thought to Delphi XE5.
There have also been a number of fixes under the hood, however two that will be noticeable are:
XE Plus Pack still costs just 40 Euros and can be purchased cheaper if ordering four or more licenses (contact us for quotes).
http://jed-software.com/xepp_purchase.htm
Download your required version from the download page.
To try XE5 Plus Pack download the trial version.
The new IDE Fix Pack 5.4 supports XE5, fixes some bugs in IDE Fix Pack patches and adds new Win32 and Win64 compiler optimizations.
Download IDE Fix Pack:
Name | IDE Version | File | Size | Downloads | Added |
---|---|---|---|---|---|
IDE Fix Pack 5.4 | 2009+UP3 | IDEFixPack2009Reg54.zip | 173.75 KB | 214 times | 2013-11-01 |
IDE Fix Pack 5.4 | 2010 | IDEFixPack2010Reg54.zip | 159.74 KB | 298 times | 2013-11-01 |
IDE Fix Pack 5.4 | XE | IDEFixPackXEReg54.zip | 147.68 KB | 378 times | 2013-11-01 |
IDE Fix Pack 5.4 | XE2+UP4+HF1 | IDEFixPackXE2Reg54.zip | 217.09 KB | 480 times | 2013-11-01 |
IDE Fix Pack 5.4 | XE3+UP1 | IDEFixPackXE3Reg54.zip | 213.54 KB | 373 times | 2013-11-01 |
IDE Fix Pack 5.4 | XE4 | IDEFixPackXE4Reg54.zip | 214.72 KB | 389 times | 2013-11-01 |
IDE Fix Pack 5.4 | XE5 | IDEFixPackXE5Reg54.zip | 213.62 KB | 788 times | 2013-11-01 |
Download fastdcc:
Name | IDE Version | File | Size | Downloads | Added |
---|---|---|---|---|---|
fastdcc 5.4 | 2009+UP3 | fastdcc2009v54.7z | 75.4 KB | 89 times | 2013-11-01 |
fastdcc 5.4 | 2010 | fastdcc2010v54.7z | 79.34 KB | 91 times | 2013-11-01 |
fastdcc 5.4 | XE | fastdccXEv54.7z | 81.36 KB | 136 times | 2013-11-01 |
fastdcc 5.4 | XE2+UP4+HF1 | fastdccXE2v54.7z | 104.53 KB | 149 times | 2013-11-01 |
fastdcc 5.4 | XE3+UP1 | fastdccXE3v54.7z | 116.06 KB | 136 times | 2013-11-01 |
fastdcc 5.4 | XE4 | fastdccXE4v54.7z | 107.91 KB | 145 times | 2013-11-01 |
fastdcc 5.4 | XE5 | fastdccXE5v54.7z | 109.16 KB | 305 times | 2013-11-01 |
Changed from 5.3 to 5.4
I just deleted over 700 “users” who registered to my blog. Most, I am sure, were just spam bots, I am sorry if some of you were real people.
Registering is now blocked as is commenting. I got tired of all the notification e-mails from WordPress. In over a year there was only ever two comments that were not spam. It’s just not worth the effort. If you want to communicate with me more directly, use my Google+ profile
Following up on my post on BitTorrent Sync here is some more information and use cases.
There is at least one alternative to BitTorrent Sync that is open source: Seafile is a cloud service. I have only read about it on their website but it looks interesting.
Now to the use case:
If you are like me you are storing lots of data on your smartphone, in particular passwords and other sensitive data. While it is convenient to have this data with you all the time there is always the danger of the phone being lost or stolen and – if you are paranoid enough – the data being stored on Google’s servers (or the servers of a different cloud service).
Of course there are many options to encrypt the data on your phone like KeePass etc. What I don’t like about these solutions is the fact that they encrypt everything, not just the sensitive parts. So if I just want to look up the URL of a website which I use so infrequently that I tend to forget it, this is rather cumbersome. Therefore I use plain text files and encrypt only the parts I deem sensitive (passwords etc.), using the txtCrypt app. Since there exist alternative implementations of the txtCrypt algorithm, including a Web App I can be sure to still get to the encrypted parts even if my phone is not available for decryption.
The other problem with the phone getting stolen is backup and accessing the backup without another phone. There are lots of note keeping apps that synchronize with cloud services (e.g. Google Keep, Evernote or Flick Note). I used all of them for a while to try finding the one that I like best. Unfortunately I didn’t feel comfortable in the knowledge that I have no control over how and where the data is stored, so I abandoned them for the text file approach. For the backup part I have started using the BitTorrent Sync app to sync to my desktop computer (which is backed up anyway). There is another advantage of this approach: You can add and edit files using a real keyboard and the text editor of your choice rather than the virtual keyboard on your phone.
Google’s new Glass platform is a very revolutionary Android device, but the question I really wanted to know is if I could develop for it with Delphi XE5. Turns out the answer is Yes.
There are actually two different options for developing Glassware: Mirror API and GDK.
The first is the Google Mirror API, which allows you to build services, called Glassware, that interact with Google Glass. It provides this functionality over a cloud-based API and does not require running code on Glass. This is accomplished through a REST and JSON based API. Thanks to the new TRESTClient components in Delphi XE5 this should be easy enough to do.
The GDK on the other hand is the avenue where you build an actual APK that runs on the Google Glass device itself. This gives you the most access to the device, its sensors and features. Turns out this is also easy enough to do with Delphi XE5.
The actual GDK builds on top of the Android SDK. You can develop apps to run on Glass with either the Android SDK or GDK, but the GDK is necessary to take advantage of some of the Glass specific features.
If you run SysCheck on Glass (which takes some effort) you discover it has an ARMv7 PRocessor rev 3 (v71) with Android OS Version 4.0.4 and NEON support. Those meet the main requirements for Delphi XE5 development. So I created a simple Hello World app and ran it.
This first screenshot shows Glass appearing in the Project Manager as a valid target (once the required USB drivers were installed, which was tricky for glass).
Here is a screenshot of the app running on Glass
I didn’t hide the status bar, which most Glassware does, and it does nothing other than serve the purpose of showing a Delphi XE5 app running on Google Glass. There were no special settings (other than the dark theme, which is a matter of taste) to make the app run on Glass. It just works.
And lastly a quick selfie of me and Glass, taken through glass.
I was hoping it would look more red than orange, but should have known Tangerine would be orange.
Rest assured, there will be more coverage of Delphi and Glass. We are just getting warmed up. This app was not using the GDK (which is still in Beta) but it is an actual Delphi app running on Glass. What an exciting day!
I just got back from Brazil and Costa Rica, which was great. Now I am headed out to different cities in North America (Yes, technical Costa Rica is in North America, but all these cities are north of Latin America). David I and Al Mannarino are also traveling across North America for a total of 27 cities. Here are my city stops:
Minneapolis – Meet and Eat
Wednesday, November 13, 2013 @ 12:00pm-2:00pm
Ruth’s Chris Steakhouse
920 2nd Avenue S #100, Minneapolis, MN
[Register]
St. Louis – Meet and Eat
Thursday, November 14, 2013 @ 12:00pm-2:00pm
Ruth’s Chris Steakhouse
315 Chestnut Street, St. Louis, MO
[Register]
Chicago – Hands on Workshop
Saturday, November 16, 2013 @ 9:30am-3:00pm
Hyatt Regency Woodfield – Schaumburg
1800 East Golf Road, Schaumburg, IL
[Register]
I’m planning to bring my Google Glass and show off Delphi XE5 running on Google Glass too.
In a Delphi application, the THintWindow class implements the small pop-up window that appears over a control at run time, when the control has its ShowHint property set to True (and has a value assigned to the Hint property).
The implementation of the THintWindow (at least what gets displayed by it, not how) is rather simple: it will display whatever string value is assigned for the Hint property of a control. If you want more control over what gets displayed by the hint window, and how, and when the hint window will popup – you can create your own version by extending the THintWindow class.
To use your own hint you would assign your own class to the global HintWindowClass variable at application start-up time, so that the new hint window type is used for hints. You can even fine tune the display of the hint window just before it pops-up using the OnHint and OnShowHint events of the TApplicationEvents.
That’s all nice and clear. But, what if the control you are using is Virtual Treeview which has its own version of the hint window implemented in TVirtualTreeHintWindow? What if you want to extend this by including some graphics along with the text that the hint window displays? Further, what if you need to have different hint values for every node displayed by the tree?
Of course, you are not working on a new application – all logic is already there, lots of methods and events already implemented.
The answers: here’s how to simply extend both the TVirtualTreeHintWindow and the TVirtualStringTree to add some node specific graphics to the hint window displaying node specific hints.
Here’s the actual real world feature I wanted to quickly have implemented: my application uses Virtual Treeview to present a folder structure containing PDF documents to the user – each node presents either a folder or a PDF file. Hints are node specific and for a file-type node some PDF values get displayed to the user (file name, PDF Title, PDF version, and alike). I wanted also to include a simple 1st page preview (as image) of the PDF file in the hint window.
Download Sample Project Source Code.
For the Virtual Treeview to display hints (node or control specific) the Hint property must be set to true. Next, there’s the HintMode property determining what the hint actually displays (single hint for control or node specific hint value and some more values). Also, there’s the HintAnimation property which determines the kind of animation when a hint is activated. Or, as those are implemented in the source code:
TVTHintMode = ( // show the hint of the control hmDefault, // show node specific hint string returned by the application hmHint, // same as hmHint but show the control's hint if no node is concerned hmHintAndDefault, // show the text of the node if it isn't already fully shown hmTooltip); // Determines the kind of animation when a hint is activated. THintAnimationType = ( // no animation at all, just display hint/tooltip hatNone, // fade in the hint/tooltip, like in Windows 2000 hatFade, // slide in the hint/tooltip, like in Windows 98 hatSlide, // use what the system is using (slide for Win9x, slide/fade for Win2K+, depends on settings) hatSystemDefault);
Before providing more details, here’s the record type each node stores internally (note: you need some basic knowledge on Virtual Treeview to follow what follows):
TTreeNodeData = record private fPreview : TJpegImage; function GetPreview: TJpegImage; public Name: string; RelativeName : string; IsFolder : boolean; property Preview : TJpegImage read GetPreview; end; PTreeNodeData = ^TTreeNodeData;
As stated, each node in my tree either presents a folder or a (PDF) file. Hence the record field names: Name is the full file/folder name; RelativeName is the path relative to the root directory selected; IsFolder stores if the node presents a folder or a file. Finally the Preview property will lazily get the graphics of the first page of the PDF file (more on that later below).
And here’s what is set in the form’s OnCreate:
tree.NodeDataSize := SizeOf(TTreeNodeData); tree.HintMode := hmHint; tree.ShowHint := true;
To have node specific hints you need to implement the OnGetHint event:
procedure TMainForm.treeGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); var data: PTreeNodeData; begin data := Sender.GetNodeData(Node); HintText := data.Name; //just display full name / file path end;
All set, now the question is how do I get some graphics also displayed by the hint window.
First step is to have my own version of the TVirtualTreeHintWindow class, of course by extending what’s already provided. If you’ve ever done some custom THintWindow implementation you know you need to override at least two methods: CalcHintRect and Paint. The CalcHintRect gets the dimensions of the hint window rectangle required to display the hint. Paint does the actual painting (of the hint text).
The second step (actually first) would be to tell to the Tree to use my own version of the TVirtualTreeHintWindow class.
And I hit the wall first time! There’s no public property or method I can call on Virtual Treeview to have it use my own version of TVirtualTreeHintWindow. There IS a method GetHintWindowClass and a comment next to it saying: “Returns the default hint window class used for the tree. Descendants can override it to use their own classes.”
Ah! I have to override the entire TVirtualStringTree (i.e. extend / make my own version) to have this. Me no like. I have it (the tree) in many forms in my application and I do not want to change all this. But, Delphi has a solution called “intercepting classes“.
So, I’ve intercepted the TVirtualStringTree, and have it as:
TVirtualStringTree = class(VirtualTrees.TVirtualStringTree) private fHintModeImage: boolean; procedure SetHintModeImage(const Value: boolean); public constructor Create(AOwner: TComponent); override; public function GetHintWindowClass: THintWindowClass; override; property HintModeImage : boolean read fHintModeImage write SetHintModeImage; end;
The newly added property HintModeImage is used to decide if the node hint should also display the image – will the tree use its own TVirtualTreeHintWindow class or my extended version.
Ok, back to extending the TVirtualTreeHintWindow class. Looking into the implementation (long live open source) I see that the protected Paint method (which I can override) is used only when HintAnimation property is “hatNone”, otherwise the class does all the rendering inside the private (cannot override) AnimationCallback method (which calls InternalPaint I also cannot override). Second wall, this time a harder one!
If I want to go cheap I must have no animation on hints – well, ok, I can leave with that (and the users of the application will have to).
Ok, so here’s the simpler part, implementation of my intercepted TVirtualStringTree:
constructor TVirtualStringTree.Create(AOwner: TComponent); begin fHintModeImage := false; inherited; end; function TVirtualStringTree.GetHintWindowClass: THintWindowClass; begin if HintModeImage then result := TVirtualTreeHintWindowEx else result := inherited; //use what tree uses end; procedure TVirtualStringTree.SetHintModeImage(const Value: boolean); begin fHintModeImage := Value; if fHintModeImage then HintAnimation := hatNone //so Paint procedure is called and can be overridden else HintAnimation := hatSystemDefault; //default end;
Finally, here’s how the implementation of my intercepted version of TVirtualTreeHintWindow looks:
function TVirtualTreeHintWindowEx.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: TCustomData): TRect; var r : TRect; hd : TVTHintData; jpg : TJpegImage; nodeData : PTreeNodeData; begin r := inherited; hd := PVTHintData(AData)^; if Assigned(hd.Tree) AND Assigned(hd.Node) AND (HintData.Tree is TVirtualStringTree) AND (TVirtualStringTree(HintData.Tree).HintModeImage) then begin nodeData := HintData.Tree.GetNodeData(hd.Node); jpg := nodeData.Preview; if Assigned(jpg) AND (NOT jpg.Empty) then begin r.Height := r.Height + jpg.Height + 4; if r.Width < jpg.Width + 4 then r.Width := jpg.Width + 4; end; end; result := r; end; procedure TVirtualTreeHintWindowEx.Paint; //called only if HintAnimation = hatNone var jpg : TJpegImage; nodeData : PTreeNodeData; begin InternalPaint(0, 0); if Assigned(HintData.Tree) AND Assigned(HintData.Node) AND (HintData.Tree is TVirtualStringTree) AND (TVirtualStringTree(HintData.Tree).HintModeImage) then begin nodeData := HintData.Tree.GetNodeData(HintData.Node); jpg := nodeData.Preview; if Assigned(jpg) AND (NOT jpg.Empty) then Canvas.Draw(2, -2 + Height - jpg.Height, jpg); end; end;
The CalcHintRect first calculates the size of the image (PDF first page preview if you remember), Paint than paints it to the hint window. A simple AND’d IF is used to ensure the tree is ok, the node is here, the data is here etc…
I guess you are asking yourself from the beginning: how do you get the preview of a page of a PDF file. In short: I’m using Debenu Quick PDF Library.
Without too many details about the Debenu Quick PDF Library (at least for now), here’s how easy is to get the image of a page of a PDF:
function TTreeNodeData.GetPreview: TJpegImage; var fh, pr : integer; ms : TMemoryStream; bmp : TBitmap; pdfFileName : string; begin if fPreview = nil then fPreview := TJpegImage.Create; if (NOT IsFolder) AND fPreview.Empty then begin pdfFileName := self.Name; //<a href="http://www.debenu.com/products/development/debenu-pdf-library/" target="_blank">http://www.debenu.com/products/development/debenu-pdf-library/</a> with TQuickPDF.Create do try fh := DAOpenFileReadOnly(pdfFileName, ''); if fh <> 0 then try pr := DAFindPage(fh, 1); if pr <> 0 then begin ms := TMemoryStream.Create; try DARenderPageToStream(fh, pr, 1, 24, ms); ms.Seek(0,0); fPreview.LoadFromStream(ms); finally ms.Free; end; end; finally DACloseFile(fh); end; finally Free; end; end; result := fPreview; end;
Note that my TTreeNodeData uses some advanced features like properties and methods in records. The Preview property is an instance of the TJpegImage. The Preview must be freed when no longer needed, and records cannot have destructors. So the question is when and where to free the image? Again, no problem, since the Tree handles record instances it exposes an event where you can free whatever object is assigned to a node when the node is destroyed, the OnFreeNode event:
procedure TMainForm.treeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var data: PTreeNodeData; begin data := Sender.GetNodeData(Node); if Assigned(data.fPreview) then data.fPreview.Free; Finalize(data^); end;
And that’s all folks. Some Delphi magic, some exploring of inner workings of controls you are using and the sky is the limit
Comments? More than welcome!