237 lines
6.1 KiB
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;
|
|
}
|
|
}
|
|
}
|
|
|