|
|
#include "gdiptest.h"
//*******************************************************************
//
// TestShapeRegion
//
//
//
//*******************************************************************
BOOL TestShapeRegion :: ChangeSettings(HWND hwndParent) { BOOL ok = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SHAPE_DLG), hwndParent, AllDialogBox, (LPARAM)((TestDialogInterface*)this));
if (ok) { // discard the saved original tree
delete origTree; origTree = NULL;
return TRUE; } else { // restore original clip region tree
delete clipTree; clipTree = origTree; origTree = NULL; return FALSE; } }
VOID TestShapeRegion :: Initialize() { shapeStack = NULL; }
VOID TestShapeRegion :: Initialize(ShapeStack *stack, TestShape* current, BOOL useClip) { origUseClip = useClip;
origStack = stack;
shapeStack->Reset();
shapeStack->Push(current); for (INT pos = stack->GetCount()-1; pos>=0; pos--) { TestShape* shape = stack->GetPosition(pos);
shapeStack->Push(shape); shape->dwFlags = shape->GetDisabled() ? ShapeDisabled : 0; }
origTree = clipTree->Clone(); }
VOID TestShapeRegion :: AddClipNode(HWND hwnd, NodeType newType) { TestShape* curShape = NULL;
TVITEMEX itemex; HWND hwndList; HWND hwndTree;
if (newType == DataNode) { hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST); INT curIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0); DeleteObject(hwndList); if (curIndex == LB_ERR) { DeleteObject(hwndList); WarningBox(_T("Failed to find shape in list.")); return; } else if (curIndex == 0) { DeleteObject(hwndList); WarningBox(_T("Can't add current (incomplete) shape in list.")); return; } curShape = shapeStack->GetPosition(curIndex); } hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
if (!curSelect) { DeleteObject(hwndTree); WarningBox(_T("No clip item selected.")); return; }
itemex.hItem = (HTREEITEM) curSelect; itemex.mask = TVIF_PARAM;
if (TreeView_GetItem(hwndTree, &itemex)) { ClipTree* curNode = (ClipTree*) itemex.lParam;
// we found current item
ClipTree* newNode = new ClipTree(newType, curShape); if (newType == DataNode) {
// if item is 'AND', 'OR' ,'XOR' then add as child
if (curNode->type != DataNode) { itemex.cChildren = 1; itemex.mask = TVIF_CHILDREN; TreeView_SetItem(hwndTree, &itemex);
curNode->AddChild(newNode); } else { // add as sibling to current node
curNode->AddSibling(newNode); }
// since node has no right siblings or children,
// this should add in relation to node's parent and
// left sibling.
newNode->AddToTreeView(hwndTree); } else { // we are adding an AND, XOR, OR node.
if (curNode->type != DataNode) { // simply change the current node's value
curNode->type = newType; if (curNode->nodeName) free(curNode->nodeName); curNode->nodeName = ClipTree::GetNodeName(curNode->type, curNode->notNode, curNode->data);
itemex.pszText = curNode->nodeName; itemex.cchTextMax = _tcslen(itemex.pszText)+1; itemex.mask = TVIF_TEXT; TreeView_SetItem(hwndTree, &itemex);
delete newNode; newNode = NULL; } else { // adding an operand type to non-operand node
// replace current node with ourselves and add
// them as parent
curNode->AddAsParent(newNode);
// delete old data item
TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM()); // add new operand node
newNode->AddToTreeView(hwndTree); // recreate data item subtree under operand node
curNode->CreateTreeView(hwndTree);
clipTree = newNode->GetRoot();
// fool select below...
newNode = curNode; } }
if (newNode) TreeView_SelectItem(hwndTree, newNode->GetHTREEITEM()); } else WarningBox(_T("Failed to find selected tree node."));
DeleteObject(hwndTree); }
VOID TestShapeRegion :: RemoveClipNode(HWND hwnd) { HWND hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
if (!curSelect) { DeleteObject(hwndTree); WarningBox(_T("No clip node selected.")); return; }
TVITEMEX itemex; itemex.hItem = (HTREEITEM) curSelect; itemex.mask = TVIF_PARAM;
if (TreeView_GetItem(hwndTree, &itemex)) { // we found current item
ClipTree* curNode = (ClipTree*) itemex.lParam;
if (curSelect == clipTree->GetHTREEITEM()) { DeleteObject(hwndTree); WarningBox(_T("Can't delete root of tree.")); return; }
ClipTree* nextFocusNode;
if (curNode->prevSibling) nextFocusNode = curNode->GetPrevSibling(); else if (curNode->nextSibling) nextFocusNode = curNode->GetNextSibling(); else nextFocusNode = curNode->GetParent();
if (curNode->HasChildren()) { if (MessageBox(hwnd, _T("Remove All Children Regions?"), _T(""), MB_YESNO) == IDYES) { TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM());
// delete all children
delete curNode; } else { ClipTree* parent = curNode->GetParent();
nextFocusNode = curNode->GetFirstChild();
// merge children with parent node
curNode->MoveChildrenToParent();
delete curNode;
// delete parent's subtree, then add it back
TreeView_DeleteItem(hwndTree, parent->GetHTREEITEM());
// recreate tree view based on new hierarchy
parent->CreateTreeView(hwndTree);
clipTree = parent->GetRoot(); } } else { // no children, just remove this single node
TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM());
delete curNode; }
if (nextFocusNode) TreeView_SelectItem(hwndTree, nextFocusNode->GetHTREEITEM()); } else WarningBox(_T("Failed to find selected tree."));
DeleteObject(hwndTree); }
VOID TestShapeRegion :: ToggleNotNode(HWND hwnd) { HWND hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
if (!curSelect) { DeleteObject(hwndTree); WarningBox(_T("No clip item selected.")); return; }
TVITEMEX itemex; itemex.hItem = (HTREEITEM) curSelect; itemex.mask = TVIF_PARAM;
if (TreeView_GetItem(hwndTree, &itemex)) { // we found current item
ClipTree* curNode = (ClipTree*) itemex.lParam;
curNode->notNode = !curNode->notNode;
free(curNode->nodeName);
itemex.pszText = curNode->nodeName = ClipTree::GetNodeName(curNode->type, curNode->notNode, curNode->data); itemex.mask = TVIF_HANDLE | TVIF_TEXT; TreeView_SetItem(hwndTree, &itemex); }
DeleteObject(hwndTree); }
VOID TestShapeRegion :: ShiftCurrentShape(HWND hwnd, INT dir) { HWND hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST);
INT curSel = SendMessage(hwndList, LB_GETCURSEL, 0, 0); INT maxList = SendMessage(hwndList, LB_GETCOUNT, 0, 0);
if (curSel == LB_ERR) { WarningBox(_T("No shape selected.")); DeleteObject(hwndList); return; } else if (dir<0 && curSel <= 1) { WarningBox(_T("Can't move up!")); DeleteObject(hwndList); return; } else if (dir>0 && (curSel == maxList-1 || curSel == 0)) { WarningBox(_T("Can't move down!")); DeleteObject(hwndList); return; }
// swap shape items to shift up or down
TestShape** shapeList = shapeStack->GetDataBuffer(); TestShape* swapTemp = NULL;
swapTemp = shapeList[curSel+dir]; shapeList[curSel+dir] = shapeList[curSel]; shapeList[curSel] = swapTemp;
SendMessage(hwndList, LB_DELETESTRING, (WPARAM) curSel+dir, 0);
SendMessage(hwndList, LB_INSERTSTRING, curSel, (LPARAM) shapeList[curSel]->GetShapeName());
DeleteObject(hwndList); }
VOID TestShapeRegion :: ToggleDisableShape(HWND hwnd) { HWND hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST);
INT curSel = SendMessage(hwndList, LB_GETCURSEL, 0, 0); if (curSel == LB_ERR) { WarningBox(_T("No shape selected.")); DeleteObject(hwndList); return; }
TestShape* shape = shapeStack->GetPosition(curSel);
// toggle disable state of shape
shape->dwFlags ^= ShapeDisabled;
// SetDisabled(!shape->GetDisabled());
// name may change based on disabled status
SendMessage(hwndList, LB_DELETESTRING, (WPARAM) curSel, 0);
SendMessage(hwndList, LB_INSERTSTRING, (WPARAM) curSel, (LPARAM) shape->GetShapeName()); SendMessage(hwndList, LB_SETCURSEL, (WPARAM) curSel, 0);
DeleteObject(hwndList); }
VOID TestShapeRegion :: UpdateShapePicture(HWND hwnd) { HWND hwndShape; HDC hdcPic; HWND hwndFrame; HDC hdcFrame; RECT rectDst; SIZE size;
INT curSel;
hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST); curSel = SendMessage(hwndShape, LB_GETCURSEL, 0, 0);
hwndFrame = GetDlgItem(hwnd, IDC_SHAPE_PIC); GetClientRect(hwndFrame, &rectDst); hdcFrame = GetDC(hwndFrame);
if (curSel == LB_ERR || curSel <= 0) { badpic: // white GDI brush
HBRUSH hbr = CreateSolidBrush(0x00FFFFFF);
FillRect(hdcFrame, &rectDst, hbr);
DeleteObject(hbr); DeleteObject(hwndFrame); DeleteObject(hdcFrame); DeleteObject(hwndShape); return; }
hdcPic = shapeStack->GetPosition(curSel)->CreatePictureDC(hwnd, &rectDst); if (!hdcPic) goto badpic; // blit shape picture into the given frame
// NOTE: should be same size
BitBlt(hdcFrame, rectDst.left, rectDst.top, rectDst.right - rectDst.left, rectDst.bottom - rectDst.top, hdcPic, 0, 0, SRCCOPY);
ReleaseDC(hwndFrame, hdcFrame); DeleteObject(hwndFrame); DeleteObject(hwndShape); }
VOID TestShapeRegion :: CleanUpPictures(HWND hwnd) { HWND hwndShape; HDC hdcPic; INT count;
// !! This code is obsolete,
// it should only be used if we wish to recreate the pictures on
// each iteration
/*
hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST);
count = SendMessage(hwndShape, LB_GETCOUNT, 0, 0);
// clean up picture hwnd for each picture...
for (INT pos = 0; pos < count; pos++) { hdcPic = (HDC) SendMessage(hwndShape, LB_GETITEMDATA, (WPARAM)pos, 0); if (hdcPic) DeleteDC(hdcPic); }
DeleteObject(hwndShape); */ }
VOID TestShapeRegion :: InitDialog(HWND hwnd) { HWND hwndTV; HWND hwndShape;
RECT frameRect; HWND hwndFrame;
hwndFrame = GetDlgItem(hwnd, IDC_SHAPE_PIC); GetWindowRect(hwndFrame, &frameRect); DeleteObject(hwndFrame);
// display list of shapes
hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST); for (INT pos = 0; pos < shapeStack->GetCount(); pos++) { TestShape* shape = shapeStack->GetPosition(pos);
SendMessage(hwndShape, LB_ADDSTRING, 0, (LPARAM)shape->GetShapeName()); } DeleteObject(hwndShape);
// add root of clip region tree to Tree View control
// for display/editing
hwndTV = GetDlgItem(hwnd, IDC_CLIP_TREE); clipTree = clipTree->GetRoot();
HTREEITEM topTree = clipTree->CreateTreeView(hwndTV);
// select root of tree
TreeView_SelectItem(hwndTV, topTree);
// expand entire tree
TreeView_Expand(hwndTV, topTree, TVM_EXPAND);
DeleteObject(hwndTV);
SetDialogCheck(hwnd, IDC_CLIP_BOOL, origUseClip); }
BOOL TestShapeRegion :: SaveValues(HWND hwnd) { origUseClip = GetDialogCheck(hwnd, IDC_CLIP_BOOL); origStack->Reset();
for (INT pos = shapeStack->GetCount()-1; pos >= 1; pos--) { TestShape* shape = shapeStack->GetPosition(pos);
origStack->Push(shape); shape->SetDisabled(shape->dwFlags & ShapeDisabled); } return FALSE; }
BOOL TestShapeRegion :: ProcessDialog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_COMMAND) { switch(LOWORD(wParam)) { case IDC_OK: if (SaveValues(hwnd)) WarningBeep(); else { CleanUpPictures(hwnd); ::EndDialog(hwnd, TRUE); } break;
case IDC_SHAPE_UP: ShiftCurrentShape(hwnd, -1); break;
case IDC_SHAPE_DOWN: ShiftCurrentShape(hwnd, +1); break;
case IDC_SHAPE_DISABLE: ToggleDisableShape(hwnd); break; case IDC_SHAPE_PEN: case IDC_SHAPE_BRUSH: break;
case IDC_CLIP_ADD: AddClipNode(hwnd); break;
case IDC_CLIP_REMOVE: RemoveClipNode(hwnd); break;
case IDC_CLIP_AND: AddClipNode(hwnd, AndNode); break;
case IDC_CLIP_OR: AddClipNode(hwnd, OrNode); break;
case IDC_CLIP_XOR: AddClipNode(hwnd, XorNode); break;
case IDC_CLIP_NOT: ToggleNotNode(hwnd); break;
case IDC_SHAPE_LIST: if (HIWORD(wParam) == LBN_SELCHANGE) UpdateShapePicture(hwnd); break;
case IDC_REFRESH_PIC: UpdateShapePicture(hwnd); break;
case IDC_CANCEL: CleanUpPictures(hwnd); ::EndDialog(hwnd, FALSE); break;
default: return FALSE; }
return TRUE; }
return FALSE; }
Region* TestShapeRegion :: GetClipRegion() { // caller must free
return clipTree->GetRegion(); }
|