Skip navigation

Tag Archives: C++

Just came across this in a C code apple example:

do
{
  // stuff..
} while (false);

The code breaks the loop when an error occurs inside it. This is kind of like try/catch/finally, where you have a simple catch(…) all block that you jump to if you “break” the loop. It seems like a poor substitute for a function call however.

Some artifacts may arise. For example, say you inherit from std::string. You want to write a function that ends up calling a method from std::string that returns a std::string: (like .substr()). Now you have an extra ctor call to construct your derived type object –

I effectively had this:

void fun( const char* msg )
{
  function = [msg](){
    // do something with msg
  }
}

Then call:

fun( string( "oh hi hello" ).c_str() ) ;

See what’s wrong? The string object whose char* ptr I passed to fun _dies_ immediately after the line executing call to fun runs. So the captured const char* ptr [msg] is invalid if function() runs at a later time (after return of call to fun())

Using integer indices into arrays of objects (instead of iterators, or pointers to the objects themselves) has saved my ass many times.

Say you have a vector<Object>. Well, you wouldn’t store pointers of type Object* to an element of this array, ever, because if the vector gets resized, all objects get deallocated/reallocated and so all your previous references will be invalid. But if you store a vector<Object*> and save an external reference to an Object* within that vector, then that’s no problem.

But anyway, storing integer arrays is much better than storing copies of pointers. For one, if the pointer gets deleted, you’re not left with an invalid / dangling pointer somewhere. Checking if a reference into the array is valid because you just have to check the integer index is between 0 and (.size()-1).

C++’s RTTI is expensive. Very expensive. Notoriously and verifiably expensive.

So how can we efficiently get information of the concrete subclass, given an abstract base class pointer, without the great expense of using RTTI?

Simple. Use an enum.

Consider the example in my stackoverflow post. What I did there is just keep a single bitfield (an int) that has concrete types bitwise OR’d in, in each derived constructor.

So, in the example posted, an object of Type BigCat would have 0111 for its typeTag field, indicating that it is an Animal, a Cat, and a BigCat. Concrete type checking is cheap as a bitwise AND.

I ran into this error before, it is described here. Basically preface whatever the offending line is with this->.

What’s wrong with this code?

class Object{
  int x ;
  Object() {
    defaults() ;
  }
  Object( int ix ) : x(ix) {
    defaults() ;
  }
  
  defaults() { 
    x=0;
  }
} ;

Well, obviously x has the value 0, instead of the initializer-list desired default value sent `ix`.

So, what happens when you have 10-15 members that all have default value initialization in defaults(), and possible assignment in the initializer list, is defaults() clobbers whatever was sent to the initializer list, since the initializer list runs first.

Well, a surprising result, never use your extern variables inside a function that runs before main.

Here’s an example:

In the header:

//extern test.  the externs are giving 0's.
struct Vector4f
{
  float x,y,z,w;
  Vector4f():x(0),y(0),z(0),w(0){}
  Vector4f( float ix, float iy, float iz, float iw ) :x(ix),y(iy),z(iz),w(iw){}
} ;

extern Vector4f Red ; // This is the weird variable..

In the main.cpp file:


static map<char, Vector4f> initMapping()
{
  map<char, Vector4f> mp ;
  mp.insert( make_pair( 'r', Red ) ) ;
  
  for( auto &p : mp )
    printf( "%c: %f %f %f %f\n", p.first, p.second.x, p.second.y, p.second.z, p.second.w );
  return mp ;
}

//Vector4f Red(1,0,0,1) ; // if this is here, Red has (1,0,0,1)
map<char, Vector4f> colorMapping = initMapping() ;
Vector4f Red(1,0,0,1) ; // if Red is only given its value HERE, when the static ctor runs, Red will be (0,0,0,0)

int main(int argc, const char * argv[])
{
  for( auto &p : colorMapping )
    printf( "%c: %f %f %f %f\n", p.first, p.second.x, p.second.y, p.second.z, p.second.w );
}

So those 2 declarations of Vector4f Red (without extern qualifier) in the cpp are the issue here. If the compiler runs into the Vector4f Red(1,0,0,1) ; BEFORE running SomeStruct::initMapping(), then the mapping has the correct value for Red in it. If the compiler first runs into Vector4f Red(1,0,0,1) only __after__ running SomeStruct::initMapping(), then the value of Red inside the map would be all 0’s.

Funky Inheritance

Or functor-based inheritance

Funky inheritance is my name for when you allow attachment of functors to specify behavior instead of always just subclassing.

This came up recently in some UI event handling code that I was writing. Buttons come and go, dialogs appear and get dismissed. Each dialog dismissal button (okButton) needs something specific to happen, but that same functionality is extremely unlikely to be reused in another dialog.

Normally, to write an object type that has customizable behavior (by a subclass), you would write a base class like this:

class Dialog
{
  virtual void onDismiss() = 0 ;
};

So, when you subclass Dialog, you override onDismiss to provide custom behavior that occurs when the dialog is dismissed (assume onDismiss would be invoked by a window manager).

class FileOpenDialog : public Dialog
{
  virtual void onDismiss()
  {
    // stuff to do when the FileOpenDialog is dismissed..
  }
};

So, that’s the regular (classical) inheritance pattern. Every time you want different functionality onDismiss(), you’d write a new subclass of Dialog. Another way to get custom code to run onDismiss is to allow onDismiss() to accept a functor that can be invoked …

class FileOpenDialog : public Dialog
{
  virtual void onDismiss( function <void ()> runThisAfter )
  {
    // stuff to do when the FileOpenDialog is dismissed..
    // then..
    runThisAfter() ;
  }
};

OR

You could write onDismiss as a functor in base class Dialog instead of using classical inheritance here:

class Dialog
{
  function< void (Dialog* that) > onDismiss ;
};

Now onDismiss is a functor (that may or may not be set).

So then customized behavior is by instance, not by class. Creating a FileOpenDialog object would then be like:

Dialog fileOpenDialog ;
fileOpenDialog.onDismiss = [](Dialog* that) {
  // Do something with `that`, which acts as `this`
  // if this were a member function ;)
} ;

When the window object handler finds out a dialog has been dismissed, it invokes the onDismiss handler if it has been set.

// It is detected that fileOpenDialog needs to be closed:
if( fileOpenDialog.onDismiss )
  fileOpenDialog.onDismiss( fileOpenDialog ) ;

// Above line manually passes `this`.
// If I am not mistaken, this is considered "Pythonic" (just kidding,
// but Python does require passing of self in a similarly visible fashion)

This may come across to you as very JavaScripty- or follow a prototypal inheritance pattern. But it actually isn’t prototypal inheritance, because objects do not inherit from other objects. Each instance of Dialog has its own behavior, that is not repeated by any other instance of Dialog.

Of course, this would need some more detail and fleshing out to really work. But this is the jist of funky inheritance. Regular inheritance is class-wide customization. Funky inheritance is instance-wide customization. Funky inheritance is great for when you need to define custom behavior (often one-off, for a button or a widget) without having to define an entire subclass.

Drawbacks of Funky Inheritance

Functors are unable to persist their own internal running state except as static variables. However statics inside a functor are inaccessible from outside the functor. This means modification of a functor’s internal values is difficult/impossible from outside the functor. So, that kind of sucks sometimes.

One way you can modify a functor’s internal state variables is to capture a pointer before entering the functor:

Object * someObject = new Object() ;
functor = [ someObject ]() {
  // now if someObject is modified outside the functor,
  // I will use "the most up to date" version of someObject.
} ;

Functors seem to be best used to send global state messages or somehow modify global state. For example, if a FileOpenDialog is modal, it may flip off the `modal` flag inside your window manager when it is dismissed. Functors are also useful to modify the object running the functor’s state as well.

I created an xml file with my newest XCode C++ theme.

It looks like this:

So, gray background, white text, all numeric constants and defines are kinda blue, classes are purple, and C preprocessor macros are red.

Starting from my previous program (Windows), connecting in Mac OS X is even EASIER, only there are a couple’a gotchas.

To code with MYSQL in Mac OS X, just install MySQL normally. In fact it comes with the `/include` and `/lib` folders when you installed it. They are in `/usr/local/mysql` (which is a link to the specific version you have).

Ok, now that’s done, here’s your C++ program:

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/mysql/include/mysql.h"

MYSQL mysql;    // MYSQL global
MYSQL * conn ;  // represents connection to database

int main()
{
  mysql_init( &mysql ) ;
  
  //   http://dev.mysql.com/doc/refman/5.0/en/mysql-real-connect.html
  conn = mysql_real_connect(  &mysql,
                              "localhost",// synonymous with 127.0.0.1
                              "root",     // connect as user="root".  Uh, bad security here..
                              "",         // my root password is blank.  REALLY bad security :)
                              "mysql",    // connect to the 'mysql' _database_ within MySQL itself.
                               0, 0, 0 ) ;
  
  // Check if connection succeeded.
  if( !conn )
  {
    printf( "Couldn't connect to MySQL database server!\n" ) ;
    printf( "Error: %s\n", mysql_error( &mysql ) ) ;
    return 1 ;
  }
  //else  puts( "Connect success" ) ;
  
  // Here, we are connected.
  // form a sql string to execute.
  if( mysql_query( conn, "select * from user" ) )
  {
    printf("Whoops!  The query failed.  Error:  %s\n", mysql_error( conn ) );
    return 1 ;
  }

  // here, query succeeded, so we can proceed to pull out results.
  MYSQL_RES * resultset ;
  MYSQL_ROW row;  // MYSQL_ROW is #defined as (char **)
  // Data ALWAYS comes back from MySQL as
  // an array of strings.  To convert it
  // to ints or whatever is YOUR JOB as the programmer.

  // mysql_store_result basically fetches
  // the entire array of results and dumps them
  // into our local program memory space (all
  // in the resultset variable.
  resultset = mysql_store_result( conn );

  // How many rows will there be?
  my_ulonglong numRows = mysql_num_rows( resultset ) ;
  printf( "There are %llu ROWS (records) of data\n", numRows ) ;
  
  // Now tell me what columns there are
  // in the result set.
  int numFields = mysql_num_fields( resultset ) ;
  printf( "There are %d FIELDS (columns) of data\n", numFields ) ;

  // Print all those column by name
  MYSQL_FIELD * fields = mysql_fetch_fields( resultset ) ;
  for( int i = 0 ; i < numFields ; i++ )
  {
    printf( "%25s", fields[i].name ) ;
  }

  printf( "\n" ) ;
  // print all results
  while( (row = mysql_fetch_row( resultset )) )
  {
    // row is 2d array of char
    // underlying type is char **
    for ( int i = 0; i < numFields ; i++ )
      printf( "%5s", row[ i ] ) ;
    
    puts( "" ) ;    // next row
  }
  
  mysql_free_result( resultset );  // Now free the result
  mysql_close( conn ) ;  // And close down.
  return 0;
}


GOTCHA #1: An easy one, but you need to link up your TARGET with the libmysqlclient.a library file. So goto your TARGETS / BUILD PHASES tab, under “Link Binary With Libraries” go select “libmysqlclient.a” from /usr/local/mysql/lib.
GOTCHA #2: This is the stupid one, COPY /usr/local/mysql/lib/libmysqlclient.18.dylib to /usr/lib/. ISN’T THAT DUMB??? Well it’s the eq of copying a DLL to C:\Windows\System32 on Windows. Just something you have to do.

If you don’t copy the .dylib you’ll get Library not loaded: libmysqlclient.16.dylib reason: image not found.

The easiest.

1. Mac OS X

sudo apachectl start

Make sure cgi is enabled in your Apache settings

sudo vi /etc/apache2/httpd.conf

Create and build the following:

#include <stdio.h>

int main(int argc, const char * argv[])
{
  //puts( "HTTP/1.1 200 OK" ) ;
  puts( "Content-Type: text/plain; charset=UTF-8" ) ;
  puts( "Status: 200 OK" ) ;
  puts( "" ) ;
  puts( "HELLO INTERNET" ) ;
}

The default folder Xcode 4.6 dumps the exec in is

/Users/YOURUSERNAME/Library/Developer/Xcode/DerivedData/PROJECTNAME-andabunchofrandomcharacters/Build/Products/Debug/PROJECTNAME

Take the exec (called PROJECTNAME) and drop it into:

/Library/WebServer/CGI-Executables/

hit http://localhost/cgi-bin/YOUREXECNAME

It should say HELLO INTERNET.

You are on your way to C++ internet freedom

You could compute them using factorials, but this is far more efficient.

// Computes n CHOOSE k
// ( n )
// ( k )
int binomial( int n, int k )
{
  // must accumulate nums/dens separately
  // to avoid roundoff error
  int nums = 1;
  int dens = 1;
  for( int i = 1 ; i <= k ; i++ )
  {
    nums *= ( n - k + i ) ;
    dens *= i ;
  }
  return nums/dens ;
}

//test
int p=7;
for( int i = 0  ; i <= p ; i++ )
  printf( "%dx^%d +", binomial(p, i), p-i ) ;
puts("");

This is a makeString() function that works like printf(). Gives you a std::string from a printf()’d one, so you can stop using sprintf() all the time and NEVER use ostringstream!

string makeString( const char *fmt, ... )
{
  va_list args ;
  va_start( args, fmt ) ;
  char msgBuffer[ 4096 ] ; // max len.  Can also use a strlen call to avoid over alloc
  vsprintf( msgBuffer, fmt, args ) ;
  return string( msgBuffer ) ;
}

I want to believe iteration style doesn’t make a difference as much as the next guy, but the fact is, it does.

In order, performance goes

For std::vector:
integer indexing FASTER THAN range based for FASTER THAN traditional iterators

For std::list:
range based for FASTER THAN traditional iterators

You can quote me on that. A test below proves it with a simple example.




#include <stdio.h>
#include <vector>
#include <list>
using namespace std ;

/////#include "Timer.h" // TIMER.h pasted below
#include <sys/time.h>

struct Timer
{
  timeval start ;
  
  Timer() { reset(); }
  
  void reset() {
    gettimeofday( &start, NULL ) ;
  }
  
  double getTime() const {
    timeval end ;
    gettimeofday( &end, NULL ) ;
    
    return end.tv_sec - start.tv_sec + (end.tv_usec - start.tv_usec)/1e6 ;
  }
  
} ;


struct O{
  int a ;
  float b;
  
  O( int ia, float ib ):a(ia),b(ib){}
  
  void print()
  {
    printf( "%d %f\n", a,b ) ;
  }
  
  void doIt()
  {
    a++;
    b++;
  }
} ;

int TESTS = 10000000 ;

int main(int argc, const char * argv[])
{
  vector os ;
  
  os.push_back( O(2, 2.2 ) ) ;
  os.push_back( O(3, 3.3 ) ) ;
  os.push_back( O(4, 4.4 ) ) ;
  
  Timer t ;
  
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( vector::iterator iter = os.begin() ; iter != os.end(); ++iter )
    {
      iter->doIt();
    }
  }
  printf( "TRADITIONAL ITERATOR : %f\n", t.getTime() ) ; // 0.755 sec
  
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( O& entry : os ) // note: if you pass by value, it's even faster
    {
      entry.doIt();
    }
  }
  printf( "NEWFANGLED RANGE BASED for : style Time %f\n", t.getTime() ) ; // 0.493 sec
  
  
  t.reset();
  for( int i = 0 ; i < TESTS ; i++ )
  {
    for( int j = 0 ; j < os.size() ; j++ )
    {
      os[j].doIt();
    }
  }
  printf( "INTEGER INDEXING Time %f\n", t.getTime() ) ; // 0.243 sec
  
  
  
  
  
  
  return 0;
}

Here’s a C++ function:

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
{
  return A<<(3*8) + B<<(2*8) + G<<(8) + R ; //LE
  //return R<<(3*8) + G<<(2*8) + B<<(8) + A ; //BE
}

What’s wrong with it?. Why doesn’t it return the correct value? Try and guess! No cheating!

Is it the bitshifting being wrong? No, that’s right

Is it that R, G, B, and A are Byte type, and Byte overflows? Nope, they are automatically promoted to int.

So guess what it is? GUESS!

YOU KNEW IT!! OPERATOR PRECEDENCE!

Bitshift has a precedence lower than +. So the shifting is off (and by WAY too much in most cases!)

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
{
  return (A<<(3*8)) + (B<<(2*8)) + (G<<(8)) + R ; //LE // works
  // You could also change to bitwise OR, which has lower prec than +
  return A<<(3*8) | B<<(2*8) | G<<(8) | R ; //LE // works
}

Arbitrary axis angle rotation C++ code, ROW MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
{
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  
  //ROW MAJOR
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c + u.z*s,        u.x*u.z*l_c - u.y*s,  0,
          u.x*u.y*l_c - u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c + u.x*s,  0,
          u.x*u.z*l_c + u.y*s,      u.y*u.z*l_c - u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;
}

Arbitrary axis angle rotation C++ code, __COLUMN__ MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
{
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  
  //COLUMN MAJOR
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c - u.z*s,        u.x*u.z*l_c + u.y*s,  0,
          u.x*u.y*l_c + u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c - u.x*s,  0,
          u.x*u.z*l_c - u.y*s,      u.y*u.z*l_c + u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;
}

I didn’t initialize the filename member:

GetOpenFileName fails if you do _not_ write a blank string to ofn.lpstrFile

Be sure to

 

sprintf( ofn.lpstrFile, “” ) ;

 

before calling OpenFileName

A simple template, to find the minimum of 3 numbers.

Can you find the bug in this code?

  template<typename T> inline T min3( const T& a, const T& b, const T& c )
  {
    if( a < b && a < c )  return a ;
    else if( b < a && b < c ) return b ;
    else return c ;
  }

Hint: Actually I’m not going to give you any hints. But it is possible for the above function to return the incorrect value.

Its not hard

Using Rich Edit controls
How to format text in rich edit controls

#include <windows.h>
#include <CommCtrl.h>
#include <Richedit.h>
#include <stdio.h>

HWND main, re;
#pragma comment( lib, "comctl32.lib" )

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );


void setColor( HWND richEditCtrl, COLORREF textColor, COLORREF bgColor )
{
  CHARFORMAT2 cf ;

  cf.cbSize = sizeof( CHARFORMAT2 ) ;
  cf.dwMask = CFM_COLOR | CFM_BACKCOLOR | CFM_EFFECTS2 ; // I'm setting only the style information
  
  cf.crTextColor = textColor ;
  cf.crBackColor = bgColor ;
  cf.dwEffects = CFE_BOLD ;
  
  SendMessage( richEditCtrl, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf ) ;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPInst, char* line, int show)
{
	InitCommonControls() ;
  LoadLibrary(TEXT("Msftedit.dll"));
  

  WNDCLASSEX wc = { 0 };
  wc.cbSize = sizeof( WNDCLASSEX ) ;
  wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wc.hInstance = hInstance;
  wc.lpfnWndProc = WndProc ;
  wc.lpszClassName = TEXT("rt");
  wc.style = CS_HREDRAW | CS_VREDRAW;

  if( !RegisterClassEx(&wc) )
    FatalAppExitA( 0, "Couldn't register window class!" ) ;
	
  main=CreateWindowEx( 0, L"rt",L"title",WS_OVERLAPPEDWINDOW,64,64,640,480,0,0,hInstance,0);
  if( !main ) 
    FatalAppExitA( 0, "Couldn't create main!" ) ;
	
  // http://msdn.microsoft.com/en-us/library/bb774367(VS.85).aspx
  re=CreateWindowEx(0, MSFTEDIT_CLASS, TEXT("Hi!  Click anywhere on the bar above.\n"),
        WS_VISIBLE | WS_CHILD | WS_VSCROLL |
        ES_MULTILINE | ES_LEFT | ES_NOHIDESEL | ES_AUTOVSCROLL | ES_READONLY,
        0, 0, 640, 480, 
        main, NULL, hInstance, NULL);
  if( !re )
    FatalAppExitA( 0, "Couldn't create your rich text box!" ) ;

  CHARFORMAT2 cf ;
  cf.cbSize = sizeof( CHARFORMAT2 ) ;
  cf.dwMask = CFM_COLOR | CFM_BACKCOLOR | CFM_EFFECTS2 ; // I'm setting only the style information
  cf.crTextColor = RGB( 255, 0, 0 ) ;
  cf.crBackColor = RGB( 255,255,255 ) ;
  cf.dwEffects = CFE_BOLD ;
  SendMessage( re, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf ) ;
	
  ShowWindow(main,show);
  ShowWindow(re,show);

	MSG Msg={0};
	while (GetMessageA(&Msg,0,0,0))
	{
		TranslateMessage(&Msg);
		DispatchMessageA(&Msg);
	}
	return 0;
}


LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    // upon creation, let the speaker beep at 50Hz, for 10ms.
    Beep( 50, 10 );
    return 0;
    break;

  case WM_PAINT:
    {
      // we would place our Windows painting code here.
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );

      // draw a circle and a 2 squares
      Ellipse( hdc, 20, 20, 160, 160 );
      Rectangle( hdc, 50, 50, 90, 90 );
      Rectangle( hdc, 100, 50, 140, 90 );

      EndPaint( hwnd, &ps );
    }
    return 0;
    break;

  case WM_SIZE:
    {
      int w = LOWORD( lparam ) ;
      int h = HIWORD( lparam ) ;
      MoveWindow( re, 0, 0, w, h, true ) ;
    }
    break;

  case WM_CHAR:
    switch( wparam )
    {
      case VK_ESCAPE: 
        PostQuitMessage( 0 ) ;
        break ;
    }
    break ;

  case WM_NCHITTEST:
  case WM_LBUTTONDOWN:
    {
      int x = LOWORD( lparam ) ;
      int y = HIWORD( lparam ) ;
      TCHAR buf[280];
      wsprintf( buf, L"Mouse is @ (%d, %d)\n", x, y ) ;

      // Move the caret to the end
      CHARRANGE crg = { LONG_MAX, LONG_MAX } ;
      SendMessage( re, EM_EXSETSEL, 0, (LPARAM)&crg ) ;

      // select random text color
      setColor( re, RGB( rand()%256, rand()%256, rand()%256 ), RGB( rand()%256, rand()%256, rand()%256 ) ) ;
      
      SendMessage( re, EM_REPLACESEL, TRUE, (LPARAM)buf ) ;
       

    }
    break ;

  case WM_RBUTTONDOWN:
    {
      // clear it with SETTEXTEX
      SETTEXTEX st ;
      st.codepage = CP_ACP ; // ansi codepage
      st.flags = ST_KEEPUNDO ;

      SendMessage( re, EM_SETTEXTEX, (WPARAM)&st, (LPARAM)"Cleared" ) ; // OVERWRITES all text
    }
    break ;

  case WM_DESTROY:
    PostQuitMessage( 0 ) ;
    return 0;
    break;

  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}

Its a bit weird, but IDXGIKeyedMutex::AcquireSync has a parameter called Key. The docs state:

Key [in]
Type: UINT64

A value that indicates which device to give access to. This method will succeed when the device that currently owns the surface calls the IDXGIKeyedMutex::ReleaseSync method using the same value. This value can be any UINT64 value.

Observations:

  • - The first AcquireSync call __Must__ be made on 0, otherwise the app hangs forever
  • - If you Acquire on 0, and you release on 1, then the next person to pick up __must__ pick up on 1

Useful if ordering. Say A picks up the mutex on 0. Then, there are 2 objects B and C that must go in the order B, C. So:

– A PICKS UP 0, RELEASES on 1
– B picks up 1, releases 2
– C picks up 2, releases 0

Now they are going in a cycle, A,B,C,A,B,C…

C cannot go before B (because it will block until B releases on 2).

If you’re not ordering, you can just always use 0 for the key.

Its weird to choke in dtor, but I had this situation where I was _inserting into a vector_, and getting a weird bug.

Naturally I start to think “must be a compiler bug..”

And you know when you get that thought, there’s something to be learned. So keep searching.

It turned out I was doing pushes of the form

vector<AABB> vec ;
vec.push_back( AABB( min, max ) ) ;

So the AABB was being

1. CONSTRUCTED with the AABB(min,max) ctor call
2. Copy constructed into the vector
3. destructed (item that was originally AABB(min,max) ctor created must be destroyed after copy into the vector)

So it was crashing on the dtor bit.

Turned out I had a non-initialized object ptr in AABB, and in ~AABB it was attempted to destroy that non-init ptr. Forgot to include init to 0 in AABB(min,max) ctor.

I was having a problem with a common C++ pattern:

//file1.h #include "file2.h" // file2.h #include "file1.h"

The header cross-inclusion sometimes results in compilation errors if “file1.h” requires a type from “file2.h” to be fully defined, and vice-versa.

So, what I started doing is stop #including every header file in every other header file and use forward declarations instead, and include the required header file in the code file that uses the class definition.

Error 1 error C2825: ‘_Alloc': must be a class or namespace when followed by ‘::’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1544


Error 2 error C2039: ‘difference_type’ : is not a member of ‘`global namespace” c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1544
Error 3 error C2146: syntax error : missing ‘,’ before identifier ‘difference_type’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1544
Error 4 error C2065: ‘difference_type’ : undeclared identifier c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1544
Error 5 error C2955: ‘std::_Iterator012′ : use of class template requires template argument list c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1548
Error 6 error C2825: ‘_Alloc': must be a class or namespace when followed by ‘::’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1550
Error 7 error C2039: ‘size_type’ : is not a member of ‘`global namespace” c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1550
Error 8 error C2146: syntax error : missing ‘;’ before identifier ‘_Sizet’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1550
Error 9 error C4430: missing type specifier – int assumed. Note: C++ does not support default-int c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1550
Error 10 error C2061: syntax error : identifier ‘_Sizet’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1558
Error 11 error C2061: syntax error : identifier ‘_Sizet’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1565
Error 12 error C2146: syntax error : missing ‘;’ before identifier ‘_Myoff’ c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1582
Error 13 error C4430: missing type specifier – int assumed. Note: C++ does not support default-int c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1582
Error 14 error C4430: missing type specifier – int assumed. Note: C++ does not support default-int c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector 1582

Not really an error, occurs when you misuse STL function swap() by adding a type parameter.

Example of code producing the error:

#include <vector>
using namespace std ;

int main()
{
  int a=7, b=5 ;

  swap<int>(a,b) ; // This should be just swap( a, b ) ; with NO <TYPE>
}

Well I always forget this pattern, so without further ado,

#include <ctime>
#include <stdio.h>

tm* getCurrentTime()
{
  static time_t raw ;
  
  // grab the current time
  time( &raw ) ;

  // Now create that timeinfo struct
  static tm* timeinfo ;
  timeinfo = localtime( &raw ) ;

  return timeinfo ;
}

void printCurrentTime()
{
  // write time into timeBuff
  static char timeBuf[ 256 ] ;
  strftime( timeBuf, 255, "%a %b %d %Y %X", getCurrentTime() ) ; // See here for % meanings

  puts( timeBuf ) ;
}

int main()
{
  printCurrentTime() ;
}

C++ pointer to a member function simple example

Original understanding from this


#include <stdlib.h>
#include <iostream>
using namespace std ;

class Obj
{
public:
  double fcn( int p1, int p2 )
  {
    return p1+p2;
  }
};

typedef double (Obj::*  /*AS*/FcnPtrType/*(end of name)*/  )( int, int ) ;

int main()
{
  // Create a pointer to A MEMBER FUNCTION OF THE "Obj" class, THAT RETURNS DOUBLE;
  // WHOSE INSTANCE NAME IS fcnPtr;
  // WHO ACCEPTS 2 ARGUMENTS, BOTH OF TYPE INT
  double (Obj::*  fcnPtr  )( int, int ) = &Obj::fcn ;

  // Let me break that down for you in steps:
  //double (Obj::*  // Create a pointer to A MEMBER FUNCTION OF "Obj" class, THAT RETURNS DOUBLE;
  //fcnPtr  )       // WHOSE INSTANCE NAME IS fcnPtr;
  //( int, int ) ;  // WHO ACCEPTS 2 ARGUMENTS, BOTH OF TYPE INT

  // Function pointer naming syntax is tricky to get the hang of,
  // but the tricky part is the NAME of the function pointer instance
  // is IN BRACKETS, BEFORE the parameter type listing.  This is
  // counter to what you'd normally expect in C++, where the
  // instance name always appears LAST in the line (breaks the
  // principle of least surprise, I suppose).
	
  // Now lets create an object (whose member function we will call
  // via the function pointer)

  Obj obj ;

  printf( "%f\n", (obj.*fcnPtr)( 3, 7 ) ) ;

  return 0;
}

A simple example that shows how to create a thread in C++ on Win32 platform

    #include <Windows.h>
    #include <stdio.h>
    
    struct Point
    {
      float x,y,z ;
    } ;
    
    DWORD WINAPI threadStartPoint( LPVOID data )
    {
      Sleep( 1000 ) ;
      Point *p = (Point*)data ;
      printf( "%f %f %f\n", p->x, p->y, p->z ) ;
      puts( "Thread job done" ) ;
      return 0 ;
    }
    
    // From main
    int main()
    {
      DWORD threadId ;
      Point p ;
      p.x=2, p.y=3, p.z=4 ;
      HANDLE handle = CreateThread( 0, 0, 
        threadStartPoint,
        (LPVOID)&p,
        0,
        &threadId
      ) ;
    
      if( !handle )
      {
        // Thread creation failed
        puts( "start fail\n" );
      }
      else
      {
        printf( "started on threadid=%d\n", threadId ) ;
      }
    
      WaitForSingleObject( handle, 2000 ) ; // wait up to 2000 ms for the other thread to complete before moving on
    
      puts( "main thread Exiting.." ) ;
      //system( "pause" ) ;
    }

Expression: vector iterator not dereferencable

A common problem C++ newbs encounter is

Expression: vector iterator not dereferencable

The deal with this statement is it usually occurs in a program like

#include <iostream>
#include <vector>
#include <deque>
using namespace std ;

int main()
{
  vector<int> a ;

  for( int i = 0 ; i < 10; i++ )
    a.push_back( i );

  for( vector<int>::iterator i = a.begin() ; i != a.end() ; ++i )
  {
    if( *i == 5 )
      a.erase( i ) ; // ERROR!!

    cout << *i << endl ;
  }
}

So on the line that says // ERROR!! is where the source of the problem is.

When you .erase from a std::vector, you actually invalidate all existing iterators. So doing ++i then, once you hit the loop repeat, is invalid now.

To fix this, simply UPDATE i AFTER YOU CALL ERASE like so:

      i = a.erase( i ) ;

What this does is SET i TO BEING THE ELEMENT AFTER THE ONE YOU JUST DELETED. The result is the program works and you don’t get the error.

Full program:

#include <iostream>
#include <vector>
#include <deque>
using namespace std ;

int main()
{
  vector<int> a ;

  for( int i = 0 ; i < 10; i++ )
    a.push_back( i );

  for( vector<int>::iterator i = a.begin() ; i != a.end() ; ++i )
  {
    if( *i == 5 )
      i = a.erase( i ) ; // Better!!

    cout << *i << endl ;
  }
}

The distance to initiate drag ‘n drop is controlled through this api..

Increasing their values helps to avoid accidental Copy of files into the same directory

#include <Windows.h>
#include <stdio.h>
int main()
{
  // DEFAULT VALUES ARE 4 and 4
  int cx,cy;
  cx = GetSystemMetrics( SM_CXDRAG ) ;
  cy = GetSystemMetrics( SM_CYDRAG ) ;
  
  printf( "cx=%d, cy=%d\n", cx, cy ) ;

  SystemParametersInfoA( SPI_SETDRAGHEIGHT, 90, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE ) ;
  SystemParametersInfoA( SPI_SETDRAGWIDTH, 90, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE ) ;


  cx = GetSystemMetrics( SM_CXDRAG ) ;
  cy = GetSystemMetrics( SM_CYDRAG ) ;
  
  printf( "cx=%d, cy=%d\n", cx, cy ) ;

 
}

Basic windows starter

// Win32

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
  AllocConsole() ;
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ;
  puts( "************** Program start **************" ) ;
  WNDCLASSEX wcx = { 0 };
  wcx.cbSize = sizeof( WNDCLASSEX ) ;
  wcx.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcx.hCursor = LoadCursor( NULL, IDC_ARROW );
  wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wcx.hInstance = hInstance;
  wcx.lpfnWndProc = WndProc;
  wcx.lpszClassName = TEXT("BasicWindow");
  wcx.style = CS_HREDRAW | CS_VREDRAW;
  RegisterClassEx( &wcx );
  
  HWND hwnd = CreateWindowEx(
    0,
    TEXT("BasicWindow"),
    TEXT("Window title!"),
    WS_OVERLAPPEDWINDOW,
    10, 10,
    200, 200,
    NULL, NULL,
    hInstance, NULL );

  ShowWindow(hwnd, iCmdShow );
  UpdateWindow(hwnd);

  MSG msg;
  while( GetMessage( &msg, NULL, 0, 0 ) )
  {
    TranslateMessage( &msg );
    DispatchMessage( &msg );
  }

  return msg.wParam ;
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    {
      // Stuff to do when the window is created
    }
    return 0;
    
  case WM_PAINT:
    {
      // we would place our Windows painting code here.
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );

      // draw a circle and a 2 squares
      Ellipse( hdc, 20, 20, 160, 160 );
      Rectangle( hdc, 50, 50, 90, 90 );
      Rectangle( hdc, 100, 50, 140, 90 );

      EndPaint( hwnd, &ps );
    }
    return 0;

  case WM_KEYDOWN:
    {
      if( wparam == VK_ESCAPE )
      {
        PostQuitMessage( 0 ) ;
        return 0 ;
      }
    }
    break ;

  case WM_DESTROY:
    {
      PostQuitMessage( 0 ) ;
    }
    return 0;
  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}

Here’s an implementation of the MD5 algorithm in C++.

Simply copy and paste into a file “md5.h”. Only dependencies are on <string.h> and <stdio.h>.

Originally adapted from the C reference implementation on this page

Tested in Visual Studio 2010.
Sample use:

Main.cpp

#include "md5.h"

int main()
{
  MD5 md5 ;
  puts( md5.digestString( "HELLO THERE I AM MD5!" ) ) ;

  // print the digest for a binary file on disk.
  puts( md5.digestFile( "C:\\WINDOWS\\notepad.exe" ) ) ;

  return 0;
}

md5.h

(No .cpp file)

#ifndef MD5_H
#define MD5_H

// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
// rights reserved.

// License to copy and use this software is granted provided that it
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
// Algorithm" in all material mentioning or referencing this software
// or this function.
//
// License is also granted to make and use derivative works provided
// that such works are identified as "derived from the RSA Data
// Security, Inc. MD5 Message-Digest Algorithm" in all material
// mentioning or referencing the derived work.
//
// RSA Data Security, Inc. makes no representations concerning either
// the merchantability of this software or the suitability of this
// software for any particular purpose. It is provided "as is"
// without express or implied warranty of any kind.
//
// These notices must be retained in any copies of any part of this
// documentation and/or software.



// The original md5 implementation avoids external libraries.
// This version has dependency on stdio.h for file input and
// string.h for memcpy.
#include <stdio.h>
#include <string.h>

#pragma region MD5 defines
// Constants for MD5Transform routine.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21






static unsigned char PADDING[64] = {
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

// F, G, H and I are basic MD5 functions.
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

// ROTATE_LEFT rotates x left n bits.
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
#define FF(a, b, c, d, x, s, ac) { \
  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
  (a) = ROTATE_LEFT ((a), (s)); \
  (a) += (b); \
  }
#define GG(a, b, c, d, x, s, ac) { \
  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
  (a) = ROTATE_LEFT ((a), (s)); \
  (a) += (b); \
  }
#define HH(a, b, c, d, x, s, ac) { \
  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
  (a) = ROTATE_LEFT ((a), (s)); \
  (a) += (b); \
  }
#define II(a, b, c, d, x, s, ac) { \
  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
  (a) = ROTATE_LEFT ((a), (s)); \
  (a) += (b); \
  }
#pragma endregion

typedef unsigned char BYTE ;

// POINTER defines a generic pointer type
typedef unsigned char *POINTER;

// UINT2 defines a two byte word
typedef unsigned short int UINT2;

// UINT4 defines a four byte word
typedef unsigned long int UINT4;


// convenient object that wraps
// the C-functions for use in C++ only
class MD5
{
private:
  struct __context_t {
    UINT4 state[4];                                   /* state (ABCD) */
    UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
    unsigned char buffer[64];                         /* input buffer */
  } context ;

  #pragma region static helper functions
  // The core of the MD5 algorithm is here.
  // MD5 basic transformation. Transforms state based on block.
  static void MD5Transform( UINT4 state[4], unsigned char block[64] )
  {
    UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];

    Decode (x, block, 64);

    /* Round 1 */
    FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
    FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
    FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
    FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
    FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
    FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
    FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
    FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
    FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
    FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
    FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

    /* Round 2 */
    GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
    GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
    GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
    GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
    GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
    GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
    GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
    GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
    GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
    GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
    GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
    GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

    /* Round 3 */
    HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
    HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
    HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
    HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
    HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
    HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
    HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
    HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
    HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
    HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

    /* Round 4 */
    II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
    II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
    II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
    II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
    II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
    II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
    II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
    II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
    II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
    II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

    state[0] += a;
    state[1] += b;
    state[2] += c;
    state[3] += d;

    // Zeroize sensitive information.
    memset((POINTER)x, 0, sizeof (x));
  }

  // Encodes input (UINT4) into output (unsigned char). Assumes len is
  // a multiple of 4.
  static void Encode( unsigned char *output, UINT4 *input, unsigned int len )
  {
    unsigned int i, j;

    for (i = 0, j = 0; j < len; i++, j += 4) {
      output[j] = (unsigned char)(input[i] & 0xff);
      output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
      output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
      output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
    }
  }

  // Decodes input (unsigned char) into output (UINT4). Assumes len is
  // a multiple of 4.
  static void Decode( UINT4 *output, unsigned char *input, unsigned int len )
  {
    unsigned int i, j;

    for (i = 0, j = 0; j < len; i++, j += 4)
      output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
  }
  #pragma endregion


public:
  // MAIN FUNCTIONS
  MD5()
  {
    Init() ;
  }

  // MD5 initialization. Begins an MD5 operation, writing a new context.
  void Init()
  {
    context.count[0] = context.count[1] = 0;
  
    // Load magic initialization constants.
    context.state[0] = 0x67452301;
    context.state[1] = 0xefcdab89;
    context.state[2] = 0x98badcfe;
    context.state[3] = 0x10325476;
  }

  // MD5 block update operation. Continues an MD5 message-digest
  // operation, processing another message block, and updating the
  // context.
  void Update(
    unsigned char *input,   // input block
    unsigned int inputLen ) // length of input block
  {
    unsigned int i, index, partLen;

    // Compute number of bytes mod 64
    index = (unsigned int)((context.count[0] >> 3) & 0x3F);

    // Update number of bits
    if ((context.count[0] += ((UINT4)inputLen << 3))
      < ((UINT4)inputLen << 3))
      context.count[1]++;
    context.count[1] += ((UINT4)inputLen >> 29);

    partLen = 64 - index;

    // Transform as many times as possible.
    if (inputLen >= partLen) {
      memcpy((POINTER)&context.buffer[index], (POINTER)input, partLen);
      MD5Transform (context.state, context.buffer);

      for (i = partLen; i + 63 < inputLen; i += 64)
        MD5Transform (context.state, &input[i]);

      index = 0;
    }
    else
      i = 0;

    /* Buffer remaining input */
    memcpy((POINTER)&context.buffer[index], (POINTER)&input[i], inputLen-i);
  }

  // MD5 finalization. Ends an MD5 message-digest operation, writing the
  // the message digest and zeroizing the context.
  // Writes to digestRaw
  void Final()
  {
    unsigned char bits[8];
    unsigned int index, padLen;

    // Save number of bits
    Encode( bits, context.count, 8 );

    // Pad out to 56 mod 64.
    index = (unsigned int)((context.count[0] >> 3) & 0x3f);
    padLen = (index < 56) ? (56 - index) : (120 - index);
    Update( PADDING, padLen );

    // Append length (before padding)
    Update( bits, 8 );

    // Store state in digest
    Encode( digestRaw, context.state, 16);

    // Zeroize sensitive information.
    memset((POINTER)&context, 0, sizeof (context));

    writeToString() ;
  }

  /// Buffer must be 32+1 (nul) = 33 chars long at least 
  void writeToString()
  {
    int pos ;

    for( pos = 0 ; pos < 16 ; pos++ )
      sprintf( digestChars+(pos*2), "%02x", digestRaw[pos] ) ;
  }


public:
  // an MD5 digest is a 16-byte number (32 hex digits)
  BYTE digestRaw[ 16 ] ;

  // This version of the digest is actually
  // a "printf'd" version of the digest.
  char digestChars[ 33 ] ;

  /// Load a file from disk and digest it
  // Digests a file and returns the result.
  char* digestFile( char *filename )
  {
    Init() ;

    FILE *file;
    
    int len;
    unsigned char buffer[1024] ;

    if( (file = fopen (filename, "rb")) == NULL )
      printf( "%s can't be opened\n", filename ) ;
    else
    {
      while( len = fread( buffer, 1, 1024, file ) )
        Update( buffer, len ) ;
      Final();

      fclose( file );
    }

    return digestChars ;
  }

  /// Digests a byte-array already in memory
  char* digestMemory( BYTE *memchunk, int len )
  {
    Init() ;
    Update( memchunk, len ) ;
    Final() ;
    
    return digestChars ;
  }

  // Digests a string and prints the result.
  char* digestString( char *string )
  {
    Init() ;
    Update( (unsigned char*)string, strlen(string) ) ;
    Final() ;

    return digestChars ;
  }
} ;

#endif

(donation should be to bill.sherif@gmail.com)

Function pointer syntax tutorial

Function pointer syntax is one of those weird, weird things that just doesn’t seem right.

double (*fun)(int,int,double*)

Can you read that?

In less than 2 paragraphs, you will!

First things first. What is a function pointer anyway? Why, its simply a variable that, instead of pointing to an object (like an int* will point to an integer, and a double* will point to a double), this weird, weird “function pointer” will actually point to __A FUNCTION__!!

WHAT?? You say. POINT TO A FUNCTION! Why, yes! It is no different than me pointing to a recipe. Its one thing to have a copy of the recipe for chocolate mousse in hand (an actual function body), and its another thing to have a hyperlink that merely __points__ to that chocolate mousse recipe (a pointer to the function). When you have a pointer to a function (hyperlink to a recipe) you can still execute it (make the recipe) but you need to remember to dereference the pointer first (follow the hyperlink to pull up the recipe).

Does that make a little bit of sense? Me hopes so.

Moving on to function pointer syntax then, it is actually not that bad to read. Say you had a function:

void SayIt()
{
  puts( "It. There.  Happy now?" ) ;
}

And you wanted to declare a function pointer to the SayIt() function in your main function:

int main()
{
  // DECLARE A FUNCTION POINTER TO THE
  // SayIt() function by the name of ptrSayIt
  void (*ptrSayIt)() ;
  // The above is probably the weirdest, non-C++ish
  // syntax you've come across.  It looks weird because
  // it is.  No, really, function pointer declaration
  // syntax is kind of mixed up.
  // 1.  First, the word VOID specifies the
  // return type of the function that you
  // will point to...
  // 2.  Second is (*ptrSayIt).  The bracket
  // and star combination (* there
  // says THIS IS A FUNCTION POINTER, NOT
  // A FUNCTION DECLARATION THAT RETURNS A POINTER
  // TO VOID* (which is what "void *ptrSayIt();" would mean!)
  // 3.  Third, the trailing brackets at the end ()
  // say that the function we are pointing to
  // won't accept any arguments when it is called.

  // If it helps, you can look at it as:
  // void(*)().  That is the type of the
  // ptrSayIt variable.  The "mixed up" part
  // is because this breaks the usual C declaration
  // syntax of TYPE    InstanceName,
  // and so its really weird to look at at first.
  // Then you kind of get used to it.  Keep reading!

  // Now the ptrSayIt variable points to the
  // SayIt function..
  ptrSayIt = &SayIt ; // you don't really need the & in front
  // but I put it to be clear

  // Now we can call the SayIt function __through__
  // the ptrSayIt pointer we just declared and set up!
  (*ptrSayIt)() ; // (*DEREFERENCE) the pointer first!
  // OUTPUTS:  "It.  There.  Happy now?"
  // TRY IT YOURSELF!
}

So this all seems very weird. But the program above works, I guarantee!

Lets do some more examples.

Declare a function pointer named Foo that points to a function marked by prototype:

int add( int a, int b ) ;

Answer:

int (*Foo)(int,int) ;

Reasoning: the return type of the function you are about to point to goes first.

int        // function pointer will point
// to a function returning int..

Then, you do this mixed up thing where you write the name of the pointer variable NOW, in brackets, with a * in front:

int (*Foo) // function pointer VARIABLE
// identifier/handle is Foo.  This is actually
// the WEIRDEST part of the syntax.

Then you follow up with the types of arguments that the function you are trying to point to will contain:

int (*Foo)( int, int )   // will point 
// to a function accepting 2 ints

Further reading

So what’s the use of function pointers? Why, many, many uses!

Now you can write functions that accept pointers to functions.. and so you can have a function have variable behavior based on what function you passed it…-

But you probably already think function pointers are cool. That’s why you stopped in to read about them!

In creating a Vector or Matrix4x4 class, it is tempting to think its a good idea to overload the == operator __not__ with an element by element comparison for exact equality (as it __should__ be!) but instead to equate it to some version of a .Near() method (where we check that each element is within some EPSILON of the corresponding element in the other matrix)

It turns out this is __not__ a very good idea for the following reason

Say you want to make a std::map<Matrix> for some reason. Now finding is based on operator== and operator<.

So you have a huge problem if you overloaded operator== to mean “approximately equal”!

More expensive key lookup, (lots of fabs()), and worse, more collisions where you may not want them!

Using RAWINPUT, based off the example, except this one is in a d3d window


#pragma region includes
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <d3d9.h>      // core direct3d
#include <d3dx9.h>     // aux libs

#include <dxerr.h>    // detailed error messages

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")  // aux libs
#ifdef _DEBUG
#pragma comment(lib,"d3dx9d.lib")
#else
#pragma comment(lib,"d3dx9.lib")
#endif

#pragma comment(lib, "dxerr.lib")

// Macros.
#define SAFE_RELEASE(ptr) if(ptr) { ptr->Release(); ptr = NULL; }
#define CAST_AS_DWORD(x) *((DWORD*)&x)
#define PI 3.14159
#pragma endregion

#pragma region define the Vertex structure
struct Vertex
{
  float x,y,z ;
  DWORD color ;
  
  // Ctor starts you at origin in black
  // with alpha (opacity) set to 100%
  Vertex()
  {
    x=y=z = 0.0f;
    color = D3DCOLOR_XRGB( 0,0,0 ) ;
  }

  Vertex( float ix, float iy, float iz )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_XRGB( 255,255,255 ) ;
  }

  // Ctor.
  Vertex( float ix, float iy, float iz,
    unsigned char ir, unsigned char ig, unsigned char ib )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_XRGB( ir, ig, ib ) ;
  }

  // Ctor that lets you pick alpha
  Vertex( float ix, float iy, float iz,
    unsigned char ir, unsigned char ig, unsigned char ib, unsigned char ALPHA )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_ARGB( ALPHA, ir, ig, ib ) ;
  }
} ;
#pragma endregion

struct Globals
{
  struct _Win
  {
    HINSTANCE hInstance;    // window app instance
    HWND hwnd;              // handle for the window
    HWND hConsole ;         // handle for the console window

    int width, height;
  } win ;

  IDirect3D9 * d3d ;
  IDirect3DDevice9 * gpu ; 
};

///////////////////////////
// GLOBALS
Globals g;

///////////////////////////
// FUNCTION PROTOTYPES
void printWindowsLastError( char *msg ) ;
inline bool CHECK( HRESULT hr, char * msg, bool stop=true ) ;  // checks for errors on the HR passed.
bool initD3D() ;         // function to initialize the BEAST that is Direct3D9
void initRawinput( HWND hwnd ) ;
void update() ;          // changes geometry of the scene
void drawAxes() ;        // draws the ever-important axes (for finding your way around your own scene!)
void draw() ;            // drawing function containing Direct3D drawing calls

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );


void printWindowsLastError( char *msg )
{
  LPSTR errorString = NULL ;

  int result = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER |
                 FORMAT_MESSAGE_FROM_SYSTEM,
                 0,
                 GetLastError(),
                 0,
                 (LPSTR)&errorString,
                 0,
                 0 );

  printf( "%s %s\n", msg, errorString ) ;
  
  LocalFree( errorString ) ;
}

inline bool CHECK( HRESULT hr, char * msg, bool stop )
{
  if( FAILED( hr ) )
  {
    printf( "%s. %s:  %s\n",
            msg, DXGetErrorStringA( hr ), DXGetErrorDescriptionA( hr ) ) ;

    // Pause so we can see the error and deal with it.
    if( stop )  system("pause") ;

    return false ;
  }

  else
    return true ;
}

/// Initializes Direct3D9.  Returns true on success.
bool initD3D()
{
  // start by nulling out both pointers:
  g.d3d = 0 ;
  g.gpu = 0 ;

  g.d3d = Direct3DCreate9( D3D_SDK_VERSION ) ;

  if( g.d3d == NULL )
  {
    // DEVICE CREATION FAILED!!!! OH NO!!!
    puts( "Oh.. PHOOEY!!!!!  Device creation FAILED!!! WHAT NOW???\n" ) ;
    return false ;
  }

  puts( "Direct3D9 creation success!" ) ;

  D3DPRESENT_PARAMETERS pps = { 0 } ;

  pps.Windowed = true ;
  pps.BackBufferCount = 1 ;
  pps.SwapEffect = D3DSWAPEFFECT_DISCARD ;
  pps.BackBufferFormat = D3DFMT_UNKNOWN ;
  pps.EnableAutoDepthStencil = true ;
  pps.AutoDepthStencilFormat = D3DFMT_D16 ;

  HRESULT hr = g.d3d->CreateDevice(

    D3DADAPTER_DEFAULT, // primary display adapter
    D3DDEVTYPE_HAL,     // use HARDWARE rendering (fast!)
    g.win.hwnd,
    D3DCREATE_HARDWARE_VERTEXPROCESSING,
    &pps,
    &g.gpu

  ) ;

  if( !CHECK( hr, "OH NOS!! I could not initialize Direct3D!  Bailing...\n" ) )
  {
    return false ;
  }

  puts( "Direct3D9 GPU device creation successful" ) ;


  #pragma region setup interleaved arrays
  D3DVERTEXELEMENT9 pos ;

  pos.Usage = D3DDECLUSAGE_POSITION ;
  pos.UsageIndex = 0 ;
  pos.Stream = 0 ;
  pos.Type = D3DDECLTYPE_FLOAT3 ;
  pos.Offset = 0 ;

  pos.Method = D3DDECLMETHOD_DEFAULT ; 

  D3DVERTEXELEMENT9 col;

  col.Usage = D3DDECLUSAGE_COLOR ;
  col.UsageIndex = 0 ;
  col.Stream = 0 ;
  col.Type = D3DDECLTYPE_D3DCOLOR ;
  col.Offset = 3*sizeof( float ) ;
  col.Method = D3DDECLMETHOD_DEFAULT ;

  D3DVERTEXELEMENT9 vertexElements[] =
  {
    pos,
    col,
    D3DDECL_END()
  } ;

  IDirect3DVertexDeclaration9 * Vdecl ;

  hr = g.gpu->CreateVertexDeclaration( vertexElements, &Vdecl ) ;
  CHECK( hr, "CreateVertexDeclaration FAILED!" ) ;

  hr = g.gpu->SetVertexDeclaration( Vdecl ) ;
  CHECK( hr, "SetVertexDeclaration FAILED!" ) ;
  #pragma endregion

  
  hr = g.gpu->SetRenderState( D3DRS_COLORVERTEX, TRUE ) ;
  CHECK( hr, "SetRenderState( COLORVERTEX ) FAILED!" ) ;

  hr = g.gpu->SetRenderState( D3DRS_LIGHTING, FALSE ) ;
  CHECK( hr, "Lighting off" ) ;

  hr = g.gpu->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) ;
  CHECK( hr, "cull mode off" ) ;

  initRawinput( g.win.hwnd ) ;

  return true ;
}

void initRawinput( HWND hwnd )
{
  puts( "Starting up rawinput devices..." ) ;

  // After the window has been created, 
  // register raw input devices
  RAWINPUTDEVICE Rid[2] ;
        
  Rid[0].usUsagePage = 0x01 ;  // magic numbers
  Rid[0].usUsage = 0x02 ;      // magically means mouse
  Rid[0].dwFlags = 0 ; // (use this if you DO NOT WANT to capture mouse)
  //Rid[0].dwFlags = RIDEV_CAPTUREMOUSE | RIDEV_NOLEGACY ;  // (use this to CAPTURE MOUSE)
  Rid[0].hwndTarget = hwnd ;

  Rid[1].usUsagePage = 0x01 ;  // magic numbers
  Rid[1].usUsage = 0x06 ;      // magically means keyboard
  Rid[1].dwFlags = 0 ;         // use RIDEV_NOHOTKEYS for no winkey
  Rid[1].hwndTarget = hwnd ;

  if( !RegisterRawInputDevices( Rid, 2, sizeof(Rid[0]) ) )
  {
    //registration failed. Check your Rid structs above.
    printWindowsLastError( "RegisterRawInputDevices" ) ;
    puts( "Could not register raw input devices. Check your Rid structs, please." ) ;
    exit(1);
  }
}

void update()
{
}

////////////////////////
// DRAWING FUNCTIONS
void drawAxes()
{

  static float axisLen = 2.0f ;
  static Vertex axis[] = {

    // x-axis is red
    Vertex( -axisLen, 0, 0, 255, 0, 0 ),
    Vertex( +axisLen, 0, 0, 255, 0, 0 ),

    // y-axis green
    Vertex( 0, -axisLen, 0, 0, 255, 0 ),
    Vertex( 0, +axisLen, 0, 0, 255, 0 ),

    // z-axis blue
    Vertex( 0, 0, -axisLen, 0, 0, 255 ),
    Vertex( 0, 0, +axisLen, 0, 0, 255 )

  } ;

  HRESULT hr = g.gpu->DrawPrimitiveUP( D3DPT_LINELIST, 3, axis, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  static float pointSize = 8.0f ;

  g.gpu->SetRenderState( D3DRS_POINTSIZE, CAST_AS_DWORD( pointSize ) ) ;

  // Draw points at end of axis.
  static Vertex points[] = {
    Vertex( axisLen, 0, 0, 255, 0, 0 ),
    Vertex( 0, axisLen, 0, 0, 255, 0 ),
    Vertex( 0, 0, axisLen, 0, 0, 255 ),
  } ;

  hr = g.gpu->DrawPrimitiveUP( D3DPT_POINTLIST, 3, points, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

}

void draw()
{
  HRESULT hr ;

  hr = g.gpu->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
    D3DCOLOR_ARGB( 255, 25, 25, 25 ), 1.0f, 0 ) ;
  CHECK( hr, "Clear FAILED!" ) ;

  #pragma region set up the camera
  D3DXMATRIX projx ;

  D3DXMatrixOrthoRH( &projx, 5, 5, 1, 100 ) ;
  //D3DXMatrixPerspectiveFovRH( &projx, PI/4, (float)g.win.width/g.win.height, 1.0f, 1000.0f ) ;

  g.gpu->SetTransform( D3DTS_PROJECTION, &projx ) ;

  D3DXMATRIX viewx ;

  int x = 2 ;
  int y = 2 ;
  D3DXVECTOR3 eye( x, y, 4 ) ;
  D3DXVECTOR3 look( x, y, 0 ) ;
  D3DXVECTOR3 up( 0, 1, 0 ) ;
  D3DXMatrixLookAtRH( &viewx, &eye, &look, &up ) ;
  g.gpu->SetTransform( D3DTS_VIEW, &viewx ) ;
  #pragma endregion

  hr = g.gpu->BeginScene() ;
  CHECK( hr, "BeginScene FAILED!" ) ;


  drawAxes();


  hr = g.gpu->EndScene() ;
  CHECK( hr, "EndScene FAILED!" ) ;

  // And finally, PRESENT what we drew to the backbuffer
  g.gpu->Present( 0, 0, 0, 0 ) ;

}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
  //////////////////
  // First we'll start by saving a copy of
  // the hInstance parameter inside our
  // "glob" of globals "g":
  g.win.hInstance = hInstance;
  // In case we need it later, we'll have it
  // with firsthand easy access.

  #pragma region part 0 - attach a console
  // Attach a console
  AllocConsole();
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ; // redirect stdout to console

  // Move the console over to the top left
  g.win.hConsole = GetConsoleWindow();
  MoveWindow( g.win.hConsole, 0, 0, 400, 400, true ) ;

  printf( "* * Computer Program Begin * *\n" ) ;
  #pragma endregion

  #pragma region part 1 - create a window
  // The next few lines you should already
  // be used to:  create a WNDCLASSEX
  // that describes the properties of
  // the window we're going to soon create.
  // A.  Create the WNDCLASSEX
  WNDCLASSEX wcx = { 0 } ;
  wcx.cbSize = sizeof( WNDCLASSEX );
  wcx.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  wcx.hCursor = LoadCursor( NULL, IDC_ARROW );
  wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wcx.hInstance = hInstance;
  wcx.lpfnWndProc = WndProc;
  wcx.lpszClassName = TEXT("Philip");
  wcx.lpszMenuName = 0;
  wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

  // Register that class with the Windows O/S..
  RegisterClassEx( &wcx );

  int width = 800, height = 600;
  int leftEdge = 400, topEdge = 25 ;
  RECT rect;
  SetRect( &rect,
    leftEdge,  // left
    topEdge,   // top
    leftEdge + width, // right
    topEdge  + height ); // bottom

  // Save width and height off.
  g.win.width = rect.right - rect.left;
  g.win.height = rect.bottom - rect.top;

  // Adjust it.
  DWORD windowStyle = WS_OVERLAPPEDWINDOW ; // typical features of a normal window
  DWORD windowExStyle = 0 ; // I want the window to be topmost

  AdjustWindowRectEx( &rect, windowStyle, false, windowExStyle );

  g.win.hwnd = CreateWindowEx(
    windowExStyle,
    TEXT("Philip"),
    TEXT("DIRECT3D WINDOW"),
    windowStyle,
    rect.left, rect.top,  // adjusted x, y positions
    rect.right - rect.left, rect.bottom - rect.top,  // adjusted width and height
    NULL, NULL,
    hInstance, NULL);

  // check to see that the window
  // was created successfully!
  if( g.win.hwnd == NULL )
  {
    FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
  }

  // and show.
  ShowWindow( g.win.hwnd, iCmdShow );

  // JUMP to the initD3D() method.
  if( !initD3D() )
  {
    FatalAppExit( 0, TEXT("SORRY!!!  DEVICE CREATION FAILED!!! YOU LOSE, WITHOUT EVEN PLAYING THE GAME!!!" ) ) ;
  }

  #pragma endregion

  #pragma region message loop
  MSG msg;

  while( 1 )
  {
    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
      if( msg.message == WM_QUIT )
      {
        break;
      }

      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
    else
    {
      update();
      draw();
    }
  }
  #pragma endregion

  //////////////
  // clean up
  SAFE_RELEASE( g.gpu ) ;
  SAFE_RELEASE( g.d3d ) ;

  // and a cheesy fade exit
  AnimateWindow( g.win.hwnd, 200, AW_HIDE | AW_BLEND );

  printf( "* * This Computer Program Has Ended * *\n" ) ;

  return msg.wParam;
}

////////////////////////
// WNDPROC
// Notice that WndProc is very very neglected.
// We hardly do anything with it!  That's because
// we do all of our processing in the draw()
// function.
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    Beep( 50, 10 );
    return 0;
    break;

  case WM_PAINT:
    {
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );
      // don't draw here.  would be waaay too slow.
      // draw in the draw() function instead.
      EndPaint( hwnd, &ps );
    }
    return 0;
    break;

  case WM_KEYDOWN:
    switch( wparam )
    {
    case VK_ESCAPE:
      PostQuitMessage( 0 );
      break;
    default:
      break;
    }
    return 0;



  case WM_INPUT: 
    {
      UINT dwSize;

      GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &dwSize, 
        sizeof(RAWINPUTHEADER));
      LPBYTE lpb = new BYTE[dwSize];
      if (lpb == NULL) 
      {
        return 0;
      } 

      int readSize = GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER) ) ;

      if( readSize != dwSize )
        puts( "ERROR:  GetRawInputData didn't return correct size!" ) ; 

      RAWINPUT* raw = (RAWINPUT*)lpb;

      if (raw->header.dwType == RIM_TYPEKEYBOARD) 
      {
        if( raw->data.keyboard.VKey == VK_SPACE )
        {
          puts( "You are pressing space" ) ;
        }
      }
      else if (raw->header.dwType == RIM_TYPEMOUSE) 
      {
        int dx = raw->data.mouse.lLastX ;
        int dy = raw->data.mouse.lLastY ;

        printf( "%d %d\n", dx, dy ) ;
      } 

      delete[] lpb; 
      return 0;
    } 

  case WM_SIZE:
    {
      int width = LOWORD( lparam ) ;
      int height = HIWORD( lparam ) ;
      printf( "RESIZED TO width=%d height=%d\n", width, height ) ;
    }
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 ) ;
    return 0;
    break;
  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}

Code to get a unicode string from an ascii string

wchar_t* getUnicode( wchar_t* unicodeDest, char* asciiSrc )
{
  int len = strlen( asciiSrc ) ;

  MultiByteToWideChar( CP_ACP, 0, asciiSrc, len, unicodeDest, len ) ;
  unicodeDest[ len ] = 0 ; // add null terminator

  return unicodeDest ;
}
char ascii = 5 + '0' ; // NICE TRICK!! gets you ascii value for 5.

First, Install Boost and be sure to choose the regex package when you install it.

Regex matching in C++ using BOOST

Regex replace in C++ using BOOST

Regex extract in C++ using BOOST

See example below.

#include <iostream>
#include <string>
#include <boost/regex.hpp> // add boost regex library
using namespace std ;

int main()
{
  // http://www.boost.org/doc/libs/1_35_0/more/getting_started/windows.html#get-boost

  // To practice regular expressions, use
  // http://weitz.de/regex-coach/
  bool quitting = false ;
  string input ;

  puts( " *** Regex MATCH test ***" ) ;
  puts( " ------------------------" ) ;
  while( !quitting )
  {
    boost::regex EXPR( "[0-9][0-9][A-Za-z]" ) ;

    cout << "The expression is:" << endl ;
    cout << EXPR << endl << endl ;
    
    cout << "Enter a string to match it, or just type Q to move on" << endl ;
    getline( cin, input ) ;

    bool matches = boost::regex_match( input, EXPR ) ;
    if( matches )
    {
      puts( "Congrats, you entered a string that matches the expression." ) ;
    }
    else if( input == "q" || input == "Q" )
    {
      puts( "Bye!" ) ;
      quitting = true ;
    }
    else
    {
      puts( "NO, that string didn't match" ) ;
    }
  }

  puts( "\n" ) ;
  puts( " *** Regex REPLACE test ***" ) ;
  puts( " --------------------------" ) ;
  quitting = false ;
  
  while( !quitting )
  {
    boost::regex EXPR( "e" ) ;
    string REPLACEMENT = "X" ;

    cout << "I am replacing: " << EXPR << " with: " << REPLACEMENT << endl ;
    cout << EXPR << endl << endl ;
    
    cout << "Enter a string with lowercase 'e' in it, or just type Q to quit." << endl ;
    getline( cin, input ) ;

    if( input == "q" || input == "Q" )
    {
      puts( "Bye!" ) ;
      quitting = true ;
    }
    else
    {
      string replaced = boost::regex_replace( input, EXPR, REPLACEMENT, boost::match_default | boost::format_sed ) ;
      cout << replaced << endl;
    }
  }


  // Finally, a test showing capturing
  boost::regex EXPR( "<food>([A-Za-z]+)</food>" ) ;
  string xmlData = "<food>pizza</food>" ;

  string replaced = boost::regex_replace(
    
    xmlData,  // the data
    
    EXPR,     // the regex

    "\\1",    // Don't forget to DOUBLE backslash
              // your regex escape sequences!!

    boost::match_default | boost::format_sed
    // You can get perl-style regex strings,
    // "sed" style regex strings,
    // or you can use boost's own 
    // extended format style strings.
    // See http://www.boost.org/doc/libs/1_33_1/libs/regex/doc/format_syntax.html
  ) ;
  cout << "EXPR: " << EXPR << endl;
  cout << "Data: " << xmlData << endl;
  cout << "The extracted data was: " << replaced << endl ;
}

This seems to be a trivial and is an inherently subjective question but I want to know what the best practice is __with reasons__.

I used to write

    char * var ;

But I started writing

    char* var ;

Because I thought that the type of var is simply char* so the * pointer should be stuck to the type so its read in “one eyeful.”

THEN I ran into a bug recently where I didn’t notice that I had declarations

    char* var1, var2 ;

And I actually didn’t realize that var2 was type char, not char*. Hmm. Then I thought, well, this way makes the most sense then:

    char *var1, *var2 ;

Currently I’m thinking the last way is the correct way now.

The VARIANT datatype is the worst, most error prone piece of shit i’ve ever seen.

look at this bug:


  for( int s = 0 ; s < count ; s++ )
  {
    _variant_t vi( s ) ;

    ADOField * field ;

    if( CHECK( fields->get_Item( vi, &field ), "Getting field item" ) )
    {
      BSTR name ;

      CHECK( field->get_Name( &name ), "getting name" ) ;

      wprintf( L"| %10s |", name );
    }

  }


Why did it crash? I’ll paste the correct non-crashing code below and see if you can find it



  for( short s = 0 ; s < count ; s++ )
  {
    _variant_t vi( s ) ;

    ADOField * field ;

    if( CHECK( fields->get_Item( vi, &field ), "Getting field item" ) )
    {
      BSTR name ;

      CHECK( field->get_Name( &name ), "getting name" ) ;

      wprintf( L"| %10s |", name );
    }

  }


See it? When I declared the counter variable s as an int, the variant type was the wrong type (it was an INT type instead of a SHORT type).

I only GUESSED this was the problem not from the amazing documentation that ms keeps on this, but from this article looking at how they browsed the thing.

I was shocked and amazed that the VARIANT type was ever in use by anyone at any point in time, and how EXTENSIVELY its used in ADO.

I mean, its an ugly type and this is a STUPID reason for a bug to exist.

OK, here it is.

Pure torture.


#define _CRT_SECURE_NO_DEPRECATE

// Before running this program, make sure you have a
// mysql32 dsn set up to connect to the 'test' database.

// Run these queries:
/*
create table users( id int, name varchar( 255 ) );

insert into users( id, name ) values ( 1, 'bob' ), ( 2, 'john' ) ;

select * from users ;
*/







#include <windows.h>
#include <stdio.h>
#include <stddef.h>     // for offsetof()
#include <cguid.h>

#include <oledb.h>
#include <oledberr.h> 
#include <msdaguid.h>
#include <msdasql.h>

#include <comdef.h>     // for _com_error()

#include <vector>
using namespace std ;


#define FIELD_NAME_LEN 255

struct User
{
  int id ;
  
  // Because the field is a varchar(255), we
  // represent that here as a char array with
  // 255 bytes maximum.
  char name[ FIELD_NAME_LEN ] ;

  User()
  {
    id = 1 ;
    strcpy( name, "unnamed user" ) ;
  }

  User( int i_id, char * i_name )
  {
    id = i_id ;
    strcpy( name, i_name ) ;
  }
} ;











///
/// Dump an error to the console,
/// including any information we can
/// get from the system about
/// the specific error.
///
void DumpError( HRESULT hr )
{
  printf( "HRESULT: %d\n", hr ) ;

  _com_error err( hr ) ;
  BSTR bstr = err.Description() ;
  printf( "Description: %s\n", bstr );
  wprintf( L"_com_error.ErrorMessage(): %s\n", err.ErrorMessage()  ) ;

  IErrorInfo * errorInfo ;
  GetErrorInfo( 0, &errorInfo );
  if( errorInfo )
  {
    BSTR description;
    errorInfo->GetDescription( & description );

    // description will be a more descriptive error message than just formatting the 
    // HRESULT because it is set by the COM server code at the point of the error

    wprintf( L"\nIErrorInfo says:  %s\n", description ) ;
  }

  printf("\n");
}



/// Its very important to CHECK ALL return codes.
/// Its a real ass-biter when something goes wrong
/// and the notification is hidden because you
/// didn't check the HRESULT of every command.
bool CHECK( HRESULT hr, char * msg, bool printSucceededMsg=false, bool quit=true )
{
  if( SUCCEEDED( hr ) )
  {
    if( printSucceededMsg )  printf( "%s succeeded\n", msg ) ;

    return true ;
  }
  else
  {
    printf( "%s has FAILED!!\n", msg ) ;

    DumpError( hr ) ;

    if( quit )  FatalAppExitA( 0, msg ) ;

    return false ;
  }
}




/// Gets you an ICommandText interface to
/// the database connected to in db.
/// ICommandText's let you send SQL queries
/// to the database.
ICommandText * GetCommand( IDBInitialize * dbInit )
{
  #pragma region talk about QueryInterface
  // QueryInterface is a funky method.

  // Basically you use it to "ask" the COM object you
  // are working with here WHETHER OR NOT IT SUPPORTS
  // ("implements") a specific interface.

  // To quote an excellent MSDN article:
  // "If an object supports an interface, it supports
  // all of the methods within that interface."
  //    http://msdn.microsoft.com/en-us/library/ms810892.aspx

  // If you're curious, take a look at the
  // "sampprov" project that comes with
  // the Windows SDK sample set
  // C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\dataaccess\oledb\sampprov

  // Therein, an implementation of the QueryInterface
  // method lies:

  /*
STDMETHODIMP CCommand::QueryInterface
(
	REFIID riid,				//@parm IN | Interface ID of the interface being queried for. 
	LPVOID * ppv				//@parm OUT | Pointer to interface that was instantiated      
)
{
	if( ppv == NULL )
		return ResultFromScode(E_INVALIDARG);

	//	This is the non-delegating IUnknown implementation
	if( riid == IID_IAccessor )
		*ppv = (LPVOID)m_pIAccessor;
	else if( riid == IID_ICommand )
		*ppv = (LPVOID)m_pICommandText;
	else if( riid == IID_ICommandText )
		*ppv = (LPVOID)m_pICommandText;
	else if( riid == IID_ICommandProperties )
		*ppv = (LPVOID)m_pICommandProperties;
	else if( riid == IID_IColumnsInfo )
		*ppv = (LPVOID)m_pIColumnsInfo;
	else if( riid == IID_IConvertType )
		*ppv = (LPVOID)m_pIConvertType;
	else if( riid == IID_IUnknown )
		*ppv = (LPVOID)this;
	else
		*ppv = NULL;
}
*/
  // OK Isn't that COOL?  All what happens is,
  // QueryInterface looks to see if "riid"
  // is one of the interface types this object
  // supports.

  // If it DOES support the interface you're
  // asking for, then it just points "ppv" to
  // its local member instance of that class.

  // If the object DOES NOT support the interface
  // you're querying for, then you get a null pointer back.

  // ISN'T THAT SIMPLE?  Its a lot simpler internally
  // than I initially thought.  Basically QueryInterface
  // is a Get_* method, only its very very generic.

  // Nothing is created in a QueryInterface method.
  // You get something that already exists within the
  // object.  QueryInterface lets you simply access it.

  // Also note that as a RULE, once a COM interface
  // is published, YOU CANNOT ADD OR REMOVE METHODS
  // FROM THAT INTERFACE.  Instead, you have to
  // define a NEW interface (hence why DirectX has
  // IDirect3D9, IDirect3D7.. etc.)
  #pragma endregion

  // So now, I ultimately want a COMMAND interface,

  // ICommandText <- IDBCreateCommand <- IDBCreateSession <- IDBInitialize
  // cmdText      <- cmdFactory       <- sessionFactory   <- dbInit
  // In words:
  // 1.  IDBInitialize spawns an IDBCreateSession
  // 2.  That IDBCreateSession is used to create an IDBCreateCommand
  // 3.  That IDBCreateCommand is used to create an ICommandText
  // 4.  The ICommandText is returned

  IDBCreateSession * sessionFactory ;
  HRESULT hr = dbInit->QueryInterface(

    IID_IDBCreateSession,      // I want an IID_IDBCreateSession interface.. which
    // I shall use to MAKE a session.

    (void**)&sessionFactory // and put it into sessionFactory variable.
  
  ) ;
  
  CHECK( hr, "creating session factory" ) ;
  
  

  // Get a command factory out of the session factory
  // We need the command factory to create ICommandText's,
  // ICommandText will hold our SQL queries eventually.
  IDBCreateCommand * cmdFactory ;
  CHECK( sessionFactory->CreateSession( NULL, IID_IDBCreateCommand, (IUnknown**)&cmdFactory ), "CreateSession" ) ;

  // Then throw away the session creator object.
  CHECK( sessionFactory->Release(), "releasing the session factory" ) ;

  // Create the command, saving in cmdText.
  // ICommandText interface contains text of an SQL query, eventually
  ICommandText * cmdText ;
  CHECK( cmdFactory->CreateCommand( NULL, IID_ICommandText, (IUnknown**) &cmdText ), "cmdFactory->CreateCommand()" ) ;
  CHECK( cmdFactory->Release(), "cmdFactory->Release()" ) ;
  

  return cmdText ;
}











///
/// Execute a prepared INSERT statement with parameters.
///
void runInsertWithParameters( IDBInitialize * db ) 
{

  //////////
  // // DBPARAMINFO.
  // This array of structs
  // will tell OLE DB the DATATYPE and NAME of the
  // columns of the table we are running our
  // prepared INSERT statement against.

  vector<DBPARAMBINDINFO> bindInfo ;
  
  // Standard type name | Type indicator table
  // contains "DBTYPE_I4" => DBTYPE_I4 mappings
  // Basically you just quote all of them, except for example
  // "DBTYPE_CHAR" => DBTYPE_STR, and
  // "DBTYPE_VARCHAR" => DBTYPE_STR as well.
  DBPARAMBINDINFO firstColumnBindInfo = { 0 } ;
  firstColumnBindInfo.pwszDataSourceType = OLESTR( "DBTYPE_I4" ) ;  // !!CAN ALSO BE "int"
  firstColumnBindInfo.pwszName = NULL ;   // The name of the __parameter__
  // Most of the time this should be NULL.
  // DO NOT SET THIS to OLESTR( "id" ),
  // or OLESTR( "@id" ), or something like this.
  // MySQL doesn't seem to support named parameters.
  // Named parameters look like this:
  //   insert into tablename (col1, col2) values ( :param1, :param2 )
  // vs UNNAMED parameters:
  //   insert into tablename (col1, col2) values ( ?, ? )
  // We're using UNNAMED parameters here.  Don't
  // mistaken this field for the name of the COLUMN
  // in the table.  Because its not that.  EVEN THOUGH
  // the MSDN example DOES get this wrong.  See this post.
  firstColumnBindInfo.ulParamSize = 4 ;   // size in bytes (obviously 4 bytes for an I4 (int-4) field)
  firstColumnBindInfo.dwFlags = DBPARAMFLAGS_ISINPUT | DBPARAMFLAGS_ISSIGNED  ; // http://msdn.microsoft.com/en-us/library/ms714917(VS.85).aspx
  firstColumnBindInfo.bPrecision = 11 ;  // bPrecision is the maximum number of digits, expressed in base 10
  firstColumnBindInfo.bScale = 0 ;

  bindInfo.push_back( firstColumnBindInfo ) ;


  DBPARAMBINDINFO secondColumnBindInfo = { 0 } ;
  secondColumnBindInfo.pwszDataSourceType = OLESTR( "DBTYPE_VARCHAR" ) ; // !!can also be "varchar(255)"
  //secondColumnBindInfo.pwszName = NULL ;
  secondColumnBindInfo.ulParamSize = FIELD_NAME_LEN ;
  secondColumnBindInfo.dwFlags = DBPARAMFLAGS_ISINPUT  ;
  secondColumnBindInfo.bPrecision = 0 ;
  secondColumnBindInfo.bScale = 0 ;

  bindInfo.push_back( secondColumnBindInfo ) ;



  
  // now, cmdText is the variable we're working with.
  // The command requires the actual text
  // as well as an indicator of its language.
  ICommandText * cmdText = GetCommand( db ) ;
  
  // Set the SQL query that will run.
  CHECK( cmdText->SetCommandText( DBGUID_DBSQL, OLESTR("insert into users ( id, name ) values (?, ?)") ), "SetCommandText" ) ;

  // Now go down into the cmdWithParams and
  // Set its ParameterInfo with the BINDINFO
  // that we just specified above.
  ICommandWithParameters * cmdWithParams ;
  CHECK( cmdText->QueryInterface( IID_ICommandWithParameters, (void**)&cmdWithParams ), "get cmdWithParams" ) ;



  // the ORDER that parameter infomation will come in inside bindInfo
  ULONG ordinals[ 2 ] = { 1, 2 } ;
  CHECK( cmdWithParams->SetParameterInfo( bindInfo.size(), ordinals, &bindInfo[ 0 ] ), "SetParameterInfo" ) ;
  CHECK( cmdWithParams->Release(), "cmdWithParams release" ) ;

  
  

  // Prepare the command.
  // MSDN:  This optional interface encapsulates command optimization,
  // a separation of compile time and run time, as found in traditional
  // relational database systems. The result of this optimization is
  // a command execution plan.
  // http://msdn.microsoft.com/en-us/library/ms713621(VS.85).aspx

  ICommandPrepare * cmdPrepare ;
  CHECK( cmdText->QueryInterface( IID_ICommandPrepare, (void**)&cmdPrepare ), "Get ICommandPrepare interface" ) ;
  CHECK( cmdPrepare->Prepare( 0 ), "Command preparation" ) ;
  CHECK( cmdPrepare->Release(), "ICommandPrepare release" ) ;



  


  // Create parameter accessors.
  #pragma region create parameter accessors
  
  IAccessor * accessor ;
  CHECK( cmdPrepare->QueryInterface( IID_IAccessor, (void**)&accessor ), "Getting IAccessor interface" ) ;

  // DBBINDING
  vector<DBBINDING> bindings ;
  
  DBBINDING firstColumnBinding = { 0 } ;
  firstColumnBinding.iOrdinal = 1 ;
  firstColumnBinding.dwPart = DBPART_VALUE ;
  firstColumnBinding.dwMemOwner = DBMEMOWNER_CLIENTOWNED ;
  firstColumnBinding.eParamIO = DBPARAMIO_INPUT ;
  firstColumnBinding.cbMaxLen = 4 ;
  
  firstColumnBinding.wType = DBTYPE_I4 ;
  firstColumnBinding.obValue = offsetof( User, id ) ;  // get byte offset of id member
  printf( "offset of id field is %d\n", firstColumnBinding.obValue ) ;

  bindings.push_back( firstColumnBinding ) ;

  DBBINDING secondColumnBinding = { 0 } ; 
  secondColumnBinding.iOrdinal = 2 ;
  secondColumnBinding.dwPart = DBPART_VALUE ;
  secondColumnBinding.dwMemOwner = DBMEMOWNER_CLIENTOWNED ;
  secondColumnBinding.eParamIO = DBPARAMIO_INPUT ;
  secondColumnBinding.cbMaxLen = FIELD_NAME_LEN ;
  
  secondColumnBinding.wType = DBTYPE_STR ;
  secondColumnBinding.obValue = offsetof( User, name ); // get byte offset of name member.
  printf( "offset of name field is %d\n", secondColumnBinding.obValue ) ;

  bindings.push_back( secondColumnBinding ) ;

  // used to get information about the validity of our binding attempt
  vector<DBBINDSTATUS> rgStatus ;
  rgStatus.resize( 2 ) ;
  


  // The hAccessor will tie the BINDING information
  // to the actual dataset used.
  HACCESSOR hAccessor ;  
  printf( "%d\n", sizeof( User ) ) ;
  
  HRESULT hr = accessor->CreateAccessor(
    
    DBACCESSOR_PARAMETERDATA,    // Accessor that will be used to specify parameter data
    
    bindings.size(),    // Number of parameters being bound
    
    &bindings[0],       // Structure containing bind information
    
    sizeof( User ), // Size of parameter structure.  This MUST be a FIXED SIZE,
    // so you cannot use a generic char* pointer in User that points to
    // a variable length string (must be predetermined size, as it is
    // char[FIELD_NAME_LEN] in this example.)

    &hAccessor,     // will contain accessor handle after this function call

    &rgStatus[0]        // will contain information about binding validity
    // after this function call is complete
  
  ) ;

  if( !CHECK( hr, "Parameter accessor creation" ) )
  {
    printf( "binding status validity: %d %d (0 means OK)\n", rgStatus[ 0 ], rgStatus[ 1 ] ) ;
    puts(
      "DBBINDSTATUS_OK = 0,\n"
	    "DBBINDSTATUS_BADORDINAL = 1,\n"
	    "DBBINDSTATUS_UNSUPPORTEDCONVERSION = 2,\n"
	    "DBBINDSTATUS_BADBINDINFO = 3,\n"
	    "DBBINDSTATUS_BADSTORAGEFLAGS = 4,\n"
	    "DBBINDSTATUS_NOINTERFACE = 5,\n"
	    "DBBINDSTATUS_MULTIPLESTORAGE = 6\n" ) ;
  }
  
  
  #pragma endregion


  #pragma region create data and insert it.
  // Create the data to insert and put it
  // into a struct.
  vector<User> users ;

  User user1( 55, "bobobo" ) ;
  users.push_back( user1 ) ;

  User user2( 56, "waniel" ) ;
  users.push_back( user2 ) ;

  
  
  // ICommand::Execute page, DBPARAMS is in it
  DBPARAMS dbParams;
  
  // pData is a pointer to an array of
  // data that contains data in the order
  // described by bindInfo.
  dbParams.pData = &users[ 0 ] ;   // the data to insert.
  dbParams.cParamSets = users.size() ;  // Number of sets of parameters
  dbParams.hAccessor = hAccessor ; // Accessor to the parameters.  tells
  // dbParams how the byte array of data
  // in pData is divided up.

  // Execute the command.
  long cRowsAffected ;
  hr = cmdText->Execute( NULL, IID_NULL, &dbParams, &cRowsAffected, NULL ) ;
  
  CHECK( hr, "Execute for the insert statement" ) ;
  printf( "%d rows inserted.\n", cRowsAffected ) ;
  

  CHECK( accessor->ReleaseAccessor( hAccessor, NULL ), "Accessor ReleaseAccessor" ) ;
  CHECK( accessor->Release(), "Release Accessor" ) ;
  CHECK( cmdText->Release(), "Release commandText" ) ;
  #pragma endregion

  
}














///
///  Delete rows just added using simple execution.
///
void myDelete( IDBInitialize*  pIDBInitialize ) 
{
  ICommandText* pICommandText = GetCommand( pIDBInitialize ) ;


  // Set the command text for first delete statement and execute
  // the command
  pICommandText->SetCommandText(
    
    DBGUID_DBSQL,
    OLESTR( "delete from users where id=6" )
    
  ) ;
  
  long cRowsAffected ;
  pICommandText->Execute( NULL, IID_NULL, NULL, &cRowsAffected, NULL ) ;

  printf( "%d rows deleted.\n", cRowsAffected ) ;

  // Do it again.
  pICommandText->SetCommandText(
    
    DBGUID_DBSQL,
    OLESTR( "delete from users where id=7" )
  
  ) ;

  pICommandText->Execute(NULL, IID_NULL, NULL, &cRowsAffected, NULL);

  printf("%d rows deleted.\n", cRowsAffected);

  pICommandText->Release();

  return;
}












void SetBSTRProperty( DBPROP & props, DWORD propertyId, OLECHAR * stringValue )
{
  props.dwPropertyID = propertyId ;
  props.vValue.vt = VT_BSTR ;
  props.vValue.bstrVal = SysAllocString( stringValue ) ;
}




























DBPROP preinitDBPROP()
{
  DBPROP prop ;
  VariantInit( &prop.vValue ) ; // equivalent: prop.vValue.vt = VT_EMPTY ;
  prop.dwOptions = DBPROPOPTIONS_REQUIRED ;
  prop.colid = DB_NULLID ;
  return prop ;
}

int main()
{
  // Init OLE and set up the DLLs.
  CoInitialize( NULL ) ;



  // We start with the IDBInitialize interface.
  // The purpose of IDBInitialize is to Initializes a data source object
  IDBInitialize * db = NULL;
  
  

  // Get the task memory allocator.
  // At this point, the original example creates
  // an IMalloc interface.
  // IMalloc can be used to allocate and manage memory.  It doesn't seem to be used in this
  // example, but I'm leaving it here for now.
  IMalloc * iMalloc = NULL;
  CHECK( CoGetMalloc( MEMCTX_TASK, &iMalloc ), "GetMalloc" ) ;
  




  #pragma region Initialize the data source
  
  // Create an instance of the MSDASQL (ODBC) provider.
  // ODBC is for connecting to an sql-based data source
  CHECK( CoCreateInstance( CLSID_MSDASQL, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&db), "starting db" ) ;

  #pragma region talk about variants
  // Set properties for this connection.
  // Declaring the properties for establishing
  // a connection to the database.

  // VARIANT PROPERTY SET.
  // Now HERE is a weird structure you don't see every day.
  // The VARIANT.

  // You might think this data structure is weird.
  // That's because it is.

  // A VARIANT encapsulates ALL the primitive types
  // that are possible in a database.  Look at its
  // struct definition in the header file or on msdn if you wish.
  
  // Notice how it has inside it like EVERY CONCEIVABLE
  // datatype:  DATE*, SHORT*, BYTE*, and even IUnknown.

  // It also has a property VARTYPE.  VARTYPE is set to
  // one of the values in the VARENUM enumeration.
  // So, using a VARIANT as an argument is a way to ANY
  // data type, specifying WHAT TYPE this VARIANT ACTUALLY
  // represents (i.e. what type its internal byte data
  // is to be interpretted as.).

  // MSDN about the vt field:  Contains the type code for the variant,
  //                           which governs how the variant is interpreted.
  #pragma endregion
  
  
  // Initialize common property options.

  // You "have to" call VariantInit() before
  // passing a variant to a function.  What VariantInit does is
  // simply set the vt field to VT_EMPTY.
  
  vector<DBPROP> props ;
  
  // Level of prompting that will be done
  // to complete the connection process.
  DBPROP initPrompt = preinitDBPROP() ;

  initPrompt.dwPropertyID = DBPROP_INIT_PROMPT ;
  initPrompt.vValue.vt = VT_I2 ;      // 2 byte integer (short).
  initPrompt.vValue.iVal = DBPROMPT_NOPROMPT ; 
  
  props.push_back( initPrompt ) ;
  


  
  // Data source name-- using the same one we set up
  // in the ODBC example http://bobobobo.wordpress.com/2009/07/11/working-with-odbc-from-c/
  DBPROP dsn = preinitDBPROP() ;
  SetBSTRProperty( dsn, DBPROP_INIT_DATASOURCE, OLESTR( "mysql32" ) ) ;
  //SetBSTRProperty( dsn, DBPROP_INIT_DATASOURCE, OLESTR( "sqlserver" ) ) ;
  props.push_back( dsn ) ;

  DBPROP username = preinitDBPROP() ;
  SetBSTRProperty( username, DBPROP_AUTH_USERID, OLESTR( "root" ) ) ;   // User ID
  props.push_back( username ) ;

  DBPROP pass = preinitDBPROP() ;
  SetBSTRProperty( pass, DBPROP_AUTH_PASSWORD, OLESTR( "" ) ) ; // Password
  props.push_back( pass ) ;
  


  // Set up the propSet, and
  // link it to the DBPROP array
  // we just created above.
  DBPROPSET propSet ;

  // Now this is an initialization property set.
  propSet.guidPropertySet = DBPROPSET_DBINIT ;

  // tell it the # of properties specified
  propSet.cProperties = props.size() ;

  // And now we assign our properties structure
  propSet.rgProperties = &props[ 0 ] ;

  // Retrieve the IDBProperties interface.
  IDBProperties * dbProperties ;
  db->QueryInterface( IID_IDBProperties, (void**)&dbProperties );
  CHECK( dbProperties->SetProperties( 1, &propSet ), "Set properties" ) ;

  #pragma region free and unload
  // Free the BSTRs that were allocated using SysAllocString()
  SysFreeString( dsn.vValue.bstrVal ) ;
  SysFreeString( username.vValue.bstrVal ) ;
  SysFreeString( pass.vValue.bstrVal ) ;

  CHECK( dbProperties->Release(), "dbprops release" ) ;
  #pragma endregion




  #pragma endregion


  // Now, after we have set the properties, fire up the database by initalizing it
  CHECK( db->Initialize(), "db->Initialize" ) ;
  




  // now set up for batch insertion
  // I want to batch insert.  In order for 
  // Sets of multiple parameters
  // (cParamSets is greater than one) can be specified only if
  // DBPROP_MULTIPLEPARAMSETS is VARIANT_TRUE

  // Note that we CANNOT set this property inline with
  // the previous batch of property state settings because
  // DBPROP_MULTIPLEPARAMSETS belongs to the DBPROPSET_DATASOURCEINFO,
  // and NOT the DBPROPSET_DBINIT set.
  props.clear();

  DBPROP multipleParamsets = preinitDBPROP() ;
  
  multipleParamsets.dwPropertyID = DBPROP_MULTIPLEPARAMSETS ;
  multipleParamsets.vValue.vt = VT_BOOL ;
  multipleParamsets.vValue.boolVal = VARIANT_TRUE ;
  
  props.push_back( multipleParamsets ) ;



  // reset the propset and reuse it
  // Now this is "Data Source Information" property set,
  // which supports setting the DBPROP_MULTIPLEPARAMSETS item
  propSet.guidPropertySet = DBPROPSET_DATASOURCEINFO ;

  // tell it the # of properties specified
  propSet.cProperties = props.size() ;

  // And now we assign our properties structure
  propSet.rgProperties = &props[ 0 ] ;





  // re-get the dbProperties interface.
  db->QueryInterface( IID_IDBProperties, (void**)&dbProperties );
  CHECK( dbProperties->SetProperties( 1, &propSet ), "Set properties 2" ) ;





  CHECK( dbProperties->Release(), "dbprops release 2" ) ;

















  // Execute a prepared statement with parameters.
  runInsertWithParameters( db ) ;
  





  // Delete rows just added.
  myDelete( db ) ;



  
  if( db != NULL )
  {
    db->Uninitialize() ;
    db->Release() ;
  }

  if( iMalloc != NULL )
    iMalloc->Release() ;

  CoUninitialize() ;

  return 0 ;
}









// Glossary:  (Extracted from http://msdn.microsoft.com/en-us/library/ms810892.aspx
// DATA PROVIDER:  A data provider is one that owns data and exposes it in a tabular form.
// Some examples are relational database systems and spreadsheets.

// SERVICE PROVIDER:  A service provider is any OLE DB component
// that does not own the data but encapsulates some service by
// producing and consuming data through OLE DB interfaces.
// Examples are query processors and transaction managers.

// BSTR:  http://msdn.microsoft.com/en-us/library/ms221069.aspx

// The BSTR is a strange animal.  It is like a Pascal string
// in that its LENGTH is stored in the first (4) bytes.
// The character data itself then follows, then there are
// TWO null terminators at the end, regardless of whether
// _UNICODE is #defined or not.

// You're supposed to create BSTR's with SysAllocString()
// and to delete them with SysFreeString().






// Important links and pages.

// ADO faq:  http://support.microsoft.com/kb/183606

// Listing of ALL OLE DB Interfaces (objects that start with I):
// http://msdn.microsoft.com/en-us/library/ms709709(VS.85).aspx

// Listing of ALL OF THE OLE DB Structures And Enumerated Types with LINKS to each
// http://msdn.microsoft.com/en-us/library/ms716934(VS.85).aspx

// Listing of ALL OLE DB PROPERTIES
// http://msdn.microsoft.com/en-us/library/ms723066(VS.85).aspx

// Data type mappings:  maps VARIANT types to OLE DB data types
// (e.g. BOOLEAN => DBTYPE_BOOL)
// http://msdn.microsoft.com/en-us/library/bb231286(VS.85).aspx


// PROPERTIES BY PROPERTY GROUPS:  This is the page that tells
// you which DBPROP_* fits under what DBPROPSET_*
// http://msdn.microsoft.com/en-us/library/ms714404(VS.85).aspx

// Fixed-Length and Variable-Length Data Types
// http://msdn.microsoft.com/en-us/library/ms715955(VS.85).aspx

Download code from esnips (thanks esnips!)

While the OLE DB for the ODBC Programmer article is excellent, there is a mistake in it.

The rgParamBindInfo array should not have names for the parameters (they should be NULL) because the prepared statement doesn’t use named parameters (they are unnamed (?,?,?,?)’s)

Because the author does not check the HRESULTS that come back from his SetParameterInfo() invokation, he doesn’t know about this error. But if you check this line:

pICmdWithParams->SetParameterInfo(nParams, rgParamOrdinals, 
        rgParamBindInfo);

with

if( FAILED( pICmdWithParams->SetParameterInfo(nParams, rgParamOrdinals, 
        rgParamBindInfo) )
{
  puts( "The 1997 article by Michael Pizzo, Jeff Cochran has a mistake in it" ) ;
}

you find it throws an error because rgParamBindInfo is wrong (it should look like this:)


  DBPARAMBINDINFO     rgParamBindInfo[] = 
        {
        OLESTR("DBTYPE_CHAR"),  0 /* OLESTR("CustomerID")*/,    5, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("CompanyName")*/,  40, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("ContactName") */,  30, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("ContactTitle") */, 30, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("Address") */,      60, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("City") */,         15, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("Region") */,       15, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("PostalCode") */,   10, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("Country") */,      15, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("Phone") */,        24, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        OLESTR("DBTYPE_VARCHAR"), 0 /* OLESTR("FAX") */,          24, 
             DBPARAMFLAGS_ISINPUT, 0, 0,
        };

Because the prepared statement looks like this:

  WCHAR               wSQLString[] = 
    OLESTR("insert into Customers (CustomerID, CompanyName, ContactName,")
    OLESTR(" ContactTitle, Address, City, Region, PostalCode, Country,")
    OLESTR(" Phone, Fax)")
    OLESTR(" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

If the prepared statement used named parameters, it would look something like this:

  WCHAR               wSQLString[] = 
    OLESTR("insert into Customers (CustomerID, CompanyName, ContactName,")
    OLESTR(" ContactTitle, Address, City, Region, PostalCode, Country,")
    OLESTR(" Phone, Fax)")
    OLESTR(" values (:CustomerID, :CompanyName, :ContactName, ")
    OLESTR(" :ContactTitle, :Address, :City, :Region, :PostalCode, :Country, ")
    OLESTR(" :Phone, :Fax)");

That’s why the docs also say The name of the parameter; it is a null pointer if there is no name. Names are normal names. The colon prefix (where used within SQL text) is stripped.

See I wasn’t aware of offsetof.

Its really good.

Its defined as:

#define offsetof(s,m)   (size_t)&reinterpret_cast<const volatile char&>(((s *)0)->m)

So when you do:

offsetof( STRUCT_TYPE, MEMBER_NAME )

You really get:

(size_t)&(char&)(((STRUCT_TYPE *)0)->MEMBER_NAME)

So its pretty neat. Basically what happens is, you get the number of bytes that MEMBER_NAME is from the beginning of the struct. .. refers to the address of member m in this object. Since the start address of this object is 0 (NULL), the address of member m is exactly the offset.

PRETTY cool. I can’t believe I’ve been listing numerical byte counts for this long..

and the hand of experience.

If you try and compile and run the microsoft sdk sampClnt using their instructions they leave out one important detail:

running sampclnt.exe
Sun Jul 12 11:22:41 2009


Connecting to the SampProv sample data provider...
Error at file: c:\program files\microsoft sdks\windows\v6.1\samples\dataaccess\oledb\sampclnt\sampclnt.cpp  line: 317  
CoCreateInstance: Returned <unknown>
Error at file: c:\program files\microsoft sdks\windows\v6.1\samples\dataaccess\oledb\sampclnt\sampclnt.cpp  line: 206  
GetSampprovDataSource: Returned <unknown>
Error at file: c:\program files\microsoft sdks\windows\v6.1\samples\dataaccess\oledb\sampclnt\sampclnt.cpp  line: 122  
DoTests: Returned <unknown>

so the fix for this is to first compile the sampprov project, then switch into C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\dataaccess\oledb\sampprov\Debug, (like, open a command prompt..)

cd C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\dataaccess\oledb\sampprov\Debug
regsvr32 sampprov.dll

THEN you can run the sampclnt example, making sure to put the .csv file it uses in the same directory as its executable.

I only knew this from a hint from this post, where he says

Hi, what is the problem with the OLEDB sample client, obtained from Data
Acess SDK 2.8?
I registered the sample provider as regsvr32 \sampprov, which was
successful.

Here is the log:

running sampclnt.exe
Thu Jun 23 12:44:52 2005

Connecting to the SampProv sample data provider…
Getting a DBSession object from the data source object…
Getting a rowset object from the DBSession object…
Error at file: c:\msdn\sample\sampclnt\sampclnt.cpp line: 517
IOpenRowset::OpenRowset: Returned DB_E_NOTABLE
Error at file: c:\msdn\sample\sampclnt\sampclnt.cpp line: 224
GetRowsetFromDBCreateSession: Returned DB_E_NOTABLE
Error at file: c:\msdn\sample\sampclnt\sampclnt.cpp line: 119
DoTests: Returned DB_E_NOTABLE

Setting up MySQL for use through ODBC.

First, recognize that THERE ARE several ways you can connect to a MySQL database from an application.

MDAC


click for larger

The 3 main ways are:

  • Native C api – compile and link-in code that can talk to MySQL WITHIN your app. This is ALMOST like making MySQL “part of your program”

  • ODBC (this article). ODBC stands for Ol’ Dirty Bastard Connector.. :) Just kidding. But it should. ODBC was first released in 1992. ODBC is short for Open Database Connectivity.

    Basically your application TALKS TO the ODBC driver THROUGH A COMMON SET OF API FUNCTIONS – the ODBC API library. The ODBC driver in turn, talks to the actual database for you. So you achieve a certain level of database API independence: you use ODBC in the same way whether programming to a MySQL database, or an MS-SQL Server database, or an Oracle database – you use the same functions and it works, as long as you have an ODBC driver for that database. So using ODBC is just ONE LEVEL of abstraction above the native C API. ODBC is still alive and kicking today and works fine.

    Aside:

    If you’re familiar with how the HAL works in Direct3D, ODBC is a little bit like the HAL.

    Direct3D function calls ODBC function calls
    HAL (hardware abstraction layer) ODBC driver
    GPU hardware itself Database software itself

    In this case, the “database” is like the GPU, and ODBC driver is that layer which transforms standard ODBC function calls into function calls that the actual database being used underneath can understand.

    If that just didn’t make any sense, ignore this whole block

    The advantage of using ODBC above the MySQL functions directly is .. well, just that you don’t have to program to the MySQL function set directly anymore. So, say you already had experience with setting up a database connection under C++/Oracle, and you want to quickly get up and running on a C++/MySQL program. Instead of going and figuring out how the MySQL native api works, you actually wouldn’t have to know any of that at all, you’d just install the ODBC driver and program “to” ODBC – this is what we’ll show how to do in this article.

  • OLE DB

    Just ANOTHER, newer, more recent library of functions that is supposed to replace ODBC. OLE DB is a low-level, high-performance interface to a variety of data stores. OLE DB, like ODBC as shown in this article, has a C-style API.

    OLE DB’s advantage over ODBC is that the underlying data provider when using OLE DB does NOT have to be a relational database.

    In fact, according to page 8 of this book

    ODBC as we have just seen, is an excellent technology for accessing SQL-based data. OLE DB incorporates this proven technology with a particular component that allows OLE DB consumers to communicate directly with ODBC providers. In other words, use OLE DB to access SQL-based data, and you gain the advantage of being able to access both relational and other forms of data with the same code.

    So it looks like this:

  • Finally, ADO, (also, ADO.NET).

    ADO is a high-level, easy-to-use interface to OLE DB.

    ADO is the NEWEST and is probably the most commonly used technology for accessing databases from MS apps. Ever heard of hibernate? Well, ADO, (which stands for ActiveX Data Objects) is BASICALLY the same idea as Hibernate. You can interact with the database through a series of functions WITHOUT EVER WRITING A LINE OF SQL. You interact with the database instead through the functionset provided by ADO.

    Can you see the layers? You can see that you should expect ADO to be somewhat slower than using ODBC directly.

    ADO is accessible in two flavors: ADO “regular” and ADO.NET. ADO.NET, clearly, is part of the .NET framework and so if you’re using a .NET application, then data access through ADO.NET is the natural standard for you.

    If you’re programming a native C++ app on the other hand, the choice whether to use native MySQL function calls, ODBC, OLE DB (directly), ADO, or ADO.NET kind of looms before you.

So, ok, on with it.

Accessing a MySQL database through ODBC

1. The first step is to install a MySQL database and create a table or two. Do it do it do it!!

2. Ok, now the SECOND step is to GET THE MySQL ODBC 5.1 DRIVER. GET THE 32-BIT DRIVER ONLY, PLEASE, EVEN IF YOU ARE ON A 64-bit MACHINE. Unless you know EXACTLY what you’re doing FOR SURE and you KNOW your compiler pushes out 64-bit applications (Visual Studio 2005/2008 pushes out 32-bit applications by default ONLY!! EVEN IF you are on a 64-bit platform!)

3. Once you’ve got that installed, OPEN UP Start -> Administrative Tools -> Data Sources (ODBC).

Note: If you DO NOT SEE “Administrative Tools” on your start menu RIGHT CLICK TASKBAR > PROPERTIES > START MENU TAB > CUSTOMIZE > FIND AND SELECT THE “DISPLAY ADMINISTRATIVE TOOLS” checkbox.

4. Ok, now in the Ol’ Dirty Bastard Connections window (ODBC Window) that you just opened in step 3, select the System DSN tab

IMPORTANT NOTE: IF YOU ARE ON A 64-BIT MACHINE, __DO NOT__, I REPEAT, __DO NOT__ USE THE ODBC Window that is accessible from the taskbar. Instead, go to START > RUN > C:\Windows\SysWOW64\odbcad32.exe.

The reason is when developing in Visual Studio 2005/2008, under normal circumstances you in fact cannot publish 64-bit applications, so you CANNOT USE the 64-bit ODBC drivers from your 32-bit application. So you must set up and use the __32-bit__ ODBC drivers instead. This is a REAL assbiter. See jlgdeveloper’s master-genius answer at http://forums.devarticles.com/microsoft-sql-server-5/data-source-name-not-found-and-no-default-driver-specified-8346.html#postmenu_203344 (repeated at bottom of this page for permanence)

5. Click ADD. You see a menu

IF YOU DO NOT SEE “MySQL ODBC 5.1 DRIVER” there, CALL 911. Or, try installing the correct version of the ODBC driver.

6. Now, pick the ODBC 5.1 item and click “FINISH” (you’re not done yet though..)

7. Fill out the connection params. This is how I filled out mine.

When you’re done click TEST. You should see the box that I see “Connection successful”

If you see this box

CALL 911, or double check your parameters and make sure your MySQL daemon is running.

8. Now that you’re done that, you should see this:

REMEMBER THAT NAME, “mysqldata” or whatever name you gave the connection in the top box. This is the name you’ll refer to from your program.

9. Now run this program. Once again I remind you IF YOU ARE ON A 64-BIT MACHINE, BE SURE TO HAVE SET UP YOUR ODBC CONNECTIONS IN THE C:\Windows\SysWOW64\odbcad32.exe WINDOW, AND NOT THE ODBC WINDOW ACCESSIBLE FROM THE START MENU. YOU HAVE BEEN WARNED.


///////////////////////////////////////////
//                                       //
// WORKING WITH OL' DIRTY BASTARD (ODBC) //
//                                       //
// You found this at bobobobo's weblog,  //
// http://bobobobo.wordpress.com         //
//                                       //
// Creation date:  July 10/09            //
// Last modified:  July 10/09            //
//                                       //
///////////////////////////////////////////
// Note also nice sample comes with
// WinSDK in C:\Program Files\Microsoft SDKs\Windows\v6.1\Samples\dataaccess\odbc\odbcsql

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>

// Here is the complete Ol' Dirty Bastard function reference:
// http://msdn.microsoft.com/en-us/library/ms714562(VS.85).aspx

// This article says you need
// to link with odbc32.lib, but taking the next line of code OUT
// doesn't seem to harm anything
#pragma comment( lib, "odbc32.lib" )

bool CHECK( SQLRETURN rc, char * msg, bool printSucceededMsg=false, bool quit=true )
{
  if( SQL_SUCCEEDED( rc ) )
  {
    if( printSucceededMsg )  printf( "%s succeeded\n", msg ) ;
    
    return true ;
  }
  else
  {
    printf( "NO!!!  %s has FAILED!!\n", msg ) ;
    
    if( quit )  FatalAppExitA( 0, msg ) ;

    return false ;
  }
}

void status( SQLSMALLINT handleType, SQLHANDLE theHandle, int line )
{
  SQLCHAR sqlState[6];
  SQLINTEGER nativeError;
  SQLCHAR msgStr[256];
  SQLSMALLINT overBy ; // the number of characters that msgStr buffer was TOO SHORT..
  
  // http://msdn.microsoft.com/en-us/library/ms716256(VS.85).aspx
  // This must be the WEIRDEST ERROR REPORTING FUNCTION I've EVER seen.
  // It requires 8 parameters, and its actually pretty .. silly
  // about the amount of state information it expects YOU to keep track of.

  // It isn't so much a "GetLastError()" function
  // as it is a "GetMeStatus( something very, very specific )" function.
  
  SQLRETURN retCode ;
  
  for( int i = 1 ; i < 20 ; i++ )
  {
    retCode = SQLGetDiagRecA(
      
      handleType,  // the type of object you're checking the status of
      theHandle,   // handle to the actual object you want the status of
      
      i, // WHICH status message you want.  The "Comments" section at the 
      // bottom of http://msdn.microsoft.com/en-us/library/ms716256(VS.85).aspx
      // seems to explain this part well.

      sqlState,    // OUT:  gives back 5 characters (the HY*** style error code)
      &nativeError,// numerical error number
      msgStr,      // buffer to store the DESCRIPTION OF THE ERROR.
      // This is the MOST important one, I suppose

      255,         // the number of characters in msgStr, so that
      // the function doesn't do a buffer overrun in case it
      // has A LOT to tell you
      &overBy      // again in case the function has A LOT to tell you,
      // the 255 character size buffer we passed might not be large
      // enough to hold the entire error message.  If that happens
      // the error message will truncate and the 'overBy' variable
      // will have a value > 0 (it will measure number of characters
      // that you 'missed seeing' in the error message).
      
    ) ;

    if( CHECK( retCode, "SQLGetDiagRecA" ) )
    {
      printf( "LINE %d:  [%s][%d] %s\n", line, sqlState, nativeError, msgStr ) ;
    }
    else
    {
      // Stop looping when retCode comes back
      // as a failure, because it means there are
      // no more messages to tell you
      break ;
    }
  }
}

int main()
{
  // Following this example, just adding a bit more
  // color and making it work with our specific example.
  
  
  // 1.  Create a handle for the environment.
  SQLHANDLE hEnv ;
  SQLRETURN retCode ;
  
  retCode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv ) ;
  
  CHECK( retCode, "allocate environment handle" ) ;
  

  // 2.  Next, set the version of ODBC to use to ODBC version 3.
  // Format of this command is a bit weird, we cast the value we're passing
  // to (void*) because the function requires it, but then we say that the
  // length of the "string" we've passed in is 0 characters long, so I assume
  // that means SQLSetEnvAttr should know to interpret the "pointer value" that
  // we passed in as actually an integer value (which is what it is).
  retCode = SQLSetEnvAttr( hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 ) ; 

  CHECK( retCode, "setting the environment attribute setting to ODBC version 3" ) ;


  // 3.  Allocate the connection handle.  Note this doesn't
  // connect us to the database YET.  We're still "ALLOCATING",
  // whatever that means :) (Hey i know what allocating is,
  // but this is an awful number of steps to follow if you
  // ask me, microsoft!!  Whatever happened to a simple init()
  // function?
  SQLHANDLE hConn ;

  CHECK( SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &hConn ), "allocate handle" ) ;

  
  

  // HOOK IT UP!!  Actually connect to the database.
  SQLCHAR* dsnName = (SQLCHAR*)"mysqldata" ;  // MUST BE THE SAME
  // as the name of the ODBC data source you set
  // in the Microsoft ODBC Administrator window.

  SQLCHAR* userid = (SQLCHAR*)"root";
  SQLCHAR* password = (SQLCHAR*)"";  // using a BLANK
  // Above are my own correct userid and password credentials to
  // be used when logging into the MySQL database server.

  // 4.  Open database connection.
  retCode = SQLConnectA(
    
    hConn,
    
    dsnName,  // name of data source we are connecting to,
    // AS PER REGISTERED IN ODBC Data Source Administrator.

    // If you are on a 64-bit machine, and you
    // DO NOT USE THE 64-bit driver.  As long as
    // your compiler publishes a 32-bit .exe (which
    // Visual Studio does), you'll keep getting:

    // [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

    // SO DON'T USE THE 64-BIT DRIVERS!  Instead, install
    // the 32-bit driver, and then managing/using
    // your 32-bit datasources in
    // c:\windows\syswow64\odbcad32.exe

    // Note that on a 64-bit windows machine, the 32-bit
    // drivers and the 64-bit drivers are managed
    // from COMPLETELY SEPARATE, BUT IDENTICAL-LOOKING
    // windows.  Its really weird.

    // On a 64-bit machine:
    // c:\windows\system32\odbcad32.exe    // 64-bit version [even though it SAYS system32_ in the path, this is the __64__ bit version on a 64-bit machine]
    // c:\windows\syswow64\odbcad32.exe    // 32-bit version [even though it SAYS syswow64_ in the path]

    // Call it stupid, scream, pull your hair out,
    // that's what it is.
    // http://stackoverflow.com/questions/949959/why-do-64bit-dlls-go-to-system32-and-32bit-dlls-to-syswow64-on-64bit-windows

    // and

    // http://blogs.sepago.de/helge/2008/04/20/windows-x64-all-the-same-yet-very-different-part-7/

    // Thanks again, Microsoft,
    // for making the 64-bit programming experience
    // such a pleasure.
    SQL_NTS,  // the DSN name is a NULL TERMINATED STRING, so "count it yourself"

    userid,
    SQL_NTS,  // userid is a null-terminated string
    
    password,
    SQL_NTS   // password is a null terminated string
    
  ) ;
  if( !CHECK( retCode, "SqlConnectA", false ) )
  {
    // if this fails, I want that extra status
    // information about WHY the failure happened.
    // status function is defined above.
    
    status( SQL_HANDLE_DBC, hConn, __LINE__ ) ;
  }


  // 6.  Create and allocate a statement
  SQLHANDLE hStmt ;
  CHECK( SQLAllocHandle( SQL_HANDLE_STMT, hConn, &hStmt ), "allocate handle for statement" ) ;

  
  // 7.  Form a query to run and attach it to the hStmt
  // this basically connects the hStmt up with
  // some results.
  SQLCHAR* query = (SQLCHAR*)"SELECT * from user" ;
  CHECK( SQLExecDirectA( hStmt, query, SQL_NTS ), "execute query" ) ;


  // 8.  Read data results that are now in the hStmt.
  retCode = SQLFetch( hStmt ) ;

  CHECK( retCode, "first sqlFetch" ) ;

  // How many rows got returned?
  SQLLEN numRows ;
  retCode = SQLRowCount( hStmt, &numRows ) ;
  printf( "%d rows were fetched, ruff.\n", numRows ) ;

  // With a query like the one we wrote (SELECT *),
  // we don't know how many columsn should be in
  // the result set at this point.
  // So we ask ODBC to tell us!
  SQLSMALLINT numCols ;
  retCode = SQLNumResultCols( hStmt, &numCols ); // SqlNumResultCols

  // Now print the column names.
  // SQLDescribeCol function
  SQLCHAR colName[ 256 ] ;
  
  SQLSMALLINT colNameLen, dataType, numDecimalDigits, allowsNullValues ;
  SQLUINTEGER columnSize ;

  for( int i = 1 ; i <= numCols ; i++ )
  {
    retCode = SQLDescribeColA( hStmt, i, colName, 255, &colNameLen, &dataType, &columnSize, &numDecimalDigits, &allowsNullValues ) ;
    if( CHECK( retCode, "SQLDescribeCol" ) )
    {
      printf( "Column #%d: '%s', datatype=%d size=%d decimaldigits=%d nullable=%d\n",
                       i,colName,   dataType, columnSize,  numDecimalDigits, allowsNullValues ) ;
    }
  }

  for( int i = 1 ; i <= numRows ; i++ )
  {
    // Datatypes
    // SQLGetData

    char buf[256];
    SQLINTEGER numBytes ;

    for( int j = 1 ;   // column counter starts at __1__, not 0.
      j <= numCols ;   // numCols retrieved above
      j++ )
    {
      retCode = SQLGetData(
      
        hStmt,
        j,           // COLUMN NUMBER of the data to get
        SQL_C_CHAR,  // the data type that you expect to receive
        buf,         // the place to put the data that you expect to receive
        255,         // the size in bytes of buf (-1 for null terminator)
        &numBytes    // size in bytes of data returned
      
      ) ;

      if( CHECK( retCode, "SqlGetData", false ) )
      {
        // Print the data we got.
        printf( "%10s", buf ) ;
      }
    
    } // end for.

    puts("");

    // Try and fetch the next result.
    // fall out of the loop if fetch fails
    // (meaning, no more data to get)
    retCode = SQLFetch( hStmt ) ;
    if( !SQL_SUCCEEDED( retCode ) )
    {
      // SQLFetch FAILS AS IT FETCHES the last row of data.
      printf( "And %d is the LAST row.. we're not getting any more after this one\n", i ) ;
    }
  }

  // So we used a FOR loop above to fetch
  // exactly numRows rows from the results.

  // The other (perhaps more common) 
  // way to do this is to use a loop like
  
  // while( SQL_SUCCEEDED( SQLFetch( hStmt ) ) )
  // {
  //   // Work with result data
  // }

  // When we do it that way, 
  // WE EXPECT/RELY ON SQLFetch TO TELL US
  // IT FAILED when we've reached the
  // LAST row of data.

  // free up resources.
  SQLFreeHandle( SQL_HANDLE_STMT, hStmt ) ;
  SQLFreeHandle( SQL_HANDLE_DBC, hConn ) ;
  SQLFreeHandle( SQL_HANDLE_ENV, hEnv ) ;
}


// Assbiters:
// 1. Be careful not to use the SUCCEEDED() macro
// instead of the SQL_SUCCEEDED() macro when
// checking your SQLRESULT values.
//
// 2. Do not use 64-bit ODBC drivers, even if on
// a 64-bit machine.  See information above.

/*
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/


Master genius John

[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

I had this error and want to let you know how it was resolved.

First, this was an ASP web application using a vb 6.0 dll to get data from a sql server 2005 database on a 64 bit windows server 2008 enterprise (vista like) server. I could only get the dll to work in component services as opposed to simply registering it.

It all worked fine upon setup, but after four windows updates one night, the error above was posted in the event viewer, and the web app crashed.

Here is the resolution:

In a 64 bit windows server operating system, there are TWO odbc managers. When you pull up the usual menu for the odbc / dsn system, it is for the 64 bit odbc manager, and 32 bit applications (vb 6.0) will not work using these dsn’s.

This is where the 32 bit odbc manager is:

C:\Windows\SysWOW64\odbcad32.exe

I hope you do not have to go through what I and three Microsoft Support engineers had to to figure this out.

Jonathan

Download the code package courtesy of esnips (thanks esnips!)

Ok, so say I have:

class Thing abstract
{
  
} ;

class Person : public Thing
{
  void MoveTo( Point p ) ;
} ;

class Building : public Thing
{
  // does NOT have MoveTo( Point p ) ;
} ;

I’m maintaining a vector<Thing*> to keep track of everything in the world.

When hittesting, a user might click on either a Building or a Person. Regardless, there’s a pointer stored to the currently selected Thing* in selectedThing.

Now, depending on what TYPE of thing is currently selected, the user can do different actions with that Thing. If the Thing* is really Person*, then a right-click somewhere on the map means one thing (i.e. move there) or for a building, a right click means (do nothign) or (set rally point).

So, if selectedThing is IN FACT a Person*, then we should call MoveTo() on the selectedThing (method exists!). But if selectedThing is NOT a person, then we should NOT call MoveTo() on it, because MoveTo() is not defined for a Building*.

What’s the best way to manage this problem?

1. typeid() reflection (which is bad because its implementation dependent and just _seems_ wrong?)
i.e. find if typeid() says selectedThing is Person* or Building*

if( typeid( selectedThing ) == classTypePerson ) 
{
  selectedThing->MoveTo( p ) ;
}
else
{
  // its not a person, so it can't move.
}

2. or maintaining separate vectors and going:

vector<Person*> people ;
vector<Building*> buildings ;

vector<Thing*> things ;

// FIND whether the selectedThing is in Person* vector or Building* vector.
for( int i = 0 ; i < people.size() ; i++ )
{
  if( people[i] == selectedThing )
  {
    // selected Thing is a person, so it can be cast
    // to Person* and MoveTo() can be executed on it
    dynamic_cast( selectedThing )->MoveTo( p ) ;
    break ;
  }
}

(( ANSWER: THE PROBLEM IS WRONG. class Thing should provide handles to “right click here” and “left click there” and the CONCRETE CLASSES should provide the implementation details. You’ve used inheritance incorrectly here and the Thing* interface DOESN’T HAVE ENOUGH METHODS if this is your problem.

So, the answer to this question is:

class Thing abstract
{
  virtual void MoveTo( Point p ) { /*do nothing by default*/ }
} ;

class Person : public Thing
{
  // actually move the person
  void MoveTo( Point p ) override ;
} ;

class Building : public Thing
{
  // does NOT (bother overriding) MoveTo( Point p ) ;
} ;

Then the code simply reduces to:

selectedThing->MoveTo( p ) ;

And so, IF the selectedThing is indeed a Building*, then selectedThing->MoveTo() boils down to (nothing happening), and if its a Person*, selectedThing->MoveTo() boils down to actual movement. Later you could build out the MoveTo command to MEAN SOMETHING ELSE to a Building, and this is EXACTLY what polymorphism is supposed to do: make different objects behave differently given the same command.

class Animal abstract { virtual void Speak() { } } ;

class Dog : public Animal {
  void Speak() { puts("Woof") ; } 
} ;

class Cat : public Animal {
  void Speak() { puts("Meow") ; } 
} ;

Here’s a simple Direct3D starter that you can copy and paste into a Visual Studio 2005/2008 project.

Assumes you have the DirectX sdk installed… many of the comments from the original were deleted in this one.


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <d3d9.h>      // core direct3d
#include <d3dx9.h>     // aux libs

#include <dxerr.h>    // detailed error messages

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")  // aux libs
#ifdef _DEBUG
#pragma comment(lib,"d3dx9d.lib")
#else
#pragma comment(lib,"d3dx9.lib")
#endif

#pragma comment(lib, "dxerr.lib")


// Macros.
#define SAFE_RELEASE(ptr) if(ptr) { ptr->Release(); ptr = NULL; }
#define CAST_AS_DWORD(x) *((DWORD*)&x)
#define PI 3.14159


#pragma region define the Vertex structure
struct Vertex 
{
  float x,y,z ;
  DWORD color ;

  // Ctor starts you at origin in black
  // with alpha (opacity) set to 100%
  Vertex()
  {
    x=y=z = 0.0f;
    color = D3DCOLOR_XRGB( 0,0,0 ) ;
  }

  Vertex( float ix, float iy, float iz )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_XRGB( 255,255,255 ) ;
  }

  // Ctor.
  Vertex( float ix, float iy, float iz,
    unsigned char ir, unsigned char ig, unsigned char ib )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_XRGB( ir, ig, ib ) ;
  }

  // Ctor that lets you pick alpha
  Vertex( float ix, float iy, float iz,
    unsigned char ir, unsigned char ig, unsigned char ib, unsigned char ALPHA )
  {
    x=ix;y=iy;z=iz;
    color = D3DCOLOR_ARGB( ALPHA, ir, ig, ib ) ;
  }
} ;
#pragma endregion





struct Globals
{
  struct _Win
  {
    HINSTANCE hInstance;    // window app instance
    HWND hwnd;              // handle for the window
    HWND hConsole ;         // handle for the console window
    
    int width, height;
  } win ;

  IDirect3D9 * d3d ;
  IDirect3DDevice9 * gpu ; 

  struct _data
  {
    Vertex verts[ 3 ] ;

    _data()
    {
      // some global data to draw and manipulate
      // for this example
      
      // Red vertex @ ( -1, 0, 0 )
      verts[ 0 ] = Vertex( -1, 0, 0, 255, 19, 0 ) ;

      // Green vertex @ ( 0, 1, 0 )
      verts[ 1 ] = Vertex(  0, 1, 0, 0, 255, 0 ) ;

      // Blue vertex @ ( 1, 0, 0 )
      verts[ 2 ] = Vertex(  1, 0, 0, 0, 0, 255 ) ;

    }
  } data ;
};

///////////////////////////
// GLOBALS
Globals g;


///////////////////////////
// FUNCTION PROTOTYPES
inline bool CHECK( HRESULT hr, char * msg, bool stop=true ) ;  // checks for errors on the HR passed.
bool initD3D() ;         // function to initialize the BEAST that is Direct3D9
void update() ;          // changes geometry of the scene
void drawAxes() ;        // draws the ever-important axes (for finding your way around your own scene!)
void draw() ;            // drawing function containing Direct3D drawing calls

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );




/////////////////////////
// FUNCTION IMPLEMENTATIONS
inline bool CHECK( HRESULT hr, char * msg, bool stop )
{
  if( FAILED( hr ) )
  {
    printf( "%s. %s:  %s\n",
            msg, DXGetErrorStringA( hr ), DXGetErrorDescriptionA( hr ) ) ;

    // Pause so we can see the error and deal with it.
    if( stop )  system("pause") ;

    return false ;
  }
  
  else
    return true ;


}

/// Initializes Direct3D9.  Returns true on success.
bool initD3D()
{
  // start by nulling out both pointers:
  g.d3d = 0 ;
  g.gpu = 0 ;
  
  g.d3d = Direct3DCreate9( D3D_SDK_VERSION ) ;

  if( g.d3d == NULL )
  {
    // DEVICE CREATION FAILED!!!! OH NO!!!
    puts( "Oh.. PHOOEY!!!!!  Device creation FAILED!!! WHAT NOW???\n" ) ;
    return false ;
  }



  puts( "Direct3D9 creation success!" ) ;
  
  D3DPRESENT_PARAMETERS pps = { 0 } ;

  pps.Windowed = true ;
  pps.BackBufferCount = 1 ;
  pps.SwapEffect = D3DSWAPEFFECT_DISCARD ;
  pps.BackBufferFormat = D3DFMT_UNKNOWN ; 
  pps.EnableAutoDepthStencil = true ;
  pps.AutoDepthStencilFormat = D3DFMT_D16 ;

  HRESULT hr = g.d3d->CreateDevice(
    
    D3DADAPTER_DEFAULT, // primary display adapter
    D3DDEVTYPE_HAL,     // use HARDWARE rendering (fast!)
    g.win.hwnd,
    D3DCREATE_HARDWARE_VERTEXPROCESSING,
    &pps,
    &g.gpu

  ) ;


  if( !CHECK( hr, "OH NOS!! I could not initialize Direct3D!  Bailing...\n" ) )
  {
    return false ;
  }



  puts( "Direct3D9 GPU device creation successful" ) ;
  







  hr = g.gpu->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE ) ;
  CHECK( hr, "SetFVF FAILED!" ) ;
  
  D3DVERTEXELEMENT9 pos ;
  
  pos.Usage = D3DDECLUSAGE_POSITION ;
  pos.UsageIndex = 0 ;
  pos.Stream = 0 ; 
  pos.Type = D3DDECLTYPE_FLOAT3 ;
  pos.Offset = 0 ;

  pos.Method = D3DDECLMETHOD_DEFAULT ; 
  
  
  D3DVERTEXELEMENT9 col;
  
  col.Usage = D3DDECLUSAGE_COLOR ;
  col.UsageIndex = 0 ;
  col.Stream = 0 ;
  col.Type = D3DDECLTYPE_D3DCOLOR ;
  col.Offset = 3*sizeof( float ) ;
  col.Method = D3DDECLMETHOD_DEFAULT ;
  
  D3DVERTEXELEMENT9 vertexElements[] =
  {
    pos,
    col,

    D3DDECL_END()

  } ;
  
  IDirect3DVertexDeclaration9 * Vdecl ;

  hr = g.gpu->CreateVertexDeclaration( vertexElements, &Vdecl ) ;
  CHECK( hr, "CreateVertexDeclaration FAILED!" ) ;

  hr = g.gpu->SetVertexDeclaration( Vdecl ) ;
  CHECK( hr, "SetVertexDeclaration FAILED!" ) ;

  hr = g.gpu->SetRenderState( D3DRS_COLORVERTEX, TRUE ) ;
  CHECK( hr, "SetRenderState( COLORVERTEX ) FAILED!" ) ;

  hr = g.gpu->SetRenderState( D3DRS_LIGHTING, FALSE ) ;
  CHECK( hr, "Lighting off" ) ;

  hr = g.gpu->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) ;
  CHECK( hr, "cull mode off" ) ;








  return true ;
}



void update()
{
  static float change = 0.01f ;
  g.data.verts[0].x += change;

  if( g.data.verts[0].x < -0.5f )
    change = 0.01f;
  else if( g.data.verts[0].x > 0.5f )
    change = -0.01f;
}


////////////////////////
// DRAWING FUNCTIONS
void drawAxes()
{

  static float axisLen = 2.0f ;
  static Vertex axis[] = {

    // x-axis is red
    Vertex( -axisLen, 0, 0, 255, 0, 0 ),
    Vertex( +axisLen, 0, 0, 255, 0, 0 ),

    // y-axis green
    Vertex( 0, -axisLen, 0, 0, 255, 0 ),
    Vertex( 0, +axisLen, 0, 0, 255, 0 ),

    // z-axis blue
    Vertex( 0, 0, -axisLen, 0, 0, 255 ),
    Vertex( 0, 0, +axisLen, 0, 0, 255 )

  } ;



  HRESULT hr = g.gpu->DrawPrimitiveUP( D3DPT_LINELIST, 3, axis, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  static float pointSize = 8.0f ;

  g.gpu->SetRenderState( D3DRS_POINTSIZE, CAST_AS_DWORD( pointSize ) ) ;

  // Draw points at end of axis.
  static Vertex points[] = {
    Vertex( axisLen, 0, 0, 255, 0, 0 ),
    Vertex( 0, axisLen, 0, 0, 255, 0 ),
    Vertex( 0, 0, axisLen, 0, 0, 255 ),
  } ;

  hr = g.gpu->DrawPrimitiveUP( D3DPT_POINTLIST, 3, points, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

}

void draw()
{
  HRESULT hr ;

  hr = g.gpu->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
    D3DCOLOR_ARGB( 255, 25, 25, 25 ), 1.0f, 0 ) ; 
  CHECK( hr, "Clear FAILED!" ) ;

  #pragma region set up the camera
  D3DXMATRIX projx ;
  
  D3DXMatrixPerspectiveFovRH( &projx, PI/4, (float)g.win.width/g.win.height, 1.0f, 1000.0f ) ;
  
  g.gpu->SetTransform( D3DTS_PROJECTION, &projx ) ;

  D3DXMATRIX viewx ;

  D3DXVECTOR3 eye( 4, 2, 4 ) ;
  D3DXVECTOR3 look( 0, 0, 0 ) ;
  D3DXVECTOR3 up( 0, 1, 0 ) ;
  D3DXMatrixLookAtRH( &viewx, &eye, &look, &up ) ;
  g.gpu->SetTransform( D3DTS_VIEW, &viewx ) ;
  #pragma endregion

  hr = g.gpu->BeginScene() ;
  CHECK( hr, "BeginScene FAILED!" ) ;

  
  #pragma region ACTUALLY __draw__

  drawAxes();


  hr = g.gpu->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 1, g.data.verts, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  #pragma endregion

  hr = g.gpu->EndScene() ;
  CHECK( hr, "EndScene FAILED!" ) ;

  // And finally, PRESENT what we drew to the backbuffer
  g.gpu->Present( 0, 0, 0, 0 ) ;



}



int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
  //////////////////
  // First we'll start by saving a copy of
  // the hInstance parameter inside our
  // "glob" of globals "g":
  g.win.hInstance = hInstance;
  // In case we need it later, we'll have it
  // with firsthand easy access.

  #pragma region part 0 - attach a console
  // Attach a console
  AllocConsole();
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ; // redirect stdout to console
  freopen( "CON", "w", stderr ) ; // redirect stderr to console

  // Move the console over to the top left
  g.win.hConsole = GetConsoleWindow();
  MoveWindow( g.win.hConsole, 0, 0, 400, 400, true ) ;

  printf( "* * Computer Program Begin * *\n" ) ;
  #pragma endregion

  #pragma region part 1 - create a window
  // The next few lines you should already
  // be used to:  create a WNDCLASSEX
  // that describes the properties of
  // the window we're going to soon create.
  // A.  Create the WNDCLASSEX
  WNDCLASSEX wcx = { 0 } ;
  wcx.cbSize = sizeof( WNDCLASSEX );
  wcx.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  wcx.hCursor = LoadCursor( NULL, IDC_ARROW );
  wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wcx.hInstance = hInstance;
  wcx.lpfnWndProc = WndProc;
  wcx.lpszClassName = TEXT("Philip");
  wcx.lpszMenuName = 0;
  wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

  // Register that class with the Windows O/S..
  RegisterClassEx( &wcx );

  int width = 800, height = 600;
  int leftEdge = 400, topEdge = 25 ;
  RECT rect;
  SetRect( &rect,
    leftEdge,  // left
    topEdge,   // top
    leftEdge + width, // right
    topEdge  + height ); // bottom

  // Save width and height off.
  g.win.width = rect.right - rect.left;
  g.win.height = rect.bottom - rect.top;

  // Adjust it.
  DWORD windowStyle = WS_OVERLAPPEDWINDOW ; // typical features of a normal window
  DWORD windowExStyle = 0 ; // I want the window to be topmost

  AdjustWindowRectEx( &rect, windowStyle, false, windowExStyle );

  g.win.hwnd = CreateWindowEx(
    windowExStyle,
    TEXT("Philip"),
    TEXT("DIRECT3D WINDOW"),
    windowStyle,
    rect.left, rect.top,  // adjusted x, y positions
    rect.right - rect.left, rect.bottom - rect.top,  // adjusted width and height
    NULL, NULL,
    hInstance, NULL);

  // check to see that the window
  // was created successfully!
  if( g.win.hwnd == NULL )
  {
    FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
  }

  // and show.
  ShowWindow( g.win.hwnd, iCmdShow );

  // JUMP to the initD3D() method.
  if( !initD3D() )
  {
    FatalAppExit( 0, TEXT("SORRY!!!  DEVICE CREATION FAILED!!! YOU LOSE, WITHOUT EVEN PLAYING THE GAME!!!" ) ) ;
  }
  
  #pragma endregion

  #pragma region message loop
  MSG msg;

  while( 1 )
  {
    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
      if( msg.message == WM_QUIT )
      {
        break;
      }

      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
    else
    {
      update();
      draw();
    }
  }
  #pragma endregion

  //////////////
  // clean up
  SAFE_RELEASE( g.gpu ) ;
  SAFE_RELEASE( g.d3d ) ;

  // and a cheesy fade exit
  AnimateWindow( g.win.hwnd, 200, AW_HIDE | AW_BLEND );

  printf( "* * This Computer Program Has Ended * *\n" ) ;
  
  return msg.wParam;
}

////////////////////////
// WNDPROC
// Notice that WndProc is very very neglected.
// We hardly do anything with it!  That's because
// we do all of our processing in the draw()
// function.
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    Beep( 50, 10 );
    return 0;
    break;

  case WM_PAINT:
    {
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );
      // don't draw here.  would be waaay too slow.
      // draw in the draw() function instead.
      EndPaint( hwnd, &ps );
    }
    return 0;
    break;

  case WM_KEYDOWN:
    switch( wparam )
    {
    case VK_ESCAPE:
      PostQuitMessage( 0 );
      break;
    default:
      break;
    }
    return 0;

  case WM_SIZE:
    {
      int width = LOWORD( lparam ) ;
      int height = HIWORD( lparam ) ;
      printf( "RESIZED TO width=%d height=%d\n", width, height ) ;
    }
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 ) ;
    return 0;
    break;
  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}






This is a very long, very long, very long tutorial about how to get started with D3D in C++.

Check it out!

//////////////////////////////////////////
//                                      //
// Direct3D basics                      //
//                                      //
// You found this at bobobobo's weblog, //
// http://bobobobo.wordpress.com        //
//                                      //
// Creation date:  July 1/09 (HAPPY CANADA DAY! ) //
// Last modified:  July 3/09            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <d3d9.h>      // core direct3d
#include <d3dx9.h>     // aux libs

#include <dxerr9.h>    // detailed error messages

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")  // aux libs
#ifdef _DEBUG
#pragma comment(lib,"d3dx9d.lib")
#else
#pragma comment(lib,"d3dx9.lib")
#endif

#pragma comment(lib, "dxerr9.lib")


// Macros.
#define SAFE_RELEASE(ptr) if(ptr) { ptr->Release(); ptr = NULL; }
#define CAST_AS_DWORD(x) *((DWORD*)&x)
#define PI 3.14159

struct Globals
{
  // Wrapping the Win32-related variables up
  // together in their own struct so they don't
  // get in the way of the Direct3D ones
  struct _Win
  {
    HINSTANCE hInstance;    // window app instance
    HWND hwnd;              // handle for the window
    HWND hConsole ;         // handle for the console window
    
    int width, height;      // the desired width and
    // height of the CLIENT AREA
    // (DRAWABLE REGION in Window)
  } win ;

  #pragma region DIRECT3D9 stuff
  ////////////////////////////
  // Declare The IDirect3D9 INTERFACE!!
  // IDirect3D9 interface
  IDirect3D9 * d3d ;        // represents the BEAST
  // that is Direct3D9 itself.  What's it for?
  
  // MSDN SAYS about the IDirect3D9 interface:
  // "Applications use the methods of the IDirect3D9 interface
  // to create Microsoft Direct3D objects and set up the
  // environment. This interface includes methods for
  // enumerating and retrieving capabilities of the device."

  // IDirect3DDevice9
  IDirect3DDevice9 * gpu ;  // represents the GPU

  // MSDN SAYS about the IDirect3DDevice9:  "Applications use the
  // methods of the IDirect3DDevice9 interface to perform
  // DrawPrimitive-based rendering, create resources, work
  // with system-level variables, adjust gamma ramp levels,
  // work with palettes, and create shaders."
  ////////////////////////////

  // The ABOVE TWO variables are
  // very important to this application.
  
  // For both of these, notice how they
  // are BOTH POINTERS to an INTERFACE.

  // What's an interface?  Well, in a few words,
  // an INTERFACE is something you "face" to
  // interact with something.  Thru means of
  // the "INTERFACE" you get information from
  // the underlying system, or send commands
  // to the underlying system, without really
  // having to understand the underlying system
  // at all to do it.  You just have to know what
  // types of commands it expects to get.

  // For example, your car.

  // The "interface" of your car is its steering wheel,
  // its dials on the dash telling you what speed
  // you're going and the RPM's you're at so you
  // don't blow the engine redlining, and also,
  // the gas and brakes, so you can send commands
  // to the car to stop and go.

  // Notice how you don't have to know a THING
  // about how an internal combustion engine works
  // to get the car to go.  Because the car's INTERFACE
  // is SO abstract (simply PUSH THE PEDAL TO GO),
  // working the car becomes incredibly simple.

  // If the car didn't have such an abstract
  // interface (like, if REALLY crummy engineers
  // made a car), then to drive that crummy car,
  // you might have to put your hands into
  // the engine and carefully push
  // vaporized gas underneath a piston, then
  // push down on the piston until it goes POP!
  // Then the car would be going!
  
  // Anyway, point is, working with a system
  // THROUGH ITS INTERFACE that the system defines
  // makes working with the system SO easy, and
  // the system itself is a black box -- its internal
  // workings are hidden from you.  Like, you
  // don't even have to know what an internal
  // combustion engine IS to be able to
  // work a modern car.  Heck, for all you know,
  // it might not even be an internal combustion
  // engine!  (It might be electric).  That's another
  // beauty about interfaces:  You can swap out
  // the nitty gritty details of the implementation
  // (e.g. software updates / patches, or the
  // difference between Direct3D9 June 2008 release
  // and March 2009 release) without affecting 
  // the programs that USE those interfaces, so long
  // as you have not CHANGED the interface itself.

  // IN the case of Direct3D9, an IDirect3DDevice9 *
  // is a pointer to, let's just say the "dashboard" ON TOP
  // OF the Direct3D9 RENDERING MACHINE.

  // Inside, the Direct3D 3D graphics "engine" is VERY complex!
  // Especially when you get to rendering textures in 3D..
  // (see this book if you want to learn that stuff!)
  
  // But with Direct3D9, you don't have to understand
  // HOW 3d graphics actually gets drawn.  You only have to
  // understand the format that D3D expects, and pass it
  // your data that you want drawn in that format.

  // OK?  So hopefully that made a little bit of sense.
  // To me Direct3D seems slightly more "centralized"
  // than OpenGL does.  With OpenGL, the "interface"
  // is a set of C-style functions that all begin
  // with gl*.  OpenGL doesn't have an "INTERFACE"
  // in the OOP sense (but that set of gl* C functions
  // is still an 'interface' though, its just a very
  // different way of creating one!)

  // Anyway, on with it.
  #pragma endregion
};

///////////////////////////
// GLOBALS
// declare one struct Globals called g;
Globals g;
//
///////////////////////////


///////////////////////////
// FUNCTION PROTOTYPES
// Windows app functions.  If need help
// understanding these, see MostBasicWindow
// and FastWindowsProgram
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );

inline bool CHECK( HRESULT hr, char * msg, bool stop=true ) ;  // checks for errors on the HR passed.

bool initD3D() ;         // function to initialize the BEAST that is Direct3D9
void printSystemInfo() ; // function that prints some system info.  can ignore if not interested
void draw() ;            // drawing function containing Direct3D drawing calls

//
///////////////////////////


/// If there was an error, the ErrorString is printed out for you to see at the console.
inline bool CHECK( HRESULT hr, char * msg, bool stop )
{
  if( FAILED( hr ) )
  {
    printf( "%s. %s:  %s\n",
            msg, DXGetErrorString9A( hr ), DXGetErrorDescription9A( hr ) ) ;

    // Pause so we can see the error and deal with it.
    if( stop )  system("pause") ;

    return false ;
  }
  
  else
    return true ;


}

///////////////////////////
// FUNCTION IMPLEMENTATIONS
/// Initializes Direct3D9.  Returns true on success.
bool initD3D()
{
  // start by nulling out both pointers:
  g.d3d = 0 ;
  g.gpu = 0 ;
  
  // Create the IDirect3D9 (d3d) object now.  We need the d3d object
  // in order to be able to create the IDirect3DDevice9 interface.
  // We can also use the d3d object to find out additional information
  // about the system we are on (such as the number of displays it has, etc).

  // [[ I know, I know.  If you think its confusing/stupid to have
  // two separate Direct3D9 things both starting with I, 
  // just bear with it because you'll see that these two objects
  // will do VERY different things, and you'll see it does
  // make a whole lot of sense to separate them out into two things.
  // Granted, they could have been named a little more distinctly,
  // but whaddya gonna do... ]]
  
  // So, the IDirect3D9 object (variable 'd3d') is the "interface"
  // or means by which we will access the Direct3D9
  // beast
  
  // And the IDirect3DDevice9 (called 'gpu') is THE
  // variable that IS OUR PROGRAMMATIC HANDLE TO THE GPU and
  // we will use it A LOT to send down triangles and stuff to the
  // gpu to be drawn.

  // we'll be using 'gpu' a lot more than 'd3d'.

  // So now, to create our 'd3d' interface.
  // Remember, FROM this interface will come
  // our 'gpu' interface.

  // Direct3DCreate9
  g.d3d = Direct3DCreate9( D3D_SDK_VERSION ) ;  // Always use D3D_SDK_VERSION

  if( g.d3d == NULL )
  {
    // DEVICE CREATION FAILED!!!! OH NO!!!
    puts( "Oh.. PHOOEY!!!!!  Device creation FAILED!!! WHAT NOW???\n" ) ;
    return false ;
  }



  // Ok, if we get here without returning, it means device creation succeeded.
  puts( "Device creation SUCCESS!!!!\nWe're in business now, son..\n" ) ;
  
  // Next we'll just print a few details about the system
  // just because we can..
  // Note how we use PURELY the 'd3d' object
  // to do this (NOT the 'gpu' device, which hasn't
  // even been created yet!)
  ///// printf( "I will now tell you some \nthings ABOUT your system.\n" );
  ///// printSystemInfo(); // BOOOOORING.
  


  puts( "Ok, Now to CREATE the 'gpu' device!!" ) ;
  
  // First, create the D3DPRESENT_PARAMETERS structure.
  // This structure will basically "explain" to the
  // IDirect3D9 interface EXACTLY WHAT we want the
  // GPU rendering surface to look like once
  // it has been created.



  // D3DPRESENT_PARAMETERS structure
  D3DPRESENT_PARAMETERS pps = { 0 } ;  // Start structure all 0'd out.

  // We're using a windowed mode, NOT fullscreen in this
  // example.  Its really annoying to program little test
  // apps in fullscreen mode.  Also when using windowed mode
  // we don't have to (in fact, we should not) specify
  // some of the other parameters, such as the refresh rate.
  pps.Windowed = true ;

  // How many backbuffers do we want?  One.
  pps.BackBufferCount = 1 ;

  // This one's interesting
  // Backbuffering.  Imagine Leonardo Davinci doing
  // a live animation for you.

  // Imagine he stood in front of the canvas,
  // and blazingly quickly, painted a live scene for you.
  // Then to make the animation effect happen, he'd have
  // to erase the canvas (paint over it in all white?) then
  // paint over that white the next frame.

  // Not that great for watching an "animation!"  even if
  // he moved blazing fast, it'd still be "flickery" having
  // to "see" the canvas get all cleared out, then see each
  // shape get drawn on.

  // So instead, Davinci has a better idea.  He will
  // use TWO canvases.  He will draw to the canvas
  // in a HIDDEN place, where you can't see it.

  // When he's done painting hte first frame, BAM,
  // he slams it in your face and you can see it.
  // He then takes a SECOND canvas, and paints to it
  // blazing fast, what should be the next frame you see.
  // Then, BAM, he slams that second canvas right in your face,
  // where you can see it.  He then quietly pulls away
  // that first canvas that had the first frame on it
  // (which you can't see anymore, because you're looking
  // at the SECOND canvas he just slammed in your face),
  // and quickly paints the NEXT (3rd) frame onto it.
  // Then, BAM, he slams that first canvas in your face
  // again, but now it has the 3rd frame on it.  He then
  // takes the SECOND canvas, and draws the 4th frame on it...

  // Do you see what's happening here?  Read it again
  // if not... the whole point is to give a MUCH smoother
  // and continuous presentation of image frames.  If you
  // didn't use a backbuffer, then the animation presented
  // would look all awful and flickery and horrible because
  // you'd basically be WATCHING the gpu do its drawing work,
  // instead of looking at nice finished product painted scenes instead.

  // Swap chains
  pps.SwapEffect = D3DSWAPEFFECT_DISCARD ; // You start with
  // 2 buffers, one that displays what you're currently
  // looking at (the "frontbuffer") and
  // one that is hidden from you (the "backbuffer").
  
  // Basically FLIP means that
  // d3d should DRAW to the BACKBUFFER first, then
  // when its done doing that, it should BAM, slam
  // that backbuffer in your face, so you can see it.
  // The former front buffer, is then DISCARDED.

  // SO, the former "backbuffer" is NOW the FRONTBUFFER.
  // And the former front buffer, we will treat
  // as the NEW "backbuffer".

  // SO draw to the OTHER buffer now (which is considered
  // as the backbuffer at the moment), when you're done,
  // BAM, slam that backbuffer in the user's face
  // (so again, the former "backbuffer" has flipped
  // and become the frontbuffer).

  // The OTHER way to do this is to DRAW TO
  // the backbuffer, then to COPY OUT the backbuffer
  // in its entirety to the front buffer.  That's
  // less efficient though, for obvious reasons
  // (copying about 2,000,000 pixels has gotta take
  // at least some time!).  Discard is nice, but
  // using it REQUIRES that you completely update
  // ALL the pixels of the backbuffer before presenting it
  // (because there's NO TELLING what will happen to
  // the frontbuffer once you've "discarded" it!
  // Microsoft says "we might do anything to it..."
  // The Clear() operation is sufficient to touch every
  // pixel on the buffer, so as long as you're calling
  // Clear() every frame, there's nothing to worry about.
  // You'll see Clear() in use a bit later in this tutorial.)

  // Pixel format to use on the backbuffer.
  pps.BackBufferFormat = D3DFMT_UNKNOWN ;   // So, this doesn't mean
  // we don't KNOW the pixel format we want.. its more
  // like saying "D3DFMT_CHOOSE_IT_FOR_ME!"
  
  // What really happens is "color conversion is done by the hardware"

  // But you can think of it as D3D should picking
  // the appropriate pixel format to use.

  
  
  // Now, we WANT Direct3D to create and manage
  // a depth buffer for this surface.  That means
  // if we draw two triangles and one is "closer"
  // than the other, then the "closer" one should
  // be drawn on top of the "further" one.  That's
  // achieved using the depth buffer
  pps.EnableAutoDepthStencil = true ;
  // Now we have to say "how deep" is the depth buffer.
  // Kind of.  How precise are the depth values?
  // The more bits you use, the more "slots of depth"
  // your depth buffer can handle.  If your depth buffer
  // used 2 bits, it might be able to handle 4 levels
  // of depth.  With 16 bits, there's a lot more levels of
  // depth.  Having many different levels of depth is
  // really important because if two objects are
  // like thought by the gpu to be at the exact same
  // "depth", then there will be "z-fighting"
  // z-fighting sample1
  // Apparently some users experienced problems
  // with z-fighting when playing GTA 4 on ATI hardware.

  // We choose a fairly "deep" pixel format (16 bits)
  // Could also choose 24 bits.
  pps.AutoDepthStencilFormat = D3DFMT_D16 ;

  // Finally, make the gpu device.
  HRESULT hr = g.d3d->CreateDevice(
    
    D3DADAPTER_DEFAULT, // primary display adapter
    D3DDEVTYPE_HAL,     // use HARDWARE rendering (fast!)
    g.win.hwnd,
    D3DCREATE_HARDWARE_VERTEXPROCESSING,
    &pps,
    &g.gpu  // THIS IS where you get
    // the ACTUAL return value (the
    // GPU device!) from this function.
    // Because this function has its
    // return value as an HRESULT,
    // the return value is used to
    // indicate success or failure.

  ) ;


  if( !CHECK( hr, "OH NOS!! I could not initialize Direct3D!  Bailing...\n" ) )
  {
    return false ;
  }



  // Successfully created direct3d9 devices
  printf( "WHOO!  We SUCCESSFULLY created the Direct3D9 GPU device\n" ) ;
  


  return true ;
}


////////////////////////
// DRAWING FUNCTION
void draw()
{
  HRESULT hr ;

  #pragma region clear
  // First, we will clear the backbuffer.  This is a VERY general use
  // function and has way more capabilities than we care to use
  // at the moment.  For example, you can choose to clear little
  // sub-rectangles of the screen ONLY instead of clearing the whole
  // screen with the first 2 params.  we're not interested in that though,
  // we just wanna clear the whole screen.

  // IDirect3DDevice9::Clear()
  hr = g.gpu->Clear(

    0, // NUMBER of sub rectangles to clear.  We set to 0 because
       // we don't want to even clear any subrectangles.. we just
       // want to clear the WHOLE thing!

    0, // you can choose to clear only a sub-region of the
       // backbuffer.  But we wanna clear the WHOLE back buffer!
       // so we pass 0 here and d3d will automatically clear the WHOLE THING for us.

    // D3DCLEAR
    D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER /* | D3DCLEAR_STENCIL */,  // next is weird, but
    // here we specify WHAT exactly we want cleared.  Because a 3d
    // buffer is actually made of several LAYERS (color layer,
    // and depth layer, and stencil layer), you choose
    // what exactly what you want cleared.  If you weren't
    // doing 3d graphics for example (you used direct3d9 to draw
    // 2d graphics, which you can!) you would have no need for
    // the depthbuffer.  So you could save a bit of time
    // (clearing a buffer is a relatively expensive operation)
    // by NOT clearing the buffers you aren't going to use.
    
    // In this example we are NOT using the stencil buffer,
    // but we ARE using the color BUFFER ITSELF (like color values)
    // hence specification of D3DCLEAR_TARGET,
    // and we ARE using the depth buffer (D3DCLEAR_ZBUFFER)
    // but we are NOT using the stencil buffer (hence me omitting
    // D3DCLEAR_STENCIL).  There's no sense in clearing out a
    // buffer that's not in use.  That's like vaccumming a room
    // that's just been vaccummed squeaky clean.
    // If you're not going to be picking up any extra dirt,
    // cleaning it again is really just a waste of time and energy.
    
    D3DCOLOR_ARGB( 255, 125, 25, 237 ),  // The color to clear
    // the backbuffer out to.
    
    1.0f, // value to clear the depth buffer to.  we clear
    // it to 1.0f because 1.0f means ("furthest away possible
    // before being out of range")

    // So we clear every value in the depth buffer to this
    // value so when something is rendered that is in view range,
    // it will definitely be closer than 1.0f!
    // (0.0f means right in our faces).
    
    0  // value to clear the stencil buffer to.  since we
    // chose NOT to clear the stencil buffer (omitted
    // D3DCLEAR_STENCIL from above), this value is
    // actually going to be ignored.
    
  ) ; 
  CHECK( hr, "Clear FAILED!" ) ;

  #pragma endregion

  #pragma region set up the camera

  // First we start by setting up the viewport.
  // the viewport "Defines the window dimensions of
  // a render-target surface onto which a 3D volume projects."
  D3DVIEWPORT9 viewport ;

  // Very clear explanations of each (and advice! :) )
  // of these members are on msdn.
  viewport.X = 0 ;
  viewport.Y = 0 ;
  viewport.Width = g.win.width ;
  viewport.Height = g.win.height ;
  viewport.MinZ = 0.0f ;
  viewport.MaxZ = 1.0f ;

  g.gpu->SetViewport( &viewport ) ;


  // Technically we don't need to set the viewport here
  // BUT you can use viewport setting to draw "picture in picture" -

  // Form the 

  // Set projection matrix
  D3DXMATRIX projx ;
  
  // Create a perspective matrix
  D3DXMatrixPerspectiveFovRH( &projx, PI/4, (float)g.win.width/g.win.height, 1.0f, 1000.0f ) ;
  
  // set
  g.gpu->SetTransform( D3DTS_PROJECTION, &projx ) ;

  // Create the view matrix
  D3DXMATRIX viewx ;

  D3DXVECTOR3 eye( 4, 2, 4 ) ;
  D3DXVECTOR3 look( 0, 0, 0 ) ;
  D3DXVECTOR3 up( 0, 1, 0 ) ;
  D3DXMatrixLookAtRH( &viewx, &eye, &look, &up ) ;
  g.gpu->SetTransform( D3DTS_VIEW, &viewx ) ;
  #pragma endregion

  // Preparing to draw
  // FVF.  WTF is an FVF?
  // MSDN:  "Flexible Vertex Format Constants, or FVF codes,
  //   are used to describe the contents of vertices
  //   interleaved in a single data stream that will
  //   be processed by the fixed-function pipeline."

  // FVF stands for "FLEXIBLE VERTEX FORMAT".  If you're familiar with
  // OpenGL, this is a completely (but some might say a little bit better..)
  // way of allowing a person to say WHAT data each vertex has tagged along
  // with it.

  // So let's tell Direct3D what data exactly each VERTEX 
  // will have.  A position?  A color?  A normal?  A texture
  // coordinate?  What do you WANT TO specify for each vertex.

  hr = g.gpu->SetFVF(
    
    D3DFVF_XYZ  // THe most OBVIOUS (and most important?) aspect of a VERTEX is
    // that it have a POSITION, XYZ.  Specifying that our vertex format
    // includes an XYZ position
    
    | D3DFVF_DIFFUSE // We also specify a diffuse color for each vertex.
    
  ) ;
  CHECK( hr, "SetFVF FAILED!" ) ;
  
  // So there we have it.  We just told d3d to expect
  // to get vertices that each have an XYZ coordinate
  // AND a color specified for them.

  

  // SO NOW, before DRAWING anything, we have to 
  // do 2 more things:
  //   #1)  Create a D3DVERTEXELEMENT9 structure
  //       which will represent our vertex format.

  //   #2)  Create an array of vertices to draw!
  
  //   #3)  Just draw it!

  // #1)  This part is a bit confusing at first,
  // but if you read through it carefully, it should
  // make sense.

  // What we need to do here is create a SPECIAL
  // kind of structure called a "VERTEX DECLARATION"
  // This VertexDeclaration will MATCH UP with
  // the "FVF" format that we set up just a couple
  // of lines ago.  Read on!

  // In the specification, we actually have to
  // obey the FVF mapping
  // on msdn.

  /////////////
  #pragma region // <position vertex element decl>
  // IDirect3DVertexDeclaration9
  
  // OK in the FVF above, we promised d3d that
  // EACH AND EVERY vertex would have a POSITION
  // and a COLOR.

  // So we declare and set up TWO D3DVERTEXELEMENT9
  // structures which explain to d3d the EXACT format
  // and nature of each vertex -

  // IS this a bit redundant?  Kind of, yes.  Getting
  // on with it.

  D3DVERTEXELEMENT9 pos ;
  
  // Here is where we say that this part
  // of the vertex will specify a POSITION
  // in space.
  pos.Usage = D3DDECLUSAGE_POSITION ;

  // This part makes sense if you understand
  // that sometimes, you want to send MORE THAN
  // one position coordinate for each vertex.
  // If that makes less sense, then think about
  // sending down more than one COLOR for each
  // vertex, for some type of funky color blending.
  pos.UsageIndex = 0 ;

  pos.Stream = 0 ; // Vertex shaders have a concept
  // of "stream".
  
  // So what's a "stream" you ask?
  // This really is QUITE an advanced topic, so my honest advice
  // to you is to completely ignore the below unless you 
  // REALLY want to know what streams are.

  // <streams>
  // There is a concept in GPU programming called "shader instancing".
  // Shader instancing is when you specify a model's geometry once,
  // then draw that same model like a million times.

  // 

  // So, you specify the model vertex data with POSITIONS on
  // channel 0, for example.  Then you specify a bunch of
  // positions on channel 1 (1,000,000 positions in your game world,
  // or something) that describe places to draw ALL the vertices
  // that are on channel 0.

  // So its really quite complicated and hard to understand.
  // Channels are like TV -- like the TV station sends like,
  // 500 channels down to your TV in parallel (hey, pretend
  // they do), the vertex data you send down to the GPU
  // all goes down to the GPU in parallel, work at drawing the same thing, kind of.
    
  // Your tv can tune into one channel at a time only, and the GPU
  // will actually tune into ALL the channels when drawing..
  // </streams>  See http://msdn.microsoft.com/en-us/library/bb147299(VS.85).aspx for more detail.
    
  // UH, where were we?  Next, we specify the actual data type of
  // the position data.

  pos.Type = D3DDECLTYPE_FLOAT3 ;  // "Vertices will use
  // 3 floats to specify their position in space".
  
  // If you are familiar with GPU datatypes and HLSL,
  // this would correspond directly with the "float3"
  // datatype in the vertex shader.
  
  // If you don't know what a vertex shader is,
  // just suffice it to say, that all this means
  // is 3 floats will be used for the POSITION
  // of the vertex.
  
  // Next we set the "offset":

  pos.Offset = 0 ;

  // In the Vertex STRUCT that WE defined,
  // this is the byte offset from the start
  // of the struct where D3D SHOULD expect
  // to find this data.
  
  // Using default method.
  pos.Method = D3DDECLMETHOD_DEFAULT ; // here's more info
  
  #pragma endregion // </position vertex element decl>
  /////////////


  /////////////
  #pragma region // <color vertex element decl>
  // Next we declare the vertex element that
  // will represent the DIFFUSE COLOR component.
  D3DVERTEXELEMENT9 col;
  
  col.Usage = D3DDECLUSAGE_COLOR ; // its a color
  col.UsageIndex = 0 ; // COLOR0
  col.Stream = 0 ;

  col.Type = D3DDECLTYPE_D3DCOLOR ; // UNFORTUNATELY you MUST
  // chose D3DDECLTYPE_D3DCOLOR when using COLOR0
  // or COLOR1.  If you write your own shader,
  // then you can use a FLOAT4 color.
  // If you try and do that, you will get
  // [5052] Direct3D9: Decl Validator: X254: (Element Error) (Decl Element [2])
  // Declaration can't map to fixed function FVF because color0/color1
  // cannot have type other than D3DDECLTYPE_D3DCOLOR
  // in the d3d extended debug output.

  
  // NEXT, the OFFSET.  The offset is
  // 3*sizeof(float) because the 'POSITION'
  // comes first and takes up 3 floats as we
  // specified above.
  col.Offset = 3*sizeof( float ) ;
  col.Method = D3DDECLMETHOD_DEFAULT ;
  #pragma endregion // </color vertex element decl>
  /////////////
  

  /////////////
  #pragma region create and set vertex declaration
  // Now put the two D3DVERTEXELEMENT9's into
  // an array and create the VertexDeclaration:
  D3DVERTEXELEMENT9 vertexElements[] =
  {
    pos,
    col,

    // VERY IMPORTANT!  D3D doesn't konw
    // HOW MANY elements you will be specifying
    // in advance, so you TELL IT by passing
    // this SPECIAL D3DVERTEXELEMENT9 object
    // which is basically just like the null
    // terminator at the end of C string.
    D3DDECL_END()
  } ;
  
  IDirect3DVertexDeclaration9 * Vdecl ;

  // Now register in the "vertexElements" array
  // we just created above into the decl
  hr = g.gpu->CreateVertexDeclaration( vertexElements, &Vdecl ) ;
  CHECK( hr, "CreateVertexDeclaration FAILED!" ) ;

  // Now SET IN that vertex declaration into the GPU
  hr = g.gpu->SetVertexDeclaration( Vdecl ) ;
  CHECK( hr, "SetVertexDeclaration FAILED!" ) ;
  #pragma endregion

  #pragma region set render states
  // FINALLY, last thing before drawing, we
  // have to set the renderstate to USE
  // the DIFFUSE component to determine the
  // color of each vertex
  // Per-Vertex Color State
  hr = g.gpu->SetRenderState( D3DRS_COLORVERTEX, TRUE ) ;
  CHECK( hr, "SetRenderState( COLORVERTEX ) FAILED!" ) ;

  
  // Turn LIGHTING off.  TRUE to enable Direct3D lighting,
  // or FALSE to disable it. The default value is TRUE.
  // __Only vertices that include a vertex normal are properly lit;
  // vertices that do not contain a normal ___employ a dot product of 0___
  // in all lighting calculations.__!

  // So if you don't disable lighting, what will actually happen is,
  // since we don't specify normals for any of our vertices,
  // they will all have a normal vertex of the 0 vector, so
  // the result is they will all be completely black.
  hr = g.gpu->SetRenderState( D3DRS_LIGHTING, FALSE ) ;
  CHECK( hr, "Lighting off" ) ;


  // Turn backface culling off.  Its good to turn this off
  // when starting out because triangles that you wind
  // ccw are discarded if this is on.
  // http://msdn.microsoft.com/en-us/library/bb204882(VS.85).aspx
  hr = g.gpu->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ) ;
  CHECK( hr, "Culling off" ) ;

  #pragma endregion

  #pragma region declare a vertex structure, create verts
  // OK?? WHEW!!  THAT was a lot of work!
  // Now let's DRAW SOMETHING!!  First,
  // we have to create a STRUCT which
  // will match up the vertex declaration
  // we specified above.

  // Practically you'd probably want this struct
  // to be declared in global space, but its declared
  // inline here just to preserve the
  // flow of information for you.

  struct Vertex 
  {
    float x,y,z ;
    DWORD color ;

    // Ctor starts you at origin in black
    // with alpha (opacity) set to 100%
    Vertex()
    {
      x=y=z = 0.0f;
      color = D3DCOLOR_XRGB( 0,0,0 ) ;
    }

    // Ctor.
    Vertex( float ix, float iy, float iz,
      unsigned char ir, unsigned char ig, unsigned char ib )
    {
      x=ix;y=iy;z=iz;
      color = D3DCOLOR_XRGB( ir, ig, ib ) ;
    }

    // Ctor that lets you pick alpha
    Vertex( float ix, float iy, float iz,
      unsigned char ir, unsigned char ig, unsigned char ib, unsigned char ALPHA )
    {
      x=ix;y=iy;z=iz;
      color = D3DCOLOR_ARGB( ALPHA, ir, ig, ib ) ;
    }
  } ;

  // Now create an array full of vertices!
  Vertex verts[] = {

    // Red vertex @ ( -1, 0, 0 )
    Vertex( -1, 0, 0, 255, 19, 0 ),

    // Green vertex @ ( 0, 1, 0 )
    Vertex(  0, 1, 0, 0, 255, 0 ),

    // Blue vertex @ ( 1, 0, 0 )
    Vertex(  1, 0, 0, 0, 0, 255 )

  } ;

  float axisLen = 2.0f ;
  Vertex axis[] = {

    // x-axis is red
    Vertex( -axisLen, 0, 0, 255, 0, 0 ),
    Vertex( +axisLen, 0, 0, 255, 0, 0 ),

    // y-axis green
    Vertex( 0, -axisLen, 0, 0, 255, 0 ),
    Vertex( 0, +axisLen, 0, 0, 255, 0 ),

    // z-axis blue
    Vertex( 0, 0, -axisLen, 0, 0, 255 ),
    Vertex( 0, 0, +axisLen, 0, 0, 255 )

  } ;

  #pragma endregion

  #pragma region ACTUALLY __draw__
  // IDirect3DDevice9::BeginScene()
  // You must call BeginScene() before you start drawing anything.
  hr = g.gpu->BeginScene() ;
  CHECK( hr, "BeginScene FAILED!" ) ;

  hr = g.gpu->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 1, verts, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  hr = g.gpu->DrawPrimitiveUP( D3DPT_LINELIST, 3, axis, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  float pointSize = 8.0f ;

  // A DWORD is 4 bytes (a WORD is 2 bytes).
  // So, what we need to do is basically cast
  // pointSize to (DWORD).  Its a bit complicated
  // about how you actually do it, so I made a macro for it.
  // The general idea is you need to "trick" SetRenderState
  // into taking your float value.. SetRenderState "thinks"
  // its a DWORD, while its actually a float.. and D3D
  // internally somehow gets it and knows to treat it as a float.
  // Kind of clunky, eh, but what can you do.
  g.gpu->SetRenderState( D3DRS_POINTSIZE, CAST_AS_DWORD( pointSize ) ) ;
  
  // Draw points at end of axis.
  Vertex points[] = {
    Vertex( axisLen, 0, 0, 255, 0, 0 ),
    Vertex( 0, axisLen, 0, 0, 255, 0 ),
    Vertex( 0, 0, axisLen, 0, 0, 255 ),
  } ;
  hr = g.gpu->DrawPrimitiveUP( D3DPT_POINTLIST, 3, points, sizeof( Vertex ) ) ;
  CHECK( hr, "DrawPrimitiveUP FAILED!" ) ;

  // endscene, and present
  // IDirect3DDevice9::EndScene()
  // You must call EndScene() to signify to the gpu that
  // you are finished drawing.  Must pair up with
  // a BeginScene() call that happened earlier.
  hr = g.gpu->EndScene() ;
  CHECK( hr, "EndScene FAILED!" ) ;

  // And finally, PRESENT what we drew to the backbuffer
  g.gpu->Present( 0, 0, 0, 0 ) ;
  #pragma endregion



}




// function that prints some system info.  can ignore this part
// if you are not interested in it.
void printSystemInfo()
{
  UINT numAdapters = g.d3d->GetAdapterCount() ;
  printf( "\n\n* * * * System information * * * *\n" ) ;
  printf( "Owner name:  Dorky Dorkinson (haha, just kidding, little easter egg there..)\n" ) ;
  printf( "Ok, the rest of this information IS real!\n" ) ;
  
  printf( "You have %d adapters\n  * (this number is bigger than 1 if you have dualview)\n", numAdapters ) ;

  // Scroll through all adapters and print some info about each
  for( int i = 0 ; i < numAdapters ; i++ )
  {
    printf( "\n\n-- ADAPTER #%d --\n", i ) ;
    printf( "On monitor #%d\n", g.d3d->GetAdapterMonitor( i ) ) ;

    // Object into which display mode info will be saved
    // by GetAdapterDisplayMode
    D3DDISPLAYMODE displayMode ;
    g.d3d->GetAdapterDisplayMode( i, &displayMode ) ;

    printf( "Has Format=%d Height=%d Width=%d RefreshRate=%d\n", displayMode.Format, displayMode.Height, displayMode.Width, displayMode.RefreshRate ) ;
    printf( "  * (format refers to the D3DFMT_ pixel mode.. e.g. 22=D3DFMT_X8R8G8B8 which is 24 bit color)\n" ) ;
    
    D3DADAPTER_IDENTIFIER9 id ; // Will hold info about the adapter
    // after call to GetAdapterIdentifier

    g.d3d->GetAdapterIdentifier( i, 0, &id ) ;
    // At this point you can see how WEIRD the API gets.
    // All I want is the adapter identifier, and here MSDN
    // says the API offers to "connect to the Internet
    // and download new MS Windows Hardware Quality Labs certificates."
    // Holy cow.  I don't want to do THAT.  So leave the flag at 0.
    
    // There's PLENTY of info here we don't care about,
    // but some of it is interesting!!  I've printed
    // only the most interesting members, leaving parts
    // like the GUID out.
    printf( "<device driver info>\n" ) ;
    printf( "  Description: %s\n  Device Id: %d\n  Device name: %s\n  Driver: %s\n",
      id.Description, id.DeviceId, id.DeviceName, id.Driver ) ;
    printf( "</device driver info>\n" ) ;
    

    UINT modeCount ;
    
    // I guess this next part just shows.. how FEW modes are
    // actually supported on a GPU.. I have an NVIDIA 8800GTS,
    // and it only supports 28 modes on D3DFMT_X8R8G8B8,
    // and 28 modes on D3DFMT_R5G6B5.  The rest, 0 modes are
    // reported as supported!

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_R8G8B8 ) ;
    printf( "D3DFMT_R8G8B8   %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A8R8G8B8 ) ;
    printf( "D3DFMT_A8R8G8B8 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_X8R8G8B8 ) ;
    printf( "D3DFMT_X8R8G8B8 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_R5G6B5 ) ;
    printf( "D3DFMT_R5G6B5   %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_X1R5G5B5 ) ;
    printf( "D3DFMT_X1R5G5B5 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A1R5G5B5 ) ;
    printf( "D3DFMT_A1R5G5B5 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A4R4G4B4 ) ;
    printf( "D3DFMT_A4R4G4B4 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_R3G3B2 ) ;
    printf( "D3DFMT_R3G3B2   %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A8 ) ;
    printf( "D3DFMT_A8       %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A8R3G3B2 ) ;
    printf( "D3DFMT_A8R3G3B2 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_X4R4G4B4 ) ;
    printf( "D3DFMT_X4R4G4B4 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A2B10G10R10 ) ;
    printf( "D3DFMT_A2B10G10R10 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A8B8G8R8 ) ;
    printf( "D3DFMT_A8B8G8R8 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_X8B8G8R8 ) ;
    printf( "D3DFMT_X8B8G8R8 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_G16R16 ) ;
    printf( "D3DFMT_G16R16   %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A2R10G10B10 ) ;
    printf( "D3DFMT_A2R10G10B10 %d modes supported\n", modeCount ) ;

    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_A16B16G16R16 ) ;
    printf( "D3DFMT_A16B16G16R16 %d modes supported\n", modeCount ) ;






    // This mode is the MOST LIKELY TO be supported on your machine.
    modeCount = g.d3d->GetAdapterModeCount( i, D3DFMT_X8R8G8B8 ) ;
    for( int j = 0 ; j < modeCount; j++ )
    {
      g.d3d->EnumAdapterModes( i, D3DFMT_X8R8G8B8, j, &displayMode ) ;

      printf( "For format=%d (D3DFMT_X8R8G8B8) Height=%d Width=%d RefreshRate=%d is SUPPORTED\n", displayMode.Format, displayMode.Height, displayMode.Width, displayMode.RefreshRate ) ;

    }


    // At this point you're thinking, "HEY!!  But i'm SURE my gpu supports
    // alpha blending!  Why are all the modes like A8R8G8B8 NOT supported!?"
    // My best stab at this is it makes no sense to DISPLAY something with
    // an alpha component still in it.  For the final image that gets displayed --
    // the alphas should already have been blended -- present day
    // monitors can only display RGB, they don't have the ability to
    // "go transparent".  Maybe one day when we work with those enormous
    // glass screens that people work with in the movies -- kinda like this one:
    // http://business.timesonline.co.uk/multimedia/archive/00339/screen-385_339034a.jpg
    // then having an ALPHA component on the display WOULD make sense.  But for
    // now, all monitors are completely opaque, and they only display colors
    // RGB.  So an alpha component makes no sense on the display itself.
    // That's why displays don't support that display mode.



    // K, FINALLY we get to the device's capabilities.
    // I love how DirectX lets you "reflect" on what
    // the hardware is in fact capable of.  Its nice.

    D3DCAPS9 caps ;
    g.d3d->GetDeviceCaps( i, D3DDEVTYPE_HAL, &caps ) ;

    // Now we have the capabilities of the device.
    // Printing all of them would be meaningless,
    // but if you want to inspect some of them, just
    // use the debugger.

  }
}





int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
  //////////////////
  // First we'll start by saving a copy of
  // the hInstance parameter inside our
  // "glob" of globals "g":
  g.win.hInstance = hInstance;
  // In case we need it later, we'll have it
  // with firsthand easy access.

  #pragma region part 0 - attach a console
  // Attach a console
  AllocConsole();
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ; // redirect stdout to console
  freopen( "CON", "w", stderr ) ; // redirect stderr to console

  // Move the console over to the top left
  g.win.hConsole = GetConsoleWindow();
  MoveWindow( g.win.hConsole, 0, 0, 400, 400, true ) ;

  printf( "* * Computer Program Begin * *\n" ) ;
  #pragma endregion

  #pragma region part 1 - create a window
  // The next few lines you should already
  // be used to:  create a WNDCLASSEX
  // that describes the properties of
  // the window we're going to soon create.
  // A.  Create the WNDCLASSEX
  WNDCLASSEX wcx = { 0 } ;
  wcx.cbSize = sizeof( WNDCLASSEX );
  wcx.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  wcx.hCursor = LoadCursor( NULL, IDC_ARROW );
  wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wcx.hInstance = hInstance;
  wcx.lpfnWndProc = WndProc;
  wcx.lpszClassName = TEXT("Philip");
  wcx.lpszMenuName = 0;
  wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

  // Register that class with the Windows O/S..
  RegisterClassEx( &wcx );

  /////////////////
  // Ok, AT THIS POINT, we'd normally
  // just go ahead and call CreateWindow().
  // And we WILL call CreateWindow(), but
  // there is something I must explain to
  // you first.  That thing is the RECT structure.

  /////////////////
  // RECT:
  //
  // A RECT is just a C struct meant to represent
  // a rectangle.
  //
  // The RECT structure WILL DESCRIBE EXACTLY WHERE
  // AND HOW WE WANT OUR WINDOW TO APPEAR WHEN WE
  // CREATE IT.
  //
  //         TOP
  //       --------
  //       |      |
  // LEFT  |      | RIGHT
  //       --------
  //        BOTTOM
  //
  // So, what we do is, we create the RECT
  // struct for our window as follows:
  RECT rect;
  SetRect( &rect, 420,  // left
    25,  // top
    420 + 800, // right
    25  + 600 ); // bottom

  // Save width and height off.
  g.win.width = rect.right - rect.left;
  g.win.height = rect.bottom - rect.top;

  // Adjust it.
  DWORD windowStyle = WS_OVERLAPPEDWINDOW ; // typical features of a normal window
  DWORD windowExStyle = WS_EX_TOPMOST ; // I want the window to be topmost

  AdjustWindowRectEx( &rect, windowStyle, false, windowExStyle );

  // AdjustWindowRect() expands the RECT
  // so that the CLIENT AREA (drawable region)
  // has EXACTLY the dimensions we specify
  // in the incoming RECT.

  // If you didn't just understand that, understand
  // this:  "you have to call AdjustWindowRect()",
  // and move on.  Its not THAT important, but its
  // good for the performance of your app.

  ///////////////////
  // NOW we call CreateWindow, using
  // that adjusted RECT structure to
  // specify the width and height of the window.
  g.win.hwnd = CreateWindowEx(
    windowExStyle,
    TEXT("Philip"),
    TEXT("TIGER-DIRECT3D WINDOW!"),
    windowStyle,
    rect.left, rect.top,  // adjusted x, y positions
    rect.right - rect.left, rect.bottom - rect.top,  // adjusted width and height
    NULL, NULL,
    hInstance, NULL);

  // check to see that the window
  // was created successfully!
  if( g.win.hwnd == NULL )
  {
    FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
  }

  // and show.
  ShowWindow( g.win.hwnd, iCmdShow );
  #pragma endregion

  #pragma region part 2 - initialize direct3d9

  // JUMP to the initD3D() method.
  if( !initD3D() )
  {
    FatalAppExit( 0, TEXT("SORRY!!!  DEVICE CREATION FAILED!!! YOU LOSE, WITHOUT EVEN PLAYING THE GAME!!!" ) ) ;
  }
  
  #pragma endregion

  #pragma region message loop
  MSG msg;

  while( 1 )
  {
    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
      if( msg.message == WM_QUIT )
      {
        break;
      }
      else
      {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
      }
    }

    // 3.  DRAW USING Direct3D.
    // This region right here is the
    // heart of our application.  THE MOST
    // execution time is spent just repeating
    // this draw() function.
    draw();

  }
  #pragma endregion

  //////////////
  // clean up
  #pragma region clean up

  // Release COM objects.  
  // What's SAFE_RELEASE()?  Well, lots of people use
  // if( pointer ) pointer->Release() ; to guard
  // against null pointer exceptions.
  
  // Like the MS examples do, I've defined
  // SAFE_RELEASE at the top of this file and
  // I'm using it here.  All it does is
  // make sure the pointer is not null before releasing it.
  SAFE_RELEASE( g.gpu ) ;
  SAFE_RELEASE( g.d3d ) ;

  #pragma endregion

  // and a cheesy fade exit
  AnimateWindow( g.win.hwnd, 200, AW_HIDE | AW_BLEND );

  printf( "* * This Computer Program Has Ended * *\n" ) ;
  
  return msg.wParam;
}

////////////////////////
// WNDPROC
// Notice that WndProc is very very neglected.
// We hardly do anything with it!  That's because
// we do all of our processing in the draw()
// function.
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    Beep( 50, 10 );
    return 0;
    break;

  case WM_PAINT:
    {
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );
      // don't draw here.  would be waaay too slow.
      // draw in the draw() function instead.
      EndPaint( hwnd, &ps );
    }
    return 0;
    break;

  case WM_KEYDOWN:
    switch( wparam )
    {
    case VK_ESCAPE:
      PostQuitMessage( 0 );
      break;
    default:
      break;
    }
    return 0;

  case WM_SIZE:
    {
      int width = LOWORD( lparam ) ;
      int height = HIWORD( lparam ) ;
      printf( "RESIZED TO width=%d height=%d\n", width, height ) ;
    }
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 ) ;
    return 0;
    break;
  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}


/*
    ____   __   __      __   __  ___
   / _  \ /  / /  /    /  /  \ \/  /
  / _/ / /  / /  /    /  /    \   /
 / _/ \ /  / /  /__  /  /__   /  /
/_____//__/ /______//______/ /__/

*/

Code package on esnips (thanks esnips!)

A lot of API’s do it. BUT WHY?
Passing a pointer to a pointer

#include <stdio.h>
#include <stdlib.h>



char * InitArrayGood0( char * a ) ;
void InitArrayGood1( char * &a ) ;
void InitArrayGood2( char ** a ) ;
void InitArrayEvil( char * a ) ;

int main()
{
  char * word = NULL ;
  
  // This way doesn't work
  InitArrayEvil( word ) ;

  // These 3 ways all work.
  word = InitArrayGood0( word );
  //InitArrayGood1( word );
  //InitArrayGood2( &word );

  if( word == NULL )
  {
    printf("Word is STILL NULL!!!  That init didn't do ANYTHING!!\n") ;
    exit(1);
  }
  else
  {
    word[0] = 'a' ;
    word[1] = 'b' ;
    word[2] = 0 ;

    puts( word ) ;
  }
}

// Does not work
// what happens here is
// the pointer value (0) is
// PASSED BY VALUE to this function.
void InitArrayEvil(char * a)
{
  // Say the array that (a) refers to
  // references a NULL variable.  Well,
  // when we first come into this function,
  //   InitArrayEvil( word ) ;
  // the value of (a) as we start
  // executing this function is 0.

  // We then assign (a) as a new array.
  
  a = new char[20];  // Fine and dandy.

  // BUT THE value of (word) in the
  // CALLING function is UNCHANGED!
  // You really have to think about why.

  // Its tricky because at first, you
  // should think "BUT I PASSED IT
  // BY REFERENCE!!  So any changes
  // to (a) in this function should
  // affect (word) in the calling function!"

  // PARAMETER PASSING IN THIS FUNCTION
  // is ACTUALLY BY VALUE.
  
  // What that means is, even though (a)
  // is a pointer to a char,
  // char * a gets initialized by COPYING
  // the value of (word) that is passed to it
  //    InitArrayEvil( word ) ;
  // If word starts out at NULL, then
  // a starts out at null.  If we subsequently
  // change the value of a, that DOES NOT CHANGE
  // the value of word!

  // Its confusing because say we had a function like
  //   void truncate( char * a )
  //   {
  //     a[ 0 ] = 0 ;
  //   }
  // 
  // call by:
  //   word = new char[ 20 ] ;
  //   word[0] = 'a'; word[1] = 'b'; word[2] = 0;
  //   truncate( word ) ;

  // THEN this function WOULD change whatever array
  // you passed to it.  Because what gets copied in
  // to (a) IS THE MEMORY ADDRESS VALUE of the variable
  // (word).  (word) is then actually manipulated
  // when (a) is manipulated in the truncate() function.

  // This is hard to wrap your head around, but once
  // you get it, it makes perfect sense.
}

// This function WORKS because
// we RETURN a.
char * InitArrayGood0(char * a)
{
  a = new char[20];

  // Here, we are RETURNING that new
  // memory address value for a.  So
  // as long as you write:
  //    word = InitArrayGood0( word )
  // You'll have no problem using this
  // function.  Actually this function
  // doesn't NEED (a) to come into it,
  // (this function should really take
  // NO parameters), but I left it there
  // for consistency.
  return a;
}

// Works
void InitArrayGood1(char * &a)
{
  // So, oddly, THIS function works,
  // but only in C++.

  // a is set up as a char* pointer,
  // but it is set up as AN ALIAS
  // to (word), the variable that exists
  // in the calling function.

  // As a result, (a) basically 
  // "reaches into" the scope of main()
  // and uses THAT SAME VARIABLE (word).

  // So assignment of (a) changes (word).
  // So this function works.
  a = new char[20];
}

// Works
// This function takes a POINTER TO A (char*)
// variable.
// NOW this will work too, and its the most
// common way of handling this type of thing
// (all the DirectX CreateDevice() functions
// use this method).  This way works in
// both C and C++.  Because now the value
// being copied into a is THE MEMORY ADDRESS
// OF THE VARIABLE (word) IN MAIN().
// This means that any change to (*a) directly
// change (word) in main(), which means this
// function can cause (word) to point to something
// new.

// The value COPIED here is the ADDRESS OF A,
// which happens to be a pointer.  Get it?
// its tough, but again once you get it, it makes
// perfect sense.
void InitArrayGood2( char ** a )
{
  *a = new char[20 ] ;
}


Writing good unit test cases is hard and requires you to be paying a lot of attention to catch problems.

Consider for example, this operator/ (vector division) method for a Vector class (NOT STRUCT!)

( Since class Vector is a class and not a struct, vec will be passed by reference. )


  public static Vector operator /( Vector vec, double divider )
  {
    vec.x /= divider;
    vec.y /= divider;

    return vec ;
  }

Above code to be used as in:

Vector v = new Vector( 15, 5 ) ;
Vector w = v / 5 ;

Can you see the bug?

You really have to be paying very close attention to ideas that the original programmer (frequently you) might have overlooked when developing the method.

Remember, Vector is a class, not a struct!

Here’s a naive first attempt at Unit test for the operator/ method:

    [TestMethod()]
    public void op_DivisionTest()
    {
      // make a vector and divide it by a constant
      Vector vec = new Vector( 4.92, 8 ) ;
      double d = 7.7 ;
      Vector actual = vec / d ;

      // Find what it should actually be:
      Vector expected = new Vector( 4.92/d, 8/d ) ;
      
      // Assert result is what you expect
      Assert.AreEqual( expected, actual );
            
    }

Can you see the problem? Can you see how this unit test FAILS to catch the real problem with this method?

Look again at the original operator/ method at the top of this page. The problem with the method is it mutates vec, since vec is passed by REFERENCE only and not by value (the method would be FINE if class Vector were struct Vector instead!

So, here’s the better unit test that catches this problem:

    [TestMethod()]
    public void op_DivisionTest()
    {
      // Compute a result, and find expected value as well
      Vector vec = new Vector( 4.92, 8 ) ;
      double d = 7.7 ;
      Vector actual = vec / d ;

      Vector expected = new Vector( 4.92/d, 8/d ) ;
      
      // Test result is what you expect:
      Assert.AreEqual( expected, actual );

      // This is "writing good unit tests".  TEST FURTHER.
      // What else should be guaranteed by this method / what
      // is the programmer to naturally assume about how the
      // method behaves and what it does to its inputs?

      // 1.  A new object, distinct instance of an object should be produced.
      Assert.AreNotSame( vec, actual ) ;
      
      // 2.  vec should remain unchanged from its original value
      Assert.AreEqual( vec, new Vector( 4.92, 8 ) ) ;
      
    }

The corrected operator/ method

For instance, here is an operator/ division method for a Vector class (NOT STRUCT!)
  public static Vector operator /( Vector vec, double divider )
  {
    Vector result = new Vector() ;

    result.x = vec.x / divider;
    result.y = vec.y / divider;

    return result ;
  }

So its easy to write crummy simple unit tests that don’t catch everything!! Unit tests aren’t catch-all.. you have to write them cleverly!

I recently discovered you can use an implicit operator (TYPENAME) to make implicit conversions happen automatically for your custom types in C#:

public class Vector
{

  public static implicit operator string( Vector v )
  {
    return v.ToString() ;
  }

}

Now you can

Vector v = new Vector();
Console.WriteLine( v ) ;

Instead of

Vector v = new Vector();
Console.WriteLine( v.ToString() ) ;

So, at first I thought, WOW! That’s great. I’m developing a Matrix and Vector class together and its nice to be able to convert the Vector to a System.Drawing.PointF automatically, so instead of defining a property like:

public class Vector
{

  public System.Drawing.PointF PointF{ get {
    return new System.Drawing.PointF( this.x, this.y ) ;
  } }

}

For use in

Vector v = new Vector( 5, 7 ) ;
graphics.FillEllipse( v.PointF, 10 ) ;

I can now:

public class Vector
{

  public static implicit operator System.Drawing.PointF( Vector v )
  {
    return new System.Drawing.PointF( v.x, v.y ) ;
  }

}

So we could actually

Vector v = new Vector( 5, 7 ) ;
graphics.FillEllipse( v, 10 ) ;  // IMPLICIT TYPE CONVERSION
// TO POINTF NOW SUPPORTED!!

So that’s nice.

BUT.

What’s NOT NICE is what the compiler does when you define an implicit operator THAT ALSO has the == operator DEFINED FOR IT, but your class does not.

So, guess what happens if I DON’T define operator== for my Vector class, but I have the implicit operator string defined as shown above?

GUESS WHAT HAPPENS???

Vector v1 = new Vector( 5, 7 );
Vector v2 = new Vector( 5, 7 ) ;
if( v1 == v2 )  // v1 AND v2 ARE CONVERTED TO STRINGS, THEN COMPARED!!
{
}

This is AWFUL!! Instead of the compiler flagging it now, with “operator not defined for type Vector” (as it would have if we didn’t define implicit operator string), the compiler merrily compiles it!

THIS IS BAD!! Not even mentioning efficiency, in my ToString() method, there’s a round off leaving only 2 decimals! This means that 2.581 and 2.589999 are EQUAL in my program right now!!

Bad! BAD .NET!! BAD!!!!!!!!

Follow

Get every new post delivered to your Inbox.

Join 43 other followers