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

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

unix.superglobalmegacorp.com

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