📄 area.cpp
字号:
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : area.cpp //
// Description: Area fill demo program, Chapter 9 //
// Version : 1.00.000, May 31, 2000 //
//-----------------------------------------------------------------------------------//
#define STRICT
#define _WIN32_WINNT 0x0500
#define WINVER 0x0500
#define WIN32_LEAN_AND_MEAN
#define OEMRESOURCE
#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <math.h>
#include "..\..\include\win.h"
#include "..\..\include\Canvas.h"
#include "..\..\include\Status.h"
#include "..\..\include\FrameWnd.h"
#include "..\..\include\Affine.h"
#include "..\..\include\Pen.h"
#include "..\..\include\Color.h"
#include "..\..\include\GDIObject.h"
#include "..\..\include\areafill.h"
#include "..\..\include\button.h"
#include "..\..\include\region.h"
#include "Resource.h"
class KMyCanvas : public KCanvas
{
virtual void OnDraw(HDC hDC, const RECT * rcPaint);
virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
int m_test;
int m_lastx;
int m_lasty;
void SetTest(int test);
void DrawCrossHair(HDC hDC, bool on);
void TestDither(HDC hDC);
void TestHatch(HDC hDC);
void TestSysColorBrush(HDC hDC);
void TestRectangle(HDC hDC);
void TestDrawFrameControl(HDC hDC);
void TestEllipse(HDC hDC);
void TestPieChart(HDC hDC);
void TestPolyFillMode(HDC hDC);
void TestFillPath(HDC hDC);
void TestRegion(HDC hDC);
void TestRegionOper(HDC hDC);
void TestRegionPaint(HDC hDC);
void TestGradientFill(HDC hDC);
KRectButton rbutton;
KEllipseButton ebutton;
public:
KMyCanvas()
{
m_test = -1;
m_lastx = -1;
m_lasty = -1;
}
};
void KMyCanvas::SetTest(int test)
{
m_test = test;
HMENU hMain = GetMenu(GetParent(m_hWnd));
TCHAR Temp[MAX_PATH];
_tcscpy(Temp, _T("Areas - "));
GetMenuString(hMain, m_test, Temp + _tcslen(Temp),
sizeof(Temp)/sizeof(TCHAR) - _tcslen(Temp), MF_BYCOMMAND);
SetWindowText(GetParent(m_hWnd), Temp);
}
BOOL KMyCanvas::OnCommand(WPARAM wParam, LPARAM lParam)
{
switch ( LOWORD(wParam) )
{
case IDM_TEST_DITHER:
case IDM_TEST_HATCHBRUSH:
case IDM_TEST_SYSCOLORBRUSH:
case IDM_TEST_RECTANGLE:
case IDM_TEST_DRAWFRAMECONTROL:
case IDM_TEST_ELLIPSE:
case IDM_TEST_PIECHART:
case IDM_TEST_POLYFILLMODE:
case IDM_TEST_FILLPATH:
case IDM_TEST_REGION:
case IDM_TEST_REGIONOP:
case IDM_TEST_REGIONPAINT:
case IDM_TEST_GRADIENTFILL:
SetTest( LOWORD(wParam) );
InvalidateRect(m_hWnd, NULL, TRUE);
return TRUE;
case IDM_FILE_EXIT:
DestroyWindow(GetParent(m_hWnd));
return TRUE;
}
return FALSE; // not processed
}
inline void Line(HDC hDC, int x1, int y1, int x2, int y2)
{
MoveToEx(hDC, x1, y1, NULL);
LineTo(hDC, x2, y2);
}
void KMyCanvas::DrawCrossHair(HDC hDC, bool on)
{
if ( (m_lastx<0) || (m_lasty<0) )
return;
RECT rect;
GetClientRect(m_hWnd, & rect);
SetROP2(hDC, R2_XORPEN);
{
KPen pen(PS_DOT, 0, RGB(0, 0, 0xFF), hDC);
Line(hDC, rect.left, m_lasty, rect.right, m_lasty);
Line(hDC, m_lastx, rect.top, m_lastx, rect.bottom);
}
}
void ZoomRect(HDC hDC, int x0, int y0, int x1, int y1, int dx, int dy, int zoom)
{
// use black pen for border
HGDIOBJ hOld = SelectObject(hDC, GetStockObject(BLACK_PEN));
for (int y=y0; y<y1; y++)
for (int x=x0; x<x1; x++)
{
COLORREF c = GetPixel(hDC, x, y);
HBRUSH hBrush = CreateSolidBrush(c);
HGDIOBJ hOld = SelectObject(hDC, hBrush);
Rectangle(hDC, dx+(x-x0)*(zoom+1), dy+(y-y0)*(zoom+1),
dx+(x-x0)*(zoom+1)+zoom+2,
dy+(y-y0)*(zoom+1)+zoom+2);
SelectObject(hDC, hOld);
DeleteObject(hBrush);
}
SelectObject(hDC, hOld);
}
void KMyCanvas::TestDither(HDC hDC)
{
SetViewportOrgEx(hDC, 10, 10, NULL);
// no outline for dither rectangle
SelectObject(hDC, GetStockObject(NULL_PEN));
for (int y=0; y<16; y++)
for (int x=0; x<16; x++)
{
HBRUSH hBrush = CreateSolidBrush(RGB(y*16+x, y*16+x, 0xFF));
HGDIOBJ hOld = SelectObject(hDC, hBrush);
Rectangle(hDC, 235+x*10, y*10, 235+x*10+9, y*10+9);
if ( x==y ) // zoom in color on diagonal line
ZoomRect(hDC, 235+x*10, y*10, 235+x*10+8, y*10+8,
80*(x%8), 180+80*(x/8), 6);
SelectObject(hDC, hOld);
DeleteObject(hBrush);
}
SelectObject(hDC, GetStockObject(BLACK_PEN));
SetViewportOrgEx(hDC, 0, 0, NULL);
}
TCHAR * HS_Names [] =
{ _T("HS_HORIZONTAL"),
_T("HS_VERTICAL"),
_T("HS_FDIAGONAL"),
_T("HS_BDIAGONAL"),
_T("HS_CROSS"),
_T("HS_DIAGCROSS")
};
void Frame(HDC hDC, int x0, int y0, int x1, int y1)
{
unsigned short ChessBoard[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 };
HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, ChessBoard);
HBRUSH hBrush = CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
HGDIOBJ hOld = SelectObject(hDC, hBrush);
// PS_ALTERNATE rectangle
PatBlt(hDC, x0, y0, x1-x0, 1, PATCOPY);
PatBlt(hDC, x0, y1, x1-x0, 1, PATCOPY);
PatBlt(hDC, x0, y0, 1, y1-y0, PATCOPY);
PatBlt(hDC, x1, y0, 1, y1-y0, PATCOPY);
int old = SetROP2(hDC, R2_MASKPEN);
Rectangle(hDC, x0+5, y0+5, x1-5, y1-5);
SetROP2(hDC, old);
// int old = SetROP2(hDC, R2_MASKPEN);
// SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
// SetTextColor(hDC, RGB(0, 0, 0));
// Rectangle(hDC, x0+5, y0+5, x1-5, y1-5);
// SetBkColor(hDC, RGB(0x0, 0x0, 0x0));
// SetTextColor(hDC, RGB(0xFF, 0, 0));
// SetROP2(hDC, R2_MERGEPEN);
// Rectangle(hDC, x0+5, y0+5, x1-5, y1-5);
SetROP2(hDC, old);
SelectObject(hDC, hOld);
DeleteObject(hBrush);
}
void SemiFillRect(HDC hDC, int left, int top, int right, int bottom, COLORREF color)
{
int nSave = SaveDC(hDC);
const unsigned short ChessBoard[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 };
HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, ChessBoard);
HBRUSH hBrush = CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
HGDIOBJ hOldPen = SelectObject(hDC, GetStockObject(NULL_PEN));
SetROP2(hDC, R2_MASKPEN);
SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
SetTextColor(hDC, RGB(0, 0, 0));
Rectangle(hDC, left, top, right, bottom);
SetROP2(hDC, R2_MERGEPEN);
SetBkColor(hDC, RGB(0x0, 0x0, 0x0));
SetTextColor(hDC, color);
Rectangle(hDC, left, top, right, bottom);
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldPen);
DeleteObject(hBrush);
RestoreDC(hDC, nSave);
}
void KMyCanvas::TestHatch(HDC hDC)
{
int nSave = SaveDC(hDC);
SetViewportOrgEx(hDC, 24, 24, NULL);
SelectObject(hDC, GetStockObject(NULL_PEN));
typedef enum { GAP = 120 };
for (int hs= HS_HORIZONTAL; hs<=HS_DIAGCROSS; hs++)
{
HBRUSH hBrush = CreateHatchBrush(hs, RGB(0, 0, 0xFF));
HGDIOBJ hOld = SelectObject(hDC, hBrush);
SetBkColor(hDC, RGB(0xFF, 0xFF, 0));
Rectangle(hDC, hs*GAP, 0, hs*GAP+89, 89);
SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
SetTextAlign(hDC, TA_CENTER);
TextOut(hDC, hs*GAP+88/2, 98, HS_Names[hs-HS_HORIZONTAL], _tcslen(HS_Names[hs-HS_HORIZONTAL]));
SelectObject(hDC, hOld);
DeleteObject(hBrush);
ZoomRect(hDC, hs*GAP, 0, hs*GAP+8, 8, hs*GAP, 120, 8);
}
/* SelectObject(hDC, GetStockObject(NULL_PEN));
SetBkColor(hDC, RGB(0xFF, 0xFF, 0));
for (int i=0; i<8; i++)
{
SetViewportOrgEx(hDC, 24+i*32+i, 300, NULL);
HBRUSH hBrush = CreateHatchBrush(HS_FDIAGONAL, RGB(0, 0, 0xFF));
HGDIOBJ hOld = SelectObject(hDC, hBrush);
Rectangle(hDC, 0, 0, 32+2, 32+2);
SelectObject(hDC, hOld);
DeleteObject(hBrush);
}
SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
*/
// Pattern Brushes Demo
HINSTANCE hCards = LoadLibrary("cards.dll");
for (int i=0; i<4; i++)
{
HBRUSH hBrush;
int width, height;
switch ( i )
{
case 0:
{
HBITMAP hBitmap = LoadBitmap(hCards, MAKEINTRESOURCE(52));
BITMAP bmp;
GetObject(hBitmap, sizeof(bmp), & bmp);
width = bmp.bmWidth; height = bmp.bmHeight;
hBrush = CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
}
break;
case 1:
{
HRSRC hResource = FindResource(hCards, MAKEINTRESOURCE(52-14), RT_BITMAP);
HGLOBAL hGlobal = LoadResource(hCards, hResource);
hBrush = CreateDIBPatternBrushPt(LockResource(hGlobal), DIB_RGB_COLORS);
width = ((BITMAPCOREHEADER *) hGlobal)->bcWidth; // old DIB format
height = ((BITMAPCOREHEADER *) hGlobal)->bcHeight;// old DIB format
}
break;
case 2:
case 3:
{
HRSRC hResource = FindResource(hCards, MAKEINTRESOURCE(52-28), RT_BITMAP);
HGLOBAL hGlobal = LoadResource(hCards, hResource);
hBrush = CreateDIBPatternBrush(hGlobal, DIB_RGB_COLORS);
width = ((BITMAPCOREHEADER *) hGlobal)->bcWidth; // old DIB format
height = ((BITMAPCOREHEADER *) hGlobal)->bcHeight; // old DIB format
}
}
HGDIOBJ hOld = SelectObject(hDC, hBrush);
POINT P = { i*140+20 + width*i/4, 250 + height*i/4 };
LPtoDP(hDC, &P, 1);
SetBrushOrgEx(hDC, P.x, P.y, NULL); // make sure cards aligned with rectangle
Rectangle(hDC, i*140+20, 250, i*140+20+width*3/2+1, 250+height*3/2+1);
SelectObject(hDC, hOld);
DeleteObject(hBrush);
if ( i==3 )
{
Frame(hDC, i*140+20-10, 250-10, i*140+20+width*3/2+10, 250+height*3/2+10);
// SemiFillRect(hDC, i*140+20-10, 250-10, i*140+20+width*3/2+10, 250+height*3/2+10, RGB(0, 0, 0xFF));
ZoomRect(hDC, i*140+20-10, 250-10, i*140+20+20, 250+20,
580, 240, 6);
}
}
RestoreDC(hDC, nSave);
}
LRESULT KMyCanvas::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lr;
switch( uMsg )
{
case WM_CREATE:
m_hWnd = hWnd;
SetTest(IDM_TEST_DITHER);
rbutton.DefineButton(10, 10, 50, 50);
ebutton.DefineButton(70, 10, 50, 50);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(m_hWnd, &ps);
OnDraw(hDC, &ps.rcPaint);
if ( m_test== IDM_TEST_REGIONOP )
{
rbutton.DrawButton(hDC);
ebutton.DrawButton(hDC);
}
DrawCrossHair(hDC, true);
EndPaint(m_hWnd, &ps);
}
return 0;
case WM_MOUSEMOVE:
{
HDC hDC = GetDC(hWnd);
DrawCrossHair(hDC, false); // erase
m_lastx = LOWORD(lParam); m_lasty = HIWORD(lParam);
if ( m_test==IDM_TEST_REGIONOP )
{
rbutton.UpdateButton(hDC, lParam);
ebutton.UpdateButton(hDC, lParam);
}
DrawCrossHair(hDC, true); // restore
ReleaseDC(hWnd, hDC);
TCHAR temp[32];
wsprintf(temp, _T("(%d, %d)"), m_lastx, m_lasty);
m_pStatus->SetText(0, temp);
}
return 0;
case WM_LBUTTONDOWN:
{
if ( m_test==IDM_TEST_REGIONOP )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -