📄 area.cpp
字号:
static TCHAR mess[128];
RECT rect;
GetRgnBox(hRegion, & rect);
if ( PtInRegion(hRegion, x, y) )
wsprintf(mess, "(%d, %d) in [%d,%d,%d,%d]", x, y, rect.left, rect.top, rect.right, rect.bottom);
else
wsprintf(mess, "(%d, %d) not in [%d,%d,%d,%d]", x, y, rect.left, rect.top, rect.right, rect.bottom);
return mess;
}
BOOL RectContainedInRegion(HRGN hrgn, CONST RECT * lprc)
{
HRGN hCombine = CreateRectRgnIndirect(lprc);
CombineRgn(hCombine, hrgn, hCombine, RGN_OR);
BOOL rslt = EqualRgn(hCombine, hrgn);
DeleteObject(hCombine);
return rslt;
}
void KMyCanvas::TestRegionOper(HDC hDC)
{
HRGN hRgn1 = CreateRectRgn(0, 0, 0, 0);
HRGN hRgn2 = CreateRectRgn(0, 0, 1, 1);
HRGN hRgn3 = CreateRectRgn(1, 1, 1, 1);
HRGN hRgn4 = CreateRectRgn(10, 10, 1, 1);
HRGN hRgn5 = CreateEllipticRgn(10, 10, 1, 1);
HRGN hRgn6 = CreateRectRgn(- (1<<27), - (1<<27), (1<<27)-1, (1<<27)-1);
Label(hDC, 180, 10, TestPtInRegion(0, 0, hRgn1));
Label(hDC, 180, 30, TestPtInRegion(0, 0, hRgn2));
Label(hDC, 180, 50, TestPtInRegion(1, 0, hRgn2));
Label(hDC, 180, 70, TestPtInRegion(1, 1, hRgn3));
Label(hDC, 320, 10, TestPtInRegion(1, 1, hRgn4));
Label(hDC, 320, 30, TestPtInRegion(5, 5, hRgn5));
Label(hDC, 320, 50, TestPtInRegion(5, 5, hRgn6));
if ( EqualRgn(hRgn1, hRgn3) )
Label(hDC, 340, 70, "Empty Set Unique");
else
Label(hDC, 340, 70, "Empty Set Not Unique");
RECT rect = { 2, 2, 4, 5 };
RectContainedInRegion(hRgn4, & rect);
RectContainedInRegion(hRgn2, & rect);
DeleteObject(hRgn1);
DeleteObject(hRgn2);
DeleteObject(hRgn3);
DeleteObject(hRgn4);
DeleteObject(hRgn5);
DeleteObject(hRgn6);
////////////////////////////////
{
HRGN hRgn1 = CreateEllipticRgn(0, 0, 110, 100);
HRGN hRgn2 = CreateEllipticRgn(0, 50, 110, 150);
HBRUSH red = CreateSolidBrush(RGB(0, 0, 0xFF));
for (int i=0; i<6; i++)
{
const TCHAR * Title[] = { "Two Regions", "RGN_AND", "RGN_OR", "RGN_XOR", "RGN_DIFF", "RGN_COPY" };
SetViewportOrgEx(hDC, 20+i*115, 90, NULL);
FrameRgn(hDC, hRgn1, red, 1, 1);
FrameRgn(hDC, hRgn2, red, 1, 1);
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
switch ( i )
{
case 1: CombineRgn(hRgn, hRgn1, hRgn2, RGN_AND); break;
case 2: CombineRgn(hRgn, hRgn1, hRgn2, RGN_OR); break;
case 3: CombineRgn(hRgn, hRgn1, hRgn2, RGN_XOR); break;
case 4: CombineRgn(hRgn, hRgn1, hRgn2, RGN_DIFF); break;
case 5: CombineRgn(hRgn, hRgn1, hRgn2, RGN_COPY); break;
}
KGDIObject brush(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0)));
PaintRgn(hDC, hRgn);
DeleteObject(hRgn);
Label(hDC, 0, 160, Title[i]);
}
}
// Test GetRegionData
{
HBRUSH brush[2];
brush[0] = CreateSolidBrush(RGB(0, 0, 0xFF));
brush[1] = CreateSolidBrush(RGB(0xFF, 0xFF, 0));
for (int i=0; i<4; i++)
{
SetViewportOrgEx(hDC, 20+i*170, 280, NULL);
HRGN hRgn;
const TCHAR * desp1[] = { "CreateRectRgn",
"CreateRoundRectRgn",
"CreateEllipticRgn",
"CreatePolygonRgn"
};
const TCHAR * desp2[] = { "(0, 0, 21, 21)",
"(0, 0, 21, 21, 10, 10)",
"(0, 0, 21, 21)",
"(0, 0, 21, 0, 10, 21)"
};
switch (i)
{
case 0: hRgn = CreateRectRgn(0, 0, 21, 21); break;
case 1: hRgn = CreateRoundRectRgn(0, 0, 21, 21, 10, 10); break;
case 2: hRgn = CreateEllipticRgn(0, 0, 21, 21); break;
case 3: {
POINT P[] = { 0, 0, 21, 0, 10, 21 };
hRgn = CreatePolygonRgn(P, 3, WINDING);
}
}
KRegion region;
region.GetRegionData(hRgn);
// DeleteObject(hRgn);
TCHAR temp[64];
RECT rect = region.m_pRegion->rdh.rcBound;
Label(hDC, 0, 148, desp1[i]);
Label(hDC, 0, 168, desp2[i]);
wsprintf(temp, "rcBound: [%d, %d, %d, %d]", rect.left, rect.top, rect.right, rect.bottom);
Label(hDC, 0, 190, temp);
wsprintf(temp, "nCount : %d", region.m_nRectCount);
Label(hDC, 0, 210, temp);
wsprintf(temp, "Size : %d bytes", region.m_nRegionSize);
Label(hDC, 0, 230, temp);
Rectangle(hDC, rect.left * 7, rect.top*7, rect.right*7, rect.bottom*7);
for (int j=0; j<region.m_nRectCount; j++)
{
rect = region.m_pRect[j];
rect.left *= 7;
rect.right *= 7;
rect.top *= 7;
rect.bottom *= 7;
FillRect(hDC, & rect, brush[j&1]);
}
/////////// Play with ExtCreateRegion
if ( region.m_nRectCount>=2 )
{
RECT r = region.m_pRect[0];
region.m_pRect[0] = region.m_pRect[region.m_nRectCount-1];
region.m_pRect[region.m_nRectCount-1] = r;
}
// {
// long t = region.m_pRect[0].left;
// region.m_pRect[0].left = region.m_pRect[0].right;
// region.m_pRect[0].right = t;
// }
HRGN hRgn1 = region.CreateRegion(NULL);
if ( hRgn1 )
Label(hDC, 0, 250, "OK");
else
Label(hDC, 0, 250, "Fail");
if ( hRgn1 )
{
GetRgnBox(hRgn1, & rect);
wsprintf(temp, "rcBound: [%d, %d, %d, %d]", rect.left, rect.top, rect.right, rect.bottom);
Label(hDC, 0, 270, temp);
if ( EqualRgn(hRgn, hRgn1) )
Label(hDC, 100, 250, "Equal");
else
Label(hDC, 100, 250, "Not Equal");
SetViewportOrgEx(hDC, 20+i*170, 280+300, NULL);
Rectangle(hDC, rect.left * 7, rect.top*7, rect.right*7, rect.bottom*7);
region.GetRegionData(hRgn1);
for (int j=0; j<region.m_nRectCount; j++)
{
rect = region.m_pRect[j];
rect.left *= 7;
rect.right *= 7;
rect.top *= 7;
rect.bottom *= 7;
FillRect(hDC, & rect, brush[j&1]);
}
DeleteObject(hRgn1);
}
DeleteObject(hRgn);
}
DeleteObject(brush[0]);
DeleteObject(brush[1]);
}
/*
{
RGNDATA rgn[5];
RECT rr = { 0, 0, 100, 100 };
rgn[0].rdh.dwSize = sizeof(rgn[0].rdh);
rgn[0].rdh.iType = RDH_RECTANGLES;
rgn[0].rdh.nCount = 2;
rgn[0].rdh.nRgnSize = 2 * sizeof(RECT);
rgn[0].rdh.rcBound = rr;
memcpy(rgn[0].Buffer, & rr, sizeof(rr));
memcpy(rgn[0].Buffer+sizeof(rr), & rr, sizeof(rr));
HRGN hRgn = ExtCreateRegion(NULL, sizeof(rgn), rgn);
}
*/
SetViewportOrgEx(hDC, 0, 0, NULL);
}
void KMyCanvas::TestRegionPaint(HDC hDC)
{
HBRUSH yellow = CreateSolidBrush(RGB(0, 0, 0xFF));
HPEN blue = CreatePen(PS_SOLID, 3, RGB(0xFF, 0xFF, 0));
SelectObject(hDC, blue);
SelectObject(hDC, yellow);
// SetBkMode(hDC, TRANSPARENT);
SetROP2(hDC, R2_MASKNOTPEN);
RoundRect(hDC, 50, 50, 130, 150, 40, 40); Label(hDC, 50, 160, "RoundRect");
HRGN hRgn = CreateRoundRectRgn(50, 50, 130, 150, 40, 40);
OffsetRgn(hRgn, 90, 0); PaintRgn(hDC, hRgn); Label(hDC, 140, 30, "PaintRgn");
OffsetRgn(hRgn, 90, 0); FillRgn(hDC, hRgn, yellow); Label(hDC, 230, 160, "FillRgn");
OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn, yellow, 1, 1); Label(hDC, 320, 30, "FrameRgn(1,1)");
OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn, yellow, 1, 10); Label(hDC, 410, 160, "FrameRgn(1,10)");
OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn, yellow, 10, 1); Label(hDC, 500, 30, "FrameRgn(10,1)");
OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn, yellow, 10, 10); Label(hDC, 590, 160, "FrameRgn(10,10)");
OffsetRgn(hRgn, 90, 0); InvertRgn(hDC, hRgn); Label(hDC, 680, 30, "InvertRgn");
DeleteObject(hRgn);
int nSave = SaveDC(hDC);
SetMapMode(hDC, MM_ANISOTROPIC);
SetViewportOrgEx(hDC, 200, 200, NULL);
SetViewportExtEx(hDC, 15, 15, NULL);
hRgn = CreateRoundRectRgn(0, 0, 20, 20, 10, 10);
FrameRgn(hDC, hRgn, yellow, 1, 1);
DeleteObject(hRgn);
RestoreDC(hDC, nSave);
SelectObject(hDC, GetStockObject(WHITE_BRUSH));
SelectObject(hDC, GetStockObject(BLACK_PEN));
DeleteObject(yellow);
DeleteObject(blue);
// SetBkMode(hDC, OPAQUE);
SetROP2(hDC, R2_COPYPEN);
}
class KGradient
{
COLORREF m_c0;
COLORREF m_c1;
TRIVERTEX m_vertex[12];
ULONG m_index [12];
public:
KGradient(COLORREF c0, COLORREF c1)
{
m_c0 = c0;
m_c1 = c1;
}
void Define(int i, int x, int y, int cr);
BOOL Fill(HDC hDC, int nVertex, int nMesh, DWORD nMode, const POINT * pPoint, const int *pColor);
};
void KGradient::Define(int i, int x, int y, int c)
{
m_index[i] = i;
m_vertex[i].x = x;
m_vertex[i].y = y;
m_vertex[i].Red = ( ( GetRValue(m_c0) * c + GetRValue(m_c1) * (2-c) ) / 2 ) << 8;
m_vertex[i].Green = ( ( GetGValue(m_c0) * c + GetGValue(m_c1) * (2-c) ) / 2 ) << 8;
m_vertex[i].Blue = ( ( GetBValue(m_c0) * c + GetBValue(m_c1) * (2-c) ) / 2 ) << 8;
m_vertex[i].Alpha = 0;
}
BOOL KGradient::Fill(HDC hDC, int nVertex, int nMesh, DWORD nMode, const POINT * pPoint, const int *pColor)
{
for (int i=0; i<nVertex; i++)
Define(i, pPoint[i].x, pPoint[i].y, pColor[i]);
return ::GradientFill(hDC, m_vertex, nVertex, m_index, nMesh, nMode);
}
void KMyCanvas::TestGradientFill(HDC hDC)
{
const COLORREF c0 = RGB(0x20, 0x20, 0x20);
const COLORREF c1 = RGB(0xF0, 0xF0, 0x20);
for (int i=0; i<4; i++)
GradientRectangle(hDC, 100+110*i, 50, 200+110*i, 150, c0, c1, i*45);
for (i=0; i<4; i++)
SymGradientRectangle(hDC, 100+110*i, 160, 200+110*i, 260, c0, c1, i*45);
for (i=0; i<4; i++)
CornerGradientRectangle(hDC, 100+110*i, 270, 200+110*i, 370, c0, c1, i);
CenterGradientRectangle(hDC, 560, 150, 660, 250, c0, c1);
CenterGradientRectangle(hDC, 560, 260, 660, 360, c1, c0);
// Buttons
SetViewportOrgEx(hDC, 20, 400, NULL);
RoundRectButton(hDC, 0, 0, 80, 80, 0, 10, RGB(0x20, 0x20, 0x20), RGB(0xF0, 0xF0, 0x20));
RoundRectButton(hDC, 100, 0, 180, 80, 40, 10, RGB(0xF0, 0x20, 0x20), RGB(0x20, 0xF0, 0x20));
RoundRectButton(hDC, 200, 0, 280, 80, 80, 10, RGB(0xFF, 0xFF, 0x20), RGB(0x20, 0x20, 0xF0));
GradientRectangle(hDC, 0, 100, 200, 200, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 0);
HLSGradientRectangle(hDC, 0, 220, 200, 320, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 200);
RadialGradientFill(hDC, 400, 150, 400 , 150 , 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 8);
RadialGradientFill(hDC, 620, 150, 620-30, 150-60, 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 16);
RadialGradientFill(hDC, 840, 150, 840-30, 150+30, 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 256);
SetViewportOrgEx(hDC, 0, 0, NULL);
{
RECT r = { 700, 50, 850, 50+150 };
KGDIObject blue(hDC, CreatePen(PS_SOLID, 3, RGB(0, 0, 0xFF)));
KGDIObject yellow(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0)));
Rectangle(hDC, 700, 50, 850, 50+150);
BrickPatternFill(hDC, 700, 50, 850, 50+150, 15, 15);
BrickPatternFill(hDC, 860, 50, 860+150, 50+150, 10, 10);
}
}
void KMyCanvas::OnDraw(HDC hDC, const RECT * rcPaint)
{
switch ( m_test )
{
case IDM_TEST_DITHER: TestDither(hDC); break;
case IDM_TEST_HATCHBRUSH: TestHatch(hDC); break;
case IDM_TEST_SYSCOLORBRUSH: TestSysColorBrush(hDC); break;
case IDM_TEST_RECTANGLE: TestRectangle(hDC); break;
case IDM_TEST_DRAWFRAMECONTROL: TestDrawFrameControl(hDC); break;
case IDM_TEST_ELLIPSE: TestEllipse(hDC); break;
case IDM_TEST_PIECHART: TestPieChart(hDC); break;
case IDM_TEST_POLYFILLMODE: TestPolyFillMode(hDC); break;
case IDM_TEST_FILLPATH: TestFillPath(hDC); break;
case IDM_TEST_REGION: TestRegion(hDC); break;
case IDM_TEST_REGIONOP: TestRegionOper(hDC); break;
case IDM_TEST_REGIONPAINT: TestRegionPaint(hDC); break;
case IDM_TEST_GRADIENTFILL: TestGradientFill(hDC); break;
}
}
class KMyFrame : public KFrame
{
virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ( uMsg==WM_NCPAINT )
{
KFrame::WndProc(hWnd, uMsg, wParam, lParam);
HDC hDC = GetDCEx(hWnd, (HRGN) wParam, 0x10000 | DCX_WINDOW|DCX_INTERSECTRGN);
RECT rect;
GetWindowRect(hWnd, & rect);
OffsetRect(&rect, - rect.left, - rect.top);
for (int i=0; i<4; i++)
{
FrameRect(hDC, & rect, GetSysColorBrush(COLOR_SCROLLBAR+i));
InflateRect(&rect, -1, -1);
}
ReleaseDC(hWnd, hDC);
return 0;
}
else
return KFrame::WndProc(hWnd, uMsg, wParam, lParam);
}
void GetWndClassEx(WNDCLASSEX & wc)
{
KFrame::GetWndClassEx(wc);
wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_AREA));
}
public:
KMyFrame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
KToolbar * pToolbar, KCanvas * pCanvas, KStatusWindow * pStatus) :
KFrame(hInstance, pButtons, nCount, pToolbar, pCanvas, pStatus)
{
}
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
{
KMyCanvas canvas;
KStatusWindow status;
KMyFrame frame(hInst, NULL, 0, NULL, & canvas, & status);
frame.CreateEx(0, _T("AreaDemo"), _T("Areas"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
frame.ShowWindow(nShow);
frame.UpdateWindow();
frame.MessageLoop();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -