primitives test from the Windows 2000 Graphics API Backbook

Used with permission from Damon Chandler <dmc27@ee.cornell.edu>

Makefile still needs to be converted to ReactOS Makefile
and SEH needs to be disabled.

svn path=/trunk/; revision=4886
This commit is contained in:
Steven Edwards 2003-06-13 19:39:30 +00:00
parent 3da2ebbda8
commit eda4cb882d
4 changed files with 520 additions and 0 deletions

View file

@ -0,0 +1,69 @@
# Makefile - Proj_Listing5_1.dsp
ifndef CFG
CFG=Proj_Listing5_1 - Win32 Debug
endif
CC=gcc
CFLAGS=
CXX=g++
CXXFLAGS=$(CFLAGS)
RC=windres -O COFF
ifeq "$(CFG)" "Proj_Listing5_1 - Win32 Release"
CFLAGS+=-fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -W
LD=$(CXX) $(CXXFLAGS)
LDFLAGS=
LDFLAGS+=-Wl,--subsystem,windows
LIBS+=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32
else
ifeq "$(CFG)" "Proj_Listing5_1 - Win32 Debug"
CFLAGS+=-fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W
LD=$(CXX) $(CXXFLAGS)
LDFLAGS=
LDFLAGS+=-Wl,--subsystem,windows
LIBS+=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32
endif
endif
ifndef TARGET
TARGET=primitives.exe
endif
.PHONY: all
all: $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
%.o: %.cc
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<
%.o: %.cxx
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<
%.res: %.rc
$(RC) $(CPPFLAGS) -o $@ -i $<
SOURCE_FILES= \
mk_font.cpp \
primitives.cpp
HEADER_FILES=
RESOURCE_FILES=
SRCS=$(SOURCE_FILES) $(HEADER_FILES) $(RESOURCE_FILES)
OBJS=$(patsubst %.rc,%.res,$(patsubst %.cxx,%.o,$(patsubst %.cpp,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(filter %.c %.cc %.cpp %.cxx %.rc,$(SRCS)))))))
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
.PHONY: clean
clean:
-rm -f $(OBJS) $(TARGET)

View file

@ -0,0 +1,69 @@
// ------------------------------------------------------------------
// Windows 2000 Graphics API Black Book
// Chapter 4 - Utility functions
//
// Created by Damon Chandler <dmc27@ee.cornell.edu>
// Updates can be downloaded at: <www.coriolis.com>
//
// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
// if you have any questions about this code.
// ------------------------------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <windows.h>
#include <cassert>
#include "mk_font.h"
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
namespace font {
// creates a logical font
HFONT MakeFont(
IN HDC hDestDC, // handle to target DC
IN LPCSTR typeface_name, // font's typeface name
IN int point_size, // font's point size
IN const BYTE charset, // font's character set
IN const DWORD style // font's styles
)
{
//
// NOTE: On Windows 9x/Me, GetWorldTransform is not
// supported. For compatibility with these platforms you
// should initialize the XFORM::eM22 data member to 1.0.
//
XFORM xf = {0, 0, 0, 1.0};
GetWorldTransform(hDestDC, &xf);
int pixels_per_inch = GetDeviceCaps(hDestDC, LOGPIXELSY);
POINT PSize = {
0,
-MulDiv(static_cast<int>(xf.eM22 * point_size + 0.5),
pixels_per_inch, 72)
};
HFONT hResult = NULL;
if (DPtoLP(hDestDC, &PSize, 1))
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = PSize.y;
lf.lfCharSet = charset;
lstrcpyn(reinterpret_cast<LPTSTR>(&lf.lfFaceName),
typeface_name, LF_FACESIZE);
lf.lfWeight = (style & FS_BOLD) ? FW_BOLD : FW_DONTCARE;
lf.lfItalic = (style & FS_ITALIC) ? true : false;
lf.lfUnderline = (style & FS_UNDERLINE) ? true : false;
lf.lfStrikeOut = (style & FS_STRIKEOUT) ? true : false;
// create the logical font
hResult = CreateFontIndirect(&lf);
}
return hResult;
}
//-------------------------------------------------------------------------
} // namespace font

View file

@ -0,0 +1,39 @@
// ------------------------------------------------------------------
// Windows 2000 Graphics API Black Book
// Chapter 4 - Utility functions
//
// Created by Damon Chandler <dmc27@ee.cornell.edu>
// Updates can be downloaded at: <www.coriolis.com>
//
// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
// if you have any questions about this code.
// ------------------------------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#ifndef CH4_UTILS_H
#define CH4_UTILS_H
#include <windows.h>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// change namespace name appropriately to suit your needs
namespace font {
// font options
static const ULONG FS_NONE = 0x00000000;
static const ULONG FS_BOLD = 0x00000001;
static const ULONG FS_ITALIC = 0x00000002;
static const ULONG FS_UNDERLINE = 0x00000004;
static const ULONG FS_STRIKEOUT = 0x00000008;
// creates a logical font
HFONT MakeFont(IN HDC hDestDC, IN LPCSTR typeface_name,
IN int point_size, IN const BYTE charset = ANSI_CHARSET,
IN const DWORD style = FS_NONE);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#endif // CH4_UTILS_H
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

View file

@ -0,0 +1,343 @@
// ------------------------------------------------------------------
// Windows 2000 Graphics API Black Book
// Chapter 5 - Listing 5.1 (Output Primitives Demo)
//
// Created by Damon Chandler <dmc27@ee.cornell.edu>
// Updates can be downloaded at: <www.coriolis.com>
//
// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu
// if you have any questions about this code.
// ------------------------------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <windows.h>
#include <cassert>
// for the MakeFont() function...
#include "mk_font.h"
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HINSTANCE hInst;
const char* WndClassName = "GMainWnd";
LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam,
LPARAM LParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR,
int nCmdShow)
{
hInst = hInstance;
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpszClassName = WndClassName;
wc.lpfnWndProc = MainWndProc;
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(
COLOR_BTNFACE + 1
);
if (RegisterClass(&wc))
{
HWND hWnd =
CreateWindow(
WndClassName, TEXT("Output Primitives Demo"),
WS_OVERLAPPEDWINDOW | WS_CAPTION |
WS_VISIBLE | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInst, NULL
);
if (hWnd)
{
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return 0;
}
//------------------------------------------------------------------
enum OutPrimitive {
opLine, opBezier, opRectangle, opRoundRect,
opEllipse, opArc, opPie, opChord, opCustom
};
void DrawPrimitive(IN HDC hDC, IN const RECT& RPrimitive,
IN OutPrimitive PrimitiveID)
{
RECT R = RPrimitive;
InflateRect(&R, -10, -10);
switch (PrimitiveID)
{
case opLine:
{
const POINT PLine[] = {{R.left, R.top}, {R.right, R.bottom}};
Polyline(hDC, PLine, 2);
break;
}
case opBezier:
{
const POINT PControlPoints[] = {
{R.left, R.top},
{(R.right - R.left) / 2, R.top},
{(R.right - R.left) / 2, R.bottom},
{R.right, R.bottom}
};
PolyBezier(hDC, PControlPoints, 4);
break;
}
case opRectangle:
{
Rectangle(hDC, R.left, R.top, R.right, R.bottom);
break;
}
case opRoundRect:
{
RoundRect(hDC, R.left, R.top, R.right, R.bottom, 20, 20);
break;
}
case opEllipse:
{
Ellipse(hDC, R.left, R.top, R.right, R.bottom);
break;
}
case opArc:
{
const POINT PRads[] = {
{(R.right - R.left) / 3 + R.left, R.top},
{(R.right - R.left) / 3 + R.left, R.bottom}
};
Arc(hDC, R.left, R.top, R.right, R.bottom,
PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y);
break;
}
case opPie:
{
const POINT PRads[] = {
{(R.right - R.left) / 3 + R.left, R.top},
{(R.right - R.left) / 3 + R.left, R.bottom}
};
Pie(hDC, R.left, R.top, R.right, R.bottom,
PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y);
break;
}
case opChord:
{
const POINT PRads[] = {
{(R.right - R.left) / 3 + R.left, R.top},
{(R.right - R.left) / 3 + R.left, R.bottom}
};
Chord(hDC, R.left, R.top, R.right, R.bottom,
PRads[0].x, PRads[0].y, PRads[1].x, PRads[1].y);
break;
}
case opCustom:
{
const POINT PVertices[] = {
{R.left, (R.bottom - R.top) / 2 + R.top},
{(R.right - R.left) / 2 + R.left, R.top},
{R.right, (R.bottom - R.top) / 2 + R.top},
{(R.right - R.left) / 2 + R.left, R.bottom}
};
Polygon(hDC, PVertices, 4);
break;
}
}
}
//------------------------------------------------------------------
HWND hListBox = NULL; // handle to the list box
HBRUSH hListBrush = NULL; // handle to the list box brush
HPEN hListPen = NULL; // handle to the list box pen
HFONT hListFont = NULL; // handle to the list box font
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
hListBox =
CreateWindowEx(
WS_EX_CLIENTEDGE, TEXT("LISTBOX"), TEXT(""),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT |
LBS_OWNERDRAWFIXED,
0, 0, 640, 480,
hWnd, NULL, hInst, NULL
);
assert(hListBox != NULL);
SetWindowLong(
hListBox, GWL_ID, reinterpret_cast<LONG>(hListBox)
);
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Line")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Bezier Curve")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Rectangle")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Rounded Rectangle")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Ellipse")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Arc")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Pie Slice")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Chord")));
SNDMSG(hListBox, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(TEXT("Custom")));
hListBrush = CreateSolidBrush(PALETTERGB(64, 192, 64));
hListPen = CreatePen(PS_SOLID, 3, PALETTERGB(0, 0, 0));
HDC hScreenDC = GetDC(NULL);
try
{
// MakeFont() from Chapter 4
hListFont = font::MakeFont(
hScreenDC, "Impact", 20, ANSI_CHARSET,
font::FS_BOLD | font::FS_UNDERLINE
);
}
catch (...)
{
ReleaseDC(NULL, hScreenDC);
}
ReleaseDC(NULL, hScreenDC);
break;
}
case WM_MEASUREITEM:
{
LPMEASUREITEMSTRUCT lpmis =
reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam);
assert(lpmis != NULL);
if (lpmis->CtlID == reinterpret_cast<UINT>(hListBox))
{
lpmis->itemHeight = 150;
return TRUE;
}
break;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpdis =
reinterpret_cast<LPDRAWITEMSTRUCT>(lParam);
assert(lpdis != NULL);
if (lpdis->CtlID == reinterpret_cast<UINT>(hListBox))
{
SaveDC(lpdis->hDC);
try
{
SelectObject(lpdis->hDC, hListBrush);
SelectObject(lpdis->hDC, hListPen);
SelectObject(lpdis->hDC, hListFont);
bool selected = (lpdis->itemState & ODS_SELECTED);
COLORREF clrText = GetSysColor(
selected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT
);
HBRUSH hListBrush = GetSysColorBrush(
selected ? COLOR_HIGHLIGHT : COLOR_WINDOW
);
// fill the background
FillRect(lpdis->hDC, &lpdis->rcItem, hListBrush);
// render the output primitive
RECT RPrimitive = lpdis->rcItem;
InflateRect(&RPrimitive, -5, -5);
RPrimitive.right = static_cast<int>(
0.6 * lpdis->rcItem.right + 0.5
);
FillRect(
lpdis->hDC, &RPrimitive,
reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1)
);
DrawPrimitive(
lpdis->hDC, RPrimitive,
static_cast<OutPrimitive>(lpdis->itemID)
);
if (selected) InvertRect(lpdis->hDC, &RPrimitive);
DrawEdge(lpdis->hDC, &RPrimitive, EDGE_SUNKEN, BF_RECT);
// render the text
TCHAR text[13];
if (SNDMSG(hListBox, LB_GETTEXT, lpdis->itemID,
reinterpret_cast<LPARAM>(&text)) != LB_ERR)
{
RECT RText = RPrimitive;
RText.left = RPrimitive.right;
RText.right = lpdis->rcItem.right;
SelectObject(lpdis->hDC, hListFont);
SetBkMode(lpdis->hDC, TRANSPARENT);
SetTextColor(lpdis->hDC, clrText);
DrawText(lpdis->hDC, text, -1, &RText,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
// indicate keyboard focus
if (lpdis->itemState & ODS_FOCUS)
{
RECT RFocus = lpdis->rcItem;
InflateRect(&RFocus, -1, -1);
DrawFocusRect(lpdis->hDC, &RFocus);
}
}
catch (...)
{
RestoreDC(lpdis->hDC, -1);
}
RestoreDC(lpdis->hDC, -1);
return TRUE;
}
break;
}
case WM_SIZE:
{
MoveWindow(
hListBox, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE
);
return 0;
}
case WM_DESTROY:
{
if (hListBrush) DeleteObject(hListBrush);
if (hListPen) DeleteObject(hListPen);
if (hListFont) DeleteObject(hListFont);
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//-------------------------------------------------------------------------