From Azure Autoscaling to Next Gen Desktop Development not Forgetting Firmware on the Way
Friday, 31 October 2008
DirectX - The Next Episode
Here is the home page for DirectX.
http://msdn.microsoft.com/en-us/directx/default.aspx
You can't call yourself knowledgeable about Windows programming if you don't know DirectX. The tutorials requires a basic familiarity Win32 programming such as the Windows message loop architecture (translate/dispatch).
DXUT is layer built on top of Direct3D to make tools easier to build. It simplifies the process for creating a "device" and processing Windows messages. Other tutorials focus e.g on creating a wave effect using a vertex shader.
Finally, if you think DirectX is just for games programmers think again. WPF, Microsoft's new GUI technology, renders graphics in DirectX via milcore.dll.
Thursday, 30 October 2008
Joys of DGV -> DataGrid "Grande Vitesse"
If you have been using the old DataGrid of yore, you need to familiarise yourself with the diffs between DataGrid and DataGridView. DGV adds features missing from the mere Datagrid, understand bound and unbound data.
What MSDN says about "wor friend" DGV est (SCooBee DOO, DOO = dgv):
DGV is Truly Scalable!!! We can go from SMALL, read-only data views to LARGE EDITABLE views of data.
DGV is Truly Customisable!!! You can programmatically create your own CUSTOM SORTS and create your own types of CELLS. Yahoo! Awesomable customisable grid here we come!
DGV is Truly BINDABLE! (more on this amazing BINDABILITY property later!)
It will bind like a MAGENTRON to objects implementating:
1. Immortal IList interface of System.Collections fame (wa-hoo, that includes one-dimensional arrays! I am so pleased!)
2. AWESOME IListSOURCE interface, of System.ComponentModel fame (for "bindable" lists), implementes IList incidentally, the key question being does it offer any additional beneficiences? no major differences, except naming convention... just seems like this is the wrapper version for WinForm components...DataTable and DataSet implement the IListSource interface.
There are also to other classes capable of binding nicely to the DGV, they both have BINDING in their worth-mentioning names:
1. IBindingList interface.
2. IBindingListView interface.
Key Question - what are the actual physical mechanics of data binding to the DGV?
Most of time, you will create a BindingSource component containing most of the details of connecting to the data source. The BS component can represent any WinForms data source (WA-HOO)!
Make sure binding source for DGV is set programmatically and not via the IDE (you will have problems).
Style-wise, dgv.AutoResizeColumns should be used with caution, especially if you have set "preferred" widths for your columns.
Wednesday, 29 October 2008
Good Post on Enums as Ints
http://blogs.msdn.com/peterhal/archive/2005/08/01/446357.aspx
Here's also a useful snippet showing how to iterate through enums in C#, useful if you are populating a ComboBox for example:
foreach (string s in Enum.getValuesOf(enum)) {}
Incremental Linking
But I recently found a problem in managed DLL compilation where object files were getting rebuilt but not correctly even after clean builds.
I traced the problem to the linker not refreshing some new code. Turning off incremental linking fixed this right away. I knew MSVC was using this heavily since my faulty builds were very quick and slowed down (but were 100% correct) when built without incremental linking.
Visual Studio Shortcuts
Cntrl-MO Collapse ALL
Cntrl-ML Expand ALL
Shift-ALT-Enter In/Out of full screen mode
Shift-F5 Exit debugging
F12 - go to definition of identifier under cursor
Sunday, 26 October 2008
Principles of C# Composition
"Make the paragraph the unit of composition: one paragraph to each topic".
#endregion
#region Windows Joe, Principles of C# Composition
- When storing dates in data structures use DateTimes rather than one of multiple string formats. There are special situations when it is preferable to use strings e.g. when all the strings in the application are guaranteed to be in the same format.
- Don't make assumptions about objects being reference or value types. Apart from user-defined classes and obvious things like ints, many objects in the .NET framework are inconsistently implemented - they may be values or references. ADO.NET in .Net 1.1 is an example. Use properties to get and set these variables explicitly rather than rely on reference-value semantics.
- Use object adapters. Avoid class adapters.
Saturday, 25 October 2008
Gregorian, Julian or Korean?
Unfortunately the Calendar math of .NET is not so user-friendly especially when compared to recent additions to Python, for example.
Here is a small program that uses the Calendar class of Python 2.5 to generate dates for all weekends between 2000 and 2020. As you can see, the Calendar class is highly user-friendly (with its use of iterators) and also very ISO-friendly.
import sys
import datetime
from calendar import Calendar
def getdays(year):
c = Calendar(0) # creates a calendar with firstweek=0 (0 is Monday)
for j in range(1, 13):
for dt in c.itermonthdates(year, j):
isoweekday = dt.isoweekday()
if isoweekday == 6 or isoweekday == 7:
print dt.isoformat()
def main(args):
for year in range(2000, 2020):
days = getDays(year)
Beat that, .NET!
.NET possesess an eponymous Calendar class in its System.Globalization namespace (perhaps more appropriately named System.Localization, in the humble view of Windows Joe). In fact, .NET is so obsessed with Localization e.g. of date-time formats, that they completely ignore the fact that international ISO standards exist.
So the challenge - how do we program the same thing in C#? (Answer in the Comments section).
Friday, 24 October 2008
LogDisplayName: A Case Study in Windows in Object-Level Security
Let's see what event logs look like in XP and Vista.
EventLog objects have "secure" methods (LogDisplayName)
Write a small program using System.Diagnostics.EventLog.GetEventLogs() method and logobject.LogDisplayName property to find and display event logs to the user. You will be flooded with SecurityExceptions! Here are the reasons!
1. Running code from an untrusted location (e.g. untrusted UNC path) - this results in the following: System.Security.SecurityException: Request for the permission of type 'System.Diagnostics.EventLogPermission' (insert culture and public key token info here) failed. Copying the assembly locally worked, but there were still exceptions.
2. Protected Registry Access - my locally-running program worked fine for Internet Explorer, Hardware Events and some others but not for My Computer. The error was: System.Security.SecurityException: Requested registry access is not allowed. The answer lay in the registry itself. Right clicking on "Eventlog" in the registry (below) revealed all.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog
This idea of "secure methods" in an API resemble the "object model guard" on the Outlook API. This prevents client programs e.g. automatically sending email on behalf of the user, without explicit user consent. A buzzword for this concept of "secure methods" is object-level security. A rather old but useful post on SecurityException debugging .NET can be found here, on the .NET security blog. "Secure methods" are also configurable in Java via the SecurityManager class.
Wednesday, 22 October 2008
How to Hunt for Easter Eggs in Python Open Source Code
Conceive a simple code block with your favourite open source library then run:
python -m pdb simple.py
Type s and hit return repeatedly to step through the code. This gets boring after 10 seconds and you'll want to do more stuff. Type help and you'll see a slew of commands.
- j [linenumber] e.g. j 10 -> you need to be a good guesser here, you'll have a problem if you jump before or after the current code block
- commands - if your program is crashing, go into pdb, type commands and hit return and you will get a magic stack trace
- cont - restart the debugger if you're at the end of traipsing through your program
quit will exit the debugger. Now explore the other commands and make a list of your top 5 favourite debugger commands.
bugs as easter eggs
pdb is a great (though basic) for bug finding. Many people find bug-finding frustrating and gripe when difficulties come their way.
Think of bug finding as looking for Easter eggs. You understand a system well when you know all the Easter eggs hidden within it.
When faced with a new bug - celebrate! Difficulties will teach you much more than random success and "first-time lucky" code - you won't learn much from those kinds of experiences. Debug patiently, study the bugs, understand fully why they happen.
real-life easter egg examples
Here's a real-life Easter egg example I found in Python's BeautifulSoup (quick introduction - Python's BeautifulSoup (needs Py2.2 upwards) has two parts: BeautifulSoup for html, BeautifulStoneSoup for xml/sgml (built on sgmllib); it has a simple object model 1) PageElement - base class for Tag and NavigableString, and 2) NavigableString - base class for CData, PI, Comment, Declaration).
Grep for "enterprise" and you will see the Easter egg!
Here's another example where the above techniques were used to find a bug in a test program f0r BeautifulSoup, where the error message alone was insufficient to find the problem. I've copied the rogue code here for your perusal. Can you find the error using pdb? (you will need to install BeautifulSoup first obviously!). Here's the code:
import sys from BeautifulSoup import BeautifulSoup
def main(args): try: html = open("file", "r").readlines()
soup = BeautifulSoup(html)
soup.prettify()
print soup
except Exception, e: print e
main(sys.argv)
Look at the code above. What is it trying to do? What precise data transformations are taking place?
This is a good example of the caution needed when plugging the output of one API as input to another API. You need a clear understanding of the data types you are dealing with, and sometimes the internal represenation of those types (e.g. concept of "blittability" in .NET). It also shows that in dynamically typed languages you sometimes need to think even more carefully about data types.
A related post on UbuWorld entitled "Dynamic Typing Doesn't Mean You Don't Have to Think About Types" explores this idea with some more examples when "type-consciousness" is vital to debugging dynamically-typed programs.
We struggle with bugs when we forget programming is not magic but a very precise art form that is heavily dependent on exact data representation for things to work together correctly. Abstraction and dynamic typing (Scylla and Charybdis or programming languages) hides complexity but abstractions break when they are assembled in unexpected ways e.g. across API boundaries as illustrated above. Cost of such simplifications is that they make debugging more difficult, by giving the illusion of simplicity. Under the covers, very precise data transformations and memory allocations and deallocations are taking place. Don't forget this. Programming is a very precise art form.
Hint: the above example requires a one-line change to get it to work.
Happy Hunting.
Save as type: Web archive, singe file (*.mht)
Saturday, 18 October 2008
"Manifestation" of Managed DLLs
Managed DLLs are sometimes referred to in Visual Studio circles as "metadata files".
Flying without Intellisense
- creates an empathy for the programmers of yore who had no auto-completion
- forces you to learn api method names accurately ....avoid conundrums like is it length or size...hmmm....I need to troll through all the auto-complete suggestions to find out which. thus it is a time-saver in the long-term.
- forces you to design api names that are easily memorable and fit for purpose. You will also be tempted (probably) to shorten complex template names with typedefs, something you probably do already, but without IntelliSense you will be forced to embrace these disciplined habits!
- In certain mixed-mode programming tasks, IntelliSense may need to be disabled for performance reasons
- sometimes the .pcb file is locked and you can't use it anyway
If you want to be an AWESOME visual studio programmer (and who doesn't) try flying without IntelliSense from time to time. It's also more physically demanding to type all those method names (think of IntelliSense as the "power steering" of Visual Studio) but it's worth it.
Ghost on Windows
Download a Windows build of GPL Ghostscript 8.63. It's a 10meg download (most of the memory being taken up by gsdll32.dll which is about 8.6MB). It is written by PDL vendor Artifex software. (PDL = Page Description Language). Also useful to grab is the graphical interface GSView. This install into C:\~PF\Ghostgum. You will need to add the following to your path:
- C:\~PF\gs\gs8.63\bin
- C:\~PF\Ghostgum\gsview
Error/Info Messages when Opening PS files
- Displaying non DSC file - DSC=Document Structuring Conventions, set of instructions Adobe wrote to maintain consistent PostScript language between drivers and platforms.
Learn Postscript
Find out more about PostScript the product and PostScript the language here.
Thursday, 16 October 2008
Programming C++/CLI (VS2005/2008)
C++CLI (formerly but sometimes still referred to as "Managed C++") is a potent technology for making C++ code intelligible from C# client programs. Fortunately or unfortunately, .NET does not have any javah style tools that can automatically generate managed C++ headers for a given c# source file. S0 for now, you have to write your headers manually. But Managed C++ also allows for much greater flexibility than Java in writing managed/unmanaged interfaces and thus more variety of designs are possible.
The main keywords in C++/CLI are as follows.
- ref -- as in "public ref class" declares a managed class or struct.
- hat operator -- e.g. in return types such as System::String^, denotes a handle to an object on the managed heap (this is a separate heap maintained by the CLR and implements asynchronous gc).
- percent operator -- this denotes a tracking reference and can apply to ValueTypes (e.g. int%) or reference types (e.g. String^%) to denote a modifiable parameter passed by reference.
- gcnew - when returning managed objects e.g. return gcnew String("kill germs"); or, if converting from an STL string, you might do something like this: return gcnew String( stlString.c_str() ).
Arguments, Return Types and the Blittability of Data Types: Strings and Arrays are non-blittable!
To make sense to C#, all return types must be CLR types and denoted as being on the managed heap using the hat operator. Inputs, though, can be C data types e.g. pointers, which are legal in C# provided pointers to stack allocated objects are used in an unsafe context, and pointers to heap-allocated (and hence managed) objects are pinned (i.e. not shifted around by the garbage collector). It is a design decision whether to allow unmanaged data as inputs into your managed C++ interface.
Certain data types are blittable across language boundaries, the standards ones for C++/C# are enumerated in this article on blittable and non-blittable types. These include System.Single, System.Double, System.Byte, System.IntPtr but NOT System.String, System.Array or System.Char. STRINGS AND ARRAYS REQUIRE SPECIAL CODE WHEN MOVING BETWEEN C# AND C++!!!
Core C# Keywords for interacting with C++/CLI are as follows:
- fixed - used to create pinning pointers. multiple pointers of the same type can be "fixed" in the same clause e.g fixed (byte* src=array1, dest=array2) {...}. Otherwise use nested fix statements. "fixed" is just syntactic sugar for GCHandle.Alloc(pointer_into_some_array, GCHandleType.Pinned).
- GCHandle - see fixed, relates to handling a managed type from unmanaged memory. Four kinds of GCHandle can be created, a pinned handle (commonly used), a normal handle, Weak handle and WeakTrackResurrection. GCHandles are allowed to be value types, the reason for this is that the lifetime of a GCHandle is controlled by Alloc and Free and not the garbage collector. Don't get too excited though - ARRAYS of GCHandles still need to be created on the managed heap!
Also, take a look at this msdn example. Two other fundamental concepts in Managed C++ are pinned pointers and interior pointers. Interior pointers are pointers into the CLI heap which point to managed objects (or members thereof) and thus have a magical "dynamic" property which normal pointers do not have (and do not need), namely tracking objects as they move through the heap. As we will discuss later, care must be taken when converting between interior pointers and pinned pointers!
System.Array class
It is worth knowing this class well, since it is the base class for all arrays in the CLR! Avoid provoking errors like "Add is not a method of System::Array". Also, as we know, arrays do not transmit seamlessly between C# and C++. Let's get down to business. Array is a "ref" class and an "abstract" class - only instantiable in its derived form. Despite this you can't derive from Array directly. If you try you get the error "cannot derive from special class 'System.Array'". Useful methods and properties:
- Length (property). 32 bit integer representing number of elements. For a multidimensional array, call it d, to find the number of elements allocated for the first vector, we need d[0].Length. For 64 bit we need to use LongLength.
In C# the basic syntax for defining a (rectangular) multidimensional array is as follows:
int [,] myArray = new int[2,2]; myArray[0,0] =1; myArray[0,1]=2;
But this is not the only syntax. There is also a syntax for jagged, or non-rectangular, arrays. It looks like C++ (although you can't define arrays in C++ as below, you need subscripts, and brackets following the variable name rather than preceding it, but that's by the by):
double[][] locationCodes = new double[2][]; locationCodes[0] = new double[3];
These jagged arrays can be represented in Managed C++ using the templated form of the Array class: array<array<double>^>^ locationCodes = gcnew array<array<double>^>(num_arrays);
Can I pin a multidimensional array?
The short answer is no. A multidimensional array contains System.Arrays, which are non-blittable types and .NET DOES NOT ALLOW PINNING OF ARRAYS OF NON-BLITTABLE TYPES (GCHandle will generate a run-time exception). Pinning an array of primitive types is not a problem.
If you pin an array of arrays by a) pinning the subarrays b) pinning the main array (using a pinning pointer, as GCHandle won't allow pinning of arrays of non-blittable types) your program will compile. However, passing in your MD array from C# to Managed C++ then forwarding to a native C++ function (which copies the arrays) may result in a System.AccessViolationException: Attempted to read or write protected memory.
Let's work on the idea of pinning subarrays for a moment. How do we store the pinned pointers? In an array perhaps? An STL vector of pinned pointers will create pointers to pinned pointers, this is illegal - "pointer to pinned pointer disallowed by CLR". A native array defined using [] is illegal too - since "a native array cannot contain a managed type". A managed array (array<pin_ptr<double>>^ is illegal - "a managed array cannot have this type". Neither can you have an array of references to pin_ptrs because both pointers and references to pinned pointers are illegal. The bottom line is you can't store pinned pointers in a collection. What you can store, though, are GCHandles. So, to create an array of pinned pointers, the trick is: gcnew an array of GCHandles, use Length to find the number of pointers in the array, loop from i=o to maxdimensions, then use GCHandle::Alloc to pin the vectors in each dimension. You will then need to use pin_ptr to pin the array of pointers (GCHandle won't work since it doesn't pin Arrays of non-blittables).
GCHandles and pin_ptr are synergistic. What can a GCHandle do that a pin_ptr cannot do? Answer: GCHandles can be stored in collections. What can a pin_ptr do that a GCHandle cannot do? Answer: a pin_ptr can point to an array of a non-blittable type.
Copying Arrays
Given the complexities of using pin_ptrs and GCHandles, an easier alternative to interfacing with C and C++ functions is to simply copy managed arrays into their unmanaged equivalents. Here Marshal.Copy proves useful. (Marshal is one of the core classes in InteropServices).
Marshal.Copy copies data from managed arrays to unmanaged pointers and vice versa. Only problem is - it's designed for one-dimensional arrays. To copy multidimensional arrays into unmanaged memory, you need to write your own custom marshaller. This is easy provided you know how to program in C (knowledge of simple facts like - malloc returns void*, I need to cast it to a pointer to my specific data type e.g. int* or double*). Knowledge of C# is not enough, you need to know BOTH C AND C++ to be an awesome interop specialist. There is no restriction on the use of malloc and free from within managed C++ classes - use them to your advantage.
C++CLI MindMatter
Herb Sutter's blog - http://blogs.gotdotnet.com/hsutter/. Herb Sutter is the cool dude who brought us GOTW and joined MSFT's Developer and Platform Evangelism Division in 2002 to create more awesome C++ experiences in Visual Studio. Another very good post on malloc, new and custom memory allocation (useful in MC++) can be found here. And another interesting blog post on design choices in interop here.
C++/CLI is also formalised in an ECMA standard, number 372.
C++/CLI Programming Style (typedefs and pointer conversions)
If you decide to use typedefs for managed types e.g. typedef pin_ptr
Differences between C++ and Managed C++ (C++/CLI)
Can't supply default arguments to member functions of managed type, C3222.
Care with the Delete Operator
Calling delete twice on the same pointer officially results in undefined behaviour. In MSVC it results in the message: "Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse). Calling delete on null pointers is safe though so it is good to set pointers to NULL after delete.
A double delete may happen in a ref class if a destructor and finalizer both delete the same unmanaged pointer.
Deterministic and Nondetermistic Finalization
"ref" classes in CLI extend IDisposable (automatically) and call the (deterministic) destructor when obj.Dispose() is called.
Criticism of CLI
There are a number of objections to CLI.
Wednesday, 15 October 2008
.NET Data Binding Architecture
BindingNavigator
The Data Binding Idiom is a Good One.
But let's say I have a dozen controls all on one form, each with different binding requirements. How scalable is this metaphor? Do I create new BindingSources for each one?
Classic C# Programming Offences (includes Managed C++ Gotchas)
- Not declaring your constructors as explictly public (unless of course you are programming a singleton) [minus 10 points]
- Trying to resize a text box vertically, when the multi-line property is set to false. [minus 5 points]
- Trying to click on the toolbox in Visual Studio when you're not in Design View. [minus 9 points]"
- Looking up the "Editable" property in a control when the correct property is "Read-only" (old school!) [minus 3 points]
- Using \n in a text box and expecting a newline (you need \r\n) [minus 5 points]
- Trying to pin the memory of a stack-allocated object like so: double d=5; fixed (double* ptrd = &d); you will get the error "cannot use fixed to take address of an already fixed expression". [minus 10 points - shows a fundamental lack of understanding of .NET memory management]
- Trying to create an array or vector of pinned pointers. [minus 5 points]
- Using new instead of gcnew in a Managed C++ program [minus 1 point]
- Returning null instead of NULL from Managed C++ (reversed for C#) [minus 5 points - you don't know MS C Compiler]
- Using ref to pass a reference type rather than a value type [minus 20 points]
- Trying to add a Scrollbar to a Panel (use AutoScroll property!) [minus 2 points]
- Writing a callback function as private.
Tuesday, 14 October 2008
Exploring DLLs using PE Explorer (I recommend the Export Viewer!)
Cntrl-F for "entry" which takes you to the DLL entrypoint which should look something like this:
push ebp
move ebp, esp
etc
EBP is the (32-bit) frame pointer or the base pointer, unlike the stack pointer ESP, the base pointer is only manipulated explicitly. ESP always points to the last element used on the stack (NOT the first free element).
Cntrl-E takes you to the Export Viewer.
Monday, 13 October 2008
Visual Studio Multi-Targeting Support
http://weblogs.asp.net/scottgu/archive/2007/06/20/vs-2008-multi-targeting-support.aspx
Getting your Head Around Layout Management in Visual C#
Friday, 10 October 2008
How good is DevExpress for Visual Studio .NET?
XtraCharts suite - Harvard Graphics style pie charts (2d and 3d), donut charts, Gantt charts
XtraPivotGrid - integrates with charts, nice!
Sunday, 5 October 2008
Embrace the API: Programming Model Re-engineering (aka Aggressive API refactoring)
Flex versus WPF
Despite the pain of adapting to new programming models, libraries need to adapt to change, which means PEOPLE (consumers) also need to change. This brings me on to my next point concerning PEOPLE'S ATTITUDES to programming model re-engineering.
"The difference between greatness and mediocrity in Windows programming can be perceived in many ways. One metric is the speed by which the Windows Programmer can quickly adapt to radically different programming models. The Great One will be able to assimilate new APIs massively quickly and start programming in them straight away, no matter how intractable and problematic the API may initially seem. On sensing a new API approaching, the senses of the Windows programming are immediately sharpened, instinct kicks in and a process of lightning-fast power-learning is initiated. The millions of programs the Great One has written are instantly referenced and put into the context of the new API function calls. Automatic memorisation commences. Like an avid art collector, the SuperPower Windows Programmer desires to acquire API mastery swiftly and add to their ever-expanding skills collection. The SuperPower Windows Programmer may even be willing to embrace functionally-inferior but more modern APIs . Contrast this with the mediocre programmer, their emotional response is a negative one, a slow process of gradual learning and conscious and pained memorisation commences. Thus SuperPower Windows Programmers are quantum leaps ahead of their sub-par rivals. They are like eagles soaring above, surveying everything, their rivals are like meerkats down below, constantly digging up the dust to hide from predators".
Friday, 3 October 2008
Mantra-Based Programming and the "Programming Athlete"
If you feel your coding session is going haywire take the following actions. Consciously control the flow of your thoughts, don't act/code anything without feeling you are in a state of calmness and complete control over your coding. Stop time in your own mind. Stop being a whirlwind, breathe and see the bigger picture.
Use mantras to refocus your mind.
Then go back and finish your program.
Prototyping Numerical Algorithms in Windows - Excel as a Viable Alternative to Matlab
Writing a Custom Worksheet Function in MS Excel (Alt-F11, Alt-Q)
Excel is a remarkable product that can be customised. Starting with the basics, everyone should know how to write a custom worksheet function in Excel. Example: Write a worksheet function that returns 2*PI.
Alt-F11 (make sure the cell is not in edit mode)
Function TwoPi() As Double
TwoPi = 2 * Excel.WorksheetFunction.Pi
End Function
Alt-Q
Excel worksheet functions only recalculate when their inputs change. If you change the definition of the function, and the arguments remain the same, the function will not recalculate with shift-F9. I discovered this bug when I tried to change a function definition dynamically at run-time, using a set of cells to specify coefficients. Changed the def, pressed shift-F9 and ... nothing happened.
Macro Security (Digital Signed Macros)
If your macro security level is set to high you will only be able to run signed macros from trusted sources. Alt-TMS will allow you to change your settings. Alt-TD in the VBA editor will help you set digital signatures for your macros.
Option Explicit
When developing algos in VB Option Explicit is your friend. Avoid creating variable names implicitly, which can lead to difficulty debugging your algorithm.
Function Overloading in Excel VBA Macros
This is not allowed. Any attempt to do so will result in "Ambiguous Name detected". I think this is ok for the simplicity of the language. You can get round this by putting version numbers on your overloaded functions.
Name Lookup Bugs in Excel 2002
Create custom worksheet function. Call it F. Rename it to F1. Rename it to F. #NAME error. Rename it back to F1. It works. May need to do a few iterations before you see the bug.
There are other name lookup errors that can occur which are not bugs. For example, editing a function in a module in worksheet A and testing it out in worksheet B will not work. Each worksheet is effectively a separate namespace.
Min/Max in Excel VBA
Amazingly VBA doesn't have a min/max function!!! So use Excel's instead (example: Application.Max(5,2)).
Random Number Generation
In Matlab you can use the function rand(10) to choose a number between 1 and 10. To do this in Excel you can use the function RANDBETWEEN(1, 10) but this relies on Analysis ToolPak being a valid add-in in your Excel. If you don't have access to Analysis ToolPak you can write the following worksheet function:
Function Random() as Double
Randomize: Random = Excel.WorksheetFunction.Ceiling( Rnd * 10, 1)
End Function
Custom Worksheet Functions in C#
Msdn Blog Post on Excel C#.
Programming Addicts
Furthermore, are some programmers addicted to both programming AND exercise? What drives people to such addiction?
"Exercise addiction" is a term coined by Dr William Glasser , the "Warren Buffet of psychiatry", in a 1976 study of long-distance runners. He identifies a negative addiction when a SINGLE DAY away from the gym or pool causes distress. For some programmers, perhaps a day away from programming causes distress, hence we see the parallel's with Glasser's study.
But Why? Is it the endorphins of exercise, the joy of achieving something or just the impulse of crazy competition taking control of our psyche?
Originally a chemical engineer, Dr Glasser went into psychiatry when he realised that was his real interest in life. Who can blame him? Psychiatry is an important and fascinating discipline! As Donald Trump famously states: "Don't Waste Your Life on Work You Don't Love; Passion Will Help You Do Better". Read the blog of The Donald here.
In the 5th Century BC, psychotic traits were considered supernatural in origin (see wikipedia).
The Relevance of Charles Petzold's Programming Windows in a Modern .NET World
Some might say that the Mighty Programming Windows using C and the Windows API is a topic only of historical relevance. Certainly the modern .NET programmer has no business using the Windows API in day-to-day programming ...in theory. What happens when an API function isn't exposed in the .NET framework. Well, we could just expose it manually in .NET and be done with it ....do we really need to know what's going on inside, or read a thousand plus pages to work out Windows' inner workings?
It all boils down to one thing. Do you WANT to be the best Windows programmer in the world or don't you? If the answer is an unwavering, unhesitating YES then you NEED, I repeat, NEED, to read Charles' book on Programming Windows quick-time. Don't delay.
Charles talks about the history of Windows and facts every aficionado of the operating system should know of the top of their hat - starting from Windows 1.0 "tiled windows" release in November 1985, the year "Iron Mike"/"The Baddest Man on the Planet" made his professional debut in Albany, NY, moving on to Windows 2.0 in 1987 (overlapping windows), the year the NY Giants defeated the Denver Broncos in the SuperBowl, then Windows 3.0 in 1990 (support for 16-bit protected mode in 286 and upwards), the year 300,000 people in Lithuania demonstrated for independence.
In April 1992, the legendary Windows 3.1 was released (a few months later in September, Black Wednesday took place, knocking the pound and lira out of the ERM). Hello TrueType fonts, OLE (remember OCX controls?) and standardized dialog boxes. Then Win95 in 1995 and Win98 in 1998. Charles summarises that the "Windows API has remained quite consistent since Windows 1.0" except in the area of function calls: "Windows 1.0 supported fewer than 450 function calls; today there are thousands". He also underlines the differences between Win16 and Win32. If you don't know about this, read the book.
The first program, which starts with #include windows.h
Good Programming Blogs (not just OK ones)
Also check out this list of the top CLR bloggers.