colorchord/colorchord2/WinDriver.c

237 lines
6.1 KiB
C

//Copyright (c) 2011 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
//Portion from: http://en.wikibooks.org/wiki/Windows_Programming/Window_Creation
#include "DrawFunctions.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h> //for alloca
static HINSTANCE lhInstance;
static HWND lsHWND;
static HDC lsHDC;
static HBITMAP lsBackBitmap;
static HDC lsWindowHDC;
static HBRUSH lsHBR;
static HPEN lsHPEN;
static HBRUSH lsClearBrush;
static unsigned int lsLastWidth;
static unsigned int lsLastHeight;
static void InternalHandleResize()
{
DeleteObject( lsBackBitmap );
lsBackBitmap = CreateCompatibleBitmap( lsHDC, lsLastWidth, lsLastHeight );
SelectObject( lsHDC, lsBackBitmap );
}
uint32_t CNFGColor( uint32_t RGB )
{
CNFGLastColor = RGB;
DeleteObject( lsHBR );
lsHBR = CreateSolidBrush( RGB );
SelectObject( lsHDC, lsHBR );
DeleteObject( lsHPEN );
lsHPEN = CreatePen( PS_SOLID, 0, RGB );
SelectObject( lsHDC, lsHPEN );
return RGB;
}
void CNFGTackSegment( short x1, short y1, short x2, short y2 )
{
POINT pt[2] = { {x1, y1}, {x2, y2} };
Polyline( lsHDC, pt, 2 );
SetPixel( lsHDC, x1, y1, CNFGLastColor );
SetPixel( lsHDC, x2, y2, CNFGLastColor );
}
void CNFGTackRectangle( short x1, short y1, short x2, short y2 )
{
RECT r;
if( x1 < x2 ) { r.left = x1; r.right = x2; }
else { r.left = x2; r.right = x1; }
if( y1 < y2 ) { r.top = y1; r.bottom = y2; }
else { r.top = y2; r.bottom = y1; }
FillRect( lsHDC, &r, lsHBR );
}
void CNFGClearFrame()
{
RECT r = { 0, 0, lsLastWidth, lsLastHeight };
DeleteObject( lsClearBrush );
lsClearBrush = CreateSolidBrush( CNFGBGColor );
SelectObject( lsHDC, lsClearBrush );
FillRect( lsHDC, &r, lsClearBrush );
}
void CNFGSwapBuffers()
{
int thisw, thish;
RECT r;
BitBlt( lsWindowHDC, 0, 0, lsLastWidth, lsLastHeight, lsHDC, 0, 0, SRCCOPY );
UpdateWindow( lsHWND );
//Check to see if the window is closed.
if( !IsWindow( lsHWND ) )
{
exit( 0 );
}
GetClientRect( lsHWND, &r );
thisw = r.right - r.left;
thish = r.bottom - r.top;
if( thisw != lsLastWidth || thish != lsLastHeight )
{
lsLastWidth = thisw;
lsLastHeight = thish;
InternalHandleResize();
}
}
void CNFGTackPoly( RDPoint * points, int verts )
{
int i;
POINT * t = (POINT*)alloca( sizeof( POINT ) * verts );
for( i = 0; i < verts; i++ )
{
t[i].x = points[i].x;
t[i].y = points[i].y;
}
Polygon( lsHDC, t, verts );
}
void CNFGTackPixel( short x1, short y1 )
{
SetPixel( lsHDC, x1, y1, CNFGLastColor );
}
void CNFGGetDimensions( short * x, short * y )
{
*x = lsLastWidth;
*y = lsLastHeight;
}
//This was from the article
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
//This was from the article, too... well, mostly.
void CNFGSetup( const char * name_of_window, int width, int height )
{
static LPSTR szClassName = "MyClass";
RECT client, window;
WNDCLASS wnd;
int w, h, wd, hd;
HINSTANCE hInstance = GetModuleHandle(NULL);
lsLastWidth = width;
lsLastHeight = height;
wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
wnd.lpfnWndProc = MyWndProc;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); //default icon
wnd.hCursor = LoadCursor(NULL, IDC_ARROW); //default arrow mouse cursor
wnd.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wnd.lpszMenuName = NULL; //no menu
wnd.lpszClassName = szClassName;
if(!RegisterClass(&wnd)) //register the WNDCLASS
{
MessageBox(NULL, "This Program Requires Windows NT", "Error", MB_OK);
}
lsHWND = CreateWindow(szClassName,
name_of_window, //name_of_window,
WS_OVERLAPPEDWINDOW, //basic window style
CW_USEDEFAULT,
CW_USEDEFAULT, //set starting point to default value
lsLastWidth,
lsLastHeight, //set all the dimensions to default value
NULL, //no parent window
NULL, //no menu
hInstance,
NULL); //no parameters to pass
lsWindowHDC = GetDC( lsHWND );
lsHDC = CreateCompatibleDC( lsWindowHDC );
lsBackBitmap = CreateCompatibleBitmap( lsWindowHDC, lsLastWidth, lsLastHeight );
SelectObject( lsHDC, lsBackBitmap );
lsClearBrush = CreateSolidBrush( CNFGBGColor );
lsHBR = CreateSolidBrush( 0xFFFFFF );
lsHPEN = CreatePen( PS_SOLID, 0, 0xFFFFFF );
ShowWindow(lsHWND, 1); //display the window on the screen
//Once set up... we have to change the window's borders so we get the client size right.
GetClientRect( lsHWND, &client );
GetWindowRect( lsHWND, &window );
w = ( window.right - window.left);
h = ( window.bottom - window.top);
wd = w - client.right;
hd = h - client.bottom;
MoveWindow( lsHWND, window.left, window.top, lsLastWidth + wd, lsLastHeight + hd, 1 );
InternalHandleResize();
}
void WindowsTerm();
void CNFGHandleInput()
{
int ldown = 0;
MSG msg;
while( PeekMessage( &msg, lsHWND, 0, 0xFFFF, 1 ) )
{
TranslateMessage(&msg);
switch( msg.message )
{
case WM_QUIT:
case WM_DESTROY:
case WM_CLOSE:
printf( "Close\n" );
WindowsTerm();
TerminateProcess( 0, 0 );
break;
case WM_MOUSEMOVE:
HandleMotion( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, ( (msg.wParam & 0x01)?1:0) | ((msg.wParam & 0x02)?2:0) | ((msg.wParam & 0x10)?4:0) );
break;
case WM_LBUTTONDOWN: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 1, 1 ); break;
case WM_RBUTTONDOWN: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 2, 1 ); break;
case WM_MBUTTONDOWN: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 3, 1 ); break;
case WM_LBUTTONUP: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 1, 0 ); break;
case WM_RBUTTONUP: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 2, 0 ); break;
case WM_MBUTTONUP: HandleButton( (msg.lParam & 0xFFFF), (msg.lParam>>16) & 0xFFFF, 3, 0 ); break;
case WM_KEYDOWN:
case WM_KEYUP:
HandleKey( tolower( msg.wParam ), (msg.message==WM_KEYDOWN) );
break;
default:
DispatchMessage(&msg);
break;
}
}
}