Annotation of q_a/samples/regions/regions.c, revision 1.1

1.1     ! root        1: /************************************************************************\
        !             2: *
        !             3: *  PROGRAM:     Regions.c
        !             4: *
        !             5: *  PURPOSE:     To demonstrate the region APIs in Win32, namely:
        !             6: *
        !             7: *                          CombineRgn()
        !             8: *                          CreateEllipticRgn()
        !             9: *                          CreateEllipticRgnIndirect()
        !            10: *                          CreatePolygonRgn()
        !            11: *                          CreatePolyPolygonRgn()
        !            12: *                          CreateRectRgn()
        !            13: *                          FillRgn()
        !            14: *   #ifdef NOTIMPLEMENTED  FrameRgn()   #endif
        !            15: *                          GetRgnBox()
        !            16: *                          InvertRgn()
        !            17: *                          OffsetRgn()
        !            18: *                          PaintRgn()
        !            19: *                          PtInRegion()
        !            20: *                          RectInRegion()
        !            21: *                          SetRectRgn()
        !            22: *
        !            23: *               The EqualRgn() API is *not* called in this program.
        !            24: *
        !            25: *  FUNCTIONS:
        !            26: *               WinMain()       - initialization, create window, msg loop
        !            27: *               MainWndProc()   - processes main window msgs
        !            28: *               AboutDlgProc()  - processes About dialog box msgs
        !            29: *               RgnBoxDlgProc() - processes RgnBox dialog box msgs
        !            30: *               MyCreateRgn()   - calls any one of Create*Rgn*() APIs
        !            31: *               MyCombineRgn()  - calls CombineRgn() API
        !            32: *               TrackRect()     - creates\draws\deletes a tracking rectangle
        !            33: *                                 (for use with RectInRegion menu item.)
        !            34: *               Reset()         - enables\disables menu items, modifies
        !            35: *                                 global vars (rgnArray[], currRgn).
        !            36: *
        !            37: *  COMMENTS:    This program allows a user to create the different kinds
        !            38: *               of regions available in Win32, and to perform the various
        !            39: *               operations on them. All operations are immediately
        !            40: *               reflected on the screen. The order in which the regions
        !            41: *               are created determines the order in which they are drawn,
        !            42: *               as well as which operation affects which region(s); for
        !            43: *               example, the last region created will be drawn on top of
        !            44: *               the others, and the operations in "Options" menu will
        !            45: *               affect this region. When two regions are combined the
        !            46: *               second region will be destroyed.
        !            47: *
        !            48: \************************************************************************/
        !            49: 
        !            50: #include <windows.h>
        !            51: #include "regions.h"
        !            52: 
        !            53: 
        !            54: 
        !            55: /************************************************************************\
        !            56: *
        !            57: *  FUNCTION:    WinMain (standard WinMain INPUTS/RETURNS)
        !            58: *
        !            59: *  GLOBAL VARS: hInst - Handle of program instance
        !            60: *
        !            61: \************************************************************************/
        !            62: 
        !            63: int APIENTRY WinMain (HANDLE hInstance, HANDLE hPrevInstance,
        !            64:                       LPSTR lpCmdLine, int nCmdShow)
        !            65: { HWND hWnd;
        !            66:   MSG  msg;
        !            67: 
        !            68:   if (!hPrevInstance)
        !            69:   { PWNDCLASS pWndClass;
        !            70: 
        !            71:     pWndClass = (PWNDCLASS) LocalAlloc (LPTR, sizeof(WNDCLASS));
        !            72:     if(!pWndClass)
        !            73:     { MessageBox (NULL, "REGIONS: LocalAlloc() failed", NULL, MB_OK |
        !            74:                   MB_ICONHAND);
        !            75:       return(FALSE);
        !            76:     }
        !            77: 
        !            78:     pWndClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
        !            79:     pWndClass->hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        !            80:     pWndClass->lpszMenuName  = (LPSTR) "Menu";
        !            81:     pWndClass->lpszClassName = (LPSTR) "Main";
        !            82:     pWndClass->hbrBackground = GetStockObject (DKGRAY_BRUSH);
        !            83:     pWndClass->hInstance     = hInstance;
        !            84:     pWndClass->style         = NULL;
        !            85:     pWndClass->lpfnWndProc   = (WNDPROC)MainWndProc;
        !            86: 
        !            87:     if (!RegisterClass (pWndClass))
        !            88:     { MessageBox (NULL, "REGIONS: RegisterClass() failed", NULL, MB_OK |
        !            89:                   MB_ICONHAND);
        !            90:       return(FALSE);
        !            91:     }
        !            92: 
        !            93:     LocalFree (LocalHandle ((LPSTR)pWndClass));
        !            94:   }
        !            95:   hInst = hInstance;
        !            96:   hWnd  = CreateWindow ("Main", "Regions API Sample",
        !            97:                         WS_OVERLAPPED | WS_CAPTION |
        !            98:                         WS_SYSMENU | WS_MINIMIZEBOX,
        !            99:                         CW_USEDEFAULT, CW_USEDEFAULT,
        !           100:                         220, 280, NULL, NULL, hInstance, NULL);
        !           101:   if (!hWnd)
        !           102:     return (NULL);
        !           103: 
        !           104:   ShowWindow(hWnd, nCmdShow);
        !           105:   UpdateWindow(hWnd);
        !           106: 
        !           107:   while (GetMessage(&msg, NULL, NULL, NULL))
        !           108:   { TranslateMessage(&msg);
        !           109:     DispatchMessage(&msg);
        !           110:   }
        !           111:   return (msg.wParam);
        !           112:   UNREFERENCED_PARAMETER(lpCmdLine);
        !           113: }
        !           114: 
        !           115: 
        !           116: 
        !           117: /************************************************************************\
        !           118: *
        !           119: *  FUNCTION:    MainWndProc (standard window procedure INPUTS/RETURNS)
        !           120: *
        !           121: *  GLOBAL VARS: hInst    - Handle of program instance
        !           122: *               rgnArray - Array of RGNSTRUCTs describing regions user has
        !           123: *                          created
        !           124: *               currRgn  - Index (in rgnArray) of most recently created
        !           125: *                          region. If -1 then no regions created. Otherwise,
        !           126: *                          values range from 0 to MAXRGNSTRUCTS - 1.
        !           127: *               hMenu    - Handle of main window's menu.
        !           128: *
        !           129: *  LOCAL VARS:  rect     - Scratch rectangle used in various places.
        !           130: *               ptr      - Pointer to a TRACKRECTSTRUCT (used for
        !           131: *                          tracking rectangle).
        !           132: *               i        - For-loop variable.
        !           133: *               hdc      - Scratch HDC used in various places.
        !           134: *               lButtonFlag - Tells what to do when left mouse button goes
        !           135: *                             down (eg. nothing, check point in region,
        !           136: *                             check rect in region).
        !           137: *               bOffsetRgnFlag - A BOOL which tells whether to offset up
        !           138: *                                and left or down and right.
        !           139: *
        !           140: \************************************************************************/
        !           141: 
        !           142: LONG APIENTRY MainWndProc (HWND hWnd, UINT message, UINT wParam,
        !           143:                            LONG lParam)
        !           144: { static RECT             rect;
        !           145:   static PTRACKRECTSTRUCT ptr;
        !           146:   static BOOL             bOffsetRgnFlag = FALSE;
        !           147:   static WORD             lButtonFlag = 0;
        !           148:          int              i;
        !           149:          HDC              hdc;
        !           150: 
        !           151:   switch (message)
        !           152:   { case WM_CREATE:
        !           153:       hMenu   = GetMenu (hWnd);
        !           154:       currRgn = -1;
        !           155:       Reset (RESET_ALL);
        !           156:       break;
        !           157: 
        !           158:     case WM_COMMAND:
        !           159:       switch (LOWORD(wParam))
        !           160:       { case IDM_ERASE:
        !           161:           Reset (RESET_ALL);
        !           162:           InvalidateRect (hWnd, NULL, TRUE);
        !           163:           break;
        !           164: 
        !           165:         case IDM_OFFSETRGN:
        !           166: 
        !           167:           /**************************************************************\
        !           168:           *  Offset rgnArray[currRgn].hrgn either down & right, or up &
        !           169:           *  left (depending on bOffsetRgnFlag). Toggle bOffsetRgnFlag.
        !           170:           \**************************************************************/
        !           171: 
        !           172:           if (bOffsetRgnFlag)
        !           173:             OffsetRgn (rgnArray[currRgn].hrgn, 15, 10);
        !           174:           else
        !           175:             OffsetRgn (rgnArray[currRgn].hrgn, -15, -10);
        !           176:           bOffsetRgnFlag = ~bOffsetRgnFlag;
        !           177:           InvalidateRect (hWnd, NULL, TRUE);
        !           178: 
        !           179:           break;
        !           180: 
        !           181:         case IDM_INVERTRGN:
        !           182:           hdc = GetDC (hWnd);
        !           183:           InvertRgn (hdc, rgnArray[currRgn].hrgn);
        !           184:           ReleaseDC (hWnd, hdc);
        !           185:           break;
        !           186: 
        !           187: #ifdef NOTIMPLEMENTED
        !           188: 
        !           189:         case IDM_FRAMERGN:
        !           190:           hdc = GetDC (hWnd);
        !           191: 
        !           192:           FrameRgn (hdc, rgnArray[currRgn].hrgn,
        !           193:                     GetStockObject (WHITE_BRUSH), 2, 2);
        !           194:           ReleaseDC (hWnd, hdc);
        !           195:           break;
        !           196: #endif
        !           197: 
        !           198:         case IDM_PTINRGN:
        !           199: 
        !           200:           /**************************************************************\
        !           201:           *  Uncheck "RectInRgn" menu item, toggle "PtInRgn" menu item,
        !           202:           *  toggle lButtonFlag
        !           203:           \**************************************************************/
        !           204: 
        !           205:           if (lButtonFlag == IDM_RECTINRGN)
        !           206:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_RECTINRGN,
        !           207:                             MF_UNCHECKED | MF_BYCOMMAND);
        !           208:           if (lButtonFlag == IDM_PTINRGN) {
        !           209:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_PTINRGN,
        !           210:                             MF_UNCHECKED | MF_BYCOMMAND);
        !           211:             lButtonFlag = 0;
        !           212:           }
        !           213:           else {
        !           214:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_PTINRGN,
        !           215:                             MF_CHECKED | MF_BYCOMMAND);
        !           216:             lButtonFlag = IDM_PTINRGN;
        !           217:           }
        !           218:           break;
        !           219: 
        !           220:         case IDM_RECTINRGN:
        !           221: 
        !           222:           /**************************************************************\
        !           223:           *  Uncheck "PtInRgn" menu item, toggle "RectInRgn" menu item,
        !           224:           *  toggle lButtonFlag
        !           225:           \**************************************************************/
        !           226: 
        !           227:           if (lButtonFlag == IDM_PTINRGN)
        !           228:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_PTINRGN,
        !           229:                             MF_UNCHECKED | MF_BYCOMMAND);
        !           230:           if (lButtonFlag == IDM_RECTINRGN) {
        !           231:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_RECTINRGN,
        !           232:                             MF_UNCHECKED | MF_BYCOMMAND);
        !           233:             lButtonFlag = 0;
        !           234:           }
        !           235:           else {
        !           236:             CheckMenuItem (GetSubMenu (hMenu, 0), IDM_RECTINRGN,
        !           237:                             MF_CHECKED | MF_BYCOMMAND);
        !           238:             lButtonFlag = IDM_RECTINRGN;
        !           239:           }
        !           240:           break;
        !           241: 
        !           242:         case IDM_SETRECTRGN:
        !           243: 
        !           244:           /**************************************************************\
        !           245:           *  Reset rgnArray[currRgn].hrgn to be the rectangle which
        !           246:           *  currently bounds it.
        !           247:           \**************************************************************/
        !           248: 
        !           249:           GetRgnBox  (rgnArray[currRgn].hrgn, &rect);
        !           250:           SetRectRgn (rgnArray[currRgn].hrgn, (int) rect.left,
        !           251:                       (int) rect.top, (int) rect.right,
        !           252:                       (int) rect.bottom);
        !           253:           InvalidateRect (hWnd, NULL, TRUE);
        !           254:           break;
        !           255: 
        !           256:         case IDM_GETRGNBOX:          /* put up dlg which call GetRgnBox */
        !           257:           DialogBox (hInst, "RgnBox", hWnd, (DLGPROC)RgnBoxDlgProc);
        !           258:           break;
        !           259: 
        !           260:         case IDM_ELLIPSE:                     /* create an elliptic rgn */
        !           261:           MyCreateRgn (ELLIPTIC_RGN);
        !           262:           InvalidateRect (hWnd, NULL, TRUE);
        !           263:           break;
        !           264: 
        !           265:         case IDM_POLYPOLYGON:               /* create a polyPolygon rgn */
        !           266:           MyCreateRgn (POLYPOLYGON_RGN);
        !           267:           InvalidateRect (hWnd, NULL, TRUE);
        !           268:           break;
        !           269: 
        !           270:         case IDM_RECT:                      /* create a rectangular rgn */
        !           271:           MyCreateRgn (RECT_RGN);
        !           272:           InvalidateRect (hWnd, NULL, TRUE);
        !           273:           break;
        !           274: 
        !           275:         case IDM_AND:                        /* combine previous 2 rgns */
        !           276:           MyCombineRgn (RGN_AND);
        !           277:           InvalidateRect (hWnd, NULL, TRUE);
        !           278:           break;
        !           279: 
        !           280:         case IDM_COPY:                       /* combine previous 2 rgns */
        !           281:           MyCombineRgn (RGN_COPY);
        !           282:           InvalidateRect (hWnd, NULL, TRUE);
        !           283:           break;
        !           284: 
        !           285:         case IDM_DIFF:                       /* combine previous 2 rgns */
        !           286:           MyCombineRgn (RGN_DIFF);
        !           287:           InvalidateRect (hWnd, NULL, TRUE);
        !           288:           break;
        !           289: 
        !           290:         case IDM_OR:                         /* combine previous 2 rgns */
        !           291:           MyCombineRgn (RGN_OR);
        !           292:           InvalidateRect (hWnd, NULL, TRUE);
        !           293:           break;
        !           294: 
        !           295:         case IDM_XOR:                        /* combine previous 2 rgns */
        !           296:           MyCombineRgn (RGN_XOR);
        !           297:           InvalidateRect (hWnd, NULL, TRUE);
        !           298:           break;
        !           299: 
        !           300:         case IDM_ABOUT:                      /* put up About dialog box */
        !           301:           DialogBox (hInst, "AboutBox", hWnd, (DLGPROC)AboutDlgProc);
        !           302:           break;
        !           303:       }
        !           304:       return (NULL);
        !           305: 
        !           306:     case WM_LBUTTONDOWN:
        !           307:     {
        !           308:       /******************************************************************\
        !           309:       *  if the "PtInRgn" menu item is checked, then see if the point at
        !           310:       *  which this event happened is within currRgn, MessageBeep if so.
        !           311:       *
        !           312:       *  else if the "RectInRgn" menu items are checked, then start
        !           313:       *  tracking rectangle mode
        !           314:       \******************************************************************/
        !           315: 
        !           316:       if (lButtonFlag == IDM_PTINRGN)
        !           317:       { if (currRgn > -1)
        !           318:           if (PtInRegion (rgnArray[currRgn].hrgn, (int) LOWORD(lParam),
        !           319:                           (int) HIWORD(lParam)))
        !           320:             MessageBeep (0);
        !           321:       }
        !           322:       else if (lButtonFlag == IDM_RECTINRGN)
        !           323:         if ((ptr = TrackRect (NULL, TRECT_NEW, hWnd, lParam)) == NULL)
        !           324: 
        !           325:         /****************************************************************\
        !           326:         *  If TrackRect failed to LocalAlloc, then disable the
        !           327:         *  IDM_RECTINRGN opion.
        !           328:         \****************************************************************/
        !           329: 
        !           330:           EnableMenuItem (GetSubMenu (hMenu, 0), IDM_RECTINRGN,
        !           331:                           MF_DISABLED | MF_GRAYED | MF_BYCOMMAND);
        !           332: 
        !           333:       return (NULL);
        !           334:     }
        !           335:     case WM_MOUSEMOVE:
        !           336: 
        !           337:       /******************************************************************\
        !           338:       *  if in tracking rectangle mode call TrackRect
        !           339:       \******************************************************************/
        !           340: 
        !           341:       if (lButtonFlag == IDM_RECTINRGN && GetCapture () == hWnd)
        !           342:         TrackRect (ptr, TRECT_PAINT, hWnd, lParam);
        !           343:       return (NULL);
        !           344: 
        !           345:     case WM_LBUTTONUP:
        !           346: 
        !           347:       /******************************************************************\
        !           348:       *  if in tracking rectangle mode call TrackRect, check out the final
        !           349:       *  rectangle, and see if it intersects currRgn
        !           350:       \******************************************************************/
        !           351: 
        !           352:       if (lButtonFlag == IDM_RECTINRGN && GetCapture () == hWnd)
        !           353:       {
        !           354:         /****************************************************************\
        !           355:         *  call TrackRect with TRECT_PAINT so it updates the rectangle
        !           356:         *  for the last time, then again with TRECT_DELETE so it frees
        !           357:         *  up the TRACKRECTSTRUCT it allocated
        !           358:         \****************************************************************/
        !           359: 
        !           360:         TrackRect (ptr, TRECT_PAINT, hWnd, lParam);
        !           361:         rect = ptr->trackRect;
        !           362:         TrackRect (ptr, TRECT_DELETE, hWnd, lParam);
        !           363:         if (RectInRegion (rgnArray[currRgn].hrgn, &rect))
        !           364:           MessageBeep (0);
        !           365:       }
        !           366:       return (NULL);
        !           367: 
        !           368:     case WM_PAINT: {
        !           369:       PAINTSTRUCT ps;
        !           370:       COLORREF    crColor;
        !           371:       HBRUSH      hBrush;
        !           372: 
        !           373:       hdc = BeginPaint (hWnd, &ps);
        !           374: 
        !           375:       /******************************************************************\
        !           376:       *  For each rgn we created determine appropriate color & draw it
        !           377:       \******************************************************************/
        !           378: 
        !           379:       for (i = 0; i <= currRgn; i++)
        !           380:       { if (rgnArray[i].hrgn != NULL)
        !           381:         { crColor = 0x000000;
        !           382:           if (rgnArray[i].type & ELLIPTIC_RGN)    /* add some red */
        !           383:             crColor |= 0x0000ff;
        !           384:           if (rgnArray[i].type & POLYPOLYGON_RGN) /* add some green */
        !           385:             crColor |= 0x00ff00;
        !           386:           if (rgnArray[i].type & RECT_RGN)        /* add some blue */
        !           387:             crColor |= 0xff0000;
        !           388:           hBrush = CreateSolidBrush (crColor);
        !           389: 
        !           390:           /**************************************************************\
        !           391:           *  Alternately, the following would work:
        !           392:           *     SelectObject (hdc, hBrush);
        !           393:           *     FillRgn (hdc, rgnArray[i].hrgn);
        !           394:           \**************************************************************/
        !           395: 
        !           396:           FillRgn (hdc, rgnArray[i].hrgn, hBrush);
        !           397:           DeleteObject (hBrush);
        !           398:         }
        !           399:       }
        !           400:       EndPaint (hWnd, &ps);
        !           401:       return (NULL);
        !           402:     }
        !           403:     case WM_DESTROY:
        !           404: 
        !           405:       PostQuitMessage(NULL);
        !           406:       return (NULL);
        !           407:   }
        !           408:   return (DefWindowProc(hWnd, message, wParam, lParam));
        !           409: }
        !           410: 
        !           411: 
        !           412: 
        !           413: /************************************************************************\
        !           414: *
        !           415: *  FUNCTION:    AboutDlgProc (standard dialog procedure INPUTS/RETURNS)
        !           416: *
        !           417: *  COMMENTS:    Displays "about" message
        !           418: *
        !           419: \************************************************************************/
        !           420: 
        !           421: BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam,
        !           422:                             LONG lParam)
        !           423: { switch (message)
        !           424:   { case WM_INITDIALOG:
        !           425: 
        !           426:       return (TRUE);
        !           427: 
        !           428:     case WM_COMMAND:
        !           429: 
        !           430:       if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        !           431:       { EndDialog(hDlg, TRUE);
        !           432:         return (TRUE);
        !           433:       }
        !           434:       return (TRUE);
        !           435:   }
        !           436:   return (FALSE);
        !           437:   UNREFERENCED_PARAMETER(lParam);
        !           438: }
        !           439: 
        !           440: 
        !           441: 
        !           442: /************************************************************************\
        !           443: *
        !           444: *  FUNCTION:    RgnBoxDlgProc (standard dialog procedure INPUTS/RETURNS)
        !           445: *
        !           446: *  GLOBAL VARS: rgnArray - Array of RGNSTRUCTs describing regions user has
        !           447: *                          created
        !           448: *               currRgn  - Index (in rgnArray) of most recently created
        !           449: *                          region. If -1 then no regions created. Other-
        !           450: *                          wise, values range from 0 to MAXRGNSTRUCTS - 1.
        !           451: *
        !           452: *  COMMENTS:    Displays bounding rectangle of most recently created
        !           453: *               region.
        !           454: *
        !           455: \************************************************************************/
        !           456: 
        !           457: BOOL APIENTRY RgnBoxDlgProc (HWND hDlg, UINT message, UINT wParam,
        !           458:                              LONG lParam)
        !           459: {
        !           460:   switch (message)
        !           461:   { case WM_INITDIALOG:
        !           462:     { RECT rect;
        !           463:       char buf[15];
        !           464: 
        !           465:       /******************************************************************\
        !           466:       *  get the bounding rect of currRgn, fill in the dlg controls
        !           467:       *  with text string describing the bounding rect.
        !           468:       \******************************************************************/
        !           469: 
        !           470:       if (GetRgnBox (rgnArray[currRgn].hrgn, &rect) == SIMPLEREGION)
        !           471:         SetDlgItemText (hDlg, 102, "SIMPLEREGION");
        !           472:       else
        !           473:         SetDlgItemText (hDlg, 102, "COMPLEXREGION");
        !           474: 
        !           475:       wsprintf (buf, "%ld", rect.left);
        !           476:       SetDlgItemText (hDlg, 107, buf);
        !           477:       wsprintf (buf, "%ld", rect.top);
        !           478:       SetDlgItemText (hDlg, 108, buf);
        !           479:       wsprintf (buf, "%ld", rect.right);
        !           480:       SetDlgItemText (hDlg, 109, buf);
        !           481:       wsprintf (buf, "%ld", rect.bottom);
        !           482:       SetDlgItemText (hDlg, 110, buf);
        !           483: 
        !           484:       return (TRUE);
        !           485:     }
        !           486:     case WM_COMMAND:
        !           487: 
        !           488:       if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        !           489:       { EndDialog(hDlg, TRUE);
        !           490:         return (TRUE);
        !           491:       }
        !           492:       return (TRUE);
        !           493:   }
        !           494:   return (FALSE);
        !           495:   UNREFERENCED_PARAMETER(lParam);
        !           496: }
        !           497: 
        !           498: 
        !           499: 
        !           500: /************************************************************************\
        !           501: *
        !           502: *  FUNCTION:    MyCreateRgn
        !           503: *
        !           504: *  INPUTS:      rgnStyle - The type of region to create (ELLIPTIC_RGN,
        !           505: *                          POLYPOLYGON_RGN, RECT_RGN)
        !           506: *
        !           507: *  GLOBAL VARS: rgnArray          - Array of RGNSTRUCTs describing regions
        !           508: *                                   user has created.
        !           509: *               currRgn           - Index (in rgnArray) of most recently
        !           510: *                                   created region. If -1 then no regions
        !           511: *                                   created. Otherwise, values range from
        !           512: *                                   0 to MAXRGNSTRUCTS-1.
        !           513: *               hMenu             - Handle of main window's menu.
        !           514: *               ellipseRect       - Rectangle bounding elliptical region.
        !           515: *               polyPolygonPoints - The points for the polyPolygon region.
        !           516: *               polyPolygonCounts - The count of points for each polygon
        !           517: *                                   in the polyPolygon region.
        !           518: *               rectRect          - The points for the rectangular region.
        !           519: *
        !           520: *  COMMENTS:    Creates a region (based on rgnStyle), increments currRgn,
        !           521: *               and fills in rgnArray[currRgn].
        !           522: *
        !           523: \************************************************************************/
        !           524: 
        !           525: void MyCreateRgn (WORD rgnStyle)
        !           526: { if (++currRgn == 0)         /* if this is 1st rgn enable options menu */
        !           527:     Reset (ENABLE_OPTIONS);
        !           528:   else if (currRgn == 1)      /* if this is 2nd rgn enable combine menu */
        !           529:     Reset (ENABLE_COMBINERGN);
        !           530:   rgnArray[currRgn].type = rgnStyle;
        !           531: 
        !           532:   switch (rgnStyle)
        !           533:   { case ELLIPTIC_RGN:
        !           534: 
        !           535:       /******************************************************************\
        !           536:       *  The following will also work here:
        !           537:       *     CreateEllipticRgn ((int) ellipseRect.left,
        !           538:       *                        (int) ellipseRect.top,
        !           539:       *                        (int) ellipseRect.right,
        !           540:       *                        (int) ellipseRect.bottom);
        !           541:       \******************************************************************/
        !           542: 
        !           543:       rgnArray[currRgn].hrgn = CreateEllipticRgnIndirect (&ellipseRect);
        !           544: 
        !           545:       EnableMenuItem (GetSubMenu (hMenu, 1), IDM_ELLIPSE,
        !           546:                       MF_GRAYED | MF_DISABLED | MF_BYCOMMAND);
        !           547:       break;
        !           548: 
        !           549:     case POLYPOLYGON_RGN:
        !           550: 
        !           551:       /******************************************************************\
        !           552:       *  Alternately, several calls to CreatePolygonRgn could be made.
        !           553:       \******************************************************************/
        !           554: 
        !           555:       rgnArray[currRgn].hrgn = CreatePolyPolygonRgn (polyPolygonPoints,
        !           556:                                                      polyPolygonCounts,
        !           557:                                                      POLYPOLYGONCOUNT,
        !           558:                                                      WINDING);
        !           559:       EnableMenuItem (GetSubMenu (hMenu, 1), IDM_POLYPOLYGON,
        !           560:                       MF_GRAYED | MF_DISABLED | MF_BYCOMMAND);
        !           561:       break;
        !           562: 
        !           563:     case RECT_RGN:
        !           564: 
        !           565:       /******************************************************************\
        !           566:       *  Alternately, a call to CreatePolygonRgn could be made.
        !           567:       \******************************************************************/
        !           568: 
        !           569:       rgnArray[currRgn].hrgn = CreateRectRgn (rectRect.left,
        !           570:                                               rectRect.top,
        !           571:                                               rectRect.right,
        !           572:                                               rectRect.bottom);
        !           573: 
        !           574:       EnableMenuItem (GetSubMenu (hMenu, 1), IDM_RECT,
        !           575:                       MF_GRAYED | MF_DISABLED | MF_BYCOMMAND);
        !           576:       break;
        !           577:   }
        !           578: }
        !           579: 
        !           580: 
        !           581: 
        !           582: /************************************************************************\
        !           583: *
        !           584: *  FUNCTION:    MyCombineRgn
        !           585: *
        !           586: *  INPUTS:      fnCombineMode- Operation to perform on the two regions
        !           587: *                              (RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR,
        !           588: *                              RGN_XOR)
        !           589: *
        !           590: *  GLOBAL VARS: rgnArray- Array of RGNSTRUCTs describing regions user has
        !           591: *                         created
        !           592: *               currRgn - Index (in rgnArray) of most recently created
        !           593: *                         region. If -1 then no regions created. Otherwise,
        !           594: *                         values range from 0 to MAXRGNSTRUCTS - 1.
        !           595: *
        !           596: *  COMMENTS:    Combines the two regions rgnArray[currRgn-1] and
        !           597: *               rgnArray[currRgn] using fnCombineMode, placing the
        !           598: *               results in rgnArray[currRgn-1]. Destroys rgnArray[currRgn]
        !           599: *               and decrements currRgn.
        !           600: *
        !           601: \************************************************************************/
        !           602: 
        !           603: void MyCombineRgn (int fnCombineMode)
        !           604: {
        !           605:   if (currRgn >= 1) /* only if two or more regions have been created */
        !           606:   { CombineRgn (rgnArray[currRgn-1].hrgn, rgnArray[currRgn-1].hrgn,
        !           607:                 rgnArray[currRgn].hrgn, fnCombineMode);
        !           608: 
        !           609:     rgnArray[currRgn-1].type |= rgnArray[currRgn].type;
        !           610: 
        !           611:    /* Delete the second of the two regions after combining */
        !           612: 
        !           613:     DeleteObject (rgnArray[currRgn--].hrgn);
        !           614: 
        !           615:     if (currRgn == 0)
        !           616:       Reset (DISABLE_COMBINERGN);
        !           617:   }
        !           618: }
        !           619: 
        !           620: 
        !           621: 
        !           622: /************************************************************************\
        !           623: *
        !           624: *  FUNCTION:    Reset
        !           625: *
        !           626: *  INPUTS:      action - Describes which reset action to take, eg. which
        !           627: *                        menus to enable/disable etc...
        !           628: *
        !           629: *  GLOBAL VARS: rgnArray - Array of RGNSTRUCTs describing regions user has
        !           630: *                          created
        !           631: *               currRgn  - Index (in rgnArray) of most recently created
        !           632: *                          region. If -1 then no regions created. Other-
        !           633: *                          wise, values range from 0 to MAXRGNSTRUCTS - 1.
        !           634: *               hMenu    - Handle of main window's menu.
        !           635: *
        !           636: *  COMMENTS:    Sets appropriate menu states and deletes old regions
        !           637: *               according to "action" parameter.
        !           638: *
        !           639: \************************************************************************/
        !           640: 
        !           641: void Reset (WORD action)
        !           642: { UINT i;
        !           643: 
        !           644:   switch (action)
        !           645:   { case RESET_ALL:
        !           646:       if (currRgn > 0)
        !           647:         for (i = 0; i <= (UINT) currRgn; i++)
        !           648:           DeleteObject (rgnArray[i].hrgn);
        !           649:       currRgn = -1;
        !           650:       for (i = IDM_ERASE; i <= IDM_GETRGNBOX; i++)
        !           651:         EnableMenuItem (GetSubMenu (hMenu, 0), i, MF_DISABLED | MF_GRAYED
        !           652:                                                   | MF_BYCOMMAND);
        !           653:       for (i = IDM_ELLIPSE; i <= IDM_RECT; i++)
        !           654:         EnableMenuItem (GetSubMenu (hMenu, 1), i, MF_ENABLED |
        !           655:                                                   MF_BYCOMMAND);
        !           656:       for (i = IDM_AND; i <= IDM_XOR; i++)
        !           657:         EnableMenuItem (GetSubMenu (hMenu, 2), i, MF_DISABLED | MF_GRAYED
        !           658:                                                   | MF_BYCOMMAND);
        !           659:       break;
        !           660: 
        !           661:    case ENABLE_OPTIONS:
        !           662:       for (i = IDM_ERASE; i <= IDM_GETRGNBOX; i++)
        !           663:         EnableMenuItem (GetSubMenu (hMenu, 0), i, MF_ENABLED |
        !           664:                                                   MF_BYCOMMAND);
        !           665:       break;
        !           666: 
        !           667:    case ENABLE_COMBINERGN:
        !           668:       for (i = IDM_AND; i <= IDM_XOR; i++)
        !           669:         EnableMenuItem (GetSubMenu (hMenu, 2), i, MF_ENABLED |
        !           670:                                                   MF_BYCOMMAND);
        !           671:       break;
        !           672: 
        !           673:    case DISABLE_COMBINERGN:
        !           674:       for (i = IDM_AND; i <= IDM_XOR; i++)
        !           675:         EnableMenuItem (GetSubMenu (hMenu, 2), i, MF_DISABLED | MF_GRAYED
        !           676:                                                   | MF_BYCOMMAND);
        !           677:       break;
        !           678:   }
        !           679: }
        !           680: 
        !           681: 
        !           682: /************************************************************************\
        !           683: *
        !           684: *  FUNCTION:    TrackRect()
        !           685: *
        !           686: *  INPUTS:      ptr    - Pointer to a PTRACKRECTSTRUCT.
        !           687: *               action - Message selecting what action to take.
        !           688: *               hWnd   - Window handle for the window the track rect
        !           689: *                        exists within.
        !           690: *               lParam - Fourth param to window proc (as with WM_MOUSEMOVE,
        !           691: *                        WM_LBUTTONDOWN, WM_LBUTTONUP...) desribing
        !           692: *                        event location.
        !           693: *
        !           694: *  RETURNS:     A pointer to a new TRACKRECTSTRUCT if msg == TRECT_NEW,
        !           695: *               NULL if msg != NEW
        !           696: *
        !           697: *  COMMENTS:    This function provides tracking rectangle functionality.
        !           698: *
        !           699: \************************************************************************/
        !           700: 
        !           701: PTRACKRECTSTRUCT TrackRect (PTRACKRECTSTRUCT ptr, int action, HWND hWnd,
        !           702:                             LONG lParam)
        !           703: { if ((ptr == NULL) && (action != TRECT_NEW))  return NULL;
        !           704: 
        !           705:   switch (action)
        !           706:   {
        !           707:     /********************************************************************\
        !           708:     *  TRECT_NEW: Allocate new PTRACKRECTSTRUCT. Fill in initial values
        !           709:     *             for the fields of the structure. Set up the HDC
        !           710:     *             correctly.
        !           711:     *
        !           712:     *  return - pointer to the new object.
        !           713:     \********************************************************************/
        !           714: 
        !           715:     case TRECT_NEW:
        !           716:     { PTRACKRECTSTRUCT ptr;
        !           717: 
        !           718:       if ((ptr = LocalAlloc (LPTR, sizeof (TRACKRECTSTRUCT))) == NULL)
        !           719:       { MessageBox (hWnd, "REGIONS: LocalAlloc() failed", "Err!",
        !           720:                     MB_OK | MB_ICONEXCLAMATION);
        !           721:         return NULL;
        !           722:       }
        !           723: 
        !           724:       /* initialize the HDC and other fields. */
        !           725:       ptr->hdc = GetDC(hWnd);
        !           726:       SetROP2(ptr->hdc, R2_NOT);
        !           727:       SelectObject (ptr->hdc, GetStockObject (NULL_BRUSH));
        !           728:       SelectObject (ptr->hdc, CreatePen (PS_SOLID, 2,
        !           729:                    (COLORREF) 0x01000009));
        !           730: 
        !           731:       /* initialize the size. */
        !           732:       ptr->trackRect.left = ptr->trackRect.right =
        !           733:                             (LONG) (ptr->xOrigin = LOWORD (lParam));
        !           734:       ptr->trackRect.top = ptr->trackRect.bottom =
        !           735:                             (LONG) (ptr->yOrigin = HIWORD (lParam));
        !           736: 
        !           737:       SetCapture (hWnd);
        !           738:       GetClientRect (hWnd, &(ptr->clientRect));
        !           739:       return (ptr);
        !           740:     }
        !           741: 
        !           742:     /********************************************************************\
        !           743:     *  TRECT_DELETE: Free up the memory allocated for the tracking rect.
        !           744:     *                Also, erase the last rectangle we drew.
        !           745:     \********************************************************************/
        !           746: 
        !           747:     case  TRECT_DELETE:
        !           748:       Rectangle (ptr->hdc, (int) ptr->trackRect.left,
        !           749:                            (int) ptr->trackRect.top,
        !           750:                            (int) ptr->trackRect.right,
        !           751:                            (int) ptr->trackRect.bottom);
        !           752:       ReleaseDC (hWnd, ptr->hdc);
        !           753:       LocalFree (LocalHandle ((LPSTR)ptr));
        !           754:       ReleaseCapture ();
        !           755:       return NULL;
        !           756: 
        !           757:     /********************************************************************\
        !           758:     *  TRECT_PAINT: Draw the tracking rectangle (involves erasing last
        !           759:     *               rectangle at old coordinates, and drawing new rect
        !           760:     *               at new coordinates).
        !           761:     \********************************************************************/
        !           762: 
        !           763:     case TRECT_PAINT:
        !           764: 
        !           765:       /******************************************************************\
        !           766:       *  Remove the last rectangle we painted by painting over it again
        !           767:       \******************************************************************/
        !           768: 
        !           769:       Rectangle (ptr->hdc, (int) ptr->trackRect.left,
        !           770:                            (int) ptr->trackRect.top,
        !           771:                            (int) ptr->trackRect.right,
        !           772:                            (int) ptr->trackRect.bottom);
        !           773: 
        !           774:       /******************************************************************\
        !           775:       *  We want to restrict our Rectangle() calls to paint within the
        !           776:       *  client area, so do a bounds check on lParam and reset any
        !           777:       *  values which fall outside the client area (eg. <1,
        !           778:       *  >clientRect.left, >clientRect.top).
        !           779:       \******************************************************************/
        !           780: 
        !           781:       if ((SHORT)LOWORD(lParam) < 1)
        !           782:         lParam &= 0xffff0000;
        !           783:       else if (LOWORD(lParam) > (WORD) (ptr->clientRect.right- 1))
        !           784:         lParam = MAKELONG ((WORD) ptr->clientRect.right - 1,
        !           785:                            HIWORD(lParam));
        !           786: 
        !           787:       if ((SHORT)HIWORD(lParam) < 1)
        !           788:         lParam &= 0x0000ffff;
        !           789:       else if (HIWORD(lParam) > (WORD) (ptr->clientRect.bottom - 1))
        !           790:         lParam = MAKELONG (LOWORD(lParam),
        !           791:                            (WORD) ptr->clientRect.bottom - 1);
        !           792: 
        !           793:       ptr->trackRect.left   = (LONG) (ptr->xOrigin > LOWORD(lParam)
        !           794:                                ? LOWORD(lParam) : ptr->xOrigin);
        !           795:       ptr->trackRect.right  = (LONG) (ptr->xOrigin > LOWORD(lParam)
        !           796:                                ? ptr->xOrigin : LOWORD(lParam));
        !           797:       ptr->trackRect.top    = (LONG) (ptr->yOrigin > HIWORD(lParam)
        !           798:                                ? HIWORD(lParam) : ptr->yOrigin);
        !           799:       ptr->trackRect.bottom = (LONG) (ptr->yOrigin > HIWORD(lParam)
        !           800:                                ? ptr->yOrigin : HIWORD(lParam));
        !           801: 
        !           802:       /******************************************************************\
        !           803:       *  Redraw the tracking rectangle
        !           804:       \******************************************************************/
        !           805: 
        !           806:       Rectangle (ptr->hdc, (int) ptr->trackRect.left,
        !           807:                            (int) ptr->trackRect.top,
        !           808:                            (int) ptr->trackRect.right,
        !           809:                            (int) ptr->trackRect.bottom);
        !           810:       return NULL;
        !           811:   }
        !           812: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.