Wednesday, February 22, 2006

Posting data with TWebbrower

With a TWebbrowser component it is possible to post data to a webpage. Suppose you have an application with a webbrowser and your application requires a login, and the website also uses a login. The user should now login twice. And that is just to much!

You can however post data to the website with the Navigate method of the webbrowser component.
The declaration of the method is as follows:

procedure Navigate(const URL: WideString; var Flags: OleVariant;
var TargetFrameName: OleVariant;
var PostData: OleVariant); overload;

The last parameter PostData can be used to transfer the login information to the webpage, as if the user pressed the login button of the login form.

procedure LoginWithPostData(AUserName:String;
APassWord:String; LoginUrl:String; AWebBrowser:TWebBrowser);
var
varPostData, varHeader : OleVariant ;
x : variant;
postdata : string;
arPostdata : array of byte;
i,l: integer;
bch : byte;

begin
postdata := 'UserCode='+AUserName+'&PassWord='+APassWord;
SetLength(arPostdata, Length(PostData));
for i := 1 to Length(postdata) do begin
arPostdata[i-1] := Ord(postdata[i]);
end;
varPostData := arPostdata;
varHeader :=
'Content-Type: application/x-www-form-urlencoded\r\n';
AWebBrowser.Navigate(LoginUrl,EmptyParam,EmptyParam,
varPostdata, varHeader);
end;


Step 1: Create a string with the postdata
Step 2: Fill an array of byte with the string characters.
Step 3: Assign the array to an OleVariant.
Step 4: Set the appropriate encoding to a OleVariant (varHeader)
Step 5: Navigate the browser.

You should be logged in now!

You could of course also do it the other way around, log in the webbrowser and read the postdata from the BeforeNavigate event. (Just posted by your user and on its way to the webserver)
The disadvantage with this method is that you should parse the postdata string to get the username and you should somehow find out if the user was autorised by the webpage. One way to achieve it is to check the url in the NavigateComplete event of the browser to be the protected url (Page). If the protected page is loaded the user should be logged in and you can then login your application.
The first method, posting the data to the webserver from your application is however the best one.

Friday, February 17, 2006

Wednesday, February 08, 2006

Borland Announces Plan to Divest IDE Product Lines

Read the press release here.

In summary I read it like this:
Borland is seeking a buyer to create a separate company where all the IDE stuff related products will be placed. (Delphi, C#, C++ etc) This company will stay strong related to Borland who will focus on ALM and SDO.

David I has posted an open letter to the non-technical newsgroup, read it here.
There is also a blogpost here.

As far as I can see this could be a good thing for Delphi (BDS2006) although it is also quite shocking to begin with.
I only think that the name Borland should be for the IDE company, let the ALM company come up with a new name. Borland and Development Tools is said in one breath.

Tuesday, February 07, 2006

BDS2006, BDP and memo fields

Lately I encountered some strange problems using the Borland Data Provider (BDP) in a ASP.NET project. At first I thought I had solved it, but eventually (mostly because of project scope changes) it made me change from BDP to OleDB.

The project is a database-driven website for which I use BDP to connect to the database.

Why Borland DataProvider?

Borland DataProvider has some benefits compared to the standard .NET providers (SQL/OleDB):

  • BDP is database independent (Same components for SQL and local databases)
  • Connection pooling
  • Easy data remoting components

The database is used to provide the content of the website. At first I used a SQL Server database and found out that having two text fields (memo fields) in the SELECT clause causes the text fields to be truncated to 1024 chars. This is inconvient!
[update: Problem solved, see below]

Having only one text field in the SELECT works just fine! That is strange, isn't it? [No]

In SQL Server however I could of course change one of the Text fields to a varchar with a (max) length of 4000. Not the most elegant way, I know, but it is a rather small database only holding the website content. Problem solved.
Now, for other reasons, my customer wants to use an Access database instead. No problem! As said BDP components are database vendor independent!
Except, of course, that varchar fields in Access are limited to 255 chars, so I ended up with two truncated memo fields. :-(

The only solution left was to change from BDP to OleDB. This switch was easy because the BDP components are similar to the standard .NET providers.
My project now contains two database technologies, BDP and OleDB. All works fine but I can not call it elegant. (I keep the BDP, because there might be a switch back to SQL Server in the future.)

I only can imagine that this is a bug in the Borland Data Provider so I added a report to quality central. You can find it under QC number #24314

Update 8-2-2006:
Well I imagined it wrong. It seemed to be a property of the BdpConnection called BlobSize, which is default set to 1024! Well QC report withdrawn!
Wow this one was really hard to find! :-)

Wednesday, February 01, 2006

Old papers, still up-to-date

In the 'old' days I have made a few tutorials about Delphi(4/5) for The Software Developer Pages. These tutorials and papers are still available behind my company's website. They are available in english and dutch, and not updated for ages, but some papers are still up-to-date today. The most papers are at beginner-level because, guess what, I was those days a beginner.
There is even Delphi 5 code available for download which should be working easily in BDS2006.

The main page can be found here. (Note I do not update this anymore, so it looks a bit odd now)
Some still up-to-date papers are:

I keep a permanent link to this papers on this blog.

Friday, January 27, 2006

BDS2006 small features, great impact

It is always amazing how small things can have such a great impact on your daily work. The new features in the BDS2006 editor like live templates are obviouos because you can see it immediately while working in the editor. 'Small' improvements and features are discovered along the path.

Lately I noticed a tiny red bug (in dutch we call it a lieveheersbeestje) on a tab in the editor after debugging an application.

It seems that BDS2006 opens units, necessary for debugging, on the fly and implicit closes them when the debug session ends. (This is an editor option) If you stop debugging in such a unit Delphi keeps that unit open. Ain't that great?

I remember debugging a C# project in Visual Studio 2003 where I ended up with an endless list of tabs which is very annoying in my opinion. In VS you have the tabs for design and code besides each other on top of the editor. BDS2006 (and previous versions) have an extra tab at the bottom of the editor for switching between design and code. So in BDS2006 you always have the half amount of tabs in the top tab control compared with VS2003.

So these small features in BDS2006 are great! It gets even better if you popup the context menu on the tab. If you don't want BDS2006 to close the debugged units implicit(an editor option) you can close them by yourself using 'Close all pages opened while debugging' option. Hack you can even close all pages except the one that is active.

Small things, great stuff!

Tuesday, January 17, 2006

ECO Adventures: Inheritance

Inheritance is one of the five pilars of Object Oriented Programming. In ECO inheritance is, I can tell you now, a piece of cake.
Consider this 'real world' model:


Developer and SalesMan inherit the behavior from Person. Developer and SalesMan are specializations of Person. Implementing this model in a VCL Win32 application using TDataSet would consider a lot of work. For instance the, in fact one-on-one relation must be maintained in the database. A person is either a Developer or a SalesMan, a person can not be both. (if you don't agree you should read this blogpost :-) )
Anyway implementing this becomes, even in Delphi with TDataSet, more complex. In ECO it is a very straight forward process.

Create the windows (ECO) application
Drop three datagrids(dgPerson, dgDeveloper, dgSalesMan) on the form and three ExpressionHandles (ehPerson, ehDeveloper, ehSalesMan) And oh, don't forget to compile first!

Setting the ExpressionHandles
ehPerson:
Name->'ehPerson'
Roothandle->rhRoot (Don't forget to set the Roothandles EcoSpaceType property!)
Expression->Person.AllInstances (Use the OCL Editor here)

ehDeveloper:
Name->'ehDeveloper'
Roothandle->rhRoot
Expression->Developer.AllInstances

ehSalesMan:
Name->'ehSalesMan'
Roothandle->rhRoot
Expression->SalesMan.AllInstances

Setting the datagrids
dgPerson:
DataSource->ehPerson

dgDeveloper:
DataSource->ehDeveloper

dgSalesMan:
DataSource->ehSalesMan

To make things complete drop two buttons for the Developer and SalesMan grid. Connect the roothandle property to ehDeveloper and ehSalesMan and set the for both buttons the property ECOListAction to Add.

Well this is pretty much it! You can see that the grids have all the appropiate attributes for their classes. By running the application we can test it:

Notice that adding a developer or salesman automatic means adding a person. So again the model does all the hard work in the background.
While still scratching the surface of ECO it becomes clear that ECO is very powerfull framework, taking a lot of the work load. Making this little application with TDataSets would be harder (although it can be done). For instance after inserting the Developer you would have to code to get a person in the person table.

Guess what: We did not code at all!

Monday, January 16, 2006

Refactor all the way

After using BDS 2006 for three weeks now I must say it is a real piece of art. I can not think of one reason to go back to Delphi 7. For me the most valuable new features are the improved and extended refactorings. It takes some time to get used, using them, old habbits just don't disappear that easy :-) I guess.

What I always found a bit annoying in Delphi coding was the fact that changing the parameters of an existing method, meant a lot code cruising. OK, you can't have it all but figure this:

In Delphi 7, to change a parameter of a method you should do something similar like this:

1. Change the parameter in the implementation section (iow the method)
2. Surf (Ctrl-Click) to the interface section to change the decleration
3. Ctrl + Arrow Down to go back to the implementation

Delphi 2006, and in specific Together, dramatically improved things. With refactoring you can now change the parameterlist of a method, and Together will take care of changing the declaration (or vica versa)!

The 'Change Parameters' refactor dialog:


With this dialog you can add or alter parameters in a very easy way. Other 'My favourite' refactorings are:

  • Extract method (Existed already in D2005)
  • Find unit (Helps you finding the unit for the uses clause)
  • Declare variable

The new and improved refactorings in BDS 2006 boost productivity, no doubt about that. This and the other editor improvements, like Live templates, made upgrading to BDS2006 worthwhile.

Monday, January 09, 2006

Fooling around with TWebbrowser

For a project I needed to edit a HTML page within a Delphi Win32 application. Delphi has a TWebbrowser component which appeared to be suitable for this situation.
TWebbrowser in fact is a wrapper over Microsoft's Shell Doc Object and Control library (SHDOCVW.DLL) and it brings webbrowser functionality to your application. With a TWebbrowser it is easy to navigate the web and files. There are a lot resources to find on the internet, here I share some of my experiences.

Using TWebbrowser for editing
As said before I needed to edit a HTML webpage. You can get the Document (from the loaded webpage) with MSHTML, a library providing WYSIWYG editing for Internet Explorer and thus TWebbrowser. This HTMLDocument provides access to all the elements of a webpage, and allows you to edit the page visually.
After adding MSHTML to your uses clause you can get the document as follows:

Getting the document:
HTMLDocument2Ifc := (MyWebbrowser.Document as IHTMLDocument2);

Note that the webpage must be completed loaded otherwise the object will be nil.

With a IHTMLDocument2 interface object we can edit the webpage. Now for this project I needed to place links absolute on the page aligned with some body background. But the first thing we need to do is setting the document in edit mode.

Setting the document in edit mode:
HTMLDocument2Ifc.DesignMode := 'On'; //Use 'Off' to switch desingmode off

Setting the body background:
(HTMLDocument2Ifc.body as IHTMLBodyElement).background := AFileName;
HTMLDocument2Ifc.body.style.backgroundRepeat :='no-repeat';

Setting the document for absolute positioning (2-D positioning):
HTMLDocument2Ifc.execCommand('2D-Position', false,true);


Now we can drag the links (wrapped by a span) around on the webpage.

With the execCommand method you can easily do a lot of editing on selected text in the document. To name a few:


HTMLDocument2Ifc.execCommand('Bold', false,0);
HTMLDocument2Ifc.execCommand('Italic', false,0);

HTMLDocument2Ifc.execCommand('FontSize', false, 4); //Set the font size of selected text
HTMLDocument2Ifc.execCommand('InsertImage', true,0); //Use default insert image dialog


There is a lot more, check microsoft MSHTML site for everything.

Another feature of the HTMLDocument2 is that you can get collections of images, links and styles of the webpage. For example you could get all the picture sources as follows:

for i := 0 to HTMLDocument2Ifc.images.length -1 do
begin

Item := HTMLDocument2Ifc.images.item(i, null) as Ihtmlelement;
lbItems.AddItem(Item.getAttribute('src',0) + ' [A Picture]', nil);
end;


Well there is a lot more to explore, but it is easier then you might think at forehand. Here are some links with more resources, to fool around with, on TWebbrowser:

Microsoft MSHTML site
Webbrowser to the max (about.delphi.com)
Brian Cryer TWebbrowser page
MSHTML Editier modus German site with examples.
WebSVN Code examples.


Tuesday, January 03, 2006

ECO Adventures: Master-Detail

I finally have the time to play with ECO and learn about what it is.
In this episode of 'The ECO adventures' I create a Master-Detail model.

In VCL it is very easy to create a master-detail relationship between two datasets (TDataSets) using the mastersource property. In ADO.NET you can make such relations within the .net dataset, but implementing them is a bit different compared with the TDataSet.
In ECO, it is again relative easy to implement.

Making the model
Take this model, where we have Customers and Projects. This two objects has a relation, where a customer has zero or more projects, and a project belongs, of course, to one customer.
In ECO we can model it like this:



Take an extra look at the /Project attribuut. This is a derived attribuut, in this case showing the projectnumber (an integer) and the description in one field.
This can be done by OCL. The expression for this one is:

self.Number.asString + '-' + self.description

You can easily create this with the OCL expression editor.

I have created this model in a ECO Package, so that it can be used in multiple client applications. (Winform and ASP.NET)

Making the Winform Application
Just add a ECO Winform Application to your projectgroup with the ECO package and make a project reference to the ECO dll. In this case it is the MasterDetail.dll.
After setting the reference, you must select the package in the ECO space of the Winform application, to let the application know that it can use the package.

After that you must first recompile for further designtime support.

Now we can create the GUI. The form has standard a few ECO components, with among others the rhRoot, wich connects the form to the ECO space. (The reference to the model)
Select the ECO space in the ECOSpaceType property of the rhRoot.

Connecting to the object instances of our classes (Customers and Projects) we use ExpressionHandles, which are connected to the model through the roothandle (rhRoot).

To get the project details, we have to use a CurrencyManagerHandle, which has the grid (in general a GUI control) with Customers as the BindingContext. Through this handle we connect to projects of a specific Customer. (This is like the CurrencyManager in ADO.NET)

So let's make this GUI:





Create a new expressionhandler and call this ehCustomers.
Set properties as below:
  • Roothandle -> rhRoot
  • Expression -> Customer.AllInstances (Use the OCL editor for this by invoking it with the ... button)

Set the property DataSource of the customer grid to ehCustomers. Notice that the grid shows the column name already!
ECO has some strong listactions build in to invoke operations directly on your objects. Set the property ECOListAction of the button right from the grid to 'Add'. And the Roothandle to ehCustomers.

Run the application.

OK this works. So far pretty easy, isn't it? Well now we want to see the projects of a specific customer in the other grid.
Here we need the CurrencyManagerHandle. Drop a CurrencyManagerhandle on the form and set the properties as follows:

  • Name -> cmCustomer
  • RootHandle -> ehCustomers
  • BindingContext -> CustomerDataGrid

The currencymanagerhandle will select a single instance of a customer (iow the selected customer in the grid).

To get the projects we need to drop another Expressionhandle, with the following properties set:

  • Name -> ehProjects
  • RootHandle -> cmCustomer (yes the CurrencyManagerHandler...)
  • Expression -> self.Projects (To select in the OCL editor through the Roles node)

Connect the projectgrid to ehProjects and assign the button for the Add list action.

Run the application.

Well this was pretty much it. Set the property Autoform on the grids to true and you already have a complete working application.

Conclusion:
ECO is a new way of programming (to me it is) .The way to use it is a little different compared to the database-driven approach although the main concept is the same. Keeping the business rules (like the relation) in the model is a strong benefit for the ECO approach. This was 'my first ECO application', and it was not all that hard. One thing to remember is to Compile your application often, this is needed for the designtime support I guess, otherwise you will sometime s look for property values you need which will not be there.

This ECO adventure will be continued...

Saturday, December 24, 2005

BDS 2006 in the works...

Well I installed BDS2006 lately and found some time to work with it. Here are my 'first' impressions.

  • Installation went smooth, taking about 25 minutes.
  • Converting D7 win32 applications went easy, only thing I had to change was the fact that the SQL property of a TADOQuery is now of type TWideStrings instead of TStrings. So I had to change on three location code like this : MyAdoQuery.SQL := AStringList to MyAdoQuery.SQL.Text := AStringList.Text. No problem what so ever.
  • Converting an Delphi 8 ASP.NET application was a bit confusing at first, because Delphi didn't see it as a ASP.NET application. Well it was my own fault, I had not all the files in my version control system included, copying it all from another PC worked well. As posted in an early entry I did have a few problems connecting to a SQL Server database with BDP in my ASP.NET application. The problem was that connecting to the database timed out. After struggling around with it for a while I found out that the problem was in the connection string. Where it says hostname I had ' localhost' changing this to '(local) or ' .' solved the problem. I still can not understand what the problem is with localhost. It could be a IIS problem, a SQL Server problem or a Delphi 2006 problem. Anyone...?
  • BDS2006 start up speed is fine. Especially starting up one personality is very fast, however don't try to load a project type from another one. :-)
  • Coding is fine. Live templates are cool, I had to get used to it though. Together integration is marvelous, ECO is even better!

Well time to pack up my old Delphi 7 and Delphi 8 and move all my projects over to BDS 2006.

Monday, December 19, 2005

I have it :-)

A few days ago BDS 2006 arrived! :-)
Because I'm rebuilding my house at this moment I had to find my PC between the building stuff (and dust) to install it. (My laptop has 256 Mb, I don't think it is a good idea to install it on that, perhaps I will try this later.)

Installation on my PIV 2,4 GHz with 512 Mb went smooth and took about 25 minutes.
Played a little and this beast is really fast and stable.
I got an error running an Delphi 8 ASP.NET application on my connections, somehow the 'old' connection components generated some error in the BdpConnectionStrings.xml file.
I remember such a problem during a Delphi 8 update, but I really don't have the time to investigate it now. Anyone reading this familiair with this problem? Any suggestion is much appreciated. By the way new connections are no problem at all.
(Maybe it is better to uninstall Delphi 8 first....)

The livetemplates are very cool and easy to use.
Well back to building, painting and other stuff, one thing is sure rebuilding your house during a Delphi release is no good idea. :-s

Thursday, December 15, 2005

Delphi 2006, editor shortcuts

Adam Markowitz has listed all the 'common used' short cuts in Delphi 2006.

I sure don't know (or use) them all, yet.

View the list here.

Wednesday, December 14, 2005

Live templates video

While waiting for my Delphi to arrive (back ordered next week :( ) Daniel R Wolf has a really great video on templates. (and more)

In the #3 video he shows how easy it is to make your own templates. These templates are really 'super man' food!

Watch them all here.

Tuesday, December 06, 2005

BDS2006 video's

While I'm still waiting for BDS2006 to arrive on my doorstep, there is a lot of information about BDS2006 from lucky ones who already got it!

A great introduction video (and more to come according the page) has been made by Daniel R. Wolf from Delphi-Praxis. The first video shows the VCL designer improvements and the live templates in the editor. Even if you don't speak German it is a great video. Super!

A lot information can be gained from all the blogs out there. My primary source is
http://www.delphifeeds.com and of course the Borland blogs.

It seems that BDS2006 really is a blast! :-)

And the waiting continues....... :(

Updated:
Looks like BDS2006 hits The Netherlands now. My supplier changed the tag 'Expected' to 'New!' yesterday 5-12-2006. (Santa Claus day to be specific :-) )

Tuesday, November 29, 2005

Delphi 2006 launch in Amsterdam

Today was the Delphi 2006 launch in Amsterdam, the Netherlands. The event was attended by about 200- 300 developers. (This is a wild guess...I did not count them.)

First David Intersimone gave an introduction to the new Delphi, the history and the future. He showed and discussed the Delphi roadmap.
Cary Jensen gave an overview of the improved IDE, showing the new productivity features. To name a few:
  • New refactorings
  • Live templates
  • Block completion
  • And more, much more...
  • ....

Especially the possibility to build and share your own templates is very nice.

After that Jason Vokes gave a small introduction of the ALM stuff (Starteam and CaliberRM) and an introduction to the C++ personality. A nice, C++ feature only, is Codeguard, which works in (debug mode) runtime to track bugs which are not spotted by the compiler. Looks like a great feature to me for Delphi. (in the future, that is)

After the break Jeroen Pluimers showed all the Together stuff. Really Live Source. The most of this seems to exist in the Enterprise and Architect SKU. This is very cool stuff, and I'm beginning to hang over to the Enterprise SKU already :-). But this was only the beginning....

Then it was time for Delphi's Golden Egg: ECO III.
Bob Swart (alias Dr Bob) gave an impressive ECO demo. He made an application in 3/4 of a hour without a single line of code. That means without a single line of Delphi or C# code.
He designed an UML Package, added classes with attributes, derived attributes and operations which he then used in a Delphi for .NET winforms application. All necessary coding was done in the Object Constrained Language (OCL) with small expression and statements. He also added a 'state machine' diagram to his model, using guards and..., well forgive me there was so much, but it looked relative easy to implement. He showed what the real power of ECO is: Give you the chance to focus on the business needs of the application. ECO takes care of all the underlying stuff. (like persistence mapping etc.)
Another great feature of ECO is the possibility to reverse engineer an existing database. Well Bob showed it in about, euh... 5 minuts. Sweet!
Jason Vokes had to drag Bob from the stage, because otherwise we still would be there. :-)

So what did we learn?

  • Delphi 2006 has lots of new productivity features for Win32, .NET (Delphi/C++/C#)
  • Delphi 2006 integrates Starteam and Caliber RM (Enterprise and Architect SKU)
  • Delphi 2006 Together integration is mature now
  • Delphi 2006 ECO III is the future of Software Development

For a few weeks I have been dubbing between the Pro and Enterprise edition. But now I now I want to use Together and ECO III so I will definitly go for the Enterprise edition.

It was a great afternoon......


Wednesday, November 23, 2005

Var injection and code completion

One of the great new things of Delphi 2006 is Var injection. It allows you to declare a variable in the middle of your code while the IDE takes care of placing it in the var section of your procedure. (At Nick's delphi blog post you can see how it actually works.)

No doubt, this kind of tricks boost your productivity!

Thinking it over, one of the things that, sometimes annoys me in Delphi coding is the fact that the procedure head in the initialization section of the unit must be the same as the procedure decleration itself. In fact this is no problem, but is has to be maintained during changes in, for example the parameters of the procedure.
For new procedures Code completion takes care of this when you create either the initialize or the procedure itself.

For example typing this in the initialization section of your unit:

procedure MyProcedure;

Clicking Control+SHIFT+C makes the procedure itself:

procedure TMyForm.MyProcedure;
begin

end;

This is great!, however adding an additional parameter in code (after rethinking the procedure) forces you to change the other manually. And that is in big units a lot of code cruising.

Would it be a good idea to use code completion also on existing procedures, so that for example editing the above procedure like this:

procedure MyProcedure(IForgotAParameter : Boolean);
begin
//Do some stuff
end;

....clicking Control+SHIFT+C updates the initialization section and vica versa.

Maybe the together support in Delphi2006 makes this easier?
Don't know, have to wait a little longer.........by the way 29 november 2005, Dutch Delphi 2006 launch in Hoofdorp. For more information click here.

Thursday, November 17, 2005

AJAX

Ajax is a new technology (in fact a combination of 'old' technology's) to drive your website. (I always thought it was our famous dutch football team from Amsterdam)
Ajax is hot(or hype). But what is it?

Ajax stands for Asynchronous Javascript And XML, it combines XML, HTML, DOM, Javascript and XMLHTTP. Bottom line is that it can solve the problem of many postbacks to your server by allowing you to load only parts of the webpage in the browser via XML.

For a good introduction and (.NET) example you better check out this dotnetbips article.
More on the technology can be found in this article.
Marco Cantu gave a BOF session on Ajax and Delphi at the BorCon, the slides can be found here.

Certainly will give this a try one day.

Thursday, November 10, 2005

DevCon papers, code and slides

The papers/code and slides from the DevCon sessions are available for download at :

http://bdn.borland.com/devcon05/delphi

Note that not all papers are submitted for download yet, probably because of the fact that DevCon has not ended yet.

Update:
Watch DevCon (or is it BorCon!?) keynote on BDN here.
Containing:

  • Opening video
  • Conference opening by David I
  • SDO by Rick Jackson
  • Tod Nielsen, the new CEO

Great stuff, must attend next year..... :-)

Wednesday, November 02, 2005

Incremental search.....supprise

Yesterday I was reading on the coding horror blog a rant about searching document files with Ctrl+F.
It said that Visual Studio has incremental search(Ctrl+I), which after I tested it is very usefull. I thought it is (was) a pity that Delphi does not (didn't) have incremental searching.

Today I read a comment on Nick Hodges blog entry Firefox my Delphi that Delphi has incremental searching from at least version 5!
Just click CTRL+E and it works.......

I must have missed something all this years, or this is one of the most secret shortcuts outthere. :-)

Use an image as your UIBarButtonItem

Using an image as your UIBarButtonItem in your navigationcontroller bar can only be achieved by using a common UIButton as the BarButtonItem...