Saturday, August 28, 2004

I'm back

... one step at a time. I've just landed at home after a holiday week at Lanzarote, and after reviewing some 300+ emails I'm ready to continue.

The planning includes to use this week (I'm still on holiday) to work for my new RaC customer: the upgrading of an old project to .NET that I've already posted. I've been able to start it at Lanzarote (yes, I'm a workaholic, so what?) but I'll have to step on the gas if I want to have it finished by September 15. It's almost a sure thing that I'll need more time than that, as usual, but this client seems understanding and not in a hurry.

Some pictures:
Playa Blanca, Lanzarote

The wonderful Playa Blanca (White Beach), at Lanzarote. Someday I'll come back, for sure. And in better company, that's for sure too.

Return code 0

This is me, enjoying (I'm not exactly thrilled by alcohol) a Tequila Sunrise.

Tuesday, August 10, 2004

Cheated

Oh, yeah. My worst fears have come true and that sucker Bryan (my RaC customer gets away and is not going to pay me the pittance of $250 for a complete, full web application he's got; and the net result is that he gets the complete package for a lousy sum of $75. Of course, I only had left the negative rating I've endorsed him on RaC's rating system, so next coders working for him know what to expect from this low-life no-paying scum. Let me copypaste, 'cause I don't wanna keep thinking about this. This is the rating I've posted for him on RaC which sort of comprises the whole story:


This buyer has, quite simply, deceived me. My initial bid for him was $150, but he told me it was too high. I told him that I really wanted to do the job and that I was willing to make a bid of $75, but that he was going to give me an aditional $75 bonus when the web application was up, running and giving him some money. My fatal mistake was to propose this via a MSN chat, instead of Rent a Coder's bidding system.
After that, he made a lot of modifications to the interface design, database design, and what the application can do: from a simple candle selling website it became a full-fledged application with email sending capability, rich text editing, users handling, database and content manipulation and so on.
After all that modifications were done or in the works (not before making it, I'm that dumb) I asked him for an aditional $100, to make the total $250. He didn't reply anything, so I thought it was okay with him. I finished the application, uploaded and set it on his server, gave him the source code and helped him with a configuration problem on his computer. And then I waited for him to accept the work as 100% complete, to no avail. I waited for a month.
On another previous project, this guy put me a '1' rating because he couldn't contact me for a week. In this very project, this guy started an arbitration because I told him that I was moving to another country because of work and maybe it was impossible for me to finish it, after all it was only 98% completed. And he put this in arbitration a whole day after I told him the news. Really patient.
And after a month of waiting for him to accept the project (and after seeing him evade me on MSN, and knowing he was logging to RaC and attending other bids except mine), I can't stand it anymore and I put it on arbitration. His response? to accept the work as 100% complete and pay me... my initial bid of $75. When I remind him of our arrangement, he doesn't even take the time to reply me. So this guy now has a full-fledged, complete and working web application for the money I spent in cigarettes last week.
Yes, it's my fault and I've learned my lesson. Learn from my experience, guys, and never, ever make an arrangement with any customer (it doesn't matter how well you think you know them) outside RaC's site. If you do and things go wrong, it's their word against yours, and RaC's facilitators and arbitrators cannot do anything about it. It's that simple.


Son of a bitch.

By the way, excuse my french, folks; but I'm really, really angry. It won't happen again.

Monday, August 09, 2004

Towards a new paradigm?

Today I've been grabbed by my technical director and I've had a meeting with him, like that, very early on a Monday morning and without previous notice.

The thing is that he hasn't see me working before (I've always been working on our client's offices), but he says he likes my working style, my way of investigating and developing, that I'm proactive, which comes to mean that I work like a mule, but saying it nicely. And I guess that's what firms want nowadays: a guy eager to work on working hours, out of working hours, on weekends, even slept. Jeez. Proactive.

The thing is that what I've been offered it's not bad: I'm out of the rooster of programmers avaliable to work on client's offices and I begin to be part of the in-house development team for internal and external projects, whithout leaving the office.

Doing what? Well, if there's some new .NET project, I'll do that. If there isn't (and that's the trend now, trend that I simply don't understand), I have to migrate to Java. Yuck.

Right now I'm only thinking on my future holidays (next friday, here I come!) and by September, when I'm back, I'll start again being a junior programmer, learning Java all by myself. No way they'll pay me some classes, no, it's cheaper (for them) that I'm the one doing the study via internet tutorials, practices, books (that I have to buy from my own money, of course) and banging my head against my desk in frustation every once in a while. Spanish version of IT learning. Nice, uh?

And I better learn quick, because I'm already enrolled in a team which has to develop an 8-month Java application, using a lot of things that right now sound like Chinese babbling to me.

I'll try to continue this blog focus on .NET. But don't be frightened if every once in a while I start talking crap like packages instead of namespaces, being unable of multiple inheritance, the complete exercise in frustation that is trying to debug anything on Eclipse, and so on.

Oh, my.

Friday, August 06, 2004

VS 2005 Express Betas

Here you can download the Beta Express versions of the several languages of next edition's Visual Studio, .NET 2005. According to Alex Yakhnin on his blog, Express IDEs could be completely free. That would be a move which could do Microsoft a lot of credit,... and give away a lot of reasons from a lot of big-mouths.

Hangover

Well, today has been an interesting day at work. On one hand, although I still have a little hangover because of yesterday's working excesses, I've discovered something interesting and I've used a tool that until now I didn't have the opportunity (or the need) to use. Let me explain.

The .NET CF program that our client wants requires that some functions are done after rotating the desktop: being a mobile application, some guy more intelligent than me thought during design time that it would be nice to be able to rotate the desktop so some screens had a different, sleeker design. Of course, doing this with a 21'' screen is complicated, but with a PDA is done with a simple wrist turn. The thing is that the manufacturer of our chosen PDAs (Gotive) has kindly sent us (and it's the least they could do, taking into account the price of each of the machines and the amount we've bought) their propietary SDK, a single DLL file with a CHM help file.

Taking a look at the help file I realize that the DLL is little else that a wrapper for the API functions of Windows CE. A quite complete wrapper, because it includes functions to handle screen rotation, screen backlight, bar-code reading with the integrated reader, and so on. Of all those functions, I only wanted to use the one that changes the screen rotation and the one that returns the current screen rotation angle. How could I call only those functions and forget the rest of the wrapper functions? The answer: ILDASM.

Microsoft's ILDASM is included with VS .NET 2003 (although I believe it was included also in the first version), and allows us to de-compile an .EXE, .DLL, .OBJ or .LIB file created with any .NET language. Not so fast, kid. This is not going to give you the source code of anything. What it does is extracting from a compiled file the intermediate language from Microsoft, or MSIL, and display it on screen or to a file.

Let's do an example: this is an embarrassingly simple piece of code, which just writes on screen a "Hello, World!" string 5 times:



using System;
namespace ILDASM_Test
{
class HiBoring
{
[STAThread]
static void Main(string[] args)
{
for(int i=0; i<5; i++)
{
Console.Write("Hello, world!!\n");
}
Console.Write("Press any key to finish\n");
Console.ReadLine();
}
}
}


We build the solution for obtaining an .EXE file, in this case; and then we open the .NET console. We head for the folder where the .EXE resides and type ildasm <file_name.exe> where file_name should be the name of our compiled code. And we get the following window:








On it we can see how from an .EXE we have a namespace called ILDASM_Test, which contains a class called HiBoring, with a Main() method which is the one that interests us. If we double-click on the Main() method we get a window with the following code flush:



.method private hidebysig static void Main(string[] args)
cil managed
{
.entrypoint
.custom instance void
[mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 39 (0x27)
.maxstack 2
.locals init ([0] int32 i)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_0012
IL_0004: ldstr "Hello, world!!\n"
IL_0009: call void [mscorlib]System.Console::Write(string)
IL_000e: ldloc.0
IL_000f: ldc.i4.1
IL_0010: add
IL_0011: stloc.0
IL_0012: ldloc.0
IL_0013: ldc.i4.5
IL_0014: blt.s IL_0004
IL_0016: ldstr "Press any key to finish\n"
IL_001b: call void [mscorlib]System.Console::Write(string)
IL_0020: call string [mscorlib]System.Console::ReadLine()
IL_0025: pop
IL_0026: ret
} // end of method HiBoring::Main


As you can see is no crystal-clear code but you can find out interesting things.

Well, after this mini-class about Microsoft de-compiler, let's get on with it. I opened the .DLL file containing the SDK for our PDA (remember?) and I double-clicked on the method SetRotation() 'cause my intuition ;-) told me that that method may have something to do with the ability I want to invoke, which is rotating the desktop. And I find out on the MSIL code an obvious P/Invoke API calling to a function located in the DLL lcdapi.dll. API which, by the way, is not documented and displays no Google results as of today. Luckily, its signature is quite simple, and the needed P/Invoke is like this:



[DllImport("lcdapi.dll")]
static extern bool GLCDSetRotation(int Degrees);


Very simple. And voilá, thanks to this I've saved 52 Kbs of unnecessary DLL file, extracting just the function I need via the de-compiling of a manufacturer's DLL file which is just a wrapper. I've had some curious problems with the function (and which function is problem free on .NET CF?), but I'll talk about that tomorrow, when it's solved.

Important note: this post, and the rest containing source code, look so pretty thanks to Jean-Claude Manoli and his amazing on-line tool for C# code formatting, the c# code format. To each his due.

Thursday, August 05, 2004

Back in business

After some days with no posting, I'm back in business.

The PDA project is almost (90%) finished, it's already working on the
client and there are only some finishing touches pending. It's been
hard. My schedule report this month is going to be funny, to
say the very least: last Monday I worked for thirteen and a half
hours
, and on Tuesday the whole enchilada, 24 hours.
In real time too, no ellipses; just like
in the TV.

Of course, and as a compensation, I didn't work yesterday:
after all I believe I wouldn't be of much use snoring loudly over my
keyboard, or walking aimlessly like a zombie.

Anyway, I can now face this project with a much more easy pace: the client
has already some soft (and hard, we also provide them with the
combat PDAs); and
they can begin testing and working with that. By the way, I've ended
up feeling a certain love for the damned things. They're rugged, they
have a big screen and their external keys can be very useful. But
above all that, I feel really grateful for their OS: Windows CE
.NET, which means they have the Compact Framework already incorporated
on the OS, which means installations XCopy are allowed: you
simply copy the executable file (along any non-CF DLL needed) on a
destination folder on the PDA file system and done.

I do keep a thorn on my side, though: the login feature. After
two whole frustrating weeks dedicated to it, without visible results;
in the end the client comes telling us it's a not-so-vital
feature because, after all, every user is going to have his very own
personal PDA, which means everone of them could store its personal
information on the registry, along with login information and
everything else. If I'd known this, I could have had more time for the
rest of the features and it would have been a much more complete
application. Apart from the failed login code, the more remarkable
features of the applications are the P/Invoke routines for changing
the screen orientation of the PDA, the code for loading application
parameters from a XML file, and the buttons loaded: I had to create
a custom button for this, because CF's current version don't allows
color, font or any change to a button control in run-time. href="http://www.paulyao.com">Mr. Paul Yao has told me that CF's
next version will bring many upgraded features, among them a total
control face-lift and an upgrading of the P/Invoke procedures.

And it was really necessary, this last one. P/Invoke, or Platform
Invoke
, is the name given to the techniques used for handling
not managed code; or in other words calling the APIs. The same
thing we've been doing a lot in Visual Basic 6, but more complicated.

Generally, when you code a Windows desktop application (now called a
WinForms application), you'll only use APIs for really strange and
esoteric functions. In the other hand, with Compact Framework
applications we'll soon discover that API invoking is needed to make
almost everything. For example, if we need that our application to run
others or processes: API. If we want our application to execute
always-on-top, that is always the first one in the z-order and
not to be overlapped by any other application: API. If we want to
destroy or end another application: API. And a long and painful list
of much more examples.

It has some logic, if you stop to think about it. There are a lot of
features from the normal Framework that are not included on the
Compact Framework for a very simple reason: space. You cannot install
the full-blown Framework on the tiny memory space a normal PDA has.
Thus, programming features that are really easy to code with the
Framework turns out to be a very complicated task with the Compact
Framework, just because those Framework functions are not included.

So it seems logical to think that .NET CF programmers are going to make a
lot of API calling.

So it seems logical to think that .NET CF programmers will be using
P/Invoke much more that normal .NET programmers.

So it seems logical to port the whole P/Invoke classes from .NET
Framework to the CF, or even upgrading them for the CF. After all,
they're much more needed.

No way.

They are also diminished: they lack methods, structures and type
conversions. And I frankly can't understand it: I don't believe they
were going to eat up that much space that its presence would
make the final Compact Framework would be intolerable for PDAs. Its
another of those difficult to understand design decisions from
Microsoft. But anyway, I've been told by Paul Yao (and he's in the
backstage of all this) that P/Invoking capabilities are going
to be complete (or, at least, much more improved) on the next version
of Visual Studio .NET, 2005.

We'll see what the boys and girls at Microsoft understand for much
improved
.