Skip navigation

Tag Archives: win32

Its not hard

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

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

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

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


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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

    }
    break ;

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

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

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

  }

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


/////////////////////////////////////////////////////////////////
// AddingATimer.cpp                                            //
// Shows how to add a timer that causes Windows to pass us
// a WM_TIMER message every few seconds.
/////////////////////////////////////////////////////////////////
// USING THE WINDOWS TIMER:
// DEFINE some constants for the timers.
#define TIMER_SECOND 1		// first timer identified by integer 1
#define TIMER_MINUTE 2		// second timer identified by integer 2
// we will use these constants when we first create the timers,
// then Windows will use these numbers to notify us when each
// timer event has occurred.

#include <windows.h>



// Prototype for WndProc function
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM );

/////////////////////////////////////////////////////////////////
// WinMain:  Application entry point for Windows applications. //
//                                                             //
// Just as said every C++ program starts at main,              //
// every Windows program will start at WinMain.                //
/////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPSTR lpCmdLine, int nShowCmd )
{
  // String used to identify our application
  TCHAR applicationClassName[] = TEXT("FirstWindowApp");

#pragma region -_1.  CREATE THE WNDCLASSEX STRUCTURE/OBJECT_-
  WNDCLASSEX window;		// Look at members of this struct.
  // Below, we initialize all of them.

  window.cbClsExtra		= 0;						// extra bytes
  window.cbSize			= sizeof(WNDCLASSEX);		// keeps track of its own size
  window.cbWndExtra		= 0;						// extra bytes
  window.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
  window.hCursor			= LoadCursor(NULL, IDC_HAND);	// load hand cursor
  //Tip:  type in IDC_ then press CTRL+SPACE to get a list of avail. cursors

  window.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	// large icon
  window.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);	// small icon that shows up in top left of window
  window.hInstance		= hInstance;				// program's instance handle that was first passed to WinMain by windows when program was first run
  window.lpfnWndProc		= WndProc;					// function pointer to WndProc function
  window.lpszClassName	= applicationClassName;		// window class name.. defined above
  window.lpszMenuName		= NULL;						// main menu
  window.style			= CS_OWNDC | CS_HREDRAW | CS_VREDRAW;	// redraw on horizontal or vertical resize
#pragma endregion

#pragma region -_2.  REGISTER THAT WNDCLASSEX STRUCTURE WITH WINDOWS O/S + CREATE WINDOW_-
  if(!RegisterClassEx( &window ))
  {
    MessageBox(NULL, TEXT("Something's wrong.. quitting"), TEXT("error"), MB_OK);
    return 1;		// return from WinMain.. i.e. quit
  }

  // CREATE THE WINDOW AND KEEP THE HANDLE TO IT.
  HWND		hwnd;			// declare a handle to a window
  hwnd = CreateWindowExW(	WS_EX_TOPMOST,			// extended window style.. this sets the window to being always on top
    applicationClassName,	// window class name.. defined above
    TEXT("WINDOW TITLE"),	// title bar of window
    WS_OVERLAPPEDWINDOW,	// window style
    CW_USEDEFAULT, 40,		// initial x, y start position of window
    // CW_USEDEFAULT means "let Windows choose it"

    400, 160,				// initial width, height of window
    NULL, NULL,				// parent window, window menu
    hInstance, NULL);		// program instance handle, creation params

  // now we show and paint our window, so it appears
  ShowWindow(hwnd, nShowCmd );		// you have to ask that your Window be shown to see it
  UpdateWindow(hwnd);					// paint the window

#pragma endregion

#pragma region -_3.  MESSAGE LOOP_-

  MSG			msg;
  // this is the struct that holds the message
  // msg.hwnd - handle to the window to whom the message is for
  // msg.message - type of message for the window (mouse click, key press, key up, etc)
  // msg.lParam - a parameter that contains data.  the data it contains DEPENDS ON THE MESSAGE!!
  // msg.wParam - a parameter that contains data.  the data it contains DEPENDS ON THE MESSAGE!!
  // msg.time - the time the message was created
  // msg.pt - cursor position in screen coordinates when message was posted

  // enter the message loop
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);	
    DispatchMessage(&msg);	// send off to WndProc for processing
  }
#pragma endregion

  return 0;	// end program once we exit the message loop
}

////////////////////////////////////////////////////////////////////////
// WndProc - "Window procedure" function -- this function gets called
// by Windows whenever there is a "message" available for
// your window.
// A "message" is available for your window whenever something "happens"
// to it -- i.e. the user clicks on it, or the user types a key when your
// window has "input focus"
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  HDC			hdc;
  PAINTSTRUCT	ps;
  RECT		rect;

  // this switch looks at the message that was passed to the WndProc function.
  // There are tons of possible messages..
  // WM_CREATE:	// message passed to WndProc when the window is first created
  // WM_PAINT:	// message passed when there is a request from O/S to paint window
  // WM_KEYDOWN:	// message passed when a key is being pressed down.. see MSDN for more

  // Generally, all messages to the window will start with WM_
  switch(message)
  {
  case WM_CREATE:			// WndProc gets sent the WM_CREATE message when
    {					// the window is first created

      // (if you don't have the 8254 chip (lots of modern pc's don't!))
      MessageBeep( 1 ) ;

      // upon creation, beep 3 times @ 500Hz
      //Beep( 500, 10 );
      //Beep( 500, 10 );
      //Beep( 500, 10 );


      // Upon window creation, we want to initialize the timers:
      SetTimer( hwnd, TIMER_SECOND, 1000, NULL );
      SetTimer( hwnd, TIMER_MINUTE, 60000, NULL );
      return 0;		// return from WndProc
    }
    break;

  case WM_PAINT:
    {
      // if the message was "paint the window", just draw the text "This is my window..."
      hdc = BeginPaint(hwnd, &ps);		// hdc is a "handle to a device context"
      GetClientRect(hwnd, &rect);			// the "client rectangle" is the window area but
      // EXCLUDING the title bar and borders
      DrawText(hdc, TEXT("This is my window..."), -1, &rect, DT_SINGLELINE | DT_BOTTOM | DT_VCENTER );
      EndPaint(hwnd, &ps);
      return 0;
    }
    break;

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

    // +++ new.
  case WM_TIMER:
    {
      switch(wParam)
      {
      case TIMER_SECOND:
        //Beep(200, 20);		// just tick every time the WM_TIMER message is passed
        MessageBeep( 1 ) ;
        break;
      case TIMER_MINUTE:
        //Beep(700, 100);		// beep higher every minute
        MessageBeep( 1 ) ;
      }
      return 0;
    }
    break;

  }

  // If message was NOT handled by us, we pass it off to
  // the windows operating system to handle it.
  return DefWindowProc(hwnd, message, wParam, lParam);
}




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


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

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

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

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

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

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

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

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

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

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

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

    int width, height;
  } win ;

  IDirect3D9 * d3d ;
  IDirect3DDevice9 * gpu ; 
};

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

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

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


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

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

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

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

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

    return false ;
  }

  else
    return true ;
}

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

  g.d3d = Direct3DCreate9( D3D_SDK_VERSION ) ;

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

  puts( "Direct3D9 creation success!" ) ;

  D3DPRESENT_PARAMETERS pps = { 0 } ;

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

  HRESULT hr = g.d3d->CreateDevice(

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

  ) ;

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

  puts( "Direct3D9 GPU device creation successful" ) ;


  #pragma region setup interleaved arrays
  D3DVERTEXELEMENT9 pos ;

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

  pos.Method = D3DDECLMETHOD_DEFAULT ; 

  D3DVERTEXELEMENT9 col;

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

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

  IDirect3DVertexDeclaration9 * Vdecl ;

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

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

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

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

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

  initRawinput( g.win.hwnd ) ;

  return true ;
}

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

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

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

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

void update()
{
}

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

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

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

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

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

  } ;

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

  static float pointSize = 8.0f ;

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

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

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

}

void draw()
{
  HRESULT hr ;

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

  #pragma region set up the camera
  D3DXMATRIX projx ;

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

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

  D3DXMATRIX viewx ;

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

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


  drawAxes();


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

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  #pragma endregion

  #pragma region message loop
  MSG msg;

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

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

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

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

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

  return msg.wParam;
}

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

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

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



  case WM_INPUT: 
    {
      UINT dwSize;

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

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

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

      RAWINPUT* raw = (RAWINPUT*)lpb;

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

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

      delete[] lpb; 
      return 0;
    } 

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

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

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

So, you’re trying to make an MFC app?

Just to show you how simple it CAN BE, here’s one:

#include <afxwin.h>

class App : public CWinApp
{
public:
  BOOL InitInstance() override 
  {
    this->m_pMainWnd = new CFrameWnd() ;
    ((CFrameWnd*)this->m_pMainWnd)->Create( NULL, TEXT("MFC example!" ) ) ;
    this->m_pMainWnd->ShowWindow( TRUE ) ;

    return TRUE ;
  }
};

App app ;

BEFORE COMPILING, YOU MUST DO THIS in the project’s property page (right click your project name in the “Solution Explorer” and select “Properties”)

! OK. Finally

Download the esnips code package to get green_man.ico!

/////////////////////////////////////////////
//                                         //
// Minimizing C++ Win32 App To System Tray //
//                                         //
// You found this at bobobobo's weblog,    //
// https://bobobobo.wordpress.com           //
//                                         //
// Creation date:  Mar 30/09               //
// Last modified:  Mar 30/09               //
//                                         //
/////////////////////////////////////////////

// GIVING CREDIT WHERE CREDIT IS DUE!!
// Thanks ubergeek!  http://www.gidforums.com/t-5815.html

#pragma region include and define
#include <windows.h>
#include <shellapi.h>
#include <stdio.h>

#ifdef UNICODE
#define stringcopy wcscpy
#else
#define stringcopy strcpy
#endif

#define ID_TRAY_APP_ICON                5000
#define ID_TRAY_EXIT_CONTEXT_MENU_ITEM  3000
#define WM_TRAYICON ( WM_USER + 1 )
#pragma endregion

#pragma region constants and globals
UINT WM_TASKBARCREATED = 0 ;

HWND g_hwnd ;
HMENU g_menu ;

NOTIFYICONDATA g_notifyIconData ;
#pragma endregion


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);



#pragma region helper funcs
// These next 2 functions are the STARS of this example.
// They perform the "minimization" function and "restore"
// functions for our window.  Notice how when you "minimize"
// the app, it doesn't really "minimize" at all.  Instead,
// you simply HIDE the window, so it doesn't display, and
// at the same time, stick in a little icon in the system tray,
// so the user can still access the application.
void Minimize()
{
  // add the icon to the system tray
  Shell_NotifyIcon(NIM_ADD, &g_notifyIconData);

  // ..and hide the main window
  ShowWindow(g_hwnd, SW_HIDE);
}

// Basically bring back the window (SHOW IT again)
// and remove the little icon in the system tray.
void Restore()
{
  // Remove the icon from the system tray
  Shell_NotifyIcon(NIM_DELETE, &g_notifyIconData);

  // ..and show the window
  ShowWindow(g_hwnd, SW_SHOW);
}

// Initialize the NOTIFYICONDATA structure.
// See MSDN docs http://msdn.microsoft.com/en-us/library/bb773352(VS.85).aspx
// for details on the NOTIFYICONDATA structure.
void InitNotifyIconData()
{
  memset( &g_notifyIconData, 0, sizeof( NOTIFYICONDATA ) ) ;
  
  g_notifyIconData.cbSize = sizeof(NOTIFYICONDATA);
  
  /////
  // Tie the NOTIFYICONDATA struct to our
  // global HWND (that will have been initialized
  // before calling this function)
  g_notifyIconData.hWnd = g_hwnd;
  // Now GIVE the NOTIFYICON.. the thing that
  // will sit in the system tray, an ID.
  g_notifyIconData.uID = ID_TRAY_APP_ICON;
  // The COMBINATION of HWND and uID form
  // a UNIQUE identifier for EACH ITEM in the
  // system tray.  Windows knows which application
  // each icon in the system tray belongs to
  // by the HWND parameter.
  /////
  
  /////
  // Set up flags.
  g_notifyIconData.uFlags = NIF_ICON | // promise that the hIcon member WILL BE A VALID ICON!!
    NIF_MESSAGE | // when someone clicks on the system tray icon,
    // we want a WM_ type message to be sent to our WNDPROC
    NIF_TIP;      // we're gonna provide a tooltip as well, son.

  g_notifyIconData.uCallbackMessage = WM_TRAYICON; //this message must be handled in hwnd's window procedure. more info below.
  
  // Load da icon.  Be sure to include an icon "green_man.ico" .. get one
  // from the internet if you don't have an icon
  g_notifyIconData.hIcon = (HICON)LoadImage( NULL, TEXT("green_man.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE  ) ;

  // set the tooltip text.  must be LESS THAN 64 chars
  stringcopy(g_notifyIconData.szTip, TEXT("Green man.. here's looking at ya!"));
}
#pragma endregion

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int iCmdShow )
{
  TCHAR className[] = TEXT( "tray icon class" );

  // I want to be notified when windows explorer
  // crashes and re-launches the taskbar.  the WM_TASKBARCREATED
  // event will be sent to my WndProc() AUTOMATICALLY whenever
  // explorer.exe starts up and fires up the taskbar again.
  // So its great, because now, even if explorer crashes,
  // I have a way to re-add my system tray icon in case
  // the app is already in the "minimized" (hidden) state.
  // if we did not do this an explorer crashed, the application
  // would remain inaccessible!!
  WM_TASKBARCREATED = RegisterWindowMessageA("TaskbarCreated") ;

  #pragma region add a console
  // add a console, because I love consoles.
  // To disconnect the console, just comment out
  // the next 3 lines of code.
  //// AllocConsole();
  //// AttachConsole( GetCurrentProcessId() ) ;
  //// freopen( "CON", "w", stdout ) ;
  #pragma endregion
  
  #pragma region get window up
  WNDCLASSEX wnd = { 0 };

  wnd.hInstance = hInstance;
  wnd.lpszClassName = className;
  wnd.lpfnWndProc = WndProc;
  wnd.style = CS_HREDRAW | CS_VREDRAW ;
  wnd.cbSize = sizeof (WNDCLASSEX);

  wnd.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wnd.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wnd.hCursor = LoadCursor (NULL, IDC_ARROW);
  wnd.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE ;
  
  if (!RegisterClassEx(&wnd))
  {
    FatalAppExit( 0, TEXT("Couldn't register window class!") );
  }
  
  g_hwnd = CreateWindowEx (
    
    0, className,
    
    TEXT( "Using the system tray" ),
    WS_OVERLAPPEDWINDOW,
    
    CW_USEDEFAULT, CW_USEDEFAULT, 
    400, 400, 

    NULL, NULL, 
    hInstance, NULL
  );

  // Add the label with instruction text
  CreateWindow( TEXT("static"), TEXT("right click the system tray icon to close"), WS_CHILD | WS_VISIBLE | SS_CENTER,
                  0, 0, 400, 400, g_hwnd, 0, hInstance, NULL ) ;
  
  // Initialize the NOTIFYICONDATA structure once
  InitNotifyIconData();


  ShowWindow (g_hwnd, iCmdShow);
  #pragma endregion

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


  // Once you get the quit message, before exiting the app,
  // clean up and remove the tray icon
  if( !IsWindowVisible( g_hwnd ) )
  {
    Shell_NotifyIcon(NIM_DELETE, &g_notifyIconData);
  }

  return msg.wParam;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  if ( message==WM_TASKBARCREATED && !IsWindowVisible( g_hwnd ) )
  {
    Minimize();
    return 0;
  }

  switch (message)
  {
  case WM_CREATE:

    // create the menu once.
    // oddly, you don't seem to have to explicitly attach
    // the menu to the HWND at all.  This seems so ODD.
    g_menu = CreatePopupMenu();

    AppendMenu(g_menu, MF_STRING, ID_TRAY_EXIT_CONTEXT_MENU_ITEM,  TEXT( "Exit" ) );

    break;
  
  case WM_SYSCOMMAND:
    switch( wParam & 0xfff0 )  // (filter out reserved lower 4 bits:  see msdn remarks http://msdn.microsoft.com/en-us/library/ms646360(VS.85).aspx)
    {
    case SC_MINIMIZE:
    case SC_CLOSE:  // redundant to WM_CLOSE, it appears
      Minimize() ; 
      return 0 ;
      break;
    }
    break;


  // Our user defined WM_TRAYICON message.
  // We made this message up, and we told
  // 
  case WM_TRAYICON:
    {
      printf( "Tray icon notification, from %d\n", wParam ) ;
      
      switch(wParam)
      {
      case ID_TRAY_APP_ICON:
        printf( "Its the ID_TRAY_APP_ICON.. one app can have several tray icons, ya know..\n" ) ;
        break;
      }

      // the mouse button has been released.
      
      // I'd LIKE TO do this on WM_LBUTTONDOWN, it makes
      // for a more responsive-feeling app but actually
      // the guy who made the original post is right.
      // Most apps DO respond to WM_LBUTTONUP, so if you
      // restore your window on WM_LBUTTONDOWN, then some
      // other icon will scroll in under your mouse so when
      // the user releases the mouse, THAT OTHER ICON will
      // get the WM_LBUTTONUP command and that's quite annoying.
      if (lParam == WM_LBUTTONUP)
      {
        printf( "You have restored me!\n" ) ;
        Restore();
      }
      else if (lParam == WM_RBUTTONDOWN) // I'm using WM_RBUTTONDOWN here because
      {
        printf( "Mmm.  Let's get contextual.  I'm showing you my context menu.\n" ) ;
        // it gives the app a more responsive feel.  Some apps
        // DO use this trick as well.  Right clicks won't make
        // the icon disappear, so you don't get any annoying behavior
        // with this (try it out!)

        // Get current mouse position.
        POINT curPoint ;
        GetCursorPos( &curPoint ) ;
        
        // should SetForegroundWindow according
        // to original poster so the popup shows on top
        SetForegroundWindow(hwnd); 

        
        
        // TrackPopupMenu blocks the app until TrackPopupMenu returns
        printf("calling track\n");
        UINT clicked = TrackPopupMenu(
          
          g_menu,
          TPM_RETURNCMD | TPM_NONOTIFY, // don't send me WM_COMMAND messages about this window, instead return the identifier of the clicked menu item
          curPoint.x,
          curPoint.y,
          0,
          hwnd,
          NULL

        );
        printf("returned from call to track\n");


        // Original poster's line of code.  Haven't deleted it,
        // but haven't seen a need for it.
        //SendMessage(hwnd, WM_NULL, 0, 0); // send benign message to window to make sure the menu goes away.
        if (clicked == ID_TRAY_EXIT_CONTEXT_MENU_ITEM)
        {
          // quit the application.
          printf("I have posted the quit message, biatch\n");
          PostQuitMessage( 0 ) ;
        }
      }
    }
    break;

  // intercept the hittest message.. making full body of
  // window draggable.
  case WM_NCHITTEST:
  {
    // http://www.catch22.net/tuts/tips
    // this tests if you're on the non client area hit test
    UINT uHitTest = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
    if(uHitTest == HTCLIENT)
      return HTCAPTION;
    else
      return uHitTest;
  }

  case WM_CLOSE:
    printf( "Got an actual WM_CLOSE Message!  Woo hoo!\n" ) ;
    Minimize() ;
    return 0;
    break;

  case WM_DESTROY:
    printf( "DESTROY!!\n" ) ;
    PostQuitMessage (0);
    break;

  }

  return DefWindowProc( hwnd, message, wParam, lParam ) ;
}



Download esnips code package (thanks esnips! :)

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

This example just shows how to use DevIL to open, create, and save an image

Great tutorial here too

Pretty neat.

#undef _UNICODE

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

#include <windows.h>


#include "il.h"
#include "ilu.h"  // for image creation and manipulation funcs.

#pragma comment( lib, "DevIL.lib" )
#pragma comment( lib, "ILU.lib" ) 

// Wow. DevIL is amazing.

// From http://gpwiki.org/index.php/DevIL:Tutorials:Basics

// The library consists of three sub-libraries:
//  * IL - main DevIL library. It allows you to load and save images to files. Every function in this library have 'il' prefixed to their name.
//  * ILU - this library contains functions for altering images. Every function in this library have 'ilu' prefixed to their name.
//  * ILUT - this library connects DevIL with OpenGL. Every function in this library have 'ilut' prefixed to their name. 

int main()
{
  ilInit();
  printf("DevIL has been initialized\n");
  
  // Loading an image
  ILboolean result = ilLoadImage( "4px.png" ) ;

  if( result == true )
  {
    printf("the image loaded successfully\n");
  }
  else
  {
    printf("The image failed to load\n" ) ;
    
    ILenum err = ilGetError() ;
    printf( "the error %d\n", err );
    printf( "string is %s\n", ilGetString( err ) );
  }

  int size = ilGetInteger( IL_IMAGE_SIZE_OF_DATA ) ;
  printf("Data size:  %d\n", size );
  ILubyte * bytes = ilGetData() ;

  for( int i = 0 ; i < size; i++ )
  {
    // see we should see the byte data of the image now.
    printf( "%d\n", bytes[ i ] );
  }


  // Other info.
  int bpp = ilGetInteger( IL_IMAGE_BITS_PER_PIXEL ) ;
  
  printf("bpp: %d   IL_IMAGE_FORMAT: %d\n",
    
    bpp,
    ilGetInteger( IL_IMAGE_FORMAT )
    
  ) ;


  ilClearColour( 0, 255, 0, 255 ) ;




  // generate image data as just array of bytes.

  // get width and height of your desktop
  int width  = GetSystemMetrics( SM_CXVIRTUALSCREEN ) ;
  int height = GetSystemMetrics( SM_CYVIRTUALSCREEN ) ;

  int bytesToUsePerPixel = 3 ;  // RGB
  // we coulda used 4, if we wanted a "transparency" component,
  // but we don't want this png to use trans.

  // duh, the size of a byte is obviously ONE BYTE,
  // but this is just a formality to PERHAPS
  // make the code a bit more clear.
  int sizeOfByte = sizeof( unsigned char ) ;

  // So this computation gets the size
  // that the image data array should be.
  // (width*height)   *   (#bytes to use per pixel) really.
  int theSize = width * height * sizeOfByte * bytesToUsePerPixel ;

  unsigned char * imData =(unsigned char*)malloc( theSize ) ;

  for( int i = 0 ; i < theSize ; i++ )
  {
    imData[ i ] = i % 255 ;
  }
  
  
  // Let's make an image now.
  // the next line "generates an image" within the
  // DevIL STATE MACHINE.

  // DevIL is cool because it has this concept of
  // your "currently selected image".

  // So, when you call all the DevIL library functions,
  // (such as ilTexImage to change an images properties),
  // notice how there's no passing of any big data struct,
  // pointer to an image, or anything like that.
  
  // That's because the ONLY reference YOU get
  // as the user of the OpenIL API IS this INT
  // value:
  ILuint imageID = ilGenImage() ;

  // there.  We just created a NEW image (which will start out
  // to being 1x1 pixels or something like that)
  // our REFERENCE to this 1x1 pixel image IS
  // the integer number imageID.

  // NOW, we "select-in" the image we just generated
  // as the one we're currently working on.
  ilBindImage( imageID ) ;

  // From HENCE FORTH (until we call ilBindImage() again)
  // WE ARE WORKING ON "imageID".  ANY calls to
  // ilTexImage, or ilGetInteger, or WHATEVER are in
  // reference to the LAST IMAGE WE LAST BOUND.

  // So the new image we just created is rather.. empty.
  printf("New image!  width=%d,  height=%d,  bpp=%d\n",

    ilGetInteger( IL_IMAGE_WIDTH ),
    ilGetInteger( IL_IMAGE_HEIGHT ),
    ilGetInteger( IL_IMAGE_BPP )
    );

  printf("About to tex up your image\n");
  ilTexImage(
    
    width,
    height,
    
    1,  // OpenIL supports 3d textures!  but we don't want it to be 3d.  so
    // we just set this to be 1
    
    3,  // 3 channels:  one for R , one for G, one for B
    
    IL_RGB,  // duh, yeah use rgb!  coulda been rgba if we wanted trans
    
    IL_UNSIGNED_BYTE,  // the type of data the imData array contains (next)
    
    imData  // and the array of bytes represneting the actual image data
    
  ) ;

  printf("Your image was texxed\n");

  printf("Now width=%d,  height=%d,  bpp=%d\n",

    ilGetInteger( IL_IMAGE_WIDTH ),
    ilGetInteger( IL_IMAGE_HEIGHT ),
    ilGetInteger( IL_IMAGE_BPP )
    );

  // allow openIL to overwrite the file
  // we created last time
  ilEnable(IL_FILE_OVERWRITE);
 
  // actually save out as png
  ilSave( IL_PNG, "output.png" ) ;

  // now try saving as jpg
  ilSave( IL_JPG, "output.jpg" ) ;
  
  // now save as bmp
  ilSave( IL_BMP, "output.bmp" ) ;


  // Look at the file sizes!  For this TYPE
  // of image, png is the best because its
  // flat colors repeated.

  // On my mahcin eht png is 94KB and the BMP is 11000kB!
  // the jpg comes out at 3000kb.

  // PNG RULES!!

  // lets give another example where jpg will
  // be better...

  // cahnge im data to being just pure noise
  for( int i = 0 ; i < theSize ; i++ )
  {
    imData[ i ] = rand()%255 ;
  }


  // now set the data in the image with this new data array
  ilSetData( imData ) ;

  // save again

  // actually save out as png
  ilSave( IL_PNG, "outputNoise.png" ) ;

  // now try saving as jpg
  ilSave( IL_JPG, "outputNoise.jpg" ) ;
  
  // now save as bmp
  ilSave( IL_BMP, "outputNoise.bmp" ) ;


  // Wowo!   So for this last test, PNG was
  // worse than jpg and bmp!  that's remarkable.
  // I actually didn't know that coudl happen.

  printf("and done");

}

As usual, download the code from esnips! (thanks esnips!)

How can I attach a console to my win app?

A common question that usually points people to this 1997 article (which remarkably should still work!).

Besides a few codeguru or codeproject articles that do the same, here is a simple example that only takes 3 lines of code on top of your basic window creation code

All you have to know:

  // The important lines:
  AllocConsole() ;
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ;


#include <windows.h>

#include <stdio.h>
#include <stdlib.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 );

// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )          
{

  // these next few lines create and attach a console
  // to this process.  note that each process is only allowed one console.
  AllocConsole() ;
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ;

  printf("HELLO!!! I AM THE CONSOLE!" ) ;


  WNDCLASSEX wc = { 0 };
  wc.cbSize = sizeof( WNDCLASSEX ) ;
  wc.cbClsExtra = 0;  // ignore for now
  wc.cbWndExtra = 0;  // ignore for now
  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; // Redraw the window

  RegisterClassEx( &wc );

  HWND hwnd = CreateWindowEx( 0, TEXT("Philip"), TEXT("window's title!"), WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, hInstance, NULL );      

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

  MSG msg;

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

  return msg.wParam;    // return from WinMain
}

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 );
    printf("HELLO!!! I AM THE CONSOLE!" ) ;
    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 );
      printf("HELLO!!! I AM THE CONSOLE!" ) ;

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

  case WM_LBUTTONDOWN:
    printf("STOP POKING MEEE!!!\n") ;
    break;

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

  }

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



Additional ref: Msdn on console handling in general

MSDN on “consoles”

Console functions on msdn

The HWND of the desktop “window” is actually 0.

You can get the DC of the desktop window using:


HDC desktopDC = GetDC( HWND_DESKTOP ) ;

// or
HDC desktopDC2 = GetDC( NULL ) ;

// or
HDC desktopDC3 = GetDC( 0 ) ;

// same diff 

// don't forget to
ReleaseDC( HWND_DESKTOP, desktopDC ) ;
// when you're done!

make a screensaver in C++ win32

citing my collective sources.

MSDN link

I’ve always wanted to create a screensaver, just never got around to it.

There are a few things on codeproject that explain how to create a screensaver in C#.

But its easier in C++, in my opinion

Finally, here it is! A starter.

You CAN hook in OpenGL or whatever, but this just uses a simple backbuffer

You could easily create something like mystify or some kind of fractal thing using this starter kit

#include <windows.h>
#include <scrnsave.h>
#include <commctrl.h>

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

#ifdef UNICODE
#pragma comment(lib, "scrnsavw.lib")
#else
#pragma comment(lib, "scrnsave.lib")
#endif
#pragma comment(lib, "comctl32.lib")




// COMPILE AND RENAME .EXE FILE TO .SCR.
// DOUBLE CLICK TO LAUNCH.
// MOVE TO C:\WINDOWS\SYSTEM32 DIRECTORY
// (AS WHATEVER.SCR) AND IT WILL AUTOMATICALLY
// APPEAR IN THE DROPDOWN MENU AS A VALID
// SCREENSAVER TO CHOOSE!

// WORKS WHEN COMPILED UNDER VISUAL STUDIO 2005.

// DOES __NOT__ WORK UNDER VISUAL STUDIO 2008.



#pragma region globals
HWND winhwnd ;
HBITMAP backBMP ;
HDC backDC ;
int backBufferCX, backBufferCY ;

int totalPoints ;


#define TIMER 1
#pragma endregion




LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message)
  {
  case WM_CREATE:
    {
      // Create a compatible bitmap with the width, height
      // of the desktop.
      winhwnd = hwnd ; // save.

      backBufferCX = GetSystemMetrics( SM_CXVIRTUALSCREEN ) ;  // SM_CXSCREEN is just the primary.  this is BOTH.
      backBufferCY = GetSystemMetrics( SM_CYVIRTUALSCREEN ) ;

      //HDC desktopHdc = GetDC( NULL ) ; // give me the hdc of the desktop.
      HDC winhdc = GetDC( winhwnd ) ; // give me the hdc of this app.
      backBMP = (HBITMAP)CreateCompatibleBitmap( winhdc, backBufferCX, backBufferCY ) ;
      



      // now, you need to associate a dc with this
      // bitmap.  the DC holds all the info about brushes, etc.
      backDC = CreateCompatibleDC( winhdc ) ;
      ReleaseDC( winhwnd, winhdc ) ;


      // select it in.  here we have to associate
      // the DC we made (compatible with the window's hdc)
      // with the bitmap we made (compatible with the window's bitmap)
      SelectObject( backDC, backBMP ) ;

      
      totalPoints = 0 ;

      char buf[300] ;
      
      sprintf( buf, "desktop width:  %d     height:  %d", backBufferCX, backBufferCY ) ;
      TextOutA( backDC, 20, 20, buf, strlen( buf ) );
      //MessageBoxA( NULL, buf, "Debug info", MB_OK ) ;





      // Timer for animation
      SetTimer( winhwnd, TIMER, 24, NULL ); 
    }
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  case WM_PAINT:
    // blit the back buffer onto the screen
    {
      PAINTSTRUCT ps ;

      HDC hdc = BeginPaint( hwnd, &ps );
      BitBlt( hdc, 0, 0, backBufferCX, backBufferCY, backDC, 0, 0, SRCCOPY ) ;

      EndPaint( hwnd, &ps ) ;
    }
    break;

  case WM_TIMER:

    // draw an extra point in a random spot.
    SetPixel( backDC, rand()%backBufferCX, rand()%backBufferCY, RGB( 255,0,0 ) ) ;

    TextOutA( backDC, rand()%backBufferCX, rand()%backBufferCY, "B", 1 );
    totalPoints++ ;

    if( totalPoints > 300 )
    {
      // clear by filling out the back buffer with black rectangle
      HBRUSH oldBrush = (HBRUSH)SelectObject( backDC, GetStockObject( BLACK_BRUSH ) ) ;
      Rectangle( backDC, 0, 0, backBufferCX, backBufferCY );
      SelectObject( backDC, oldBrush ) ; // put the old brush back
      // Not keeping the system's BLACK_BRUSH

      totalPoints = 0 ;
    }

    RECT r ;
    GetClientRect( winhwnd, &r );
    InvalidateRect( hwnd, &r, false ) ;
    

    break;
  default:
    return DefScreenSaverProc(hwnd, message, wParam, lParam);
  }
  return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
  return TRUE;
}



Get the code from my esnips (thanks esnips!)

How to create a backbuffer win32

This example shows how quickly

The steps:

  1. Get a window up
  2. In WM_CREATE (or just anywhere before message loop start), initialize the backbuffer
    • BACKBUFFER_SURFACE = CreateCompatibleBitmap()
    • BACKBUFFER_DRAWTOOL = CreateCompatibleDC()
    • SelectObject() your createdCompatibleBitmap into your CreatedCompatibleDC
  3. All drawing should happen to your BACKBUFFER_SURFACE __via__ your BACKBUFFER_DRAWTOOL
  4. In a draw() routine that runs once a loop, BitBlt( BACKBUFFER_DRAWTOOL into main window DC )
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


HWND winhwnd;
HDC		backDC;
HBITMAP backBufferBMP;
int		backBufferCX;
int		backBufferCY;
TCHAR * winClassName = TEXT("backbufferwin") ;

// prototypes
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd );


inline void draw()
{
  HDC winhdc = GetDC( winhwnd ) ;
  // Now copy the back buffer to the front buffer.
  BitBlt(

    winhdc,	// destination buffer
    0, 0,	// x, y to start writing to in the destination buffer
    // counted from top left corner of dest HDC (window)

    // Width, height to copy for
    backBufferCX, backBufferCY,

    backDC, // SOURCE buffer.  We're taking from that back canvas

    0, 0,		// x pt, y pt to START copying from
    // SOURCE.  counted from top left again

    // And we just want a straight copy.
    SRCCOPY );

  ReleaseDC( winhwnd, winhdc ) ;
}




void InitBackBuffer()
{
  backBufferCX = 512;
  backBufferCY = 300;

  HDC winhdc = GetDC( winhwnd );

  /*

  Imagine you have 2 things:
  - a canvas on which to draw (call this your HBITMAP)
  - set of brushes you will use to draw (call this your HDC)

  1.  HBITMAP.  Canvas
  ___________________
  |       *         |
  |   *             |
  |     HBITMAP     |
  |    draw here    |
  |_________________|

  2.  HDC.  Set of brushes.
  <-*
  []-*
  ()-*

  */

  // Create the HBITMAP "canvas", or surface on which we will draw.
  backBufferBMP = CreateCompatibleBitmap( winhdc, backBufferCX, backBufferCY );
  if(backBufferBMP == NULL)
    printf( "failed to create backBufferBMP" );


  // Create the HDC "device context", or collection of tools
  // and brushes that we can use to draw on our canvas
  backDC = CreateCompatibleDC( winhdc );
  if(backDC == NULL)
    printf( "failed to create the backDC" );

  // Permanently associate the surface on which to draw
  // ("canvas") (HBITMAP), with the "set of brushes" (HDC)

  // "select in" the backBufferBMP into the backDC
  HBITMAP oldbmp = (HBITMAP)SelectObject( backDC, backBufferBMP );


  // Delete the "canvas" that the backDC was
  // going to draw to.  We don't care about it.
  DeleteObject( oldbmp );



  /// Release the dc of the main window itself
  ReleaseDC( winhwnd, winhdc );
}


// Just as said every C++ program starts at main,              //
// every Windows program will start at WinMain.                //
/////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nShowCmd )
{
#pragma region get window up
  WNDCLASSEX window = { 0 } ;
  window.cbSize			= sizeof(WNDCLASSEX);
  window.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);		// BLACK_BRUSH, DKGRAY_BRUSH
  window.hCursor = LoadCursor(NULL, IDC_HAND);			// load hand cursor.. make to guitar
  window.hIcon = LoadIcon(NULL, IDI_APPLICATION);		// large icon for app
  window.hIconSm = LoadIcon(NULL, IDI_APPLICATION);		// small icon that shows up in top left of window
  window.hInstance = hInstance;							// program's instance handle that was first passed to WinMain by windows when program was first run
  window.lpfnWndProc = WndProc;								// function pointer to WndProc function
  window.lpszClassName = winClassName;							// window class name
  window.lpszMenuName = NULL;									// menu name -- but our app has no menu now
  window.style = CS_HREDRAW | CS_VREDRAW;				// window style --

  if(!RegisterClassEx( &window ))
  {
    MessageBox(NULL, TEXT("Something's wrong with the WNDCLASSEX structure you defined.. quitting"), TEXT("Error"), MB_OK);
    return 1;		// return from WinMain.. i.e. quit
  }

  // CREATE THE WINDOW AND KEEP THE HANDLE TO IT.
  winhwnd = CreateWindowEx(	0/*WS_EX_TOPMOST*/,			// extended window style.. this sets the window to being always on top
    winClassName,			// window class name.. defined above
    TEXT("Double buffering and using a backbuffer"),// title bar of window
    WS_OVERLAPPEDWINDOW,// window style
    400, 200,		        // initial x, y start position of window
    800, 600,	          // initial width, height of window.  Can also be CW_USEDEFAULT to let Windows choose these values
    NULL, NULL,			  	// parent window, window menu
    hInstance, NULL);		// program instance handle, creation params

  // now we show and paint our window, so it appears
  ShowWindow( winhwnd, nShowCmd );		// you have to ask that your Window be shown to see it
  UpdateWindow(winhwnd);					// paint the window
#pragma endregion

#pragma region message loop

  MSG			msg;

  while(1)
  {
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if(msg.message == WM_QUIT)
      {
        PostQuitMessage(0);
        break;
      }
      TranslateMessage(&msg);	// translates 'character' keyboard messages
      DispatchMessage(&msg);	// send off to WndProc for processing
    }
    else
    {
      // could put more update code in here
      // before drawing.
      draw();
    }
  }
#pragma endregion

  return 0;	// end program once we exit the message loop
}




////////////////////////////////////////////////////////////////////////
// WndProc - "Window procedure" function
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message)
  {
  case WM_CREATE:
    {
      // As soon as the window is first created, create
      // the back buffer.
      InitBackBuffer() ;

      // now just draw something into it for fun
      char buf[300];
      sprintf( buf, "HELLO.  Left click to add stars.  Right click to clear." );
      TextOutA( backDC, 20, 20, buf, strlen(buf) );

      return 0;
    }
    break;

  case WM_PAINT:
    {
      PAINTSTRUCT	ps;

      HDC winhdc = BeginPaint(hwnd, &ps);

      // Do nothing here.  All drawing happens in draw(),
      // and you draw to the backbuffer, NOT the
      // front buffer.

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

  case WM_LBUTTONDOWN:	// this message occurs when the left mouse button is clicked in our window's client area
    {
      int xPos = LOWORD( lParam );
      int yPos = HIWORD( lParam );

      // Set pixel @ pos of click IN BACK BUFFER
      // to red.
      SetPixel( backDC, xPos, yPos, RGB( 255, 0, 0 ) );

      return 0;
    }
    break;

  case WM_RBUTTONDOWN:
    {
      // clear by filling out the back buffer with black rectangle
      HBRUSH oldBrush = (HBRUSH)SelectObject( backDC, GetStockObject( BLACK_BRUSH ) ) ;
      Rectangle( backDC, 0, 0, backBufferCX, backBufferCY );
      SelectObject( backDC, oldBrush ) ; // put the old brush back, not bothering
      // to catch the system BLACK_BRUSH
    }
    break;

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

  // If message was NOT handled by us, we pass it off to
  // the windows operating system to handle it.
  return DefWindowProc(hwnd, message, wParam, lParam);
}





You know, its amazing how BASIC the inner workings of the windows o/s can be.

The way the o/s offers you screensavers is if the filename has the extension .scr.

What’s even more amazing is it seems to launch from a dos/mode 8-character maximum archaic launcher.

fake-screensaver

The filename was Fake_screensaver.scr. The launcher launched it as its 8 character alias fake_s~1.scr. Isn’t that amazing??? Like somewhere down there is 8 character mode stuff.. right in winxp.

Maybe Raymond Chen would know