Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

623 lines
13 KiB

  1. #include "gdiptest.h"
  2. //*******************************************************************
  3. //
  4. // TestShapeRegion
  5. //
  6. //
  7. //
  8. //*******************************************************************
  9. BOOL TestShapeRegion :: ChangeSettings(HWND hwndParent)
  10. {
  11. BOOL ok = DialogBoxParam(hInst,
  12. MAKEINTRESOURCE(IDD_SHAPE_DLG),
  13. hwndParent,
  14. AllDialogBox,
  15. (LPARAM)((TestDialogInterface*)this));
  16. if (ok)
  17. {
  18. // discard the saved original tree
  19. delete origTree;
  20. origTree = NULL;
  21. return TRUE;
  22. }
  23. else
  24. {
  25. // restore original clip region tree
  26. delete clipTree;
  27. clipTree = origTree;
  28. origTree = NULL;
  29. return FALSE;
  30. }
  31. }
  32. VOID TestShapeRegion :: Initialize()
  33. {
  34. shapeStack = NULL;
  35. }
  36. VOID TestShapeRegion :: Initialize(ShapeStack *stack,
  37. TestShape* current,
  38. BOOL useClip)
  39. {
  40. origUseClip = useClip;
  41. origStack = stack;
  42. shapeStack->Reset();
  43. shapeStack->Push(current);
  44. for (INT pos = stack->GetCount()-1; pos>=0; pos--)
  45. {
  46. TestShape* shape = stack->GetPosition(pos);
  47. shapeStack->Push(shape);
  48. shape->dwFlags = shape->GetDisabled()
  49. ? ShapeDisabled : 0;
  50. }
  51. origTree = clipTree->Clone();
  52. }
  53. VOID TestShapeRegion :: AddClipNode(HWND hwnd, NodeType newType)
  54. {
  55. TestShape* curShape = NULL;
  56. TVITEMEX itemex;
  57. HWND hwndList;
  58. HWND hwndTree;
  59. if (newType == DataNode)
  60. {
  61. hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  62. INT curIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
  63. DeleteObject(hwndList);
  64. if (curIndex == LB_ERR)
  65. {
  66. DeleteObject(hwndList);
  67. WarningBox(_T("Failed to find shape in list."));
  68. return;
  69. }
  70. else if (curIndex == 0)
  71. {
  72. DeleteObject(hwndList);
  73. WarningBox(_T("Can't add current (incomplete) shape in list."));
  74. return;
  75. }
  76. curShape = shapeStack->GetPosition(curIndex);
  77. }
  78. hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
  79. HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
  80. if (!curSelect)
  81. {
  82. DeleteObject(hwndTree);
  83. WarningBox(_T("No clip item selected."));
  84. return;
  85. }
  86. itemex.hItem = (HTREEITEM) curSelect;
  87. itemex.mask = TVIF_PARAM;
  88. if (TreeView_GetItem(hwndTree, &itemex))
  89. {
  90. ClipTree* curNode = (ClipTree*) itemex.lParam;
  91. // we found current item
  92. ClipTree* newNode = new ClipTree(newType, curShape);
  93. if (newType == DataNode)
  94. {
  95. // if item is 'AND', 'OR' ,'XOR' then add as child
  96. if (curNode->type != DataNode)
  97. {
  98. itemex.cChildren = 1;
  99. itemex.mask = TVIF_CHILDREN;
  100. TreeView_SetItem(hwndTree, &itemex);
  101. curNode->AddChild(newNode);
  102. }
  103. else
  104. {
  105. // add as sibling to current node
  106. curNode->AddSibling(newNode);
  107. }
  108. // since node has no right siblings or children,
  109. // this should add in relation to node's parent and
  110. // left sibling.
  111. newNode->AddToTreeView(hwndTree);
  112. }
  113. else
  114. {
  115. // we are adding an AND, XOR, OR node.
  116. if (curNode->type != DataNode)
  117. {
  118. // simply change the current node's value
  119. curNode->type = newType;
  120. if (curNode->nodeName)
  121. free(curNode->nodeName);
  122. curNode->nodeName = ClipTree::GetNodeName(curNode->type,
  123. curNode->notNode,
  124. curNode->data);
  125. itemex.pszText = curNode->nodeName;
  126. itemex.cchTextMax = _tcslen(itemex.pszText)+1;
  127. itemex.mask = TVIF_TEXT;
  128. TreeView_SetItem(hwndTree, &itemex);
  129. delete newNode;
  130. newNode = NULL;
  131. }
  132. else
  133. {
  134. // adding an operand type to non-operand node
  135. // replace current node with ourselves and add
  136. // them as parent
  137. curNode->AddAsParent(newNode);
  138. // delete old data item
  139. TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM());
  140. // add new operand node
  141. newNode->AddToTreeView(hwndTree);
  142. // recreate data item subtree under operand node
  143. curNode->CreateTreeView(hwndTree);
  144. clipTree = newNode->GetRoot();
  145. // fool select below...
  146. newNode = curNode;
  147. }
  148. }
  149. if (newNode)
  150. TreeView_SelectItem(hwndTree, newNode->GetHTREEITEM());
  151. }
  152. else
  153. WarningBox(_T("Failed to find selected tree node."));
  154. DeleteObject(hwndTree);
  155. }
  156. VOID TestShapeRegion :: RemoveClipNode(HWND hwnd)
  157. {
  158. HWND hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
  159. HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
  160. if (!curSelect)
  161. {
  162. DeleteObject(hwndTree);
  163. WarningBox(_T("No clip node selected."));
  164. return;
  165. }
  166. TVITEMEX itemex;
  167. itemex.hItem = (HTREEITEM) curSelect;
  168. itemex.mask = TVIF_PARAM;
  169. if (TreeView_GetItem(hwndTree, &itemex))
  170. {
  171. // we found current item
  172. ClipTree* curNode = (ClipTree*) itemex.lParam;
  173. if (curSelect == clipTree->GetHTREEITEM())
  174. {
  175. DeleteObject(hwndTree);
  176. WarningBox(_T("Can't delete root of tree."));
  177. return;
  178. }
  179. ClipTree* nextFocusNode;
  180. if (curNode->prevSibling)
  181. nextFocusNode = curNode->GetPrevSibling();
  182. else if (curNode->nextSibling)
  183. nextFocusNode = curNode->GetNextSibling();
  184. else
  185. nextFocusNode = curNode->GetParent();
  186. if (curNode->HasChildren())
  187. {
  188. if (MessageBox(hwnd, _T("Remove All Children Regions?"), _T(""), MB_YESNO) == IDYES)
  189. {
  190. TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM());
  191. // delete all children
  192. delete curNode;
  193. }
  194. else
  195. {
  196. ClipTree* parent = curNode->GetParent();
  197. nextFocusNode = curNode->GetFirstChild();
  198. // merge children with parent node
  199. curNode->MoveChildrenToParent();
  200. delete curNode;
  201. // delete parent's subtree, then add it back
  202. TreeView_DeleteItem(hwndTree, parent->GetHTREEITEM());
  203. // recreate tree view based on new hierarchy
  204. parent->CreateTreeView(hwndTree);
  205. clipTree = parent->GetRoot();
  206. }
  207. }
  208. else
  209. {
  210. // no children, just remove this single node
  211. TreeView_DeleteItem(hwndTree, curNode->GetHTREEITEM());
  212. delete curNode;
  213. }
  214. if (nextFocusNode)
  215. TreeView_SelectItem(hwndTree, nextFocusNode->GetHTREEITEM());
  216. }
  217. else
  218. WarningBox(_T("Failed to find selected tree."));
  219. DeleteObject(hwndTree);
  220. }
  221. VOID TestShapeRegion :: ToggleNotNode(HWND hwnd)
  222. {
  223. HWND hwndTree = GetDlgItem(hwnd, IDC_CLIP_TREE);
  224. HTREEITEM curSelect = TreeView_GetSelection(hwndTree);
  225. if (!curSelect)
  226. {
  227. DeleteObject(hwndTree);
  228. WarningBox(_T("No clip item selected."));
  229. return;
  230. }
  231. TVITEMEX itemex;
  232. itemex.hItem = (HTREEITEM) curSelect;
  233. itemex.mask = TVIF_PARAM;
  234. if (TreeView_GetItem(hwndTree, &itemex))
  235. {
  236. // we found current item
  237. ClipTree* curNode = (ClipTree*) itemex.lParam;
  238. curNode->notNode = !curNode->notNode;
  239. free(curNode->nodeName);
  240. itemex.pszText = curNode->nodeName =
  241. ClipTree::GetNodeName(curNode->type,
  242. curNode->notNode,
  243. curNode->data);
  244. itemex.mask = TVIF_HANDLE | TVIF_TEXT;
  245. TreeView_SetItem(hwndTree, &itemex);
  246. }
  247. DeleteObject(hwndTree);
  248. }
  249. VOID TestShapeRegion :: ShiftCurrentShape(HWND hwnd, INT dir)
  250. {
  251. HWND hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  252. INT curSel = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
  253. INT maxList = SendMessage(hwndList, LB_GETCOUNT, 0, 0);
  254. if (curSel == LB_ERR)
  255. {
  256. WarningBox(_T("No shape selected."));
  257. DeleteObject(hwndList);
  258. return;
  259. }
  260. else if (dir<0 && curSel <= 1)
  261. {
  262. WarningBox(_T("Can't move up!"));
  263. DeleteObject(hwndList);
  264. return;
  265. }
  266. else if (dir>0 && (curSel == maxList-1 || curSel == 0))
  267. {
  268. WarningBox(_T("Can't move down!"));
  269. DeleteObject(hwndList);
  270. return;
  271. }
  272. // swap shape items to shift up or down
  273. TestShape** shapeList = shapeStack->GetDataBuffer();
  274. TestShape* swapTemp = NULL;
  275. swapTemp = shapeList[curSel+dir];
  276. shapeList[curSel+dir] = shapeList[curSel];
  277. shapeList[curSel] = swapTemp;
  278. SendMessage(hwndList, LB_DELETESTRING, (WPARAM) curSel+dir, 0);
  279. SendMessage(hwndList, LB_INSERTSTRING, curSel,
  280. (LPARAM) shapeList[curSel]->GetShapeName());
  281. DeleteObject(hwndList);
  282. }
  283. VOID TestShapeRegion :: ToggleDisableShape(HWND hwnd)
  284. {
  285. HWND hwndList = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  286. INT curSel = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
  287. if (curSel == LB_ERR)
  288. {
  289. WarningBox(_T("No shape selected."));
  290. DeleteObject(hwndList);
  291. return;
  292. }
  293. TestShape* shape = shapeStack->GetPosition(curSel);
  294. // toggle disable state of shape
  295. shape->dwFlags ^= ShapeDisabled;
  296. // SetDisabled(!shape->GetDisabled());
  297. // name may change based on disabled status
  298. SendMessage(hwndList, LB_DELETESTRING, (WPARAM) curSel, 0);
  299. SendMessage(hwndList, LB_INSERTSTRING, (WPARAM) curSel,
  300. (LPARAM) shape->GetShapeName());
  301. SendMessage(hwndList, LB_SETCURSEL, (WPARAM) curSel, 0);
  302. DeleteObject(hwndList);
  303. }
  304. VOID TestShapeRegion :: UpdateShapePicture(HWND hwnd)
  305. {
  306. HWND hwndShape;
  307. HDC hdcPic;
  308. HWND hwndFrame;
  309. HDC hdcFrame;
  310. RECT rectDst;
  311. SIZE size;
  312. INT curSel;
  313. hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  314. curSel = SendMessage(hwndShape, LB_GETCURSEL, 0, 0);
  315. hwndFrame = GetDlgItem(hwnd, IDC_SHAPE_PIC);
  316. GetClientRect(hwndFrame, &rectDst);
  317. hdcFrame = GetDC(hwndFrame);
  318. if (curSel == LB_ERR || curSel <= 0)
  319. {
  320. badpic:
  321. // white GDI brush
  322. HBRUSH hbr = CreateSolidBrush(0x00FFFFFF);
  323. FillRect(hdcFrame, &rectDst, hbr);
  324. DeleteObject(hbr);
  325. DeleteObject(hwndFrame);
  326. DeleteObject(hdcFrame);
  327. DeleteObject(hwndShape);
  328. return;
  329. }
  330. hdcPic = shapeStack->GetPosition(curSel)->CreatePictureDC(hwnd, &rectDst);
  331. if (!hdcPic)
  332. goto badpic;
  333. // blit shape picture into the given frame
  334. // NOTE: should be same size
  335. BitBlt(hdcFrame,
  336. rectDst.left,
  337. rectDst.top,
  338. rectDst.right - rectDst.left,
  339. rectDst.bottom - rectDst.top,
  340. hdcPic,
  341. 0,
  342. 0,
  343. SRCCOPY);
  344. ReleaseDC(hwndFrame, hdcFrame);
  345. DeleteObject(hwndFrame);
  346. DeleteObject(hwndShape);
  347. }
  348. VOID TestShapeRegion :: CleanUpPictures(HWND hwnd)
  349. {
  350. HWND hwndShape;
  351. HDC hdcPic;
  352. INT count;
  353. // !! This code is obsolete,
  354. // it should only be used if we wish to recreate the pictures on
  355. // each iteration
  356. /*
  357. hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  358. count = SendMessage(hwndShape, LB_GETCOUNT, 0, 0);
  359. // clean up picture hwnd for each picture...
  360. for (INT pos = 0; pos < count; pos++)
  361. {
  362. hdcPic = (HDC) SendMessage(hwndShape, LB_GETITEMDATA, (WPARAM)pos, 0);
  363. if (hdcPic)
  364. DeleteDC(hdcPic);
  365. }
  366. DeleteObject(hwndShape);
  367. */
  368. }
  369. VOID TestShapeRegion :: InitDialog(HWND hwnd)
  370. {
  371. HWND hwndTV;
  372. HWND hwndShape;
  373. RECT frameRect;
  374. HWND hwndFrame;
  375. hwndFrame = GetDlgItem(hwnd, IDC_SHAPE_PIC);
  376. GetWindowRect(hwndFrame, &frameRect);
  377. DeleteObject(hwndFrame);
  378. // display list of shapes
  379. hwndShape = GetDlgItem(hwnd, IDC_SHAPE_LIST);
  380. for (INT pos = 0; pos < shapeStack->GetCount(); pos++)
  381. {
  382. TestShape* shape = shapeStack->GetPosition(pos);
  383. SendMessage(hwndShape, LB_ADDSTRING, 0, (LPARAM)shape->GetShapeName());
  384. }
  385. DeleteObject(hwndShape);
  386. // add root of clip region tree to Tree View control
  387. // for display/editing
  388. hwndTV = GetDlgItem(hwnd, IDC_CLIP_TREE);
  389. clipTree = clipTree->GetRoot();
  390. HTREEITEM topTree = clipTree->CreateTreeView(hwndTV);
  391. // select root of tree
  392. TreeView_SelectItem(hwndTV, topTree);
  393. // expand entire tree
  394. TreeView_Expand(hwndTV, topTree, TVM_EXPAND);
  395. DeleteObject(hwndTV);
  396. SetDialogCheck(hwnd, IDC_CLIP_BOOL, origUseClip);
  397. }
  398. BOOL TestShapeRegion :: SaveValues(HWND hwnd)
  399. {
  400. origUseClip = GetDialogCheck(hwnd, IDC_CLIP_BOOL);
  401. origStack->Reset();
  402. for (INT pos = shapeStack->GetCount()-1; pos >= 1; pos--)
  403. {
  404. TestShape* shape = shapeStack->GetPosition(pos);
  405. origStack->Push(shape);
  406. shape->SetDisabled(shape->dwFlags & ShapeDisabled);
  407. }
  408. return FALSE;
  409. }
  410. BOOL TestShapeRegion :: ProcessDialog(HWND hwnd,
  411. UINT msg,
  412. WPARAM wParam,
  413. LPARAM lParam)
  414. {
  415. if (msg == WM_COMMAND)
  416. {
  417. switch(LOWORD(wParam))
  418. {
  419. case IDC_OK:
  420. if (SaveValues(hwnd))
  421. WarningBeep();
  422. else
  423. {
  424. CleanUpPictures(hwnd);
  425. ::EndDialog(hwnd, TRUE);
  426. }
  427. break;
  428. case IDC_SHAPE_UP:
  429. ShiftCurrentShape(hwnd, -1);
  430. break;
  431. case IDC_SHAPE_DOWN:
  432. ShiftCurrentShape(hwnd, +1);
  433. break;
  434. case IDC_SHAPE_DISABLE:
  435. ToggleDisableShape(hwnd);
  436. break;
  437. case IDC_SHAPE_PEN:
  438. case IDC_SHAPE_BRUSH:
  439. break;
  440. case IDC_CLIP_ADD:
  441. AddClipNode(hwnd);
  442. break;
  443. case IDC_CLIP_REMOVE:
  444. RemoveClipNode(hwnd);
  445. break;
  446. case IDC_CLIP_AND:
  447. AddClipNode(hwnd, AndNode);
  448. break;
  449. case IDC_CLIP_OR:
  450. AddClipNode(hwnd, OrNode);
  451. break;
  452. case IDC_CLIP_XOR:
  453. AddClipNode(hwnd, XorNode);
  454. break;
  455. case IDC_CLIP_NOT:
  456. ToggleNotNode(hwnd);
  457. break;
  458. case IDC_SHAPE_LIST:
  459. if (HIWORD(wParam) == LBN_SELCHANGE)
  460. UpdateShapePicture(hwnd);
  461. break;
  462. case IDC_REFRESH_PIC:
  463. UpdateShapePicture(hwnd);
  464. break;
  465. case IDC_CANCEL:
  466. CleanUpPictures(hwnd);
  467. ::EndDialog(hwnd, FALSE);
  468. break;
  469. default:
  470. return FALSE;
  471. }
  472. return TRUE;
  473. }
  474. return FALSE;
  475. }
  476. Region* TestShapeRegion :: GetClipRegion()
  477. {
  478. // caller must free
  479. return clipTree->GetRegion();
  480. }