Skip navigation

Category Archives: C++

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!

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.

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.

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,  //
// https://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!)

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, //
// https://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!)

I didnt’ know this but Visual Studio 2008 has a GORGEOUS ribbon style that you can select when building an MFC app. Fully explore the project creation wizard when you build an MFC app, its worth it!

This was jaw-dropping, for me.

Understanding how to use extern variables in C/C++

Start with a visual studio project.

create 5 files, and copy/paste the contents as show below in them.

Alternatively, esnips code package! (thanks esnips!)

externVarDeclaration.h

#ifndef EXTERN_VAR_DECL_H
#define EXTERN_VAR_DECL_H

extern int i ;  // This is like a "function prototype", only
// for variables.

// The extern declaration says, "this variable doesn't exist yet,
// but it WILL exist, and its value is going to be defined
// in another file that will be part of this project when it compiles."
// (see externVarDefinition.cpp)

// So, using an EXTERN is how you share a single global variable
// ACROSS MULTIPLE FILES.
// Call it a SUPERGLOBAL.  TO understand this, think about
// functions and function prototypes.

// Defining a global function, you kind of expect it to have
// "superglobal" status..
// like, if you define a function somewhere, you should be
// able to break it apart into some prototypes and #include
// those prototypes in ANY FILE that you want
// to use those functions.  Right?

// So, the reason you have prototypes is so that multiple
// files can #include the same prototypes (function
// DECLARATIONS) then the actual code for the
// DEFINITION of the functions is in one place,
// a .cpp file (like "function_set.cpp").  This way you don't
// have multiple re-definitions of the functions declared in
// function_set.h, but you may have multiple re-declarations
// (the compiler might see the same prototype several times
// in a row, which is fine, as long as it sees the BODY
// definition only once.)

// So, an extern'd variable is a lot like that.
// You basically treat it like a function prototype, where the

///// extern int i ;

// part is the DECLARATION (like a function prototype),
// and the part in externVarDefinition.cpp:

// int i = 500 ;

// is like the DEFINITION, or function body.

// C++ can only come across the DEFINITION (value giving part) __ONCE__ for any
// given variable.

// So with externs, you can #include the "extern variable declaration" into as
// many files as you like (just like you can #include the function prototypes
// into as many different files as you wish), so long as
// the "DEFINITION" (the int i = 500 part) only occurs once, in one file.

// If you uncomment this line below, you will see
// its ILLEGAL.

//////////int j = 50 ; ////ILLEGAL

// Surprised?  Well, very illegal!

// Reason:  EVEN WITH the #ifndef #include guards
// on this file.. because this "externVarDeclaration.h" file is
// #included in more than one other file, for some reason the C++
// LINKER (__NOT__ the compiler) will flag it as an error:

// "int j" already defined in main.obj.

// One day I'd like to be able to fully understand why this is
// myself, but for now, "EXTERN solves this problem".

#endif //EXTERN_VAR_DECL_H

function_set.h

#ifndef FUNCTION_SET_H
#define FUNCTION_SET_H

#include <stdio.h>
#include "externVarDeclaration.h"

void print() ;
void print2() ;
void print3() ;
void changeI() ;

#endif //FUNCTION_SET_H

externVarDefinition.cpp

#include "externVarDeclaration.h"

int i = 500 ;

// HERE we define the VALUE of the extern'd variable i.

function_set.cpp

#include "function_set.h"

void print()
{
  printf("func1 %d\n", i);
}

void print2()
{
  printf("func2 %d\n", i);
}

void print3()
{
  printf("func3 %d\n", i);
}

void changeI()
{
  // i is shared across the whole project
  i = 2000402;
}

main.cpp

#include <stdio.h>

#include "externVarDeclaration.h"
#include "function_set.h"


int main()
{
  printf( "The extern'd var is %d\n", i ) ;

  i = 20 ;
  print();

  i = 333 ;
  print2();

  changeI();

  printf("My oh my!  the extern'd var has changed to %d\n", i ) ;
}

IS THERE an IS keyword in C++ like in C#?

YES, there is an IS keyword in C++. Just like in C#.

WRONG
WRONG

A few days ago I had this question and I saw this answer “NO” and I took it and accepted it.

Only today I saw in some sample code just use of typeid(). And guess what? typeid() turns BLUE in the IDE!


#include <iostream>
#include <string>
using namespace std;

class Entity
{
public:
  int hp ;
};

class Grunt : public Entity
{
public:
  string name ;
};

int main()
{
  Grunt grom ;
  grom.hp = 500 ;
  grom.name = "GROM HELLSCREAM!" ;

  const type_info * typeOfG = &typeid( grom ) ;

  cout << typeOfG->name() << endl;

  
  Entity wisp ;
  wisp.hp = 120 ;

  const type_info * typeOfWisp = &typeid( wisp ) ;

  cout << typeOfWisp->name() << endl; 


  // equivalent of C# is:
  //if( grom is Grunt )
  //{
  //}

  // accomplished by
  string classGrunt = "class Grunt" ;
  if( typeid(grom).name() == classGrunt )
  {
    cout << "Grom is a grunt" << endl;
  }
  else
  {
    cout << "Grom is NOT a grunt" << endl;
  }
 

  // so we coudl make this a bit more elegant by
#define is( obj, type ) typeid(obj).name()==type
  if( is( grom, classGrunt ) )
  {
    cout << "Grom is a grunt" << endl;
  }
  else
  {
    cout << "Grom is NOT a grunt" << endl;
  }
 
  /*
  class type_info {
    bool operator==( type_info rhs ) ;
    bool operator!=( type_info rhs ) ;
    int before( type_info rhs ) ;
    const char* name();
    const char* raw_name();
  } ;
  */
  
}

I’m one of those programmers who HATES it when he sees things like:


public class Grunt
{
  private int m_hp ;

  public int HP
  {
    get
    {
      return m_hp ;
    }
    set
    {
      m_hp = value ;
    }
  }
}

Encapsulation or no encapsulation, this just SEEMS dumb.

Sometimes you’ll see this written as:


public class Grunt
{
  private int m_hp ;

  public int HP
  {
    get { return m_hp ; }
    set { m_hp = value ; }
  }
}

Which further proves my point: You can compress code like that when its not meant to be looked at.

The point is, THERE IS NO POINT in having pass-thru getters/setters like this.

In languages other than C#, you’ll see people using functions of course instead of C# properties.


class Grunt
{
private:
  int m_hp ;

public:
  void ChangeHp( int toVal )
  {
    m_hp = toVal ;
  }

  int Hp()
  {
    return m_hp ;
  }
} ;

VERSUS:


class Grunt
{
public:
  int hp ;
} ;

Isn’t there a very slight performance hit for writing code that always uses methods? Yes. ++points for public members.

HOWEVER. Recently I have thought of ONE major benefit to this “methods only/no public members” style that I never really credited to the style before.

Readability.

Think of client code using the Grunt class:


Grunt g ;

if( g.Hp() > 10 )
{
  g.ChangeHp( 12 ) ;
}

VERSUS:


Grunt g ;

if( g.hp > 10 )
{
  g.hp = 12 ;
}

What reads better? g.ChangeHp( 12 ) or g.hp = 12?

Really, g.hp = 12 ; LOOKS more cryptic because even though you know what its doing if you think about it for a fraction of a second, (changing hp to 12), for the method way g.ChangeHp(12) you CANNOT READ IT without knowing exactly what it does like, even faster than the one with the =.

SO. Maybe all private members and all accessor methods aren’t such a bad idea after all.

/////
// Connects to MySQL database server from
// C or C++ program.
/////

/////////////////////////////////////////////
//                                         //
// Connecting C++ Win32 App To MySQL       //
//                                         //
// You found this at bobobobo's weblog,    //
// https://bobobobo.wordpress.com           //
//                                         //
// Creation date:  Apr 5/09                //
// Last modified:  Apr 5/09                //
//                                         //
/////////////////////////////////////////////



// !! Note!  I've included copies of the MySQL
// include headers and library files.. I've done this
// so that the project will compile and run
// more easily for you, but this DOES NOT mean
// that you should skip the SETUP-Y stuff section
// below!

// If you want MySQL to work easily for you in new
// projects, you really should set up Visual Studio
// as explained below.


#pragma region all the setup-y stuff
/////////
// MAKINET WORK: (any prince of persia 2 the shadow and the flame fans out there?)
//
// 1)  First, you OBVIOUSLY must install MySQL.
//     Be sure to download the 32-BIT VERSION (NOT THE x64)
//     of MySQL 5.1 - "Windows MSI Installer"
//     Located at http://dev.mysql.com/downloads/mysql/5.1.html#win32
//     DO NOT GET THE "WINDOWS ESSENTIALS" PACKAGE
//     DO NOT GET __ANY__ x64 crap EVEN IF you are on
//     windows 64 bit, ALWAYS use the NORMAL (non-64 bit)
//     stuff (see Ancient Dragon's comments for why:
//     http://www.programmingforums.org/thread16958.html)

//     Done that?  GOOD!!  Onto step 2.

// 2)  ENSURE THAT mysql.h is in your VISUAL STUDIO
//     PROJECT PATH SETTINGS.  If you don't do this,
//     then you'll may an error of the form of:

// Error	1	fatal error C1083: Cannot open include file: 'mysql.h':
//          No such file or directory


// For me, mysql.h is in :
// C:\Program Files\MySQL\MySQL Server 5.1\include

// But you have to tell VISUAL STUDIO THAT!!  IT doesn't know.

// Need to edit Visual Studio INCLUDE Directory settings.  here's how.

// SO I, click
//   1  TOOLS -> OPTIONS
//   2  PROJECTS AND SOLUTIONS -> VC++ DIRECTORIES (left hand panel)

//   3  (now in right hand panel),
//    from the two dropdowns there
//      (hanging like two microsoft eyes..), uh,

//   4  you just make sure under PLATFORM,
//      it says Win32,

//   5  and under SHOW DIRECTORIES FOR,
//      it says INCLUDE FILES.

//   6  THEN, click the SHINY YELLOW FOLDER,
//      and then click the '...'
//   7  and navigate to your MySQL INSTALL DIR\INCLUDE
//      add that folder there.

//    For me, I end up with an extra entry in that list that says:

//       C:\Program Files\MySQL\MySQL Server 5.1\include

//    yours may be slightly different, but not too different,
//    hey, don't try and be cool here by being REALLY different please.
//   

// OK?  So now the #include below should work for you.
// If it doesn't, INSTALL MYSQL FIRST!

// YOU MUST #INCLUDE WINDOWS.H FIRST IF YOU WANT MYSQL
// TO WORK ON WINDOWS!!
#include <windows.h>
#include <stdio.h>

// To get autocomplete to work, you may have to right-click
// your Header Files -> Add Existing Item... and pick
// mysql.h and add it to your project.  I've copy and pasted
// the file into this project, though.



// !!
// You may only use the form below if you have followed the
// installation instructions above.
/////#include <mysql.h>

#include "mysql_include/mysql.h"  // use this form if you haven't "installed"
// MySQL header files into visual studio as explained above.



// You must also add C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// to your Visual Studio LIBRARY directory settings (follow steps above again, except
// at step 5, you choose "SHOW DIRECTORIES FOR -> LIBRARY FILES"
// and at step 7, you add C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// (or whatever yours really is)


// !!
// You may only use the form below if you have followed the
// installation instructions above.
/////#pragma comment( lib, "libmysql.lib" )

#pragma comment( lib, "mysql_lib/debug/libmysql.lib" )  // use this form if you haven't "installed"
// MySQL header files into visual studio as explained above.

// libmysql.lib is what is termed an "import library" - basically
// it is what wires up function calls in this program to MYSQL
// functionality to the libmysql.dll file.

// So what about libmysql.dll?

// FINALLY, ENSURE TO COPY libmysql.dll to EITHER:  the \Debug folder
// of this project (WHERE THE FINAL .EXE RESIDES), __OR__, to
// C:\WINDOWS\System32 (if that doesn't work, then copy it to C:\WINDOWS\System).

// For me, libmysql.dll lives in
// C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// Its also included in the mysql_lib/debug folder of
// this project.

// To quote Charlie Charlie Petzold, Programming windows 5th ed:
// You can put a DLL file:

// A dynamic library must be present on the disk
// when a program is run that uses the library.
// When Windows needs to load a DLL module before running
// a program that requires it, the librar must be stored:
//   1.  In the directory containing the .exe program
//   2.  the current directory
//   3.  the Windows system directory
//   4.  the windows directory
//   5.  or a directory accessibel through the PATH string in the MS-DOC environment

// The directories are searched in the above order.


#pragma endregion





#pragma region CODING WITH MYSQL


////
// Globals
MYSQL mysql;    // the MYSQL global object.  Passed to mysql_init,
                // and there's only one of this.

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

int main()
{
  // OK!!  Now that you've got all the setup-y stuff out of the way, its
  // time to connect to MySQL!!

  // here are some great references:
  // 1)  http://c-programming.suite101.com/article.cfm/using_a_mysql_databases_with_c
  // 2)  http://dev.mysql.com/doc/refman/5.1/en/windows-client-compiling.html
  mysql_init( &mysql ) ;
  
  // PLEASE SEE DOCS PAGE FOR MORE DETAILS
  // ABOUT mysql_real_connect():
  //   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.
                                          // if you create another database, then you can
                                          // specify you'd like to connect to that one here.

                              0,          // port.  Mine is on 3306, but you can leave it as 0
                                          // and it seems to work automatically.

                              0,          // unix_socket (not in use)

                              0 ) ;       // client flag:  usually 0, unless you want special features (see docs page)
  
  // At this point you may be wondering, ok,
  // so if this is real_connect, what's fake_connect?
  // There is a mysql_connect() function!  Which is
  // basically the "fake" connect... see docs, but
  // the "fake" functions (mysql_query(), mysql_connect()),
  // are like watered down version of their _real_ counterparts.
  // Sometimes useful, sometimes not.  Again, see docs pages.


  // Check if connection succeeded.
  if( conn == NULL )
  {
    printf("Couldn't connect to MySQL database server!\n");
    printf("Error: %s\n", mysql_error( &mysql ) ) ;
    return 1 ;
  }
  else
  {
    printf("Connect success\n") ;
  }
  


  #pragma region running an actual query
  // Here, we are connected.
  // form a sql string to execute.
  
  char * query = "select * from user" ;
  int queryState;

  queryState = mysql_query( conn, query ) ;

  if( queryState != 0 )
  {
    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?
  int numRows = mysql_num_rows( resultset ) ;
  printf( "There are %d 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( "%25.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( "%25.25s", row[ i ] ) ;
    }

    // next row
    printf( "\n" ) ;
  }

  #pragma endregion
  
  // Now free the result
  mysql_free_result( resultset );

  // And close down.
  mysql_close( conn ) ;
  return 0;
}


#pragma endregion // CODING WITH MYSQL


// Your hands quiver with power.

// You are now a MySQL GURU.


// For the record, there's also:
// Connector C++:  http://forge.mysql.com/wiki/Connector_C%2B%2B
// MySQL++:  http://tangentsoft.net/mysql++/

// I chose not to use either library because.. well, I dislike
// additional layers.



// TROUBLESHOOTING:
//
// "This application has failed to start because LIBMYSQL.dll
// was not found.  Re-installing the application may fix this problem."

// So, like internet superhero says, you have 3 options:
// [ http://blog.ulf-wendel.de/?p=215 ]
// 1.  Copy LIBMYSQL.dll into you Windows system directory (C:\Windows\system and/or C:\windows\system32, whichever spins your wheels)
// 2.  You copy LIBMYSQL.dll into the current working directory 
// 3.  You add the location of the LIBMYSQL.dll to your path setting, for example using SET PATH=%PATH%;C:\path\to\LIBMYSQL.dll

// LIBMYSQL.dll is somewhere in your MYSQL INSTALLATION directory..
// so find it, and copy LIBYMSQL.dll to C:\Windows\System32 and/or C:\Windows\System
// OR copy it to the \Debug directory for this project (where the final .exe resides)



// Final note:  static lib compiling.
//#pragma comment( lib, "mysqlclient.lib" )   // doesn't work.. produces 76 errors of the form
// Error	1	error LNK2005: __aligned_malloc already defined in MSVCRTD.lib(MSVCR90D.dll)	       (from file LIBCMTD.lib)
// 
// root of problem seems to be in the warning:
//  Warning 44 warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library

// Problem docs:
//     http://curl.haxx.se/mail/lib-2006-04/0101.html
//     http://www.codeguru.com/forum/archive/index.php/t-375084.html

// MikeAThon, at the bottom of the second post there, says
// LIBCMT is the static C-runtime library (and is multi-threaded),
// whereas MSVCRTD is the dynamic linking C-runtime. See
// "How to link with the correct C Run-Time (CRT) library" at
// http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q140584& .
// According to that KB article, "the linker will issue a warning
// (LNK4098) if a resulting module attempts to combine more than
// one copy of the CRT library"

// So go into linker -> input -> ignore all default libraries (/NODEFAULTLIB)
// See Internet Superhero again for more help http://blog.ulf-wendel.de/?p=215


Download Visual Studio 2008 project files on esnips (thanks esnips!)

I really couldn’t get it.

But now I do.

The problem traces back to this example, which I won’t say anything bad about, except:

MYSQL *connection, mysql;

Now I’m pretty good with C++. I really am. But I ( forgot ? whoops : did not know) that this declaration creates:

  1. A variable, static type MYSQL *, identifier ‘connection’
  2. Another variable, static type MYSQL, identifier ‘mysql’

Did you NOT just do a double take?

Let me further elaborate.

The following lines of code ARE NOT EQUIVALENT to the bolded line above

MYSQL *connection ;
MYSQL * mysql ;

Which is effectively what I did, and which is why I got the well deserved

Unhandled exception at 0x1000edb7 in MYSQL_CLIENT_2005.exe: 0xC0000005: Access violation writing location 0x000003b0.

So the declaration:

MYSQL *connection, mysql;

When broken into 2 lines is:

MYSQL *connection ;
MYSQL mysql ;

Really, I don’t like how that is. Basically the “pointer” part of the declaration sticks to the identifier, NOT to the type specifier at the front.

I thought I could make 10 int pointers like:

int * a,b,c,d,e,f,g,h,i,j ;

But it turns out you’ve have to do:

int *a, *b, *c, *d, *e, *f, *g, *h, *i, *j ;

We all learn..

Here’s a perfect example of token pasting in C++.

On about line 427 of WinNT.h, we see:

#define __TEXT(quote) L##quote

Now what this does is basically take any string you pass __TEXT( “some string” ) and prepend an L.

So in short it turns

__TEXT( "some string" )

into

L"some string"

So, its the magic of ## that makes it work. Basically when you write

#define __TEXT(quote) L##quote

You’re saying, ok, treat quote like a variable. In the last part of the #define we see ##quote, basically that is HOW YOU BACKREFERENCE the quote “variable” of the macro that was used earlier, in a “token pasting” way – basically you know that if you tried to write:

#define __TEXT(quote) Lquote

Then it would try and look for some symbol called Lquote, which basically doesn’t exist. What you want is to PREPEND AN L in front of (whatever quote is).

So,

#define __TEXT(quote) L##quote

The double pound ## there just says to “concatenate” or smush together the literal L (since L backreferences no symbol, it will resolve to the literal character ‘L’ at compile time), smush on there quote, which will backreference resolve into “some strong”

Here’s another one

// this:
#define foreach( x, y, z ) for( vector<##x##>::iterator y = z.begin(); y != z.end(); ++y )

// turns:
foreach( string, iter, infoVector )
// ( foreach string iter in infoVector )

// into:
for(vector<string>::iterator iter = infoVector.begin(); iter != infoVector.end(); ++iter)

i’m looking at the ideas in the draft standard for C++0x.

I don’t like some of the things they’re doing.

For example, this constexpr thing.

constexpr int GetFive() {return 5;}
 
int some_value[GetFive() + 5]; //create an array of 10 integers. legal C++0x

Does this not look like a bad idea to anyone?

To be completely honest, I’ve always hated the idea of writing getters and setters that do nothing else other than straight get and set.

For example:

class Number
{
private:
int val ;
public:
void setVal( int to ) {
this->val = to ;
}
int getVal() {
return this->val ;
}

};

I mean, come on. this is a trivial class, but the getter and setter are entirely superfluous in my opinion because they don’t __DO__ anything.

A getter and setter like this, on the other hand:

class Number
{
private:
int val ;
public:
void setVal( int to ) {
if( to >= 0 )
this->val = to ;
else
this->val = 0 ;
}
int getVal() {
return this->val ;
}
};

That makes SOME sense. In this second scenario, we’re protecting val from being assigned a negative value, which is forbidden for whatever reason.

THAT use of a getter and setter I approve of. But the transparent, simple, silly getter and setter functions like the red example above (that can be autogenerated by the IDE when you work in Java Netbeans or eclipse)

  1. DO NOTHING
  2. TAKE UP SPACE
  3. look worse in code, if not for anything but the extra 3 characters you have to write getW” and setW” instead of just a simple assignment w =
  4. Can be slower (function call overhead) if no effort is taken to inline

So that same idea applies to the constexpr thing. You don’t NEED IT.

Just write the constant 5. Or #define it.

I just don’t see the point of it.

constexpr adds additional complexity to the C++ programming language while not really providing new functionality at all. Its just repeating the same general pattern of transparent getters and setters that people seem to like to use.

its easy!

in your WndProc, add a trapping for

#define WM_QUERYENDSESSION  0x11
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch( message )
  {
    case WM_QUERYENDSESSION:
      return 0; // cancel the shutdown
  }
}

That’s really it!

Q: how do i manually shut off my monitor in windows xp?

A: Reach for the switch. you know, the physical power switch?

Ah. But you want to do it PROGRAMMATICALLY. Well

// console application
#include <windows.h>

#define SCREENSAVER_START 1
#define MONITOR_OFF 2

int main( int argc, char** argv )
{
  int cmd = SCREENSAVER_START; // default when run
  // is to start screensaver.

  // if passed command line argument (no matter
  // what it is), just turn off the monitor instead.
  if( argc > 1 )
  {
    // could check argv,
    cmd = MONITOR_OFF;
  }

  switch( cmd )
  {
  case SCREENSAVER_START:
      SendMessage( HWND_TOPMOST,
                 WM_SYSCOMMAND,
                 SC_SCREENSAVE,
                 0 );  // send message to top most window
  // for screensaver to start.  that's just
  // how you programmatically start the screensaver
  // under windows!
                 break;

    case MONITOR_OFF:
        SendMessage( HWND_BROADCAST,
                 WM_SYSCOMMAND,
                 SC_MONITORPOWER,
                 (LPARAM)2 ); // turn off the monitor.
                 break;
  }
}


I keep this executable in my start menu. I create 2 shortcuts:

One called “monitor off” that has target

C:\Documents and Settings\All Users\Start Menu\Programs\Monitor Control\MonitorControl.exe” off

The other is called “screensaver start” and has target:

C:\Documents and Settings\All Users\Start Menu\Programs\Monitor Control\MonitorControl.exe”

because running the executable with no arguments starts the screensaver.

the sample code from the OpenGL RedBook

A collection of a couple of more GLUT examples

Nate Robins OpenGL tutors programs

(very good for gaining an intuitive understanding!)

SURPRISINGLY GOOD MSDN OpenGL reference

If you like this site & want to see more posts, buy me a coffee! Even a $1 donation would make me really happy. Thanks for reading
(bill.sherif@gmail.com)

//////////////////////////////////////////
//                                      //
// Using zlib                           //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 22/08            //
// Last modified:  Feb 23/08            //
//                                      //
//////////////////////////////////////////

//////////////////////////////////////////
//////////////////////////////////////////
///////////  BEFORE YOU START  ///////////
//////////////////////////////////////////
//////////////////////////////////////////

// Visit zlib.net, bookmark it,
// and grab the dll version of zlib.

// Once you get zlib, as the docs say:
// "Copy ZLIB1.DLL to the SYSTEM or the
//  SYSTEM32 directory."

// C:\WINDOWS\System32 may not work for you
// if you're on 64-bit.  Instead, use
// the C:\WINDOWS\System directory.

// If you don't do this, you get this error
// when you try to launch any program
// that uses "zlib1.dll":

/*
     "THIS APPLICATION has failed to start
      because zlib1.dll was not found.
      Re-installing the application
      may fix this problem."
*/

// This is because Windows can't find
// the dll.

// The other option is to place the
// .dll file in the same directory
// as the EXECUTABLE that uses the
// dll.  So, you'd copy out zlib1.dll
// into the Using_zlib\debug folder,
// since that's where visual studio
// dumps the final executable after building.

/////////////////////
// QUICK NOTES ABOUT .LIB AND .DLL FILES:
//
// .LIB FILES:
//
// .lib files are library files and they
// are used for static linking.  That is,
// they contain precompiled code that other
// applications can link to.  When you link
// your application with a .lib library, then
// the .lib library's code is intermixed
// with your own code in the final executable.

// .DLL FILES:
//
// .dll files are dynamically linked library files 
// and applications link to them at runtime.

/////////////
// WHAT'S A DLL?

// What's a DLL anyway?

// DLL stands for DYNAMICALLY
// LINKED LIBARY.

// Why "LIBRARY"?  Well, clearly because
// the .DLL is just a LIBRARY of
// FUNCTIONS that you can CALL.

// ZLIB is really just a bunch of
// subroutines that you use to zip
// and unzip data.

// "DYNAMICALLY LINKED":  Because
// the actual code of ZLIB (that performs
// the zipping and unzipping operations),
// is going to REMAIN STORED inside of
// zlib.dll.

// Even though your program that you write
// will make calls to zlib's functions,
// THERE WILL BE NO _ACTUAL_ ZLIB CODE
// IN __YOUR__ FINAL EXECUTABLE.

// In other words, the actual ZIP /UNZIP
// code routines WILL NOT be packed into
// YOUR final executable that you build
// with your code when you use zlib.dll.

// Instead, your code will contain REFERENCES TO
// the actual executable code pieces inside
// of zlib.dll, and WINDOWS will resolve
// ("LINK") your application's calls with
// the .dll file's subroutines DYNAMICALLY
// (AT RUN TIME).

// Hence the term "dynamically linked library".
// Because the LINKING of the code happens
// DYNAMICALLY ("dynamically" just means
// "at run time", just like "dynamically allocated
// memory" is memory that you allocate at
// run time using malloc()).

// So at the end of the day, a .dll file 
// just contains a bunch of CODE.

// The difference comes in in HOW the
// Windows operating system manages
// that code.

///////////////////////////
// WHAT'S THIS FILE?
//
// This project shows you how to use zlib.
// Its a console project, because there's
// no need to create a window to demonstrate
// use of zlib.

// "words.txt" was generated from the 5 letter
// words listed @ http://www.math.toronto.edu/~jjchew/scrabble/lists/common-5.html

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

#include <windows.h>

// the zlib.h header file contains
// function prototypes and a lot
// of information about zlib!
#include "zlibdll/include/zlib.h"

// link the static lib
#pragma comment (lib, "zlibdll/lib/zdll.lib" )


int main()
{
    srand(time(0));      // seed random number generator

    bool showOutput;     // make false if you don't want text output
    printf( "Show textual output?  [y/n]\n");
    if ( tolower(getchar()) == 'y' )
        showOutput = true;
    else
        showOutput = false;
    

    printf("*********************\n");
    printf("* zlib test file\n");
    printf("* Using version %s of zlib\n", zlibVersion() ) ;

    #pragma region _make some data to compress_
    const int NUM_WORDS = 8938;     // pre-counted constant

    char * randomWords[ NUM_WORDS ] = {
#include "words.txt"  // get in project files
    };


    const int NUM_WORDS_TO_USE = 80;

    // Fill dataOriginal with a random jumbling of
    // 80 * (5 letter words + 1 space)
    // (each word followed by a space).
    int sizeDataOriginal = 6 * NUM_WORDS_TO_USE + 1 ;
    printf("* Before compression:  your data is %d bytes\n", sizeDataOriginal );
    BYTE * dataOriginal = (BYTE*)malloc( sizeDataOriginal );
    
    for( int i = 0; i < 6 * NUM_WORDS_TO_USE; i += 6 )
    {
        int randomIndex = rand() % NUM_WORDS ;
        static char buf[6];
        strncpy( buf, randomWords[ randomIndex ], 5 );  // don't copy the NULL character.
        buf[5] = ' ';
        strncpy( (char*)(dataOriginal+i), buf, 6 );
    }

    dataOriginal[ sizeDataOriginal - 1 ] = NULL; // null terminator.
    // test it.
    printf("* \n* Here's the data we generated for you:\n\n--\n");
    if( showOutput )
    {
        for( int i = 0 ; i < sizeDataOriginal ; i++ )
        {
            putchar( dataOriginal[i] ); // coulda puts'd this
            // but wanted to be consistent.
        }
        printf("\n--\n\n");
    }
    else
        printf(" (suppressed)\n--\n\n");
    #pragma endregion

    #pragma region compress the data
    //////////////
    // compress it.
    // To compress some data, we'll use the compress()
    // function.

    // To use the compress function, we must
    // create a destination buffer to
    // hold the compressed data.

    // So how big should the compressed
    // data buffer be?
    
    // This may seem a bit weird at first,
    // but the array that is to hold the compressed
    // data must start out being AT LEAST 0.1% larger than
    // the original size of the data, + 12 extra bytes.
    
    // So, we'll just play it safe and alloated 1.1x
    // as much memory + 12 bytes (110% original + 12 bytes)

    ULONG sizeDataCompressed  = (sizeDataOriginal * 1.1) + 12;

    BYTE * dataCompressed = (BYTE*)malloc( sizeDataCompressed );

    // Now hold on, you ask.  WHY is the array
    // that's supposed to hold the COMPRESSED 
    // data ALREADY BIGGER than the original
    // data array?  This isn't compression!
    // This is meaningless expansion!
    
    // Well, you'll see that this extra space
    // in the compressed array is only TEMPORARY.
    // Just suffice it to say that zlib
    // "needs room to breathe".

    // When zlib performs compression, it will
    // need a bit of extra room to do its work.

    // When the compress() routine returns,
    // the compressedData array will have
    // been AUTOMATICALLY RESIZED by ZLIB
    // to being a smaller, compressed size.

    // We will also know the EXACT size of
    // that compressed data by looking at
    // the 'sizeDataCompressed' variable
    // AFTER the compress() routine runs.
    // That variable 'sizeDataCompressed'
    // will updated by the compress() 
    // function when we call it!
    
    // Don't worry, the "compressed" data
    // will be smaller than the original
    // data was in the end!
    int z_result = compress(
        
        dataCompressed,         // destination buffer,
                                // must be at least
                                // (1.01X + 12) bytes as large
                                // as source.. we made it 1.1X + 12bytes

        &sizeDataCompressed,    // pointer to var containing
                                // the current size of the
                                // destination buffer.
                                // WHEN this function completes,
                                // this var will be updated to
                                // contain the NEW size of the
                                // compressed data in bytes.

        dataOriginal,           // source data for compression
        
        sizeDataOriginal ) ;    // size of source data in bytes

    switch( z_result )
    {
    case Z_OK:
        printf("***** SUCCESS! *****\n");
        break;

    case Z_MEM_ERROR:
        printf("out of memory\n");
        exit(1);    // quit.
        break;

    case Z_BUF_ERROR:
        printf("output buffer wasn't large enough!\n");
        exit(1);    // quit.
        break;
    }
     
    printf("*******************************\n");
    printf("* DATA COMPRESSION COMPLETE!! :\n");
    printf("*\n");
    printf("* Compressed size is %d bytes\n", sizeDataCompressed );
    printf("* This is what it looks like:\n\n--\n");

    // Now we want to print the compressed data out.
    // Can't just printf() it because 
    // the nulls will be all over the place, and there
    // isn't necessarily a null at the end.
    if( showOutput )
    {
        for( int i = 0; i < sizeDataCompressed; i++ )
        {
            putchar( dataCompressed[i] );
        }
        printf("\n--\n\n");
    }
    else
        printf(" (suppressed)\n--\n\n");
    #pragma endregion
    
    #pragma region save compressed data to disk
    //////////////////
    // Save that compressed data to disk.
    // Maybe its save game information or
    // something.
    printf("********************************\n");
    printf("* Saving compressed data to disk\n\n");

    ///////////////////////////////////////////////
    //////////////!!!!!!!!!!!!!!!!!!!!/////////////
    //////////////!!!IMPORTANT NOTE!!!/////////////
    // You see how I'm opening the file in "wb" mode,
    // NOT just "w" mode?????
    FILE * out = fopen( "savedData.dat", "wb" );
    // Well, "wb" means BINARY MODE for writing.
    // THIS IS EXTREMELY IMPORTANT.  IF YOU DON'T
    // USE "wb" TO WRITE YOUR FILES, AND YOU DON'T
    // USE "rb" TO READ YOUR FILES, YOU FILE
    // WILL BE VERY SLIGHTLY CORRUPTED,
    // WINDOWS PROMISES YOU THAT!!

    // One of the reasons for the corruption is
    // under Windows, if you write out a
    // NEWLINE (ASCII code 10, escape sequence "\n",
    // aka the "LINEFEED" (LF)) to the output stream, 
    // then Windows puts out a 13 FIRST, then a 10.

    // 13 is the ascii code for CARRIAGE RETURN (CR),
    // and 10 is ascii code for the Linefeed (LF).

    // Now that seems awfully stupid.  Why would Windows
    // output hex 0D 0A when I clearly asked it to
    // output just 0A?

    // The answer is that Windows uses TWO CHARACTERS
    // to designate the new line:  (CRLF), NOT just LF.

    // Unix uses just LF.  Macs use just CR.  (Windows is
    // the only weirdo that uses 2 characters for a newline.
    // I suppose you could say that this is more true to the
    // original typewriter (or the dot matrix printer),
    // where you have to push the "carriage" (thing that types)
    // back to the left side (carriage return), then
    // you have to feed the paper up a line (linefeed)).

    // SO, this is significant because everytime you write
    // the integer value 10 to the output stream, IF you're
    // NOT writing in binary mode, Windows thinks you're
    // trying to write text.  So NATURALLY, if you write
    // the integer value 10 out in one of the bytes, 
    // Windows recognizes this is a linefeed and
    // write out 13 10 instead.

    // This introduces extra data into your output
    // and is enough to significantly corrupt the result.

    if( out == NULL )
    {
        printf("Couldn't open output file for writing\n");
        exit(1);    //quit
    }
    fwrite( dataCompressed, sizeDataCompressed, 1, out );
    fclose( out );
    out = NULL;
    #pragma endregion

    #pragma region read in data from disk
    ///////////////
    // Next, we'll READ the compressed data
    // from the file, then DECOMPRESS it, to
    // prove that it'll be the same as
    // the original data.
    printf("********************************\n");
    printf("* Reading in data from save file\n");
    
    //////////////!!!!!!!!!!IMPORTANT:  note "rb"
    // NOT just "r".
    FILE * readFile = fopen("savedData.dat", "rb");
    if( readFile == NULL )
    {
        printf("Couldn't open input file for reading\n");
        exit(1);    //quit
    }

    // get size of file
    fseek( readFile, 0, SEEK_END );
    ULONG fileLength = ftell( readFile );
    rewind( readFile );

    // allocate enough mems to hold entire file
    // alternatively, we could "memory map" the
    // file contents using the CreateFileMapping and
    // MapViewOfFile funcs.
    BYTE * dataReadInCompressed = (BYTE*)malloc( fileLength );

    // read in entire file
    fread( dataReadInCompressed, fileLength, 1, readFile );

    // close file
    fclose( readFile );
    readFile = NULL;

    printf("*\n* This is what I read from the saved file:\n"); 
    printf("\n--\n");
    if( showOutput )
    {
        for( int i = 0 ; i < fileLength ; i++ )
        {
            putchar( dataReadInCompressed[i] );
        }
        printf("\n--\n\n");
    }
    else
        printf(" (suppressed)\n--\n\n");
    #pragma endregion

    #pragma region decompress the read-in data
    ///////////////
    // Next, we'll decompress that
    // data we just read in from disk.

    // How large should we make the array
    // into which the UNZIPPED/UNCOMPRESSED
    // data will go?

    // WELL, there's the catch with ZLIB.
    // You never know how big compressed data
    // will blow out to be.  It can blow up
    // to being anywhere from 2 times as big,
    // or it can be (exactly the same size),
    // or it can be up to 10 times as big
    // or even bigger!
    
    // So, you can tell its a really bad idea
    // to try to GUESS the proper size that the
    // uncompressed data will end up being.

    // You're SUPPOSED TO HAVE SAVED THE INFORMATION
    // about the original size of the data at
    // the time you compress it.
    
    // There's a note on how to do that easily
    // at the bottom of this file, in the end notes.

    // FOR NOW, we're just going to 
    // use the dataSizeOriginal variable.
    printf("*******************************\n");
    printf("* Decompressing your data . . .\n");
    ULONG sizeDataUncompressed = sizeDataOriginal;
    BYTE * dataUncompressed = (BYTE*)malloc( sizeDataUncompressed );
    
    //////////////
    // now uncompress
    z_result = uncompress(
        
        dataUncompressed,       // destination for the uncompressed
                                // data.  This should be the size of
                                // the original data, which you should
                                // already know.

        &sizeDataUncompressed,  // length of destination (uncompressed)
                                // buffer

        dataReadInCompressed,   // source buffer - the compressed data

        sizeDataCompressed );   // length of compressed data in bytes

    switch( z_result )
    {
    case Z_OK:
        printf("***** SUCCESS! *****\n");
        break;

    case Z_MEM_ERROR:
        printf("out of memory\n");
        exit(1);    // quit.
        break;

    case Z_BUF_ERROR:
        printf("output buffer wasn't large enough!\n");
        exit(1);    // quit.
        break;
    }


    printf("************************\n");
    printf("* Uncompressed size is %d bytes\n", sizeDataUncompressed );
    printf("* Your UNCOMPRESSED data looks like this:\n");

    printf("\n--\n");
    if( showOutput )
    {
        for( int i = 0 ; i < sizeDataUncompressed ; i++ )
        {
            putchar( dataUncompressed[i] );
        }
        printf("\n--\n\n");
    }
    else
        printf(" (suppressed)\n--\n\n");
    #pragma endregion

    #pragma region compare decompressed data with original data
    if( memcmp( dataOriginal, dataUncompressed, sizeDataOriginal ) == 0 )
    {
        printf("* SEE?  It was EXACTLY the same.\n");
    }
    else
    {
        printf( "\n\n=====================================\n"
                "Oh. . . dear.  There is a problem.  The uncompressed data "
                "isn't exactly the same as the original data.  Your data "
                "may be corrupted.  WHOOPS!!\n"
                "Please make sure if that you are reading and writing "
                "any file i/o in BINARY MODE." );
    }
    #pragma endregion

    free( dataOriginal );
    free( dataCompressed );
    free( dataReadInCompressed );
    free( dataUncompressed );
    
}

/////////
// END NOTES:

// So in this tutorial, when I saved the
// data out to a file, I just used fwrite()
// and dumped the array of bytes with no
// information ABOUT what the file is
// whatsoever.

// in real life, that's probably not a good idea.
// You want to always output at the beginning
// of your compressed data AT LEAST the size
// the data will be when it becomes uncompressed.
// This is the only way you can know how big
// to make the "receiving array" for the uncompressed data.

// ZLIB has no "tell_me_the_size_of_this_thing_
// when_it_gets_uncompressed() function.

// You MUST keep that data in the file itself.

// So, you might create a structure like thus
// and like so:

/*

struct saveFile
{
    ULONG compressedSize;   // size of the data array, compressed
    ULONG uncompressedSize; // size when data gets uncompressed
    char what[16];          // what is this file?  may want to
                            // indicate what kind of data is saved here.

    // add whatever other info you need
    // here.

    BYTE * data;            // the actual compressed data

};

*/

// Then, just fwrite out the data,
// with a couple of fwrites().

// When you fread it, you fread the
// size fields first . . . you know
// what to do.

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

*/

Download the Visual Studio 2005 project files.

If you like this site & want to see more posts, buy me a coffee! Even a $1 donation would make me really happy. Thanks for reading
(bill.sherif@gmail.com)

I was attempting to use buffered input for the mouse and I was getting erratic behavior at first.

What was the problem?

Here we have some code. g.xPos and g.yPos are floats.

switch( inputData.dwOfs )
{
    case DIMOFS_X:
        g.xPos += inputData.dwData ;
        break;

    case DIMOFS_Y:
        g.yPos += inputData.dwData ;
        break;
}

At first glance, this appears to work fine. At least, it works fine until you try to move the mouse up or left.

Then all hell breaks loose. The mouse jumps nonsensically offscreen to the right when you pull it left, and it jumps to the extreme bottom when you move it even one pixel up.

Closer inspection reveals that insanely huge values are being added to g.xPos and g.yPos whenever you move the mouse left or up.

So you know what the problem is now, huh.

What’s the problem already?

dwData is unsigned.


int * d = (int*)&inputData.dwOfs ;

switch( inputData.dwOfs )
{
    case DIMOFS_X:
        g.xPos += *d;
        break;

    case DIMOFS_Y:
        g.yPos += *d;
        break;
}

I think microsoft made a bad typing decision here. Why is dwData unsigned when its going to carry signed data . . ?

Sheesh.

///////////////////// // This function is just for quickly // bailing out of your DirectX app when // there's an error. // There's also a few macros like DXTRACE_ERR_MSGBOX // defined in <dxerr.h> but I don't like them #include <dxerr.h> #pragma comment ( lib, "dxerr.lib" ); void exitAppWithErr( HRESULT hr, TCHAR * err ) { TCHAR fullErr[ 1024 ]; wsprintf( fullErr, TEXT("%s.\nDirectX says: \"%s: %s\"." ), err, DXGetErrorString( hr ), DXGetErrorDescription( hr ) ) ; FatalAppExit( 0, fullErr ); }
// EXAMPLE call: exitAppWithErr( hr, TEXT("Problem creating secondary sound buffer") ) ;

The trackbar is notorious for giving people trouble when trying to get started with it.

It doesn’t help that the docs or the really poor example page don’t say ANYTHING about what I’m about these small but annoying issues.

MY TRACKBAR WON’T SHOW UP!!

Try looking up the error code. If its a 1407, that’s “Cannot find window class.” That happens because you didn’t call:

InitCommonControls();

error C2065: ‘TRACKBAR_CLASS’ : undeclared identifier!

You have to

#include <commctrl.h>

error LNK2019: unresolved external symbol __imp__InitCommonControls@0 referenced in function _WinMain@16

You have to

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

Here’s a real quick example of how to get the trackbar working in a basic win32 app (no mfc or .net stuff), fast.

//////////////////////////////////////////
//                                      //
// Trackbars                            //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 13/08            //
// Last modified:  Feb 13/08            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <commctrl.h>       // must have

#pragma comment( lib, "comctl32.lib" )  // must have

////////////////////////
// TRACKBARS!

// We want to add trackbars to our
// windows application.

#define IDCHC_TRACKBAR 4

/////////////////////
// GLOBALS
HWND g_hwnd;
HWND g_trackbarhwnd;
//
/////////////////////

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


////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    #pragma region part 1 - create a window
    // A.  Create the WNDCLASS
    WNDCLASS wc;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hbrBackground = GetSysColorBrush( COLOR_APPWORKSPACE );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = TEXT("Philip");
    wc.lpszMenuName = 0; 
    wc.style = CS_HREDRAW | CS_VREDRAW;

    // B.  Register the WNDCLASS with Windows, THEN
    //     create the window.
    RegisterClass( &wc );
    g_hwnd = CreateWindow(
        TEXT("Philip"),
        TEXT("windows app"),
        WS_OVERLAPPEDWINDOW,
        10, 10,
        400, 400,
        NULL, NULL,
        hInstance, NULL );      

    ShowWindow(g_hwnd, iCmdShow );
	UpdateWindow(g_hwnd);
    #pragma endregion

    #pragma region add the trackbar
    InitCommonControls();
    g_trackbarhwnd = CreateWindow(
        TRACKBAR_CLASS, // USE PREDEFINED CLASS
                        // MUST #include  TO USE

        TEXT("da trackbar son"),    // doesn't matter what
                                    // you call it -

        WS_CHILD | WS_VISIBLE |
        // next are the Trackbar styles
        TBS_AUTOTICKS |        // trackbar has tick marks
        TBS_HORZ,              // horizontal orientation
        100, 100,
        200, 30,
        g_hwnd,//parent
        (HMENU)IDCHC_TRACKBAR,  // identifier
        hInstance,  //(HINSTANCE)GetWindowLong( g_hwnd, GWL_HINSTANCE ),
        NULL );

    if( g_trackbarhwnd == NULL )
    {
        TCHAR errbuf[300];
        wsprintf( errbuf, TEXT("error code #%d"), GetLastError() );
        FatalAppExit( 0, errbuf );
    }
    
    /////////////////
    // NOW, as SOON AS the track bar is created,
    // we pelt it with some messages to give it
    // additional information about how we want
    // it to be.  If your computer was INCREDIBLY (20MHz?)
    // slow, you'd see these changes taking place,
    // because the trackbar has already been created
    // and made visible on the main window itself
    // in the line above.
    SendMessage(g_trackbarhwnd,     // hwnd - handle to trackbar
                TBM_SETRANGE,       // message - a message to set the range
                true,               // wparam - redraw it?  yes.
                MAKELONG(0/*MIN RANGE*/, 10/*MAX RANGE*/));  // lparam
    
    // The only tricky part is lparam.
    
    // We have to use a tricky macro called MAKELONG.

    ///////////
    // SUPERFICIALLY:
    // You know how when you're processing a
    // WM_LBUTTONDOWN mouse message, the x AND
    // y position of the mouse are BOTH packed
    // into the single variable lparam?
/*
case WM_LBUTTONDOWN:
    int x = LOWORD( lparam );
    int y = HIWORD( lparam );
    break;
*/
    // WELL, MAKELONG( a, b ) works to PACK
    // a and b into a SINGLE variable of type
    // long.

    // It uses bitshifting to do so.
    // Look at its #define if interested.

    // You can send plenty of other messages
    // to your trackbar to customize its look and
    // behavior!

    SendMessage(g_trackbarhwnd, TBM_SETPAGESIZE, true, 1); 
    SendMessage(g_trackbarhwnd, TBM_SETTICFREQ, true, 0); 
    SendMessage(g_trackbarhwnd, TBM_SETPOS, true, 0); 
    SendMessage(g_trackbarhwnd, TBM_SETSEL, true, MAKELONG( 1, 5 ) );
                

    #pragma endregion

    #pragma region part 2 - enter message loop
    MSG msg;

    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    #pragma endregion

    return msg.wParam;
}

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 );
                // Nothing to draw.
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

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

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}




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

*/

Visual Studio 2005 project files for Trackbar on Win32 hosted by esnips (thanks esnips!)

There’s a good msdn article on window translucency using layered windows here.

//////////////////////////////////////////
//                                      //
// COOL TRANSLUCENT WINDOWS!            //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 13/08            //
// Last modified:  Feb 13/08            //
//                                      //
//////////////////////////////////////////


#define _WIN32_WINNT    0x0500  // ya hafta have this
// to use WS_EX_LAYERED . . it tells the compiler
// you're compiling for a platform Windows 2000
// or better 

//////////////////////////
// Using CreateWindowEx() -- why???
//
// Now you may have noticed that there's
// TWO functions that you can use
// to create a window:
//     CreateWindow();
// and
//     CreateWindowEx();

// Why use CreateWindowEx()?  Well, 
// one reason is you can make
// COOL TRANSLUCENT WINDOWS!!

// There's a ton of other features that
// you can use for Windows that have
// "EXTENDED WINDOW STYLES" -- see 
// the CreateWindowEx() docs on msdn

#include <windows.h>



/////////////////////
// GLOBALS
HWND g_hwnd;        // just a global for hwnd
//
/////////////////////

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


////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    #pragma region part 1 - use a WNDCLASSEX structure to create a window!!
    // A.  Create the WNDCLASSEX structure.
    //
    // The EX is for "EXTENDED".
    //
    // The WNDCLASSEX structure is very similar to
    // the plain old WNDCLASS structure, EXCEPT
    // that it has quite a few "EXTENDED STYLES!"
    //
    // Let's create a structure and explore.
    WNDCLASSEX wcx;

    wcx.cbClsExtra = 0; 
    wcx.cbSize = sizeof( WNDCLASSEX );  // 1.  NEW!  must know its own size.
    wcx.cbWndExtra = 0; 
    wcx.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcx.hCursor = LoadCursor( NULL, IDC_ARROW );         
    wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );     
    wcx.hIconSm = NULL;                 // 2.  NEW!!  Can specify small icon.
    wcx.hInstance = hInstance;         
    wcx.lpfnWndProc = WndProc;         
    wcx.lpszClassName = TEXT("Philip");
    wcx.lpszMenuName = 0; 
    wcx.style = CS_HREDRAW | CS_VREDRAW;

    //////////////////////////////
    // AWW.  Disappointed?  There were only
    // TWO new fields in the WNDCLASSEX structure,
    // and they weren't very exciting
        // (cbSize and hIconSm.)

    //////////////
    // BUT WAIT!!  The cool stuff is yet to come.

    // First, we get to use the RegisterClassEx() function
    // (no more plain old RegisterClass()!!!)
    // to register our WNDCLASSEX struct!! WEEHEE!
    // Actually that is not that cool.

    // B.  Register the WNDCLASSEX with Windows, THEN
    //     create the window.
    RegisterClassEx( &wcx );    // use RegisterClassEx() func!

    //////////////////
    // OK NOW IS THE COOL PART!!  We get
    // to use CreateWindowEx() to actually
    // create our window.  CreateWindowEx()
    // has ONE new params is COOL:
    g_hwnd = CreateWindowEx(
        WS_EX_LAYERED,  // NEW PARAMETER!!
            // EXTENDED STYLES! This "layered
            // style will allow us to make our window
            // TRANSLUCENT (partly see thru!)
        // "Note that WS_EX_LAYERED cannot be used for child windows."

        TEXT("Philip"), // rest are same old.
        TEXT("OOOOOOOOOOOOOOOOH!!! GHOSTLY WINDOW!!"),
        WS_OVERLAPPEDWINDOW,
        10, 10,
        400, 400,
        NULL, NULL,
        hInstance, NULL );

    /////////////
    // SetLayeredWindowAttribute:
    // MUST CALL THIS if using WS_EX_LAYERED.
    // http://msdn2.microsoft.com/en-us/library/ms633540(VS.85).aspx
    SetLayeredWindowAttributes( g_hwnd,     // handle to window to modify
                                0,          // color key (not used when using LWA_ALPHA)
                                85,         // "amount of solidness" = 0=transparent, 255=completely solid
                                LWA_ALPHA );// use my alpha value (prev arg)
                                            // to tell how see 'solid' window is.

    // Try this too, for a weird effect:
    /*
    SetWindowText( g_hwnd, TEXT("All white parts are see thru AND click thru!") );
    SetLayeredWindowAttributes( g_hwnd,         // handle to window to modify
                                RGB(255,255,255),  // colorkey
                                255,            // 0=transparent, 255=completely solid
                                LWA_COLORKEY);  // use COLORKEY specified
                                                // in 2nd arg to be
                                                // TRANSPARENT (leaves holes
                                                // in window
    */

    ShowWindow(g_hwnd, iCmdShow );
    UpdateWindow(g_hwnd);
    #pragma endregion

    #pragma region part 2 - enter message loop
    MSG msg;

    while( GetMessage(&msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    #pragma endregion

    return msg.wParam;
}

LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    case WM_CREATE:
        Beep( 50, 10 );
        return 0;
        break;

    case WM_CHAR:
        switch( wparam )
        {
        case 'G':   // make ghostly
        case 'g':
            // maintain old style, turn on WS_EX_LAYERED bits on.
            SetWindowLongPtr(   hwnd, 
                GWL_EXSTYLE, 
                GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

            SetLayeredWindowAttributes( hwnd,
                0,
                85,  /* "amount of solidness" 0=transparent, 255=solid*/
                LWA_ALPHA);
            // Everytime you make a window ghostly,
            // you MUST call SetLayeredWindowAttributes(),
            // otherwise it won't work properly.
            break;

        case 'S':   // make solid
        case 's':
            // Remove WS_EX_LAYERED from this window's style
            SetWindowLongPtr(   hwnd, 
                GWL_EXSTYLE,    // set the EX_STYLE of this window
                GetWindowLong(hwnd, GWL_EXSTYLE) &  // GET old style first
                ~WS_EX_LAYERED);  // turn WS_EX_LAYERED bits off

            // Note:  Use SetWindowLongPtr (NOT SetWindowLong()!)
            // to write code that'll work
            // on both 32-bit and 64-bit windows!
            // http://msdn2.microsoft.com/en-us/library/ms644898(VS.85).aspx
        }
        return 0;
        break;


    case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint( hwnd, &ps );
            
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

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

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}

// Toggle the "ghostliness" sample code from:
// http://msdn2.microsoft.com/en-us/library/ms632598(VS.85).aspx


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

*/

Source code available on esnips in Visual Studio 2005 project files package

OpenGL Windows

How do you get OpenGL to run in a Windows app WITHOUT using GLUT?

Here’s an example, commented in detail, showing how. Emphasis on “easy to understand.”

//////////////////////////////////////////
//                                      //
// OpenGL in a PROPER Windows APP       //
// ( NO GLUT !! )                       //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 9/08             //
// Last modified:  Feb 10/08            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")


////////////////////////
// OK, here's the deal.
//
// OpenGL is typically so hard to
// get started on Windows (what, with the
// HDC and the HGLRC and the PIXELFORMATDESCRIPTOR)
// most get turned off very quickly
// and stick with GLUT for a very long time,
// because GLUT hides away A LOT of the
// complexities of getting a window up
// and drawing into it.

// If you're still reading, you're
// probably tired of doing things the
// GLUT way, and you want to cross over
// to doing things in OpenGL using a pure
// Windows application.

// Good choice my friend!  If you want
// full control over your app, you'll 
// want to do things in pure Win32.

// Once you get used to programming in Win32,
// its not ALL THAT BAD, I promise (evil grin).

// This demo shows you how to get a basic
// window up that OpenGL can draw into,
// and explains each step in detail.

// I give some additional references at the
// bottom of the page.

//////////////////////////
// OVERVIEW:
//
// The OUTPUT of OpenGL is a two dimensional
// PICTURE of a 3D scene.

// That's right.  I said 2D.

// People often say that the process OpenGL
// goes through to render a 3D scene is just like
// a CAMERA TAKING A PHOTOGRAPH OF A REAL WORLD SCENE.
//
// So, you know obviously that a PHOTOGRAPH
// is PURELY 2D after its been developed,
// and it DEPICTS the 3D scene that it
// "took a picture" of accurately.

// That's exactly what OpenGL does.  OpenGL's JOB
// is to take all your instructions, all your
// glColor3f()'s and your glVertex3f()'s, and
// to ultimately end up DRAWING A 2D PICTURE
// from those instructions that can be displayed
// on a computer screen.

// In THIS program, our MAIN GOAL is to
// CONNECT UP the OUTPUT of OpenGL (that 2D
// image OpenGL produces)
// with YOUR APPLICATION'S WINDOW.

// Does this look familiar?

/*
     HDC hdc = GetDC( hwnd );
*/

// You should already know that the way
// you as a Windows programmer draw to
// your application's window is using
// your window's HDC.

// If this doesn't sound familiar,
// then I strongly recommend you go read up
// on Win GDI before continuing!

////////////////////////////////!
//
// So if our way to draw to our application window
// is the HDC, and OpenGL produces some 2D image
// HOW IN THE WORLD DO YOU CONNECT UP the OUTPUT
// of the OpenGL program (that 2D picture)
// WITH the HDC of a WINDOW?
//
// That's the main subject we're tackling here
// in this tutorial.
//
// And its EASY.
//
// WE'RE lucky.  Microsoft created a bunch
// of functions (all beginning with "wgl"),
// that make this job of "connecting up" the output
// of OpenGL with the HDC of our window quite easy!

/////////////////////////
// BIG PICTURE:
//
// Here's the big picture of what
// we're going to be doing here:

/*

|---------|  draws to   |-------|  copied out   |---------|  shows in  |-----------|
|         | ==========> |       | ============> |         | =========> |           |
|---------|             |-------|               |---------|            |-----------|
  OPENGL                  HGLRC                     HDC                 application
 FUNCTION                                                                 window
  CALLS                                                                     

*/

//////////////////////
// In code:  this is the steps
// we'll follow.
//
// 1.  CREATE WINDOW AS USUAL.
//
// 2.  GET DC OF WINDOW.
//     Get the HDC of our window using a line like:
//          hdc = GetDC( hwnd );
//
// 3.  SET PIXEL FORMAT OF HDC.
//     You do 3 things here:
//          Create a PFD ('pixel format descriptor')
//          ChoosePixelFormat()
//          SetPixelFormat()
//
// 4.  CREATE RENDERING CONTEXT (HGLRC).
//          wglCreateContext()
//     Create the surface to which OpenGL
//     shall draw.  It is created such that
//     it shall be completely compatible
//     with the DC of our window, (it will
//     use the same pixel format!)
//
// 5.  CONNECT THE RENDER CONTEXT (HGLRC)
//     WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
//          wglMakeCurrent()
//
// 6.  DRAW USING OPENGL.
//          glVertex3d(); glColor3d(); // ETC!
//     You call OpenGL functions to perform
//     your drawing!  OpenGL will spit out
//     its result picture to the HGLRC, which is
//     connected to the backbuffer of your HDC.
//
// 7.  SWAP BUFFERS.
//          SwapBuffers( hdc );	
//     Assuming you've picked a DOUBLE BUFFERED
//     pixel format all the way back in step 2, 
//     you'll need to SWAP the buffers so that
//     the image you've created using OpenGL on
//     the backbuffer of your hdc is shown
//     in your application window.

// And that's all!

// Ready for the code??? Let's go!

/////////////////////
// GLOBALS
//
/// Define a structure to hold all
/// of the global variables of this app.
struct Globals
{
    HINSTANCE hInstance;    // window app instance

    HWND hwnd;      // handle for the window

    HDC   hdc;      // handle to device context

    HGLRC hglrc;    // handle to OpenGL rendering context
    
    int width, height;      // the desired width and
    // height of the CLIENT AREA
    // (DRAWABLE REGION in Window)
};


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


// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );
void draw();            // drawing function containing OpenGL function calls

////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
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.hInstance = hInstance;

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

    // Register that class with the Windows O/S..
	RegisterClass(&wc);
    
    /////////////////
    // 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, 50,  // left
                    50,  // top
                    850, // right
                    650 ); // bottom
    
    // Save width and height off.
    g.width = rect.right - rect.left;
    g.height = rect.bottom - rect.top;
    
    // Adjust it.
    AdjustWindowRect( &rect, WS_OVERLAPPEDWINDOW, false );

    // 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.hwnd = CreateWindow(TEXT("Philip"),
                          TEXT("GL WINDOW!"),
                          WS_OVERLAPPEDWINDOW,
                          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.hwnd == NULL )
    {
        FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
    }

    // and show.
    ShowWindow( g.hwnd, iCmdShow );
    #pragma endregion

    #pragma region part 2 - Get DC of window we just made
    //2.  GET DC OF WINDOW, and keep it in our global
    //    variable g.  We will NOT release this DC
    //    until our app is about to exit.
    g.hdc = GetDC( g.hwnd );

    // If this keeping-DC-for-life-of-program-thing
    // disturbs you as much as it disturbed me,
    // GOOD LUCK in finding MS-based documentation to validate
    // this practice!  All examples I've seen and
    // Astle's OpenGL gaming book do it this way,
    // so. . . I suppose its ok.

    // One of the things I make sure to do is to specify
    // CS_OWNDC when I create the window,
    // so that Windows maintains a separate device context
    // for my application's window.

    // I haven't run into problems with this.  I don't
    // think you should either.
    #pragma endregion

    #pragma region part 3 - SET PIXEL FORMAT OF HDC
    //3.  SET PIXEL FORMAT OF HDC.
    //
    // We now have to set up the PIXELFORMAT
    // of our HDC.

    // A PIXEL FORMAT just describes the
    // "qualities" that each pixel in the 
    // window will have.  Do you want your
    // OpenGL app to use 24 bit color
    // ("true color" -- really high
    // quality!)?  Or 16 bit color (can look
    // a bit washed out)?

    // There are 3 substeps here:
    //    A> create the PFD and set it up to describe
    //       the pixel format we DESIRE (dream of having!)
    //
    //    B> call ChoosePixelFormat() to make windows
    //       choose us the ID of the appropriate pixel format that
    //       is CLOSEST to our dream pixel format.
    //
    //    C> Call SetPixelFormat() using the integer ID number
    //       that ChoosePixelFormat() returned to us in step B>

    // So let's do that:

    ////////////////////
    // A> CREATE PFD:
    PIXELFORMATDESCRIPTOR pfd = { 0 };  // create the pfd,
    // and start it out with ALL ZEROs in ALL
    // of its fields.

    // A good description of the PIXELFORMATDESCRIPTOR
    // struct is under the documentation
    // for the ChoosePixelFormat() function:
    // http://msdn2.microsoft.com/en-us/library/ms537556(VS.85).aspx

    // If you look at the docs, MANY of the fields
    // are "NOT USED" and REMAIN 0.
    
    // That should be something of a relief to you!
    // Look at the number of fields in this beast!

    // So we set only the fields of the pfd we care about:
    pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );    // just its size
    pfd.nVersion = 1;   // always 1

    pfd.dwFlags = PFD_SUPPORT_OPENGL |  // OpenGL support - not DirectDraw
                  PFD_DOUBLEBUFFER   |  // double buffering support
                  PFD_DRAW_TO_WINDOW;   // draw to the app window, not to a bitmap image

    pfd.iPixelType = PFD_TYPE_RGBA ;    // red, green, blue, alpha for each pixel
    pfd.cColorBits = 24;                // 24 bit == 8 bits for red, 8 for green, 8 for blue.
                                        // This count of color bits EXCLUDES alpha.

    pfd.cDepthBits = 32;                // 32 bits to measure pixel depth.  That's accurate!

    ///////////////////
    // B> Alright!  We've filled out the pfd
    // and it describes the way we want
    // our pixels to appear on the screen.
    // 
    // Now this next step is a little bit weird.
    // The thing is, there are only a couple of
    // dozen ACCEPTABLE pixel formats in existence.
    //
    // In other words, the system MIGHT NOT
    // be able to use a pixel format the likes
    // of which you have described in your
    // PIXELFORMATDESCRIPTOR.

    // What to do?? It would be awful annoying
    // to have to keep TRYING different
    // PIXELFORMATDESCRIPTORS until we found
    // one that actually WORKED on this system.

    // So MSFT has a better solution.

    // We'll make a call to a function called
    // ChoosePixelFormat().  ChoosePixelFormat()
    // will examine the PIXELFORMATDESCRIPTOR
    // structure that you send it, then it will
    // give you back an ID for the pixel format
    // that MOST CLOSELY MATCHES the pixel format you
    // SAID you wanted.

    int chosenPixelFormat = ChoosePixelFormat( g.hdc, &pfd );
    // what comes back from ChoosePixelFormat() is
    // an integer identifier for a specific pixel
    // format that Windows ALREADY knows about.
    // If you got 0 back, then there was an error.
    if( chosenPixelFormat == 0 )
    {
        FatalAppExit( NULL, TEXT("ChoosePixelFormat() failed!") );
    }

    char b[100];
    sprintf(b, "You got ID# %d as your pixelformat!\n", chosenPixelFormat);
    MessageBoxA( NULL, b, "Your pixelformat", MB_OK );
    
    /////////////////
    // C> So finally, we call SetPixelFormat() using the integer ID number
    // that ChoosePixelFormat() returned to us previously.
    int result = SetPixelFormat( g.hdc, chosenPixelFormat, &pfd );

    if (result == NULL)
    {
        FatalAppExit( NULL, TEXT("SetPixelFormat() failed!") );
    }
    // and that's all there is to setting
    // the pixel format!
    //////////
    #pragma endregion

    #pragma region part 4 - CREATE THE RENDERING CONTEXT
    //4.  CREATE RENDERING CONTEXT (HGLRC).

    // What's a rendering context?
    // Its the "surface" that OpenGL
    // will DRAW to.
    
    // The HGLRC will be created
    // such that it is COMPATIBLE
    // with the hdc.

    g.hglrc = wglCreateContext( g.hdc );
    // Created the rendering context
    // and saved handle to it in global 'g'.
    //
    // Wasn't that awfully easy to create
    // such a complicated sounding thing?
    ///////////////
    #pragma endregion

    #pragma region part 5 - CONNECT THE RENDERING CONTEXT WITH THE DEVICE CONTEXT OF THE WINDOW
    //5.  CONNECT THE RENDER CONTEXT (HGLRC)
    //    WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
    wglMakeCurrent( g.hdc, g.hglrc );

    //
    // OPEN GL INIT COMPLETED!!
    ////////////////////////////
    #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
        {
            //6.  DRAW USING OPENGL.
            // 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
    // UNmake your rendering context (make it 'uncurrent')
    wglMakeCurrent( NULL, NULL );

    // Delete the rendering context, we no longer need it.
    wglDeleteContext( g.hglrc );

    // release your window's DC
    ReleaseDC( g.hwnd, g.hdc );
    #pragma endregion

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

    return msg.wParam;
}

////////////////////////
// DRAWING FUNCTION
void draw() 
{
    // 1. set up the viewport
    glViewport(0, 0, g.width, g.height); // set viewport
    // to be the whole width and height
    // of the CLIENT AREA (drawable region) of the window,
    // (the CLIENT AREA excludes the titlebar and the 
    // maximize/minimize buttons).

    // 2. projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(float)g.width/(float)g.height, 1, 1000);

    // 3. viewing transformation
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(  0, 0, 10,
                0, 0, 0,
                0, 1, 0);

    // 4. modelling transformation and drawing
    glClearColor( 0.5, 0, 0, 0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    static float i = 0.01f;
    // Notice that 'i' is a STATIC variable.
    // That's very important. (imagine me saying
    // that like Conchords in "Business Time")
    // http://youtube.com/watch?v=WGOohBytKTU

    // A 'static' variable is created ONCE
    // when the function in which it sits first runs.
    
    // The static variable will "LIVE ON"
    // between seperate calls to the function
    // in which it lives UNTIL THE PROGRAM ENDS.

    i+= 0.001f;     // increase i by 0.001 from its
    // it had on the LAST FUNCTION CALL to the draw() function

    float c = cos( i );
    float s = sin( i );

    glBegin (GL_TRIANGLES);
        glColor3f(  c, 0, 0 );      // red
        glVertex3f( 1+c, 0+s, 0 );

        glColor3f(  c, s, 0 );      // yellow
        glVertex3f( 0+c, 1+s, 0 );

        glColor3f(  s, 0.1f, s );   // magenta
        glVertex3f(-1+c, 0+s, 0 );
    glEnd();

    //7.  SWAP BUFFERS.
    SwapBuffers(g.hdc);
    // Its important to realize that the backbuffer
    // is intelligently managed by the HDC ON ITS OWN,
    // so all's you gots to do is call SwapBuffers
    // on the HDC of your window.
}





////////////////////////
// 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_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}



////////////////
// END NOTES:
//
// Some good references:
// WGL function ref on MSDN:
// http://msdn2.microsoft.com/en-us/library/ms673957%28VS.85%29.aspx

// MSDN example from 1994 (but still good!)
// "OpenGL I: Quick Start"
// http://msdn2.microsoft.com/en-us/library/ms970745.aspx


//////////////////
// QUICK Q&A (make sure you know what's going on):
//
// QUESTION:  What's the means by which we can draw
//            to our window itself?
//
// ANSWER:  The HDC (HANDLE TO DEVICE CONTEXT).

// QUESTION:  What's the means by which OpenGL can
//            draw to the window?
//
// ANSWER:  USING that SAME HDC WE woulda used
//          to draw to it!! (more to come on this now).

/////////////////////
// It IS possible to access the bits
// of the output of OpenGL in 2 ways:
//      1)  Use glReadPixels() to obtain
//          the arrayful of pixels on the
//          screen.  You can then save this
//          to a .TGA or .BMP file easily.

//      2)  Render to a BITMAP, then
//          blit that bitmap to your HDC.
//          There's a 1995 msdn article on this:
//          "OpenGL VI: Rendering on DIBs with PFD_DRAW_TO_BITMAP"
//          http://msdn2.microsoft.com/en-us/library/ms970768.aspx



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

*/

Download the Visual Studio 2005 project files hosted by esnips! (thanks esnips!)

Preventing or stopping the screensaver from going on from your C++ Windows program

To intercept the screensaver on Win32, you trap the WM_SYSCOMMAND message in your WndProc, then you check the value of wparam. SC_SCREENSAVE is the screensaver and SC_MONITORPOWER is that windowsy force that wants to shut off the monitor to save power.

To disable either, just return 0 from the event handler function under those cases.

Example:

// This is a piece of WNDPROC:
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    .
    .
    .
        case WM_SYSCOMMAND:
        {
            // There is a system command
            // wparam has the exact command type that it is
            switch( wparam )
            {
                case SC_MOVE:
                    printf("You're moving the window!\n");
                    // don't interfere with this one, otherwise your window
                    // won't move normally when the user tries to move it!
                    break;

                case SC_SCREENSAVE:     // screensaver wants to begin
                    
                    return 0;           // returning 0 PREVENTS those things from happening
                    // Note about SC_SCREENSAVE:
                    // Try this.  Go into your settings and change
                    // your screensaver to start after 1 minute.
                    // Then run this program and sit and wait
                    // for the 1 minute.

                    // The funny thing about this, is Windows will
                    // keep trying to enter screen saver mode,
                    // by sending your app a "message" every
                    // half a second or so.

                    // If all you do is return 0; from this
                    // part, your app will keep on stopping
                    // the screensaver from starting.  And
                    // Windows will keep asking if it can
                    // start the screen saver or not, until
                    // the user does something to reset the
                    // screensaver-turn-on timer like move the mouse
                    // or press a key on the keyboard.

                    // if you wait even longer, the same thing
                    // happens with SC_MONITORPOWER, except
                    // you keep getting 2 messages now.
                    
                    case SC_MONITORPOWER:   // monitor wants to shut off - powersaver mode
                        return 0;           // returning 0 PREVENTS monitor from turning off
            } // end wparam inner switch
        } //end case WM_SYSCOMMAND
            .
            .
            .
    } // end switch(message)
} // end WndProc

GLUT files

//////////////////////////////////////////
//                                      //
// MOST BASIC GLUT APPLICATION          //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 9/08            //
// Last modified:  Feb 9/08             //
//                                      //
//////////////////////////////////////////

// GLUT is short for "OpenGL Utility Toolkit".
//
// GLUT was originally created by a genius named Mark Kilgard.
//
// GLUT exists only to allow you to easily create a
// window and draw your really cool 3D graphics into that
// window using OpenGL function calls.

// GLUT is NOT really suited to create full blown games,
// and you really should take a look at programming Windows
// if you want to do that.

// BUT, GLUT is a good place to start to understand
// OpenGL in a really simple way.

// GLUT is GREAT for simple projects and demos.

// Its clean, its simple, and it pretty much does
// all the stuff you wanna do in a demo of a short
// program.

///////////////////////////
// GLUT in Visual Studio 2005.

// Here I am explaining how to get GLUT running
// ASSUMING you're using Visual Studio 2005.

// BEFORE STARTING TO RUN THIS PROGRAM:  You must
// first INSTALL GLUT onto your system.
//      TO INSTALL GLUT on your Windows system:
//      1.  Get glut-3.7.6-bin.zip from:
// http://www.xmission.com/~nate/glut.html
//
//      2.  Unzip the file and copy glut32.dll file to:
//C:\Windows\system32
//
//      3.  Copy glut32.lib to:
//C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib
//
//      4.  Copy glut.h to:
//C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\gl

/////////
// Got it installed?  Good!  Let's continue.
/////////


// The first thing we're going to do in our GLUT application is import the
// libraries we'll need:
#include <iostream>  // include the standard
// input/output, so we can write text to the console window
using namespace std;    
#include <glut.h>  // include the OpenGL Utility Toolkit
// -- (Remember, you HAVE TO to follow instructions above
// and INSTALL GLUT first!)

// IMPORTANT:  YOU MUST #include <iostream> BEFORE <glut.h> BEFORE 
// OTHERWISE you will get an 'exit' : redefinition error.

/// render function.  This is THE function that
/// TELLS openGL what to DRAW inside our Window.
void render()
{
    glClear( GL_COLOR_BUFFER_BIT );

	#pragma region drawing code
	glPushMatrix();
		glColor3d( 1.0, 1.0, 1.0 );
		glutSolidTeapot( 0.5 );

		glColor3d( 0.0, 0.0, 1.0 );
		glTranslated( 0.0, 0.6, 0.0 );
		glutSolidTeapot( 0.25 );
	glPopMatrix();
	#pragma endregion

    glutSwapBuffers() ;
}

// Next, we'll write our main() function:
int main( int argc, char** argv )
{


/*
A note about argc and argv — CAN skip, but is good to know

Notice that main() has 2 parameters between the brackets. You might not be used to that, because normally we’d just write int main(). It turns out that when you write a GLUT application, you have to have (int argc, char** argv) between the brackets there. Now, you can take my word for it, because its not REALLY important to understanding OpenGL as to why you need argc and argv, or you can read the paragraph below to understand.

argc and argv are the command line arguments. Here’s an example.

Open the Windows command prompt (to open cmd prompt, go to START->Run, then type cmd in the box that appears there. You should see a black console window, like the one that your basic console C++ apps run in. In the black window, after the C:\Documents and Settings> type in this line:
explorer

What should happen is your windows file explorer should pop up.

Now go back to the command prompt and type in
explorer “C:\Program Files”

Notice now that the Windows disk explorer now opens in the folder “C:\Program Files”

In the above example, “C:\Program Files” is a command line argument that modifies the behaviour of the disk explorer upon its launch.

In the same way, your GLUT app will accept a string or two from the operating system environment that tell it how it should set itself up. We never have to deal with argc and argv DIRECTLY in our GLUT apps, but its good to know.
*/


    // Ok, now for the actual code of our program:

    // these next few lines "speak" to GLUT.
    // Think of GLUT like a living entity.
    // Each time you write a function call
    // that begins with glut___(something),
    // you are COMMANDING GLUT to DO SOMETHING.

    // We're going to write SEVEN (7) commands to GLUT in this program.

    glutInit(&argc, argv);              // initialize GLUT!
// (ask GLUT to
// initialize itself and get ready
// to draw graphics)

    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);      // Tell GLUT to
// be prepared to draw in all of red, green and blue
// colors (mixes of red, green and
// blue get you all 16 million
// colors available), Also double buffer the display (REQUIRED windows 7)

    glutInitWindowPosition(120,260);    // this tells GLUT
// that WHEN I decide to create a window,
// I want that Window to start
// up 120 pixels from the left
// edge of the screen, and 260
// pixels from the top edge
// of the screen.

    glutInitWindowSize(600,600);        // This tells GLUT
// that WHEN I create a window, I want
// that window to have a width
// of 600 pixels (first number is
// width), and a height of 600
// pixels (second # is height)


// Next, actually CREATE the window.  Will use
// all the information I specified above about
// window position and window size to
// create this window.
    glutCreateWindow("WOO HOO!  This is my GLUT Window!");

    glutDisplayFunc( render );          // "attach" the
// function with name "render" to 
// the "draw" event.  WHENEVER
// my window needs to be "drawn",
// AUTOMATICALLY, GLUT will CALL
// the render() function.

// When does my window need to be
// drawn you ask??  Why, whenever
// it receives a PAINT EVENT from
// the Windows O/S, of course!
// (a window gets a paint event whenever
// the windows O/S recognizes that
// a part of it needs to be redrawn.
// For example, if another window blocks
// your window, and then that
// other window is removed, then
// your window will get a paint event.)

    glutMainLoop();     // START RUNNING THE APP.
    // GOTO render() function.
    // Program is now WAITING for 'messages'
    // from the user, or from the Windows O/S.
    // _PROGRAM CONTROL NEVER RETURNS
    // TO THIS LINE OF CODE AGAIN FOR THE
    // LIFE OF THIS PROGRAM!!_
}





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

*/

Check out the Visual Studio project files on esnips

//////////////////////////////////////////
//                                      //
// Reading and writing textual data     //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 8/08             //
// Last modified:  Feb 8/08             //
//                                      //
//////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>

// How do you write to a file in C/C++?
// Its easy!

int main()
{
    ///////////////////
    // fprintf() - stands for File-PRINT-Formatted.
    //
    // Say you've got some TEXTUAL data
    // you want to print out to a simple
    // text file for your program.
    //
    // You know where to turn to.  fprintf() !
    //
    // There are a few steps we must follow here:
    // 1.  OPEN FILE TO WRITE TO
    // 2.  WRITE!
    // 3.  CLOSE THE FILE.

    // 1.  In order to write out to a file, you
    // first have to OPEN A FILE FOR WRITING.
    FILE * outfile = fopen( "shoppingList.txt", "w" );  // open "shoppingList.txt" for "w"RITING
    // 'outfile' is now a "file pointer" to
    // the file "shoppingList.txt" on disk.  outfile
    // can ONLY BE WRITTEN TO, because I opened
    // the file in a WRITE mode, indicated by
    // the "w" as the second argument to fopen()

    // Notice when I call fopen()
        // A.  If "shoppingList.txt" doesn't exist, then
        //     it will be created.
    
        // B.  If "shoppingList.txt" DOES exist, then
        //     shoppingList.txt's contents are CLEARED OUT

    // 2.  So, now that the file is open, let's write to it!
    fprintf( outfile, "Shopping list:\n" );
    fprintf( outfile, "   - Blueberries\n" );
    fprintf( outfile, "   - Raspberries\n" );
    fprintf( outfile, "   - Granola bars\n" );
    fprintf( outfile, "   - Beer\n" );

    // What if we want to write variable values?
    // Easy!  Just like printf() works, you use
    // the %d, %f, %s to tell fprintf() what types
    // of variables its printing.

    // fprint an int
    int qtips = 5000;
    fprintf( outfile, "   - %d Qtips\n", qtips );

    // fprint a float
    float purity = 99.4;
    fprintf( outfile, "   - Soap that is %.1f%% pure\n", purity );

    // 3.  DONE, so CLOSE THE FILE!
    fclose( outfile );

    ////////////////////
    // HOW DO YOU OPEN A FILE WITHOUT
    // OVERWRITING ITS CONTENTS?
    //
    // 1.  OPEN:  You open the file using "APPEND" mode.
    outfile = fopen( "shoppingList.txt", "a" ); // open "shoppingList.txt" for "a"PPENDING

    // 2.  PRINT:  anything we fprintf() here will automatically be
    // tacked onto the end of "shoppingList.txt"
    fprintf( outfile, "Don't forget the milk !" );

    // 3.  CLOSE!
    fclose( outfile );

    printf("\n\n***************************\n* Part 2 - Reading from a file\n");
    system("pause");
    ////////////////////
    // READING FROM A FILE.
    //
    // Now, we're going to write a bit of code
    // to read that file we just wrote to.

    // Here's how you do it:
    // 1.  OPEN FILE FOR READING
    // 2.  READ!
    // 3.  CLOSE FILE!

    // 1.  OPEN:
    FILE * readfile = fopen( "shoppingList.txt", "r" ); // open "shoppingList.txt" in "r"EAD mode
    char buf[300];      // create a buffer of 300 chars
                        // to temporarily dump data
                        // from the file into.

    while( !feof( readfile ) )
    {
        // 2.  READ!
        // let's read one line at a time
        fgets( buf, 300, readfile );

        // print out that line we just read in
        // to the console so we can see it
        printf( "%s", buf );
    }

    // 3. CLOSE!
    fclose( readfile );


    printf("\nPart 3 - printing the source of __this__ code file.\n");
    system("pause");
    //////////////////
    // A fairly common interview question comes next.
    //
    // "Write a C program that prints out
    // its own source code when it is
    // compiled and run."
    //
    // The trick here about this question is
    // you have to know about the __FILE__ macro.
    // 
    // __FILE__ will be automatically identified
    // with a string containing the full path
    // of the source file.
    printf("\nThe source file for this code is:  %s\n", __FILE__ );
    
    FILE * source = fopen( __FILE__, "r" ); // open __this__ file for reading
    while( !feof(source) )
    {
        // print every character in the file
        // to the console.
        printf( "%c", fgetc( source ) );
    }
}


//////////////////
// END NOTES:
//
// Note that there IS a C++ "way" to do file output
// that is "object oriented" provided through
// the 'ofstream' object.
//
// I do NOT recommend you use the ofstream
// class however.  WHY?  Because its REALLY slow.
// In simple tests I've conducted using a high performance
// counter, ofstream takes TWICE AS LONG to print
// the same stream of characters to disk
// as fprintf() does.

// See
// https://bobobobo.wordpress.com/2008/02/07/speed-tests-fprintf-vs-ofstream-and-fprintf-vs-fwrite/
// for a speed test.)

// OOP is good, but it sometimes has
// a pretty bad performance cost.

Download the Visual Studio 2005 project files hosted by esnips (thanks esnips!)

Refs
fprintf entry @ cplusplus.com
fprintf entry @ cppreference.com

I’m testing a few C/C++ funcs through having them write out 100,000 lines of data (total amounting to about 3MB) to a file.

The results: Building these with Visual Studio 2005 VC++ on Win 32:

fprintf is faster than ofstream

(fprintf nearly 2x as fast as ofstream on my machine)

fwrite is marginally faster than fprintf

(fwrite about 1.1x as fast as fprintf on my machine)

// OFSTREAM IS SLOW!!

#include <fstream>
using namespace std;

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

LARGE_INTEGER   ticksPerSecond;
LARGE_INTEGER   time1;
LARGE_INTEGER   time2;

float floatDiffTime;
const int runs = 100000;

int main()
{
    ////////////////
    // Get the speed of the CPU
    QueryPerformanceFrequency( &ticksPerSecond );
    printf( "Your computer does %lld ticks per second\n", ticksPerSecond.QuadPart );
    // %lld means type "long long" int, which is the
    // 64 bit int which is what we want here.

    // define some random valued variables to use
    // in the print statements
    int a    = 5;
    double b = 9.2919e92;
    char c   = 'x';
    char * d = "blah blah blah";


    // test start:  open a file to write to
    FILE * outfile = fopen( "testfile.txt", "w" );

    /////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );

    // test fprintf(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        fprintf(outfile, "blah %i %f %c %s\n", a, b, c, d );
        fflush( outfile );  // flush to be fair
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
    floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fprintf took %f seconds\n", floatDiffTime );

    fclose( outfile );  // close up, so we
    // can proceed to start over with
    // ofstream test.


    ////////////////
    // testing ofstream()
    ofstream out( "oftestout.txt" );

    ////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );
    //
    ////////////////////

    // test ofstream, run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        out << "blah " << a << " " << b << " " << c << " " << d << endl;
        out.flush();  // flush to be fair
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );
    //
    ////////////////////

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
    floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "ofstream took %f seconds\n", floatDiffTime );

    out.close();

    return 0;
}

But what about fprintf() vs fwrite()?

Place your bets!

// what's faster, fwrite or fprintf?

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

#include <windows.h>

LARGE_INTEGER   ticksPerSecond;
LARGE_INTEGER   time1;
LARGE_INTEGER   time2;

float floatDiffTime;
const int runs = 100000;
char buf[255];      // create a buffer for fwrite to use

int main()
{
    ////////////////
    // Get the speed of the CPU
    QueryPerformanceFrequency( &ticksPerSecond );
    printf( "Your computer does %lld ticks per second\n", ticksPerSecond.QuadPart );
    // %lld means type "long long" int, which is the
    // 64 bit int which is what we want here.

    // define some random valued variables to use
    // in the print statements
    int a    = 5;
    double b = 9.2919e92;
    char c   = 'x';
    char * d = "blah blah blah";


    // test start:  open a file to write to
    FILE * outfile = fopen( "testfile.txt", "w" );

    /////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );

    // test fprintf(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        //fprintf(outfile, "blah %i %f %c %s\n", a, b, c, d );

        // making fprintf() print a single string generated
        // by sprintf() to equalize the test
        sprintf( buf, "blah %i %f %c %s\n", a, b, c, d );   // its only fair!
        fprintf( outfile, "%s", buf );

        fflush(outfile);    // flush after going to the toilet
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
	floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fprintf took %f seconds\n", floatDiffTime );

    fclose( outfile );  // close up, so we
    // can proceed to start over with
    // fwrite test.


    ////////////////
    // testing fwrite()
    outfile = fopen( "testfile.txt", "w" );

    ////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );
    //
    ////////////////////

    // test fwrite(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        // fwrite needs a single string to write from,
        // so use sprintf to copy to a buffer
        sprintf( buf, "blah %i %f %c %s\n", a, b, c, d );
        fwrite( buf, 1, strlen( buf ), outfile );
        fflush(outfile);    // flush
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );
    //
    ////////////////////

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
	floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fwrite() took %f seconds\n", floatDiffTime );


    fclose( outfile );
    return 0;
}

In my tests here, fwrite() was faster, even though using fwrite requires an extra call to strlen().

Anyway, this was just for fun. For all intents and purposes, fprintf() is pretty much the same speed as fwrite(). BUT fprintf is DEFINITELY much faster than ofstream!

Visual Studio 2005 project files for fprintf vs ofstream test hosted by esnips (thanks esnips!)

I want the HWND and HINSTANCE of a console window. How do I get it?

hwnd console

NOTE: A few comments at the bottom of this post have pointed out the existence of several functions that actually make this easier than I have shown here: particularly HWND hwnd = GetConsoleWindow();. There’s also GetModuleHandle(), used as Hardijzer mentions in the comments below, thought I might not have used this had I been aware of it. The complete listing of console functions is here on msdn.

Its actually easy! The short of it is:


// console app
#include <iostream>
using namespace std;

#include <windows.h>

int main()
{
  char title[500];  // to hold title

  // get title of console window
  GetConsoleTitleA( title, 500 );

  // get HWND of console, based on its title
  HWND hwndConsole = FindWindowA( NULL, title );

  // get HINSTANCE of console, based on HWND
  HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwndConsole, GWL_HINSTANCE);

  //alternate way
  HWND hwndC = GetConsoleWindow() ; /* Great!!  This function
  cleverly "retrieves the window handle
  used by the console associated with the calling process", 
  as msdn says */
  
  // Then we could just get the HINSTANCE:
  HINSTANCE hInstC = GetModuleHandle( 0 ) ; // HMODULE=HINSTANCE
  //HINSTANCE hInstCons = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE );
}

See msdn article on FindWindow function.

The GetWindowLong() function, in the msdn spotlight.

We now have the HWND of the console in variable hwndConsole, and the HINSTANCE of the console window in hInstance.

Now, you COULD create a window up, because you have the HINSTANCE now. The example below illustrates the “long” of it:

//////////////////////////////////////////
//                                      //
// Getting the HWND of the Console      //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 3/08             //
// Last modified:  Feb 3/08             //
//                                      //
//////////////////////////////////////////
#include <iostream>
using namespace std;

#include <windows.h>

// So you need the handle (HWND) for the
// console window for your app.

// Who knows why.  Maybe ya just
// want it.

///////////////////////////////
// In this example, I'm:
//  1) using the HWND of the console window 
//     to get the HINSTANCE of the console window
//     (GetWindowLong() function)
//
//  2) using the HINSTANCE and HWND of the
//     console window to create a regular
//     window with a WndProc and a message
//     loop and all (WNDCLASS structure,
//     RegisterClass(), then CreateWindow())

// based off of MSDN KB article
// http://support.microsoft.com/kb/124103

// prototype for the WndProc of the window that
// we're gonna create.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );

/////////////////
// Normally, windowed apps would start
// at WinMain().
// However, remember that this is REALLY
// a console application, and we're just
// spawning a window out of it.
// This application starts at first line of main().
int main()
{
    // console window exists as soon as app start

    // get its hwnd using combo of "GetConsoleWindowTitle()"
    // and "FindWindow()"

    // Why did i call this _REGION_A_? see end notes!
    #pragma region _REGION_A_ - get HWND of console
    
    char t[500];

    GetConsoleTitleA( t, 500 );     // retrieve the text
    // of the title bar of the console window

    cout << "The title of the console window is:" << endl;
    cout << t << endl << endl;

    HWND hwndConsole = FindWindowA( NULL, t );  // FindWindowA actually
    // can get you the HWND of a window, based
    // on the text in its title bar!
    
    // Let's check to see it worked.  If the console window
    // moves after the function call below, then we know
    // that hwndConsole is really a valid handle to the console
    // window!
    MoveWindow( hwndConsole, 20, 20, 500, 500, true );  // test hwnd

    #pragma endregion

    #pragma region _REGION_B - get HINSTANCE and create a window!
    ////////////////////////
    // Getting the HINSTANCE given the HWND
    //
    // Want the HINSTANCE of a window, but
    // you only have its HWND?
    //
    // Here's how you generally get the HINSTANCE
    // of the console, based off of the HWND of
    // the console.
    HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwndConsole, GWL_HINSTANCE);
    
    ////////////////////
    // Now I'm going to create an ACTUAL WINDOW.
    //
    // Note that you always need a HINSTANCE
    // to create a window, which is why I just
    // got it in the line just above here.
    WNDCLASS wc = {0};
    wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.hCursor = LoadCursor( hInstance, IDC_ARROW );
    wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = TEXT("peter");   // name of window class .. I choose peter
    wc.style = CS_HREDRAW | CS_VREDRAW;

    if (! RegisterClass( &wc ) )
    {
        cout << "Problem with your WNDCLASS, foo." << endl;
        return 1;   // ERR, SO QUIT
    }
    
    // Create a real live window!
    // (see https://bobobobo.wordpress.com/2008/01/31/how-to-create-a-basic-window-in-c/
    // for more details on basic windows)
    HWND hwndWindow = CreateWindow(  TEXT("peter"),
                    TEXT("the window"),
                    WS_OVERLAPPEDWINDOW,
                    520, 20, 300, 300,
                    NULL,   // if you make this hwndConsole, then
                            // the console becomes this window's parent
                            // Then, this window wouldn't get an
                            // entry in the taskbar
                    NULL,
                   
                    hInstance, NULL );

    ShowWindow( hwndWindow, SW_SHOWNORMAL );    // ShowWindow() on msdn
    UpdateWindow( hwndWindow );
    #pragma endregion

    // Enter regular message loop, to process messages for
    // our window.
    #pragma region _REGION_C - message loop
    MSG msg;
    while( GetMessage( &msg, hwndWindow, 0, 0 ) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    #pragma endregion

    return msg.wParam;
}



////////////
// The WndProc for the Window that
// we eventually open up
// (This WndProc is _NOT_ FOR THE CONSOLE WINDOW!)
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
    switch( message )
    {
        case WM_CREATE:
            cout << "WINDOW SPEAKING TO YOU THROUGH THE CONSOLE." << endl;
            cout << "I'm alive!" << endl << endl;
            Beep( 40, 40 );
            return 0;
            break;

        case WM_PAINT:  // paint event
            {
                cout << "PAINT EVENT!  time to repaint!!" << endl;
                PAINTSTRUCT ps;
                HDC hdc;
                BeginPaint( hwnd, &ps );
                EndPaint( hwnd, &ps );
                return 0;
            }
            break;

        case WM_LBUTTONDOWN:    // left clicking on the client area of the window (white part)
            cout << "WHY R YA MOUSE DOWN'IN ME AT x=" << LOWORD(lparam) << " y=" << HIWORD(lparam) << " SON" << endl;
            return 0;
            break;

        case WM_NCLBUTTONDOWN:  // NONCLIENT area leftbutton down (click on "title bar" part of window)
            //cout << "AAAH!! YER GONNA MOVE ME SON.  CAREFUL SON." << endl;
            //return 0;     // this is an interesting one.
            // try UNCOMMENTING the return 0; statement here.
            // Notice that you can NO LONGER move or manipulate
            // the window by clicking on its "title bar"
            // if you return 0; from here.  The reason for that
            // is the window movement is actually handled by
            // DefWindowProc().  That's why its so important
            // to remember to pass events you don't handle to
            // DefWindowProc() -- if you don't then the Window
            // won't act in the "default" way you're so used to
            // other windows acting in (in fact, it won't even
            // show up properly)
            break;

        case WM_CHAR:   // character key
            cout << "WHY R U CHARRING ME WITH " << (char)wparam << " FOR SON" << endl;
            return 0;
            break;

        case WM_MOVE:   // moving the window
            cout << "WHY R U MOVIN' ME TO x=" << LOWORD(lparam) << " y=" << HIWORD(lparam) << " FOR SON" << endl;
            return 0;
            break;

        case WM_SIZE:
            cout << "WHY R YA SIZIN' ME TO SIZE width=" << LOWORD(lparam) << " height=" << HIWORD(lparam) << " FOR SON"<< endl;
            return 0;
            break;

        case WM_DESTROY:    // killing the window
            cout << "NOOO!!  I . . . shall . . . return !!" << endl;
            PostQuitMessage( 0 );
            return 0;
            break;
    }
    
    return DefWindowProc( hwnd, message, wparam, lparam );
}









////////////////////////
// END NOTES:
//
// If you read the MSDN article carefully,
// it says some shit about wanting to 
// SetConsoleTitle( "stupid unique title");
// The reason for that is, there is an OFF
// CHANCE that PERHAPS there's more than one
// window with the same exact TITLE
// as our console window.
//
// There's a bit of code at the bottom of the
// Visual Studio project files that shows
// how to do that.
// 

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

*/

Visual Studio 2005 project files, hosted by esnips (thanks esnips!)

//////////////////////////////////////////
//                                      //
// A Fast Windows Program               //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 3/08             //
// Last modified:  Feb 9/08             //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <math.h>   // for sin() and cos() in calculating npc pos

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

////////////////////////////
// Introduction:
// 
// In the "MostBasicWindow" project, we talked
// about creating a basic window, and how
// MOST NORMAL Windows programs use something
// called "EVENT DRIVEN PROGRAMMING".

// If you don't remember, please review
// PREREQUISITES:  BASIC WINDOWS PROGRAMMING
// (see https://bobobobo.wordpress.com/2008/01/31/how-to-create-a-basic-window-in-c/
// to get started).

// In EVENT DRIVEN PROGRAMMING, your
// program is entirely driven by EVENTS.

// If there are no events, then your
// Windows program DOES NOTHING AT ALL,
// until the next EVENT is passed to it
// by the Windows O/S in the form of a 
// MESSAGE.

// Now, this is a PROBLEM when it comes
// to programming a GAME AS A Windows application.

// If your app NORMALLY does nothing
// except when the user interacts with
// the application, then every time
// the user let go of all of the keys
// on the keyboard, the game would just
// simply PAUSE.  This is because
// the normal structure of a Windows
// application is to execute code
// IN RESPONSE TO EVENTS THAT COME
// to the window.  If there are no
// events, then the application is idle.

// That structure makes perfect sense
// for applications like MSWord or firefox, and its
// the only way things are sane inside
// that Windows Government and the
// processor doesn't blow up when you
// have 50 windows open at the same time.

// However, GAMES are different than normal
// standard windows apps like Firefox or
// MSWord.

// Games need to CONSTANTLY be running.  Games
// need to constantly update their state.
// Even if the player isn't doing anything,
// the game AI has to keep computing what
// the MONSTERS will do next.  The game
// has to have a concept of TIME that keeps
// on going on, even when the player isn't
// pressing any keys too.

///////////////////////
// RECALL:  The NORMAL WINDOWS PROGRAM MESSAGE LOOP:
/*
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        // GetMessage is a function that will not
        // return until the Windows O/S HAS A message
        // for our program.

        // Since the GetMessage() function call is
        // INSIDE the bracket for the while Loop,
        // this means that our program is essentially
        // "put on hold" or halted until the GetMessage function
        // returns.

        // If and when the user interacts with our
        // application's window, then the GetMessage()
        // function WILL return and the variable
        // msg will be filled with interesting details
        // about exactly what the user did to the window.

        TranslateMessage( &msg );   // translates 
        // the message so WndProc can process it
        // more easily.

        DispatchMessage( &msg );    // this line RESULTS IN
        // a call to WndProc(), passing the message and
        // the HWND.  This is OUR APPS CHANCE
        // to execute some code in response
        // to user events.
    }
*/

// The point is, GAMES CAN'T _WAIT_ FOR
// MESSAGES FROM THE WINDOWS O/S TO BE
// ALLOWED TO EXECUTE THEIR CODE!!

// Games need to run very quickly, and
// execute the following instructions
// __at least__ 60 times a second!

// {
//      checkWhatKeysUserIsPushingDown();
//      makeChangesToGameStateAndCalculateNextFrame();
//      draw();
// }

// Because GetMessage() blocks (doesn't return
// control to our app immediately!), it really
// creates a bottleneck for us!

// IN OTHER WORDS, WE HAVE TO STOP USING
// THE GetMessage() function!

// For our game, we DO NOT want to be WAITING
// for messages AT ALL.  Instead, we will
// use something else called PeekMessage()
// to VERY QUICKLY check to see if the
// Windows O/S has any messages for our
// Window.

// IF the Windows Government does have a message for us,
// THEN we process that message, then its
// back to our computing and drawing functions
// as usual.

// IF the Windows O/S DOES NOT
// have any messages for our Window, WE
// WANT TO CONTINUE RUNNING OUR OWN CODE
// ANYWAY -- WE DO NOT WANT TO GIVE UP
// CONTROL TO THE WINDOWS O/S.

#pragma region globals
HWND hwnd;      // store the HWND in a global now,
                // so our DRAW function can use it freely.

// player x and y positions.
float playerXPos = 50;
float playerYPos = 50;

// NPC x and y positions.
float npcXPos = 80;
float npcYPos = 80;
#pragma endregion

void check_for_user_input_through_keyboard()
{
    float diff = 0.01f;

    if( GetAsyncKeyState( VK_UP ) )
    {
        // up key being pushed, move player up
        playerYPos -= diff;
    }

    if( GetAsyncKeyState( VK_DOWN ) )
    {
        playerYPos += diff;
    }

    if( GetAsyncKeyState( VK_RIGHT ) )
    {
        playerXPos += diff;
    }

    if( GetAsyncKeyState( VK_LEFT ) )
    {
        playerXPos -= diff;
    }
}

// In this function, we're calculating
// the motion of the "npc unit" - very simple
void calculate_next_frame_of_our_program_by_shuffling_npc_around()
{
    // let's move the NPC unit around, in a circle.
    static float pos = 0.0f;
    pos += 0.1f;

    npcXPos += 0.01*sin( 0.001*pos );
    npcYPos += 0.01*cos( 0.001*pos );
}

void draw()
{
    HDC hdcTotalArtist = GetDC( hwnd ); // get the "handle to device context"
                                        // for our Window.

    // The "device context" is like a "total artist"
    // that has pens, brushes, and a canvas to draw to.

    // I explain that more below, but for now, let's
    // draw the player:
    Ellipse( hdcTotalArtist, (int)playerXPos, (int)playerYPos, (int)(playerXPos + 10), (int)(playerYPos + 10) );

    ////////////
    // Changing the pen color:
    // Now the npc unit should be a different color.
    // so this is REALLY QUICKLY how you change
    // the color of the "pen" that you're using
    // to draw.

    // The "device context" of our window is
    // like a TOTAL ARTIST.
    // The "device context" contains:
        // canvas
        // pens
        // brushes
        // and more!

    // In order to change the style in which the
    // standard GDI functions (like Ellipse) are
    // drawing, we would have to CHANGE THE
    // PROPERTIES OF THE DEVICE CONTEXT TO WHICH
    // WE ARE DRAWING.

    // So what we do is, we:
        // 1.  CREATE A NEW redpen,
        //      WITH ALL THE PROPERTIES
        //      WE WANT IT TO HAVE (solid lines, can select width as well)
        // 
        // 2.  GIVE THAT redpen TO
        //     THE device context "total artist"
        //     by using the SelectObject() function.
        //     Note that the hdc total artist can
        //     only hold ONE PEN at a time.  So
        //     you'll see in the code that when we
        //     give the hdc total artist
        //     a new pen, WE MUST CATCH THE OLD ONE
        //     IN A VARIABLE!
        //
        // 3.  DRAW AGAIN using the Ellipse()
        //     gdi function.  Since the Ellipse()
        //     function WILL draw to an HDC,
        //     then we will see RED ELLIPSE, since
        //     we just gave the hdc total artist
        //     a red pen.

    // "select the pen into" the device context
    // by using the SelectObject() function.

    // This in a sense is like GIVING the device
    // context a new brush with which to draw,
    // or a new pen with which to draw.
    HPEN redpen = (HPEN)CreatePen( PS_SOLID, 2, RGB( 255, 0, 0 ) );
    HPEN oldpen = (HPEN)SelectObject( hdcTotalArtist, redpen );

    // draw with redpen
    Ellipse( hdcTotalArtist, (int)npcXPos, (int)npcYPos, (int)npcXPos + 10, (int)npcYPos + 10 );

    // select back the old pen, then delete the red pen
    redpen = (HPEN)SelectObject( hdcTotalArtist, oldpen );
    DeleteObject( redpen );

    ReleaseDC( hwnd, hdcTotalArtist );
}

////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR szCmdLine,
                    int iCmdShow )
{
    #pragma region part 1 - STARTUP STUFF
    WNDCLASS wc;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    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("Philip");
    wc.lpszMenuName = 0; 
    wc.style = CS_HREDRAW | CS_VREDRAW;

    // B.  Register the WNDCLASS with Windows, THEN
    //     create the window.
    RegisterClass( &wc );
    hwnd = CreateWindow(
        TEXT("Philip"),
        TEXT("Fast windows app!!"),
        WS_OVERLAPPEDWINDOW,
        10, 10,
        400, 400,
        NULL, NULL,
        hInstance, NULL );      

    // Next, SHOW and PAINT the window!
    // You won't see the window if you DO NOT
    // call ShowWindow();
    ShowWindow(hwnd, iCmdShow );
	UpdateWindow(hwnd);
    #pragma endregion

    // first, we create the MSG structure.
    MSG msg;

    #pragma region OLD GETMESSAGE LOOP -- NORMALLY YOU SHOULD JUST DELETE THIS PART
    // -- commented out, but I STRONGLY ENCOURAGE
    // you to try commenting it back in to see
    // how it behaves and why we CAN'T be using
    // GetMessage() for our games.

    // IT DOES WORK, but its INCREDIBLY, INCREDIBLY
    // slow.

    // And on top of the extreme SLOW, you have to constantly
    // be inputting "messages" into the window in order
    // for anything to happen! (for the npc to move!)

    /*
    SetWindowText( hwnd, TEXT("SLOW MODE!!! - Press ESC for fast mode") );
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg ); 

        check_for_user_input_through_keyboard();
        calculate_next_frame_of_our_program_by_shuffling_npc_around();
        draw();
    }
    */
    #pragma endregion

    #pragma region part 2 - ENTER A LOOP TO CONTINUALLY KEEP CHECKING WITH WIN O/S FOR USER INTERACTION

    // Notice we changed the loop structure from the old
    // GetMessage() structure.  We're using PeekMessage() now.

    // It goes like this now:

    // while(FOREVER)
    // {
    //    if ( there's a message for our window )
    //    {
    //      translate and dispatch to WndProc for processing();
    //    }
    //  
    //    check_for_user_input_through_keyboard();
    //    calculate_next_frame_of_our_program_by_shuffling_npc_around();
    //    draw();
    // 
    // }
    SetWindowText( hwnd, TEXT("Fast windows app!!") );  // (in case you uncommented
                                                        // the GetMessage() above )
    while( 1 )  // LOOP FOREVER
    {
        // 1.  PROCESS MESSAGES FROM WINDOWS
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            // Now, this is DIFFERENT than GetMessage()!
            // PeekMessage is NOT a BLOCKING FUNCTION.
            // That is, PeekMessage() returns immediately
            // with either a TRUE (there was a message
            // for our window)
            // or a FALSE (there was no message for our window).

            // If there was a message for our window, then
            // we want to translate and dispatch that message.

            // otherwise, we want to be free to run
            // the next frame of our program.
            if( msg.message == WM_QUIT )
            {
                break;  // BREAK OUT OF INFINITE LOOP
                        // if user is trying to quit!
            }
            else
            {
              TranslateMessage( &msg );   // translates 
              DispatchMessage( &msg );    // this line RESULTS IN
              // a call to WndProc(), passing the message and
              // the HWND.

              // Note that in this program, all we're really using
              // the messaging system for is for
              // processing the QUIT message that occurs
              // when the user clicks the X on the window
              // to close it.

              // ALL OTHER application processing happens
              // in the 3 lines of code below
              // (the 'check_for_user ... ' stuff)
           }
        }
        else
        {
           check_for_user_input_through_keyboard();
           calculate_next_frame_of_our_program_by_shuffling_npc_around();
           draw();
        }
    }
    #pragma endregion

    return msg.wParam;
}

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 nothing here.
            // drawing happens in the 
            // draw() function that
            // we MANUALLY call ourselves.

            // We DO NOT rely on messages to
            // tell us when to draw when creating
            // game!  Instead, we draw when
            // we want to.

            // WHY?  Because the WM_PAINT message
            // only comes to your window WHEN
            // the Windows O/S THINKS your window
            // needs to be redrawn.  That includes
            // only events like "if your window
            // was blocked by another window,
            // then it needs to be repainted"

            // Our fast game NEEDS to be redrawn
            // 60 times a second AT LEAST, so we
            // totally BYPASS the normal windows
            // system, and draw in our draw()
            // function of our own accord.

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

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

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

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

///////////////////////
// Closing notes:
//
// IF you'll notice, when you run this
// program, if you look at your task
// manager, (CTRL+ALT+DEL), NOTICE your
// windows application (should show up
// in processes list as BasicWindowsProgramming_GameStructure.exe)
// is now a CPU HOG.  Its taking somewhere
// close to 40-50% of CPU time.

// THIS IS GOOD. YOUR APP IS TAKING
// CONTROL OF THE SYSTEM RESOURCES
// (CPU TIME).
//
// If its a game, THIS IS EXACTLY WHAT YOU
// WANT.  Games need to hog the system
// resources in order to run the best
// they possibly can given the user's
// hardware.

// Using this Windows program structure -
// a "greedy" structure if you will -
// we can create games that run as
// fast as they can.

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

*/

Visual Studio 2005 Project files hosted by esnips! (thanks esnips!)

Many, many people, when starting out with DirectX or other Microsoft technologies, go and look for a simple book on the topic.

Many newbies do not know about MSDN. Or, if they do know about MSDN, they don’t know just HOW GOOD and complete it is, simply because they’ve never tried to use it before.

The MSDN documentation CAN BE a bit annoying, simply because its so damn huge.

It is very well organized though, and if you browse through the tree hierarchy on the left (once you’ve got a good starting point!), then its very useful indeed.

The search tool doesn’t always find you the article you’re looking for though, so sometimes trying different search strings can help. Just because a bunch of weird irrelevant stuff turns up in an MSDN search, doesn’t mean that MSDN doesn’t have what you’re looking for!

IN FACT, MOST OF THE BOOKS out there on DirectX SIMPLY ADAPT OR EXPAND ON THE MSDN DOCUMENTATION. A LOT of the time, the book just provides you a subset of what MSDN provides, while not making the material all that much clearer. SOME of the books on DirectX out there are like drinking from a murky pond, while the clearer (not 100% clear, though) lake is right next to it.

As I mentioned, it can be a TAD annoying to have to LOOK FOR the appropriate MSDN article.

So here’s a pageful of links:

MAIN LINK TO DirectX SDK DOCUMENTATION, (NOVEMBER 2007) C++

The rest of these links you can find by simply following the above DirectX links, but I’m including them here for convenience.

MSDN docs on DirectInput

MSDN docs on DirectSound

More interesting stuff from MS. . .

Microsoft XNA presentations – has stuff from Gamefest, SIGGRAPH, and GDC (near the bottom of the page)

Follow this link for a great article on byte alignment.

The deal is the VC++ compiler will sometimes pad your data structures automatically so that different variables start on word boundaries.

In VC++, you can bypass the automatic compiler padding. An example follows.

#include <iostream>
using namespace std;

// In this example, the C++ compiler will actually pad
// the PaddedStruct structure definition with unnamed variables
// so that shorts start on word boundaries.
// So between c and d, an extra, unnamed 1 byte variable
// of type char will be added in automatically by the compiler.
// This is done so that application performance is better,
// but sometimes, you don't want that.

// To get your structures to be laid out in memory
// exactly as you'd like, with no padding, you have to change
// compiler behaviour with some #pragmas.  This example shows how.

// http://en.wikipedia.org/wiki/Data_structure_alignment

// Here is an example of a struct that gets AUTOMATICALLY
// padded out with an extra byte.
struct PaddedStruct
{
	char a;
	char b;
	char c;

 /* char PADDING; */ // the COMPILER will add in an extra byte here
                     // so the short gets started on a 2-byte boundary
	short d;
};


// Here is how you force the compiler to NOT add that extra PADDING char:
// Use the #pragma pack preprocessor directive to alter VC++ compiler behavior!
#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */
struct UNPaddedStruct
{
	char a;
	char b;
	char c;
	short d;
};
#pragma pack(pop)   /* revert to default compiler behavior */


int main()
{
    cout << "sizeof(paddedStruct) " << sizeof(PaddedStruct) << endl;	    // should be 5, but its actually 6

    cout << "sizeof(UNpaddedStruct) " << sizeof(UNPaddedStruct) << endl;	// WILL be 5, b/c of #pragma
    
    return 0;
}
//////////////////////////////////////////
//                                      //
// SIMPLEST WINDOWS PROGRAM             //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Jan 31/08            //
// Last modified:  Feb 9/08             //
//                                      //
//////////////////////////////////////////

#include <windows.h>

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

////////////////////////////
// Introduction:
// Basic Windows Program!
//
// This package demonstrates how to build a very basic Windows application
// on a Win O/S system from Windows 3.1 to Windows XP using C++ code.
//
// * Prerequisites to understanding this program:
//     - Already understand how to create Console applications in C++.
//     - Full understanding of C FUNCTIONS, FUNCTION PARAMETERS/ARGUMENTS.
//
// If you don't know what those are, go learn what
// they are before going on reading this!
// 

///////////////////
// OVERVIEW:
// Windows applications in C++ are easy!
// To understand them, you must first see the big
// picture.  Then you can get your hands dirty 
// and get right into the code.

///////////////////
// Big picture.
//
// Windows apps are much different than console apps.
// A console app, (which you probably are used to)
// has just a single "main" function called main().

// Every Windows app has __2__ functions that are very
// important to it.

// These 2 functions are WinMain and WndProc.  WinMain
// and WndProc really form the Windows' app's heart and soul.
// 
//    A.  WinMain:  Application STARTING POINT.  REPLACES
//                  main() function that you might be used to
//                  from regular C/C++ programs.
// 
//    B.  WndProc:  A function that PROCESSES MESSAGES from
//                  the Windows O/S as they come in.
//

///////////////////
// BUT what's a MESSAGE???
//
// The idea of "messages" takes some getting used
// to, but it is really a simple concept.
//
// The Windows Operating system is like a GOVERNMENT.
//
// All of the little windows that live inside
// (the Firefox window, the MSWord window,
// and YOUR PROGRAM's window!) are people owned
// by the Windows GOVERNMENT.
// 
// So, whenever the user attempts to interact
// with ANY program window inside that Windows Government,
// either by clicking on your window, or by pressing a key
// while your program has the "input focus" (when
// your window is "selected"),
// the Windows O/S INTERCEPTS that communication FIRST.
//
// THEN, a fraction of a second later, (almost
// instantly), the Windows O/S SENDS A a "MESSAGE"
// to YOUR Window program that "HEY! THE USER
// CLICKED ON YOU AT LOCATION (22, 405), USING
// THE RIGHT MOUSE BUTTON."  or "HEY!  THE
// USER PRESSED THE 'A' KEY, AND HE WAS ALSO HOLDING
// DOWN SHIFT WHILE HE PRESSED IT."

// THAT is what a MESSAGE is.  Its a notification
// from the Windows O/S that the user has 
// done something to your program's window.

// ONCE your program receives this
// "MESSAGE", your program can THEN execute some code
// in response to that particular MESSAGE.

// The WndProc function will contain ALL of
// your "MESSAGE HANDLING CODE" -- that is,
// the code pieces that you want executed 
// when certain window events happen.

// This is called EVENT DRIVEN PROGRAMMING.
// And in most standard Windows applications, this is
// how things happen.

// Most of a basic, standard Windows application's
// time is spent WAITING for events.

// And that is what a message is!

//////////////////////////////
// OF INSTANCES AND HANDLES.
//
// There are 2 concepts you must understand intuitively first
// before diving into Windows programming.

// Those concepts are the concept of an INSTANCE,
// and the concept of a HANDLE.

///////////////
// INSTANCES:
// The first concept is the concept of an INSTANCE of a program.

// What's an INSTANCE?

// An INSTANCE of an application is just one running OCCURRENCE of it.
// If you open up 3 different NOTEPAD.exe windows, then you have
// created __3__ different, separate INSTANCE of the NOTEPAD program
// inside your Windows Kernel.

// If you're familiar with OOP, an easy explanation is this:
    // PROGRAM CODE >> like a C++ class definition.
    // ACTUALLY RUNNING PROGRAM CODE >> like an "instance" of the class, this is an INSTANCE of the program.


///////////////
// HANDLES:
// HANDLES pop up EVERYWHERE in Windows programming (and all other
// types of programming as well!)  So I'm hoping to explain the idea
// behind a HANDLE intuitively, so that you have something to "hold onto"
// whenever you see use of HANDLES in program code.

// Think about a POT of boiling water.  Inside that pot is
// some corn on the cob being cooked.

// Now, say you want to ACCESS the pot, so you can dump its
// contents out into the sink and drain the corn.

// How do you do that?  Do you GRAB THE POT DIRECTLY??? NO!!
// That would be stupid.  Instead, you grab the HANDLE TO THE POT.
// Using the HANDLE to the pot, you manipulate the pot, slowly
// dumping out the water and leaving the corn behind.  Then you
// eat the corn and it is delicious.

// Now, in programming, the idea of a HANDLE is much the same.
// A HANDLE to a WINDOW is __NOT__ the window itself in an application
// variable.  Instead, it is a POINTER TO, A REFERENCE TO the
// window itself.

// A HANDLE TO AN INSTANCE in an application variable is NOT
// the application INSTANCE itself.  Rather, it is a POINTER TO
// that application instance.  The application instance exists
// somewhere in the Windows O/S's program memory.  You use the
// programmatic HANDLE that you have as YOUR MEANS TO MANIPULATE
// AND DEAL WITH that application instance.

// The benefits of HANDLES are many!  You'll see as we go on.
// Onto WinMain()!

////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance,    // HANDLE TO AN INSTANCE.  This is the "handle" to YOUR PROGRAM ITSELF.  More in the GLOSSARY at the bottom.
                    HINSTANCE hPrevInstance,// USELESS on modern windows (totally ignore hPrevInstance)
                    LPSTR szCmdLine,        // Command line arguments.  Explained near BOTTOM of this file.
                    int iCmdShow )          // Start window maximized, minimized, etc.
{
    // As we said before, WinMain is the application starting point.
    
    // A:  WinMain does 2 main things:
    //    1.  STARTUP STUFF:  CREATE THE WINDOW ITSELF, AND LOAD IT UP
    //        SO IT APPEARS ON THE SCREEN.
    //
    //    2.  KEEP CHECKING WITH WINDOWS O/S TO SEE IF THE USER
    //        HAS INTERACTED WITH THE APPLICATION ("MESSAGE LOOP")
    //        If the user has clicked on anything, or pressed any keys while
    //        our window is ACTIVE (our window has the "input focus")
    //        then we are to DISPATCH a MESSAGE to WndProc (make
    //        a function call to WndProc) that tells
    //        WndProc EXACTLY what the user did to our window (clicked?
    //        key pressed?), when it happened, etc.  WndProc then
    //        has the opportunity to EXECUTE SOME CODE in response
    //        to that particular user interaction.
    
    #pragma region part 1 - STARTUP STUFF
    // A.  Create WNDCLASS structure and initialize it
    // The WNDCLASS structure tells Windows WHAT KIND OF
    // WINDOW we dream of creating.
    
    // A note:  Use the TEXT() macro whenever you have a
    // string value that gets passed to a Windows
    // function.  Its good and makes life easier.
    WNDCLASS wc;
    wc.cbClsExtra = 0;  // ignore for now
    wc.cbWndExtra = 0;  // ignore for now
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );   // I want the window to have a white background
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );            // I want it to have an arrow for a cursor
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );        // I want it to have that envelope like icon
    wc.hInstance = hInstance;           // INSTANCE HANDLE -- see the GLOSSARY PART of this file for an explanation of what HINSTANCE is
    wc.lpfnWndProc = WndProc;           // Give name of WndProc function here.
    wc.lpszClassName = TEXT("Philip");  // I have named it Philip.
                                        // You could name it anything
                                        // you want, but you have to
                                        // remember the name for when
                                        // you call CreateWindow().
    wc.lpszMenuName = 0;    // no menu - ignore
    wc.style = CS_HREDRAW | CS_VREDRAW; // Redraw the window
    // on BOTH horizontal resizes (CS_HREDRAW) and
    // vertical resizes (CS_VREDRAW).  There are
    // many more window class styles!

    
    // B.  Register the WNDCLASS with Windows, THEN
    //     create the window.
    RegisterClass( &wc );   // This kind of "plants" the information
                            // about the Window we "dream"
                            // of creating somewhere inside the Windows O/S...
    
    // NOW, at this next stage, WE ACTUALLY CREATE
    // the window.  The previous lines of code
    // until this point have only been PREPARATION.

    // When we call the CreateWindow() function, we will
    // make a reference to this WNDCLASS structure (BY ITS
    // NAME -- "Philip"), and the Windows government
    // will grant us our wish and a REAL LIVE WINDOW,
    // with the properties that we specified in the
    // WNDCLASS structure!

    // NOTICE that the value that is returned from
    // CreateWindow is a variable of type HWND.

    // HWND is a "handle to a window" - its a programmatic
    // reference variable to the Window.
    // The HWND is OUR MEANS BY WHICH to manipulate
    // our Window.

    // Read the schpeal near the top of this file if
    // not sure about HANDLES.

    // Most of the time, you would want to save
    // this HWND into a global variable,
    // so you wouldn't lose it later.
    HWND hwnd = CreateWindow(
        TEXT("Philip"),         // THIS IS THE LINK
                                // to the WNDCLASS structure that
                                // we created earlier.

        TEXT("window's title!"),// appears in title of window

        WS_OVERLAPPEDWINDOW,    // STYLE of window.  WS_OVERLAPPEDWINDOW just means
                                // the window we create should have a few common features
                                // like a minimize box, a maximize box, and it should
                                // be resizeable by dragging the "thick frame" around
                                // the window. There are other styles
                                // and they all start with WS_.  Check it out in the
                                // autocomplete by typing WS_ THEN PRESSING CTRL+SPACE
                                // to make the autocomplete window come up.
        10, 10,                 // x, y start coordinates of window
        200, 200,               // width, height of window
        NULL, NULL,             // nothing and nothing (ignore to start out)
        hInstance, NULL );      // hInstance -- (see glossary), nothing

    // Next, SHOW and PAINT the window!
    // You won't see the window if you DO NOT
    // call ShowWindow();
    ShowWindow(hwnd, iCmdShow );
    UpdateWindow(hwnd);
    #pragma endregion

    #pragma region part 2 - ENTER A LOOP TO CONTINUALLY KEEP CHECKING WITH WIN O/S FOR USER INTERACTION
    // first, we create the MSG structure.
    MSG msg;
    // But WTF IS A MESSAGE???
    // A MESSAGE is something that the Windows O/S
    // SENDS your application program when
    // SOMETHING HAPPENS TO YOUR WINDOW.

    // Messages can be anything from "the user
    // has moved your window", to "the user
    // has clicked at pixel location (20, 20)" or,
    // "you need to paint yourself", or, 
    // "you have been maximized".

    // YOUR CHANCE to handle those "messages"
    // that get passed to your window comes
    // IN WNDPROC.
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        // GetMessage is a function that will not
        // return until the Windows O/S HAS A message
        // for our program.

        // Since the GetMessage() function call is
        // INSIDE the bracket for the while Loop,
        // this means that our program is essentially
        // "put on hold" or halted until the GetMessage function
        // returns.

        // If and when the user interacts with our
        // application's window, then the GetMessage()
        // function WILL return and the variable
        // msg will be filled with interesting details
        // about exactly what the user did to the window.

        TranslateMessage( &msg );   // translates 
        // the message so WndProc can process it
        // more easily.

        // Next we 'dispatch' the message, or
        // send it off to WndProc for processing.

        // Notice that there is NO EXPLICIT function
        // call to WndProc, but somehow in the bowels
        // of the Windows O/S, calling DispatchMessage
        // WILL result in a call to your WndProc function,
        // WITH the appropriate msg struct passed in
        // as well.
        
        DispatchMessage( &msg );    // this line RESULTS IN
        // a call to WndProc(), passing the message and
        // the HWND.


    }
    #pragma endregion

    return msg.wParam;    // return from WinMain
}

LRESULT CALLBACK WndProc(   HWND hwnd,      // "handle" to the window that this message is for
                            UINT message,   // TYPE of message (e.g. WM_PAINT is a message asking to paint the window)
                            WPARAM wparam,  // information about the actual message
                            LPARAM lparam ) // MORE info about the message
{
    // If WinMain was the heart of the Windows application, then
    // WndProc is the soul.

    // WndProc does just 1 thing:
    //    - Execute some bit of code in response
    //      to user interactions with our windows
    //      application.  

    // The tricky bit about WndProc is that NOWHERE IN THIS APP'S
    // CODE DO YOU EVER SEE ANY EXPLICIT FUNCTION CALLS
    // TO WndProc!!!  Does that mean WndProc never
    // gets used???

    // NO!!!  Take a look again, around where
    // we create the WNDCLASS.

    // Notice, how the WNDCLASS has lpfnWndProc = WndProc??
    // THAT is the reference to this function.

    // The WINDOWS O/S PERFORMS the function call to
    // WndProc when we call DispatchMessage().

    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_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;

        
    }

    // Now, try going into Visual Studio and
    // press WM_ then press CTRL + SPACE.

    // Or go to
    // http://msdn2.microsoft.com/en-us/library/ms632595.aspx

    // See that huge listing?  Those are ALL THE EVENTS
    // that Windows could possibly throw at our application.
    // WOW!  That's a lot of events.  WE don't want to 
    // have to write code for every single one of them!
    // But our WndProc gets called whenever ANY event
    // happens to our application.  What do we do with
    // the events we don't want to handle?
    
    // Simple.  We will pass the events we DON'T want
    // to handle to DefWindowProc().  DefWindowProc()
    // knows what to do with the events we don't want
    // to handle so that our application remains stable
    // and good.
    return DefWindowProc( hwnd, message, wparam, lparam );
}



/// GLOSSARY ///
// HINSTANCE:  "Handle" to an instance.  Every running INSTANCE
// of an application has a handle to it that is YOUR MEANS
// by which to manipulate, talk about, or refer to that specific
// application instance as it exists inside the Windows O/S.

// What's an instance again?  If you have 2 copies of the same programming running
// at the same time, then you are running 2 INSTANCES
// of the same program (2 copies of Microsoft Word, for example).
// Each INSTANCE of a program has its own INSTANCE HANDLE and
// hence its PID (ProcessID - unique integer identifier
// for each program that is currently running in the Windows O/S)
// and its own entry in the Window task manager.

// TRY THIS:  Press CTRL+ALT+DEL to bring up the Windows
// Task Manager.
    // Now switch to the PROCESSES tab.
    // Click the "IMAGE NAME" column, so that everything gets organized by name of the process.
    // Now, open NOTEPAD, 3 times.  You should have 3 Notepad windows open.
    // NOW, LOOK AT the Windows Task Manager.  Try to locate __3__ entries
    // that say NOTEPAD.EXE.  Open a fourth notepad.  Open a fifth notepad.
    // every instance of notepad you open gets its own entry in that table.

// Now HINSTANCE is exactly what it sounds like . . its a "handle"
// (a means by which to access or control) the INSTANCE of your
// program.
//
// The actual INSTANCE of your application lives inside the Windows O/S.
// But you have a HANDLE TO IT, and your HANDLE to it is your means
// by which to manipulate it, refer to it, change it, or delete it.

// HWND:  HANDLE TO A WINDOW.  This is exactly the same in CONCEPT as
//        the INSTANCE HANDLE, but now, this is a handle TO THE WINDOW ITSELF.
//        The HANDLE TO THE WINDOW is your means by which to change
//        manipulate, or refer to the window that belongs to your program.
//        A single INSTANCE of an application can have MULTIPLE window
//        handles associated with it.  THAT IS WHY when you CREATE A WINDOW,
//        using the CreateWindow() function, you MUST PASS the hInstance
//        parameter.  That is so that Windows knows which application
//        INSTANCE is attached to which WINDOW.
//
// HDC:  HANDLE TO A DEVICE CONTEXT.  Hmm.  I'm not going to explain this
//       in detail here, because we're not really using the HDC much
//       in this example.  Perhaps at a later time.


///////////////////////////
// THERE, ALL DONE - CLOSING NOTES.
// Everyone knows starting Windows Programming can be a bit hard.
// There are a few things I'd like to highlight here.
//
// Now you might be wondering, "ok, if WinMain is the application
// starting point, WHERE / WHEN / HOW does WinMain accept
// PARAMETERS?"
//
// To understand this, you must start to see your "Windows program"
// as really just a FUNCTION that Windows will call, when it is
// time to start up your application.
// 
// So where do the values of hInstance, hPrevInstance, szCmdLine
// and iCmdShow come from?
// These parameters are PASSED BY the Windows O/S AT APPLICATION START TIME.
// So all of hInstance, hPrevInstance (which is always passed as NULL)
// szCmdLine and iCmdShow are passed by the Windows O/S
// to your application.

////////////////////
// Understanding what szCmdLine is and does:
//
// Do me a favor.
// Open the Windows command prompt (go to START->Run,
// then type "cmd" in the box that appears there.)
//
// You should see a black console window, like the one that your basic console C++ 
// apps run in.  In the black window, type in:
//          explorer
// then press enter.

// What should happen is your windows file explorer should pop up.

// Now go back to the command prompt and type in
//          explorer "C:\Program Files"

// Notice now that the Windows disk explorer now opens in the folder "C:\Program Files"
// In the above example, "C:\Program Files" is a command line argument that modifies
// the behaviour of the disk explorer upon its launch.

// So the explorer.exe program is a Windows program.
// And szCmdLine WOULD BE WHERE YOU TAKE that extra string
// that is passed to the program at the time the program is
// launched.

// You won't necessarily use this at all in your programming!
// But, it is good to know.


// REFERENCES:
// If you want to know more about Windows Programming
// in this CLASSIC C++ way, then you should pick
// up a copy of Charles Petzold's "Programming Windows,
// 5th Edition"
// http://www.charlespetzold.com/pw5/
// On Amazon:  http://www.amazon.com/exec/obidos/ISBN=157231995X

// "The Petzold" is THE reference that all the game
// books out there (some of which are pretty good!)
// draw on when they write their Win32 chapter (its
// obvious from the way they've written them!)

// What's annoying is, a lot of the people who write
// those books though, never acknowledge Petzold or
// mention where they derived their Win32 understanding
// from.

// So, the Petzold is where I got my initial understanding
// anyway, and its really good.  Check it out
// from your library if you haven't the $.

// More refs:
// MSDN:  "About messages and message queues"
// http://msdn2.microsoft.com/en-us/library/ms644927(VS.85).aspx

////////////////
// MORE Closing notes:
// This is sometimes called "EVENT DRIVEN
// PROGRAMMING" -- the idea is that your
// program is entirely driven by EVENTS.
// If there are no events, then your
// Windows program DOES NOTHING.

// Note that this is NOT the case with GAMES!
// GAMES CAN'T WAIT!  Games must be fast.
// For games, you would use DirectInput,
// and things like that, and you WOULD NOT
// be WAITING for messages.  Instead,
// you want to be DIRECTLY listening
// at the keyboard and mouse for user 
// interaction with those DEVICES.


///////////////////
// You MIGHT HAVE been wondering about
// the apparent RETURN TYPE of WinMain and
// WndProc.

// Looking at those function prototypes, we have:

/*

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

*/

// For example, a question you might have might be:
// WHY is the return type of WinMain "int WINAPI"?
// That is so weird.

// The short answer, is ITS NOT!!

// The return type of WinMain is just INT.
// "WINAPI" IS NOT PART OF THE RETURN TYPE
// OF THE WinMain FUNCTION!

// The second word after the return type
// (WINAPI) is called the CALLING CONVENTION of
// the function.

// In case you're still interested, check out
// these links:
// http://support.microsoft.com/kb/100832
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_calling_conventions_topics.asp
// http://www.devnewz.com/devnewz-3-20050125UsingWin32CallingConventions.html

// A MSDN basic window example:
// http://msdn2.microsoft.com/en-us/library/aa383668(VS.85).aspx

// MSDN root page for a lot of windows stuff
// http://msdn2.microsoft.com/en-us/library/ms632586(VS.85).aspx

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

*/

Check out the Visual Studio project files [updated Feb 9 / 08] hosted by esnips! (Thanks esnips!)

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

HANDLES in Windows programming

HANDLES pop up EVERYWHERE in Windows programming. So I’m hoping to explain the idea behind a HANDLE intuitively, so that you have something to “hold onto” whenever you see use of HANDLES in program code.

Think about a POT of boiling water. Inside that pot is some corn on the cob being cooked.

Now, say you want to ACCESS the pot, so you can dump its contents out into the sink and drain the corn.

How do you do that? Do you GRAB THE POT DIRECTLY??? NO!! That would be stupid and your hand would burn. Instead, you grab the HANDLE TO THE POT. Using the HANDLE to the pot, you manipulate the pot, slowly dumping out the water and leaving the corn behind. Then you eat the corn and it is delicious.

Now, in programming, the idea of a HANDLE is much the same. In your program code, say you have a variable like:

HWND hwnd = CreateWindow( . . . ) ;

HWND is a “handle to a window”. A HANDLE to a WINDOW is __NOT__ the window itself inside the variable hwnd. Instead, it is a A REFERENCE TO the window itself. The window exists somewhere in the Windows O/S, and the idea is that you use the hwnd reference as a programmatic HANDLE that you have as YOUR MEANS TO MANIPULATE AND DEAL WITH that window.

Look at this code:

MoveWindow( hwnd, 50, 50, 200, 200, true ); // move the window referred to by
// hwnd, to x, y location (50, 50) and being 200×200 pixels in size.

With handles, you don’t have to deal with that hot pot directly (you wouldn’t know how to!) Instead, you use the Win API functions (like MoveWindow()) and PASS YOUR HANDLE TO YOUR WINDOW AS YOUR MEANS TO REFER TO AND MANIPULATE THAT WINDOW.

The same understanding applies to HINSTANCES, and any other type of handle. Remember, a HANDLE is YOUR MEANS TO MANIPULATE AND REFER TO the object in question.

Interesting and useful . .

In both C and C++, a struct is laid out flat in memory, just like an array is.

‘Course, this means that you can treat a struct as an array, without ever using a union.

The next example shows how.

#include <iostream>
using namespace std;

struct Vertex
{
    float x,y,z;
};

int main()
{
    Vertex v;
    v.x = 2.0f, v.y = 1.0f, v.z = 5.0f;
    
    // print each member of the struct
    printf( "v:  %f %f %f\n", v.x, v.y, v.z );

    // now treat as an array
    float * arr = &(v.x);    // get the address of v.x
    // since v is laid out flat in memory, just like an array
    // this will work out fine

    // struct Vertex laid out flat in memory, like
    // this, so accessing it as an array is no problem
    // ___________________
    // |     |     |     |
    // | 2.0 | 1.0 | 5.0 |
    // |_____|_____|_____|
    //    x     y     z

    for( int i = 0; i < 3; i++ )
    {
        printf( "v[%d]:  %f\n", i, arr[i] );
    }
}

Incidently, this is the same way you would access a C++ STL vector’s internals as a regular C++ array.

Something like:

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

int main()
{
    vector<int> v;
    v.push_back( 2 );
    v.push_back( 5 );
    v.push_back( 7 );

    // now normally, you may think
    // its fine to just go through
    // the elements of v like this:
    printf("Using [] operator on v:\n");
    for( int i = 0; i < v.size(); i++ )
    {
        printf("v[%d]:  %d\n", i, v[i] );
    }
    
    // And it IS fine, mostly.

    // However, sometimes you're working with a 
    // C API that wants a REGULAR int * pointer
    // to an array, and won't accept an STL
    // vector.

    // What's one to do?  Stop using STL vectors??
    // No!! :).

    // You can get a regular (type *) C-style array
    // pointer to the internals of any STL vector:

    int * internalsPointer = &v[0];

    int length = v.size();
    printf("\n\nUsing internalsPointer\n");
    for( int i = 0; i < length; i++ )
    {
        printf("v[%d]:  %d\n", i, internalsPointer[i] );
    }

    // Its good if you need to pass the
    // vector's internals to a function that wants
    // a C-style array (e.g. OpenGL's vertex
    // array funcs).
}


Error 1 error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup MSVCRTD.lib

This happens if you’re compile/run a Windows app that has a WinMain function, but you chose “Console Application” INSTEAD of
“Windows Application” when you were creating the new project.

You fix this by right clicking on your PROJECT name, then picking the PROPERTIES dialog:
Project Property pages

Then change the subsystem to WINDOWS:
unresolved.gif


NEXT TIME,

to prevent that from happening, make sure you pick WINDOWS APPLICATION at the point where Visual Studio asks you whether you want a console app or a windows app!:

basicwindowsprog1.gif

basicwindowsprog2.gif

Note that there IS a huge difference between d3dx9.lib and d3d9.lib.

Getting error LNK2019: unresolved external symbol _D3DXVec3Normalize@8 referenced in function?

Do this

  1. In visual studio 2005, Go to TOOLS->OPTIONS.

    In that window that comes up, in the left hand side of the window, pick “PROJECTS AND SOLUTIONS” -> VC++ DIRECTORIES from the tree.

    d3d linker error fix

    ALSO do this:
    d3d include

  2. In every code file, include a line at the top that says:

    #pragma comment(lib, "d3dx9.lib")   // d3dx9.lib contains actual code for D3DX functions (like D3DXVec3Normalize)
    

Why?

Although d3dx9.h contains the function prototypes and signatures for the D3DX functions, it DOES NOT contain the actual implementation code.

The implementation code is provided IN “d3dx9.lib” which is why you have to LINK it to the executable at compile time.

Understanding va_list

Writing your own function that uses a va_list is really easy!

But first, let’s identify what a va_list is.

Think about the printf() C function.

printf(“Hello there! I like the numbers %d, %d and %d\n\n\n”, 1, 3, 7);

Obviously the output of that function call would be:

Hello there! I like the numbers 1, 3 and 7

But the key point here is, the printf() function can accept a VARYING NUMBER OF ARGUMENTS. That’s because it uses a va_list.

If you look at the signature for printf(), it looks like this:

int printf( char * format, … );

So the argument list for printf() has 2 main things:

  1. char * format – a regular string
  2. and a second special argument, … (3 dots, just like that)
  3. … is called an “ellipsis”, and it means, in plain English: “any number of optional arguments can go here.”

    So somehow, in the innermost bowels of printf(), is some sticky code that somehow retrieves each one of the the list of args you’re passing in, in the place of the “…”.

    Cool! So is it possible for us to write our functions that have their own sticky code that can process a set of VARIABLE ARGUMENTS???

    YES YOU CAN. And its actually simple!

    An example:

    #include <stdio.h>
    #include <stdarg.h>
    
    int addThemAll( int numargs, ... )
    {
        // So this function can accept a variable number
        // of arguments.  No (practically speaking) limits.
    
        // RULES you must know in order to be able to use "..." in one of your
        // own functions:
        //
        // 1)  The ... MUST appear exactly as ... 
        // It cannot be "..." (with the quotes),
        //     '...', or anything else weird.
        //
        // 2)  The ... __MUST GO LAST__ IN THE ARGUMENT LIST
        //
        // 3)  THERE MUST BE AT LEAST ONE MANDATORY, NON-OPTIONAL ARGUMENT,
        //     THAT COMES BEFORE THE ...
    
        // We'll be using these macros here:
    /*
         va_list    va_start    va_end    va_arg
    */
    
        // All of the above va_* things are actually special MACROS,
        // exclusively defined for us to use when working with
        // _V_ariable _A_rgument lists.
        
        // FIRST, we create a POINTER that will be used
        // to point to the first element of the VARIABLE
        // ARGUMENT LIST.
        va_list listPointer;
    
        // Currently, listPointer is UNINITIALIZED, however,
        // SO, now we make listPointer point to
        // the first argument in the list
        va_start( listPointer, numargs );
    
        // Notice that numargs is the LAST MANDATORY ARGUMENT
        // that the addThemAll() function takes.
        // By "LAST MANDATORY ARGUMENT", I mean 'numargs'
        // is the last argument to the addThemAll() function
        // JUST BEFORE the "..."
    
        // NEXT, we're going to start to actually retrieve
        // the values from the va_list itself.
        // THERE IS A CATCH HERE.  YOU MUST KNOW THE
        // DATA TYPE OF THE DATA YOU ARE RETRIEVING
        // FROM THE va_list.  In this example, I'm assuming
        // they're all ints, but you could always pass a format
        // string that lets you know the types.
    
        int sum = 0;
        for( int i = 0 ; i < numargs; i++ )
        {
            // GET an arg.  YOU MUST KNOW
            // THE TYPE OF THE ARG TO RETRIEVE
            // IT FROM THE va_list.
            int arg = va_arg( listPointer, int );
    
            printf( "    The %dth arg is %d\n", i, arg );
    
            sum += arg;
        }
        
        printf("--");
        printf("END OF ARGUMENT LIST\n\n");
        
        // FINALLY, we clean up by saying
        // va_end().  Don't forget to do this
        // BEFORE the addThemAll() function returns!
        va_end( listPointer );
    
        printf("The total sum was %d\n\n", sum);
    
        return sum;
    }
    
    int main()
    {
        // Try it out.
    
        printf("Calling 'addThemAll( 3, 104, 29, 46 );' . . .\n");
        addThemAll( 3, 104, 29, 46 );
    
        printf("Calling 'addThemAll( 8,   1, 2, 3, 4, 5, 6, 7, 8 );' . . .\n");
        addThemAll( 8,   1, 2, 3, 4, 5, 6, 7, 8 );
    
        return 0;
    }
    
    

    Download Visual Studio project files.

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

No, its not a joke!

Open Inventor

What’s the difference between a STRUCT and a UNION in C++?

Here’s an example!

A C++ struct will make sure to allocate space for each and every member in the struct.

For instance, if we had


struct VertexStruct
{
    float x,y,z;
};

When you create one, using a line of code like:

VertexStruct vertexstruct;

This is what VertexStruct object will look like in memory.


     vertexstruct
 ___________________
 |     |     |     |
 |     |     |     |
 |_____|_____|_____|
    x     y     z

So if we do


vertexstruct.x = 50;
vertexstruct.y = 10;
vertexstruct.z = 2;

We get this picture in memory:


     vertexstruct
 ___________________
 |     |     |     |
 | 50  | 10  |  2  |
 |_____|_____|_____|
    x     y     z

This is natural and completely what you’d expect.

Contrast STRUCT vs UNION

Now, CONTRAST THAT with a UNION. A UNION uses the SAME EXACT PIECE OF MEMORY for __ALL__ of the members inside of it.

This is kind of counter-intuitive and weird.

An example:


union VertexUnion
{
    float x,y,z;
};

When you create one, using a line of code like:

VertexUnion vertexunion;

You get this picture in memory:


 vertexunion
 _______
 |     |
 |     |
 |_____|
    x    
    y
    z

The above union effectively provides 3 ways by which to access that same single piece of memory (x, y and z).

So if you wrote code like:


vertexunion.x = 10;
vertexunion.y = 2;
vertexunion.z = 5;

You get this picture in memory:


 vertexunion
 _______
 |     |
 |  5  |
 |_____|
    x    
    y
    z

(Last x, y and z all refer to the same piece of memory. Since the last value assigned there is 5, ALL OF x, y and z have the exact same value).

WEIRD!

* Note that the sizeof( any_union ) ends up being the sizeof( largest_member_in_union ).

Download the Visual Studio 2005 project files quick demo.

Demo is hosted by esnips! (they’re awesome!)

I didn’t know that

very cool

Russell Smith says:

rigid body sim defs

Also looking at: natural motion.

There’s tons of information out there on physics programming.

Some of the sites I’ve now bookmarked:

Chris Hecker of MSFT
Erin Catto of Blizzard

In particular, I really liked the talk on Advanced Prototyping, which was delivered by CHecker and another bloke called Chaim Gingold. Great stuff.

Some more random stuff:
bokmann’s blog – but a mere software engineer
gsl

Also in News, I have found the home of the great and powerful John Miles, creator of the Miles Sound System.

EDIT: don’t listen to me

“Even if our application is throttled to a specific frame rate through a timer, the actual time between frames will vary.”

Assume I have the player’s position, velocity and acceleration in 3 vectors:

pos
vel
accel

– Player controls the acceleration vector though the keyboard.

– Game calcs velocity of character in next frame based on acceleration vector.

vel = accel * (time_passed_since_last_frame);
pos = vel * (time_passed_since_last_frame);

Or, more accurately

pos += vel * time_passed_since_last_frame + accel * time_passed_since_last_frame * time_passed_since_last_frame * 0.5f;
vel += accel * time_passed_since_last_frame;

So those are just
d = v1t + 0.5*at2
v = a * t

This works OK for moving the player around on the map, as long as frame rate is CONSTANT.

But what if a frame takes longer than usual to calculate?

Then (time_passed_since_last_frame) is TOO LARGE.

Motion becomes jerky, blocky. Player can move really far in just one frame, if that frame took particularly long to crunch out. So, this means that a collision can be missed!

Also it is a major problem when it comes to things like JUMPING.

The way I had it before, was when the player jumps by pressing the space bar, the player gets a force applied to him in the upwards direction for exactly 5 frames.

accel = (x, 1, z);

Since the amount of time that it takes to crunch out each frame varies, the player would jump different heights, depending on when / where the player was when he pressed the spacebar.

This was a problem. Was this acceptable? Did it happen in other games? I studied Quake III in action to see if the player jump height deviated at all. Not even by a pixel. Plus when you think about games like Warcraft 3 (that can run a replay out EXACTLY the same way, every time) there’s no room for this kind of error.

The player should jump exactly the same height (in game units) no matter when or where he jumps. Clearly not acceptable.

The only solution I can think of to this problem now is to treat “time” like a sort of “fuel” for the jump action.

When the player presses space bar, don’t measure the amount of “time” to apply the jump for in frames, but measure it in “seconds”.

When first jump:

player_jump_fuel = 1.0;

On every compute of player position:

if( player_jump_fuel - time_passed_since_last_frame < 0 )
{
    // overshot jump fuel.  e.g. frame took 0.1 seconds to compute, but only 0.07 seconds of jump fuel remain.
    // compute jump velocity using player_jump_fuel and NOT time_passed_since_last_frame
}

For a while, I was thinking the only solution is to NOT use time-based motion and the high performance timer. Instead, one should just decide that a “frame” represents 0.0166666666666666667 seconds (1/60 seconds) and compute next positions based on that.

And that’s actually a good solution when you think about it.

Using only the ‘virtual second’ if you wanted to slow the whole game down, all you have to do is set a global to make that “frame” represent 0.0111111111111111 seconds

So my conclusion (for now) is that using “real-time” offers absolutely no benefits while at the same time introducing a possibility of error.

If you can have perfect precision at no cost, why should you throw that to the wind?