I got to mess with a friend’s HTC One X yesterday, and while I failed miserably at using TalkBack, it presented enough of a challenge that I was intrigued.
Most of why I was having issues is because HTC Sense is made of custom widgets, which screen readers have problems with. So, naturally, I want to play around with it more… I have a weakness for geek-related challenges. I know there are some issues with the Nexus 7, but I feel like playing with it would be a lot more interesting than an iPad Mini. I mean… what can I do with an iPad mini that I’m not already doing with my iPhone 4S? It’s basically a 7.9” screen for all my existing apps. I can’t type any more easily on it (in fact, I had issues typing on the iPad 2/3), web navigation can still be tedious, ETC… but Android is an entirely new OS, with (in theory) terminal access.
I’d be interested to hear from any blind people in the comments who have iPad Minis or even regular iPads, and what they’re using them for. I’m trying not to be an impulsive person and buy a Nexus 7.
AKA Relieving Symptoms vs. Solving Problems
So, I’ve had a bug bouncing around my “I should really figure out wtf is going on here” queue for awhile. There’s a “fix” checked in, but it doesn’t actually solve the underlying problem. For users of our software, it doesn’t matter… at the moment. But there could be other instances of this same issue lurking in our codebase, just waiting for someone to push buttons in exactly the right sequence to cause a crash.
So what makes this bug so damn… buggy? One word: threads. Threads drag determinism out back kicking and screaming, beat it to death with several blunt objects, then dump the body in shark-infested waters somewhere in the Caribbean. Basically, fuck my life. It gets better, though. We actually crash because we try to get item –1 out of a vector… that’s like trying to steal the –1st cookie from the cookie jar. The C++ runtime puts a stop to this nonsense by throwing an exception… but the default exception handler calls DebugBreak(), which destroys/stops the thread that called the problematic function in the first place. Fuck my life even harder.
That brings me to the next obstacle: the offending function is a callback. It’s not just any callback, though, oh no… it’s a SAPI callback. That means it involves multiple COM servers, only one of which is ours. Yep, tripple-fuck my life. This is quickly drifting over to the wrong side of that line between “a good challenge” and “totally futile.” I’ll probably be able to figure it out eventually, with some help… but until then it will be the bane of my existance.
In the meantime, what I’ve done is put a check at the top of our misbehaving function that checks if it’s being passed a bogus value (i.e. –1 or 2^32-1) and fails gracefully. This solves the immediate, user-visible problem (i.e. flaming crash dialog box of death), but still leaves the mystery of why one of our callbacks is misfiring on a destroyed object.
Finally, I’m done with the gruelling trial of my willpower known as college. I got a b in my first summer course (applied leadership) and an a- (“a minus” for those with screen readers) in my second course, operations management. Let me tell you, that second one was a real bitch.
Work has been amazing. Seriously, I’d be bored to tears/depressed and going crazy without all the wonderful learning opportunities that work gives me. I’ve been working on an interesting and challenging project within the ReadHear PC code base. When a user inserts a removable drive (USB stick, hard drive, CD, ETC), ReadHear will search the drive for books. If it finds any, it’ll pop up a nice dialog where the user can choose a book from that drive and open it.
This scheme is all well and good when dealing with small flash drives or CDS with one or two books on them. The problem comes when you plug in… oh, let’s say, a 2 tb external drive with hundreds of thousands of files on it. Guess where the task of searching the drive is performed? The UI thread. Anyone who’s done any sort of operating systems/cs/software design work should immediately be cringing at this point. (To be fair, the original “search removable media” code was probably designed with Learning Ally CDs in mind.)
So, this was the project my superiors gave me – make it ask the user if they want to search, if they say “yes” start a worker thread to perform the search, otherwise initiate AutoPlay. Sounds simple, right? Well, it actually is… at least in terms of writing the worker thread function itself (the search code was already written and working). The problem came when I had to get the worker and UI threads talking to each other. The worker thread posts a message to the message queue of the main window when it’s complete, and the message handler does all sorts of checks to make sure the drive is valid, ETC. Here are some interesting things I’ve learned along the way.
- The Windows Shell API is a steaming pile of shit. Actually, to be more accurate, it’s the programming equivalent of a college dorm room where the occupant has decided to put all of their dirty clothes, unused crap, ETC into a corner. Look at this sample code for an example.
- Microsoft documentation is really helpful… unless it isn’t. When you have pointers to data structures inside pointers to other data structures, it gets really interesting (to say the least) when trying to cast things. And Microsoft conveniently omits all this information.
- All bets are off when it comes to User Account Control. For example, JAWS won’t read webpage windows under processes launched with elevated priveleges, and QueryCancelAutoPlay messages don’t actually work properly.
- Don’t put function calls in asserts. You’ll spend hours tracking down why things don’t work in your release build while they work just fine in the debug version.
- When inserting a USB device, the dbcv_flags member of the DEV_BROADCAST_VOLUME structure is set to 0. (Thanks for telling me this, Microsoft, and saving me the hastle of confirming in the debugger. Oh, wait…)
- Don’t #import something more than once. It’ll explode, badly.
I feel infinitely more confident in writing programs using MFC/Win32 than I did a month ago. At first, when they told me to basically have at the code and implement this stuff, I was freaking out. However, after solving all these interesting little problems, I not only feel like I’m much more familiar with the Windows API, but I feel like I’m a much better programmer because of it.
And now, for something completely different. As you may have gathered from the title of my post, there’s a new woman in my life. I met her through Shaleah, who intuited that we’d be good for each other. So far, that seems to be the case, but our 9-day stay together this/next week will prove it for sure.
One major difference (actually, there are several, but I digress) between her and my other partners is that she has a daughter. Honestly, that doesn’t turn me off like I thought it would. It scares the living shit out of me, yes… but I love both Heather and her daughter Chloe with all my heart. Heather is planning on moving out to Indiana with me. Yes, I know it’s “kinda sudden,” but she’s in a bad spot right now and really needs to get the hell out of California. I just signed the security deposit/application on my apartment, and will be moving in shortly (assuming I get approved). Heather, hopefully, will follow in mid-October.
So, that’s what’s basically going on in my life at the moment. This week is going to go by really slowly… I just want it to be Friday morning already. If I find more interesting programming tidbits, I’ll be sure to post them in some sort of humorous way.
If you've been reading my twitter feed lately, you may have noticed me complaining about excessive IE crashes. Early this morning, I got the idea to find out which module was causing the crashes (based on some forum posts I came across on Google). I had no idea how to do it in Windows 7, but it turns out you just have to look in the Event Viewer (unfortunately, I can't find said crashes off the top of my head).
So, what was the component causing these crashes? Turns out it was VBufBackend_mshtml.dll. This is the NVDA virtual buffer helper for Internet Explorer. What this does is allow NVDA to read webpages in IE. There are also corresponding libraries to assist in the accessibility of Adobe Reader and Mozilla Firefox/Thunderbird.
Why does this particular dll cause crashes, and more importantly why is it even loading a dll into iexplore.exe when NVDA isn't running? Presumably, it's the work of the "Non-visual Desktop Access" service, which I had (foolishly) set to startup type "automatic." I went in and set it to manual, and haven't had any crashes today, yet. If the crashes continue, I'll update this post. If you're using Xmarks, this isn't the cause for your crashes if you're experiencing them.