Monday, December 29, 2008

WPF-Fading Background

Well, the project I'm working on has a few pretties in it; and it has a few tabs that will appear based upon click events on other tabs. Typically, these magically appearing tabs are generated in the primary working area of the application, yet in one scenario, the appearing tab needed to be in the secondary data (for lack of a better term) area of the application.

Since, this is effectively non-standard behavior from the application, I wanted to provide a nice visual cue on this happening. I wanted the background to appear one color, and then slowly fade to its standard color.

That would be a nice, visual cue about this new window opening. So, I went forth and tried to do it. My first attempt involved using a brush, and then just changing the opacity until it was transparent. That was utter fail. So, realizing that I wasn't as clever as I had hoped, I turned to my old friend Google.

Where I discovered a bit about Storyboards and ColorAnimation objects. Now, I'm not overtly familiar with WPF, and in fact there's quite a bit that I just don't know yet about it; but I was shocked at how easily this worked.

What I did was created 2 new SolidColorBrushes, one for the FROM color and one for the TO color. These two colors would be the beginning and ending state for the background of my control. I then shoved these into my ResourceDictionary so that a) I could easily find and manipulate them and b) utilize them elsewhere if needed.

Next, I went to the user control I was working with and created on it three new objects, a storyboard, and then two local brush objects.

Then in the method I had for loading the control and its data, I created a ColorAnimation object, cloned my two new brushes into my local brush objects, and then shoved them all together. I activated a timer, and when the timer expired, then I turned on the animation to begin the fade.

Lo, and behold, it worked! And it worked well. It's pretty, it works great as an indicator, all-in-all I was quite pleased with myself.

Anyways, the following two screencaps show the relevant code in question.



Enjoy.

Friday, December 26, 2008

eComic Flying Off The Shelf

Get eComicWell, at least proverbially--after all, there's no shelves involved over at CodePlex. Anyways, I'm ecstatic as I checked the download count and it was at 42 on Wednesday, but when I checked it this morning it was at 58. And that's just for this latest version.

I've yet to get a single comment or "issue" on the software, which I'm not sure if that's a good thing or a bad one. I mean the 58 downloads (half of which are the source code) means that there's some folks at least looking at my application.

But if no one is finding any issues, does that mean it's made right or does it mean that it's just not getting used.

For the record, eComic has had a total of 92 downloads (source and application).

I just wish I knew more about actual usage, and not just the downloads. I guess I could add in some "registration" nonsense during the install process, but that's just lame, and annoying.

Hopefully, I'll have a bit of time come the new year to add in some more functionality, as I'm still wanting to add in the "Reading List" function and give it the ability to create CBZ files.

Anyways, I just wanted to toss that out there, as I'm happy that something I made is getting used.

Monday, December 8, 2008

JC App take 2

Well, after a bit of an issue on the little application I tossed together to deal with PM Lists over at the forums for TheForce.Net, I quickly got another version of it cobbled together and out to Codeplex (available here).

Now, what issues you may ask? Well, first and foremost, was an installation error having to deal with an IEFrame.dll dependency (which I assume was from WATIN). Of secondary concern I had left a message box in there, which spat out the name during every pass of sending a PM.

But, I've got those dealt with (at least I didn't receive errors when installing), and I also made a few extra modifications to the little application. The Version change Log is thus:

  • Fixed Installer Issue
  • Added option to hide the browser window while app is working
  • Turned app into multi-threaded application
  • Cleaned up the Source code
  • Added a "waiting" animation while process is running
It's nice and simple, and hopefully easy to use.

Sunday, December 7, 2008

Another little WPF Application

Well, I've tossed out another itty-bitty WPF application, it's located here: Jedi Council PM List. And while my other application (eComic) is very specific in its user-base, this one makes eComic look like MS Word in its potential user-base.

It's basically designed to be used by a subset of the users of the Jedi Council forums (http://boards.theforce.net) to allow said users send their private messages as a PM List.

Of most interest is the fact that it is web site automation via WATIN. WATIN of course is designed for automated web testing, and is something that's needed for a couple of projects that are in the wings for me.

Sunday, November 23, 2008

eComic WPF

Well I've been playing with WPF lately, and while I don't have it down 100%, I do have a working prototype (see the pretty image there). It's a great little thing, with what amounts to two panels (one for thumbnails, properties, etc and the other for the actual image) and my personal favorite of UI chioces: the Ribbon control.

I'm not sure why I like the ribbon so much, but I do like the paradigm behind it.

Anyways, the technologies hiding in this thing are as follows:

  • Ribbon Menu Control
  • WPF
  • WPF Layouts
  • Scroll Viewers
  • Zip Library
  • WPF Image Control
  • WPF Tab Control
And that's just the major things that I can remember off the top of my head.

And I'm not above admitting that it's taken me a bit to get it into this state of being able to work it. Sure, it only took a few hours to get the base system up and running, but it was ugly. The main window looked nice with its Ribbon component, but the Image Viewer popped up as a secondary window that lacked the Ribbon control.

It was in essence the very paradigm I was trying to escape from by moving the application to WPF.

Which meant that it was back to the research boards, and hunting for a way around the problem. Enter the Tab Control. I was able to override the style associated with the header of the tab, and make each of them have a label and a little "X" button.

Once that was in place, it was a simple matter of ripping out the ImageViewer as a WPF form and create the ImageViewer as a user control which can be added to a Tab Item. This is the paradigm that you get to see in the picture above.

Anyways, I've finally got all those little things sorted, and began doing communication, information exchange and UI changes from the various tab-based ImageViewers and the Thumbnail tab that hangs out on the left hand side of the application.

Next up the Resume Reading, Next & Previous Archives buttons.

Sunday, November 16, 2008

Take a Vitamin C; All Your Virus Metrics Belong to AVG

Steve Wiserman over at IntelliAdmin.com has an article talking about the recent AVG Anti-virus screw up concerning Windows XP and User32.dll.

In it, he asks the following two questions:

This makes me ask a few questions. First, how can they determine which customers are affected. Secondly how can they tie that to contact information?
Reasonable questions, and while I don't know for certain that this is how AVG has accomplished this task, here's two possible way that it could be done.

First, AVG talks to it's parents servers. We knows this because it updates itself, and it checks to see if you are running a valid license. Is it so unbelievable that they are pushing up metrics on what viruses are being caught as well? At that point it's a simple matter of connecting a installation license with the associated email address.

Second way is to push down an update to the application which checks to see if said file was stuck into quarantine or cleaned and then toss up a messagebox displaying the upgrade offer.

Now, why do I think those two ways are possible? It's simple, as a user of the software I read the EULA.
6. Miscellaneous.

a. Notice. AVG Technologies may deliver any notice required by this Agreement via pop-up window, dialog box or other device, even though you may not receive the notice unless and until you launch the Software. Any such notice will be deemed delivered on the date AVG Technologies first makes it available through the Software, irrespective of when you actually receive it.

b. Privacy.

i. You acknowledge that AVG Technologies collects certain information regarding the users of the Software, including certain personally identifiable information. You hereby consent to AVG Technologies' collection and use of such information, and agree that AVG Technologies' collection and use of such information will be governed by AVG Technologies' Privacy Policy, currently published at www.avg.com, as AVG Technologies may revise the same from time to time.
Bloody annoying things they are, but they do tell you all sorts of interesting tidbits of information about the software and what it does. Either way of discerning who was troubled by the screw up by AVG is well within their "rights" according to the EULA.

Amusing what you learn when you read those evil things, eh?

Monday, October 27, 2008

More eComic


First off, version 0.0.2.001 of eComic is now up and running over at Codeplex. The latest release can be downloaded from here. Now that that's out of the way, first I want to show off the new application icon. I like it. It just screams comic book to me.

Next thing to talk about in regards to this, was the sheer amount of THINGS that the new version does. Everything from GAMMA filtering to spellchecking to thumbnailing the archive. Of course the spellcheck functionality still isn't put out where most folks can get at it, as I'm still working on a really viable datastore for the system.

My heart is telling me that I need some data in a database for some of the functionality I'm aiming for, but at the same time I'm not going to force folks to download and install SQL Express just to run this thing.

It's getting bloated enough as is.

That said, I also don't want to use XML files as they're not an ideal solution for data searching and maintaining relational data concepts.

I tried SQL Server Compact Edition, but the last time I tried to install it, my computer threw up, and took away a large number of my programs, forcing me to do a destructive format on my box. Alas, I'll have to see what I dream up.

And just for the fun of it, here's the Changelog for the new version:

  1. Fixed Startup Issue where PC would launch multiple instances of the application when double-clicking an associated file
  2. Made Temp file clean up more robust
  3. Added in "Go To Page by Thumbnail" functionality
  4. Organized Source Code
  5. Added Slide show option to Image Viewer
  6. Generated Options Dialog
  7. Added in a Gamma Filter
  8. Made Gamma Filter preservable via the OPTIONS dialog, or per archive via the Image Viewer Context Menu
  9. Added in a Adjust Color Filter
  10. Made Adust Color Filter preservable via the OPTIONS dialog, or per archive via the Image Viewer Context Menu
  11. Added in a Contrast Filter
  12. Made Contrast Filter preservable via the OPTIONS dialog, or per archive via the Image Viewer Context Menu
  13. Added in a Brightness Filter
  14. Made Brightness Filter preservable via the OPTIONS dialog, or per archive via the Image Viewer Context Menu
  15. Added in a Color Inversion filter
  16. Added in a grayscale filter
  17. Actually implmented SAVE functionality
  18. Began working with the ComicInfo.xsd file
  19. Made new Application Icon
  20. New MAIN window
  21. Image Viewer
  22. Spellcheck added to Archive Editor

Microsoft Azure

Joel's Sharepoint blog points to a new MS technology named Azure which was released as a CTP for developers today. Being the geek that I am, I was interested so I followed the link over to the site, and saw this pretty link labeled: Azure for Web Developers.

Even more interested, I followed said link, which is when I got this image:
Just in case you don't want to click on the picture to make it bigger, that little line of text states:

The page cannot be displayed because an internal server error has occurred.
Now, I love MS development paradigms. The .NET Framework is my friend. Yet, this does not bode well for the future. We'll have to see where they take it from here.

Wednesday, October 15, 2008

My Poor PC

I've seriously damaged my home pc. I was trying to get SQL Server Compact Edition version 3.1 to install and be accessible via my instance of Visual Studio.

You would think it was a simple task, after all, I had the Mobile Components installed, and could create smart device applications. You would think...

I'm not exactly sure what happened, but somehow, someway, I've utterly fubard my install of VS. Which means that I need to load up my VS Installer, and repair VS. Of course that doesn't work, and the installer just keeps complaining and crashing.

So, muttering under my breath, I go and uninstall all the .NET development tools from my box, and try to reinstall VS again.

And again, with the no love.

My next step is to try and kill the .NET Framework (and by that I mean versions 2, 3 and 3.5). Those just flat out refuse to remove themselves as they're still applications dependent upon them.

At which point I mutter evil things about Microsoft. I'm the administrator of my PC, I should be able to remove ANYTHING regardless of what depends on it.

Considering the implications of installing and repairing applications, I delete the contents of my TEMP folder. After all, that's where setup files reside after they've been unpacked by the installer. It's from there that the repair action repairs an installation.

Again with the no love.

At this point, I'm well and truly irked. I mean I can't do any development, as none of my tools are installed, and none of them will install.

Of course, because I'm a programmer, when I screw something up, I do it all the way. Somehow, I've managed to corrupt a dozen different applications and none of them work now. Everything from PhotoShop 5.5 (definitely a non-.NET app) to this little icon app called @IconSushi (which is a .NET 2.0 app).

So, what am I left with? The only thing left to do is slick my drive. Clear it of Windows entirely and start over. Which means that I now have to backup all my data.

And you'd think that as a programmer I'd be doing all this, as I know that good data retention relies upon it. But no, I'm not doing backups (my wife backs up her images to DVD but none of my files are done that way). And I got gigs upon gigs of data waiting to be backed up.

This is what I get to work on this weekend I guess. I just feel so lucky.

Wednesday, October 8, 2008

How Dell Helps Small Businesses

A few days ago, one of the high-muck-a-mucks over at Dell came to our office for a visit. This is the guy in charge of corporate resellers for the Eastern half of the United States. So, yeah, he's a pretty high up there guy.

Now, something about our company. We are a Dell saturation reseller. The only reseller category above ours is the big-box folks such as Wal-Mart or BestBuy.

Anyways, we had this VP come visit us, and tell us all the ways that Dell could "help" the business.

The first thing is that we cannot resell Dell products to customers unless we happen to "register" said customer with Dell, and provide them the opportunity to contact said customer.

What that translates from Corporate speak to real speak is: you're our sales team now, tells us who needs hardware, and then we'll decide if you get to go ahead with the sale, or if someone else on our sales team gets the dollars.

And of course, the whole thing went to pot from that point forward. After all, who wants to give Dell all of their sales leads? I don't. And as a consumer, I don't want a company I'm doing business with providing MY personal information to a third party.

For example, if I buy a Sony TV from Best Buy, I don't expect Best Buy to say "Hey, wait a second. We need to register you with Sony, and then you'll have to wait a few days until they get back to us on whether or not we're allowed to sell you this particular piece of hardware."

I don't expect such behavior from ANY vendor I deal with. Why on earth would Dell expect someone to willingly go along with this.

What I expect is for the company I'm dealing with, to either have said merchandise in stock, and hand it over to me, to deliver said merchandise to my home or to have it on back-order and I can take delivery of it in a few days.

At no point do I expect my vendor's vendor to a) require my information or b) be given a chance to sell to me directly.

Frankly, if either occurred, I would stop use of both vendors. In terms of my example above, I'd tell Best Buy they can forcefully insert the Sony TV into their rectums and go down the street to Circuit City and buy a Philips TV.

And repeat until I find someone willing to sell to me on MY terms.

Problem 2 with the Dell visit deals with inventory. It takes Dell an average of three days to get a new server to the Jackson Metro area. In this day of JIT order schemes, three days is just long enough to put a company out of business. So my bosses had the bright idea of keeping a server in stock.

Sure, we run the risk of having to eat the machine if it becomes out of date, but at the same time it means that we'd be able to respond immediately to one of our customers having a catastrophic failure of their server.

Well, Dell had issues with this. And they tied back to that whole registering thing. They did not like the fact that we held inventory for potential use.

The final problem that popped up in the Dell visit was apparently the vendor channel that we had been using for the past four+ years, has never existed. How's THAT for newspeak for you?

Now, to use the vendor channel there were two options. Option 1 is to become certified on a piece of hardware which my bosses do not want to push as an option for our clients. And to become certified, it means we would need to purchase said hardware--despite not needing it in our infrastructure.

Brilliant move there Dell.

Option 2 is to go through some classes to become approved to resell Dell merchandise through the vendor channel. One drawback there is that the classes aren't offered, and the Dell VP who was here had no clue WHEN they would be offered. If at all.

Yet another brilliant move.

So, where does that leave us? More or less, we're in a position where it would be detrimental to our business to sell Dell. Dell knows this, and doesn't care. Nor does Dell care that the business model they are trying to force on their resellers is inherently anti-privacy, and anti-small business.

I've long heard all the horror stories about Dell, but I've long pushed them, especially for business-class users.

Now, at this point, I'm just happy that the last laptop I bought my wife was a Gateway.

Tuesday, September 30, 2008

eComics, MRU's and My Recent Documents

Well, my testbed for WindowsForms development has received another release. Version 0.0.1.003 of eComic is now up, and waiting for downloading over at Codeplex (http://www.codeplex.com/ecomic/).

Quite a number of changes for this release, most of them are fixing behaviors, getting things closer to creating/using a reading list, but there were two that I really wanted to point out. These two are new classes that I added into my source code; one is a MRU Files listing, and the other adds accessed files to the "My Recent Documents" list on the user's START menu.

The latter of the two is merely a simple WIN32 Interop wrapper for the SHELL DLL. Nothing obscenely fancy, but it works.

The former (see the source code here) is a bit more involved. It's a class, which takes in 3 things: a ToolStripMenuItem object, the application's name and the number of files that can be on the MRU list. It then generates additional ToolStripMenuItems to go into the intial ToolStripMenuItem's DropDownItems attributes.

The class itself raises an event when one of those child Menu Items are chosen, passing the selected file path & name to the parent class. I just shoved this information into the registry because that was easy for me, but it wouldn't be that hard to retrofit it to store the data into a database or even a flat file.

Friday, September 26, 2008

eComically Funny

Yes, I'm stretching with that title. But hey, I've got fun things in store for myself. Anyways, I'm almost ready to release the next alpha version of my freeware program eComic. This little bitty release is primarily to fix the ability to read the archive files when the images are contained in subfolders (recursion FTW!).

I've also pushed out more functionality on the ImageViewer screen, which will allow the user to load a random archive from that screen, and save the currently visible image to the file system.

I've also gotten rid of the ClickOnce installer and went with a more traditional MSI file. I don't know why but I just don't like that ClickOnce paradigm. It bothers me for some reason or other.

Thursday, September 18, 2008

CBR, CBZ and maybe something new

I can admit, I'm having fun with eComic. But that's neither here nor there. Currently, I support opening CBR and CBZ files, which are fundamentally RAR and ZIP files respectively. For the record, CDisplay, the initial program that dealt with these things had 4 file formats: CBR, CBZ, CBT, CBA, which corresponded to RAR, ZIP, TAR and ACE files.

The thing that makes a CB# file a CB# file, is that it is filled with images, and possibly a "Notes.txt" file. It's not a complicated file paradigm--which I do like.

Now, making them is relatively easy. You stick all the files you want in the CB# in a folder, and then zip or rar or tar or ace it up. Rename the file extension and you got yourself a file.

Bad news is that you've GOT to have them name in something sequential. Much the same way that the CB# file itself needs to be named sequentially in order for CDisplay to find the next thing to be read.

So, my thought was to have eComic create a new file type. Let's call it GNZ. Now the GNZ will fundamentally be a CBR file. Except the Notes.txt will be replaced with a Manifest.xml file.

The Manifest.xml file will have something along the lines for a schema:

Note two things of interest for the new file type:
  1. The images are given an order that they should be displayed in
  2. The note information is stored, and give a format (types can be RTF, HTML or TEXT)
... maybe I'm just too pleased with myself.

Wednesday, September 17, 2008

Codeplexing for Fun

And if only this were for profit as well..

Anyways, this past weekend, I had some spare time on my hands. And what better way to fill that spare time than to purchase lots and lots of SF/Geek memorabilia.

But, since I don't have enough money to do all of that, I decided to just wrote some code instead.

The thing is, I coupled two reasons to code into a single project.

The first reason is that I was wanting to use the ZIP libraries in .NET in a WindowsForms environment. I know I'll be dealing with them soon professionally, so I wanted to figure out how to use them, and get that out of the way.

The second thing is that I have an application I use called CDisplay, which is a sequential image viewer, which I want to extend the functionality for. Basically, I want to be able to create a "Reading List" which allows me to pick and choose which archives I want to view, and the order I want to view them in.

Why? Well, I use this to read comics. I'm a geek, it's allowed. Now, if I wanted to read say the "Fatal Attractions" crossover from the late '90's X-Men, then I'd have to read the following comics in this order:

  1. X-Factor (Volume 1) #92
  2. X-Force (Volume 1) #25
  3. Uncanny X-Men #304
  4. X-Men (Volume 2) #25
  5. Wolverine (Volume 2) #75
  6. Excalibur (Volume 1) #71
Now, if I've scanned every issue of my comic collection into my PC, and followed a wise naming convention, then the the disparate archive files would be called:
  1. xfactor_v01_0092
  2. xforce_v01_0025
  3. uncannyxmen_v01_0304
  4. xmen_v02_0025
  5. wolverine_v02_0075
  6. excaliber_v01_0071
The problem here is that these guys are NOT sequential. When I would open xfactor_v01_0092, the next logical file would be xfactor_v01_0093 not xforce_v01_0025. The xforce_v01_0025 is only the next logical file in the context of the "Fatal Attractions" storyline.

Hence the need for a reading list for this thing.

So, there you have it. I'm in the process of building this little application because, well, I'm crazy that way, and feel the need to ramble on about it here on this blog while doing so.

Without further ado, here's my codeplex site: http://www.codeplex.com/ecomic

Saturday, September 13, 2008

And A Great Big Modified Dietz To You Too

I don't work well in the heat. Especially when it's a heat without airflow. Sure, the office was only 82 degrees F, but without a fan or anything, I was just flat-out miserable and all I wanted to do was curl up somewhere and gaze at a wall or something. Heck, I seriously considered going out to the truck, and getting my gym bag to trade my work clothes for my work-out clothes, all in an effort to keep my brain from overheating.

Or in Bender parlance, I was just shy of closing my eyes, and when I re-opened them stating "Insert Girder."

Now, why is this important? And more importantly, why am I bringing my issues with heat up on my programming blog? Well, outside of the fact that the heat thing happened at work, this heat thing slapped me down while I was trying to uncover the secrets of using four different algorithms.

Sure, they all calculate the same types of data, but they do it in highly divergent ways.

What algorithms you ask? Well, they're financial ones, specifically those related to calculating Investment Performance. The four in question are: Internal Rate of Return, Daily Valuation, Modified Dietz and Modified BAI (sometimes called Modified IRR).

Now, these things are evil. They're geometric algorithms, as they deal with compounding data sets over time, with sums and subtractions in addition to, and conjunction with the compounding data.

Don't believe me? Then look at this:
Or how about this:

Yes, those are two of the formulas I'm turning into a calculator. And doing it while my brain is frying like one of those proverbial eggs.

Hmm, now if only I had some bacon.

Alas, thanks to our good friends at Wikipedia, at least some of the Modified Dietz things have been dealt with. Their article provides this VB source code for calculating Modified Dietz:

'Jelle-Jeroen Lamkamp 10 Jan 2008
Dim i As Integer: Dim Cash() As Double: Dim Days() As Integer
Dim Cell As Range: Dim SumCash As Double: Dim TempSum As Double

'Some error trapping
If rCash.Cells.Count <> rDays.Cells.Count Then MDIETZ = CVErr(xlErrValue): Exit Function
If Application.WorksheetFunction.Max(rDays) > iPeriod Then MDIETZ = CVErr(xlErrValue): Exit Function

ReDim Cash(rCash.Cells.Count - 1)
ReDim Days(rDays.Cells.Count - 1)

i = 0
For Each Cell In rCash
Cash(i) = Cell.Value: i = i + 1
Next Cell

i = 0
For Each Cell In rDays
Days(i) = Cell.Value: i = i + 1
Next Cell

SumCash = Application.WorksheetFunction.Sum(rCash)

TempSum = 0
For i = 0 To (rCash.Cells.Count - 1)
TempSum = TempSum + (((iPeriod - Days(i)) / iPeriod) * Cash(i))
Next i
MDIETZ = (dEndValue - dStartValue - SumCash) / (dStartValue + TempSum)
Thanks Wiki!!


Wednesday, September 3, 2008

Installing and Launching Applications

So, one of my myriad projects I have going on is a run-once and forget about it application which modifies the resolution order for Outlook Address books (fun stuff, I know). Forget the fact that this is evil MAPI and C++ stuff (made even eviler via Vista), and also deals with the arcane Outlook COM objects in C#, I got it working.

After a number of hours of smacking my head against the wall, I got it working.

Well, as a final bit, the client requested that it install and then run and that's all it needs to do.

My initial thought was, let's just drop it into the START folder under the program list, and have it run every time the system reboots. The client didn't want this, as all he wanted was a run once and never have to bother with again type of thing.

Well, Aaron Stebner has a solution which actives that "Run this application" checkbox in the MSI system, which can be found here.

Which was almost what I wanted. The problem there is that I want to FORCE the application to run EVERY TIME it is installed.

Which led me to this CodeProject article: Launching your application after install using Visual Studio 2005. Outside of the circular reference to my first link, and the fact that the title is slightly misleading, this does exactly what I want.

Which is launch the application AFTER the install, but prior to the INSTALLATION wizard finishing.

Which makes me happy, the client happy, and the world just that much of a better place for everyone involved.

Good times.

Monday, September 1, 2008

SQL Membership Provider

I love the .NET Login controls. They're the easiest things in the world to use--provided you're happy with the arcane and more or less evil Membership tables that are generated by aspnet_regsql routine.

And of course, I'm not.

I often want little things like using the email address as the username. Everyone knows their email address, and in ensures that I collect that information (yes, I'm sneaky).

Usually this means many hours of arcane coding while I implement my own versions of the Membership and Roles providers, when ultimately all I want to be doing is modifying things every so slightly.

This is a concept that makes me ecstatically happy once I found that the source code for the SQL Membership Providers have been released by Microsoft (a fact discovered via Scott Guthrie's blog in this post).

Sometimes I'm so behind the curve.

Tuesday, August 26, 2008

Turning off ASP.NET LOGIN RETURN URL ability

A standard part of the way that the LOGIN controls work in .NET is that they append the RETURN URL to the query string, and when you successfully log into the application, they drop you back right where you were.

Which makes sense if you're knee deep in an application when you lose your authentication ticket for some reason.

But, what happens when you don't want that behavior. How do you make it where the application always sends you to the default page regardless of where the user had been.

Fun, eh?

Basically, what must occur is that you'll need to handle an event from the LOGIN control, called LOGGEDIN. When handling this event, it then becomes a simple matter of redirecting the user to the default page of the website. What's produced looks like this:

Protected Sub Login1_LoggedIn(ByVal sender As Object, ByVal e As System.EventArgs) Handles Login1.LoggedIn
Response.Redirect("./")
End Sub

Simplicity in action, once you catch on.

Monday, August 25, 2008

My RDLC covers my footer

Running IE7 I found a fun little issue regarding the RDLC ReportViewer in .NET and my footer as defined in my CSS Layout coming from my Master Page. Basically, the footer was appearing underneath the scroll bar from the iFrames (see the image to the right there).

What confused me at first was the fact that it was happening in IE7 and not IE6. An odd state of affairs at the baset of times.

My guess as to why, is that in IE6, scrollbars are generated INSIDE the element, and they changed that in IE7, but all of us CSS coders are still telling IE to perform according to the IE6 ruleset.

So, to accomplish this little bitty task, what I needed to do was put in another CSS class into the div that wrapped my ReportViewer (and the iFrame which it generates). Since my ReportViewer is running at 400 pixels, I just created the following CSS class and applied it to the DIV that wraps around the viewer:

.viewer { height:425px;}
A small and simple bit of CSS eh?

What that snippet of CSS does is push my footer down just that little bit necessary in order to make sure that it is always displayed (see picture to the left). Also, since it's just a class, then I can apply it only on those pages where necessary rather than on the MasterPage or worse having to create a new MasterPage.

Better yet, due to CSS's ability to stack, I can just append it to an existing DIV rather than having to create a brand new div.

Wednesday, August 13, 2008

Take THAT RDLC!

I posted yesterday about some travails I was having with RDLC and the behavior of drill through reports. The basics of that was that the system was requiring a second full postback on to process any events generated by a drill through report.

Well, after a bit of sleep, I succeeded in bypassing that whole issue.

To get the necessary behavior, I worked in two steps. The first was in the DRILLTHROUGH event handler, and the second was in the PRERENDER event handler.

So, first things first. Previously, in the DRILLTHROUGH event handler I was getting my data and my parameters, and setting them to the DRILLTHROUGH report. Much the way that every document out there states you're supposed to do. To that, I say BAH!!

My solution required me to not assign the new datasets and parameters to my drillthrough report, but rather to the local report assigned to my ReportViewer class (i.e. the PARENT report).

But, this would make the drill through report devoid of data you claim? Well, that's the whole bit about the PRERENDER class. In there, I check the ReportViewer's LocalReport instance to determine if we're in a DRILLTHROUGH situation, and if so, then I call the PERFORMBACK function of the ReportViewer class.

Which basically pushes us back to the parent report (i.e. the one that I assigned the new datasets to).

Insert an appropriate level of diabolical laughter here, and then we're all sorts of good to go. Now, onto my next problem.

Tuesday, August 12, 2008

RDLC Post Backs

Now, I'm annoyed.

I've never been overly fond of the whole Crystal Reports/MS Reporting control schemes. It's more of the fact that I just don't like reporting than anything inherently wrong with those controls.

Yet, I'm now true and peeved concerning RDLC.

Backstory: I'm building this report, which displays 3 levels of the application's hierarchy at a time, and that bottom level is responsible for doing the drill through effect. Well, going from step 1 to step 2 worked perfectly fine. But stepping from 2 to 3 just cause a postback and redisplaying 2 on the first click. On the second click, the step 3 portion of the report displays correctly. Additional playing about with the EVENT HANDLERS show that this behavior occurs regardless of which event is being fired (though some events still process).

So, now that that huge blurb of backstory is done, I'm still stuck here trying my darnedest to figure out just what is going on.

EDIT: Solving problems since '77.

Thursday, August 7, 2008

First Day of Next Month in VB.Net

This is not exactly that hard of a thing, it's just something that I've found myself doing quite a bit in one of my current projects, and I thought of this nice, easy way to do it which I don't want to lose.

Previously to do this, I'd add a month to the current date, use that date object to get the month as integer, build the new date as a string, and then cast said string to a DateTime object.

That's a lot of steps for what should fundamentally be a simple exercise.

Well, it is; provided you don't do it how I was. Check out this snippet of code:

Now.AddDays((Now.Day - 1) * -1).AddMonths(1)
Beautiful huh? What's happening here is that I'm using the NOW function to return a date, I am then subtracting the current day-1 from that date object. What that works out to is as follows: if today's the 15th, then by plugging into the AddDays function 15-1*-1 I'm literally subtracting 14 days from the 15th, which leaves us with the 1st. Pretty huh?

Once I got to the first of the current month, I then add a month to that date, which will return the first of the next month.

Thursday, July 3, 2008

Eight Reasons....

PC Magazine's website has an article up concerning eight reasons why we should have metered internet.

So, without further ado, here's my personal rebuttal on just why he's wrong on those reasons.

Elimination of bandwidth caps, restrictions, and throttling.
Ultimately, that's what metering is. It's bandwidth caps, restrictions and throttling, except that if you happen to go over, you get slapped with huge fines.

Promotion of higher speeds.
Only if the user is willing to pay for it. A weak argument if you ask me, especially in light of the fact that it fails as a possible model. If a user is being charged for length of time online, then why would the network providers be willing to increase the speed?

Moderate users would pay less than they pay now
And?

Download junkies would pay for their habit
I actually pay for my habit now. I pay more for higher bandwidth speeds than those that don't want that. And the all-you-can-eat buffet fails here as well. The costs associated with a few people who consume extreme amounts, is more than offset by those who consume moderate (or less) amounts.

Spammers pay more for junking up the Web
No. Those people who are not knowledgable enough to not have their machines turned into zombie-bots (or any other type of bot) end up paying more for junking up the web. Additionally, this would curtail such efforts as SETI@Home or the Human Genotype project which used excess bandwidth and CPU cycles for processing large information sets.

Elimination of the net neutrality issues
The author of the article believes that all these issues will go away, and he's right, they will be because all the reasons for having net neutrality will have been implemented. Net Neutrality insists on all network traffic being the same. Once you have metered internet it is a simple jump to having different tiers of which types of bandwidth you can use. You can have 100 Megs of UDP traffic, and 1Gig of HTTP traffic, with it coming from ABC Domain at X speed, and everywhere else and Y speed.

Development of IPTV mechanisms
Yes, I only get 10Megs of Internet a month, so I want to spend it on internet television.

Energy savings (aka "green")
Now, this is just stretching for things. If I don't turn off my PC or Modem now, and I'm considered a moderate user, why would I change that behavior if moderate users would not be affected by going to metered access?

Additionally, one needs to define a moderate user? As an IT professional, my definition of moderate usage may be different than someone who works at a general store, and just uses the Internet to check their email. I need that bandwidth, especially if I work from the house, and have connected to either my office's network, or a client's network via VPN. And would a VPN connection get metered twice? Once on my end, and then again on the other?

No, unlimited connectivity is not an unsustainable concept, nor should it be looked to as an answer to any of the issues raised by the article in question. And in fact makes some of the worse (I'm looking at the SPAM and the Net Neutrality bits right there). Metered Internet is just another effort by the Cable Companies to change what has become the standard way of accessing the internet into something more like their current customer-hostile business model which provides packages of a hundred and fifty channels, of which the customer really only wants a dozen or two of.

Cross posted to my annoyed ranting blog the KrashPAD

Monday, June 23, 2008

Failures in Ajax

I use the Prototype JavaScript library a lot.

Of course a prime use of the library is its AJAX functionality. I like it, and prefer it immensely over the Microsoft implementation found in AJAX.NET.

There is one issue though--and it's a documentation issue. Mainly, the Prototype JS API documentation does not clearly state how to view the error message one would receive on a FAILURE.

Since I primarily use this blog as a place to store things that I may need again in the future, here's the relevant code:

function failure (transport){alert(transport.responseText); }
Amusingly, simple, no?

The parameter passed in is your standard AJAX RESPONSE object from the Prototype library, so you have a number of other options that you can utilize outside of just the responseText. In fact it's the exact same object passed to the success methods and all the other callback methods that are exposed via the AJAX REQUEST method.

Friday, May 16, 2008

Prototype and the Web Service

I'm a .NET programmer. Fundamentally, that's just what I do. Yet, I have a secret. It's a dark one for a .NET programmer, but I have it nonetheless.

I hate ASP.NET AJAX.

It would probably be more accurate to say that I despise it.

With a passion.

It's bloated, and It's never behaved as I expected it to. Maybe it's because I learned AJAX by rolling out my own implementation and then finding Prototype, FLEX and MooTools before finally settling down and really learning Prototype well enough that I can use it without constant references to it's API documentation.

I was doing that while Microsoft was trudging along with Atlas.

What's worse is the fact that ASP.NET AJAX just doesn't downgrade well. I'm a big proponent of the HIJAX style of AJAX implementation, meaning that it's built without all those fancy doo-dads, and then they get layered in, and the CLICK events for buttons and links get hijacked and used for AJAX-style goodness.

Yet, while working this way, I have struggled often against an issue with using Prototype library within .NET. Mainly the fact that Web Services did not want to play nice.

That, and only that, was the reason that I consistently went back and suffered with Microsoft's bloated variety of AJAX.

But, I've solved THAT problem.

Web Services' webmethods are nothing more than functions which return SOAP messages. Which means that they are accessed via a standard HTTP POST. Now, that's not a problem at all. Prototype's AJAX functionality has that down pact. The problem is all that SOAP XML which the web service wraps around the JSON that I'm actually returning.

Well, I finally actually, read that full page that is displayed when you're testing a web service through the browser. Oddly, the information I needed most to solve this problem was way down at the bottom. Which means I had to scroll to see it.
Yes, that little blurb tells you not only exactly what to send, where to send it, but ALSO the exact format of the SOAP messages that is being returned wrapped around my JSON string.

One could almost hear my cold, dead contractor's heart patter in my chest.

While it is not the most ELEGANT solution, as that would involve actually parsing the XML to retrieve my JSON, I merely did a quick replace on the XML tags, substituting an empty string in their place. A quick evalJSON call later, and lo an behold I have my JSON object running happily.

Wednesday, April 2, 2008

The Case of the Mysterious IP Address

All right, sometimes I think people do things just because they're stupid. Unfortunately, it will on occasion be people in my profession. I got a IM a week or two ago from a friend who had a friend who needed a bit of work down for his website. So I looked into it.

The primary issue with the website was that he was getting errors on almost all of his pages. Looking at them, I quickly realized that they were the pages which were served from the database.

Upon further research, I discovered that the database was hard-coded into the Web.Config file as an IP Address.

As far as I can tell, that IP address doesn't serve a database. If it does, either the database has been destroyed or the account has been disabled.

Anyways, it's clear that the account cannot log into the datastore to retrieve the user's content.

Now, as a software professional, this throws up major, major red flags in my mind. While I retain the rights to any software which I create, the data that is used by my software is, and always will be my user's. At no point should my user not be able to get at their data due to my policies.

Which is the case here.

So, I went and fixed the issues--mainly be creating hard-coded pages where the dynamically served ones had been.

Then to just take the proverbial cake, I tried to grab a copy of the website so I could open it up in my instance of Visual Studio and compile things for more efficient use by IIS and to fix some errors that were going on in the photo gallery software. This led me to discover that the photo gallery is some odd-ball, custom component, where the source code was hiding elsewhere.

So, not only did I get the chance to tell this guy that his web developer/host company managed to lose his data for him (which he really liked his website copy) but I was going to have to rebuild his photo gallery to make the errors it was displaying go away.

You can imagine the joy said individual had when hearing this. If the original developer wasn't just ignoring his phone calls, emails and letters, I'm certain he'd have gotten his ear chewed off. Truth be told, I was perfectly willing to do the chewing for the guy.

It's companies and developers like that that give us all bad names.

Monday, March 24, 2008

XML DTD as Data Requirements

I've forgotten how much I've enjoyed generating requirements. There's something almost soothing about generating a System Specification from a bunch of functional descriptions, and then derive that down to a series of Software Requirements Specs which can be used to actually build software.

It's fun.

Anyways, now that I'm about to push on to design documents, I realize that I'll need to generate some DTDs for XML Messages which I'll be sending back and forth as well as utilizing as local data storage.

Luckily, I have found a tool for that. Hit Software has an online converter which takes in an XML file and generates either a DTD or an XML SCHEMA. Additionally, you can import a DTD and get back the XML SCHEMA. Makes generating those things bunches easier.

Monday, March 17, 2008

Wowzer, it's been a while....

It's been so long since I've had content to push to this blog. After all, the work at SAKS ended up not being very mind-stimulating. Or technical. I'd hesitate to call it actual work, but for the fact that they paid me to show up, despite the fact that I didn't want to be there.

All of that is over now. I've managed to acquire a job where I actually use all those skills I shoved into my head while working for TECHSOFT. And it's actually fun! Well, I think it's fun, but then again most people don't enjoy designing software with the same fervor as I.

Anyways, I am now employed by a technology company here in Jackson named Software Consulting Services (SCS). SCS is similar to TECHSOFT, as both do hardware sales, network engineering and software engineering. So, imagine the happy dance I get to do now that I'm actually designing software once again.

Blog Widget by LinkWithin