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.

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...