|
| БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО! |
|
|
Using Rectangles
The example in this section illustrates how to use the rectangle functions. It consists of the main window procedure from an application that enables the user to move and size a bitmap.
When the application starts, it draws a 32-pixel by 32-pixel bitmap in the upper left corner of the screen. The user can move the bitmap by dragging it. To size the bitmap, the user creates a target rectangle by dragging the mouse, then drags the bitmap and "drops" it on the target rectangle. The application responds by copying the bitmap into the target rectangle. The window procedure that allows the user to move and size the bitmap is given in the following example.
LRESULT CALLBACK MainWndProc(hwnd, uMsg, wParam, lParam) HWND hwnd; /* handle of window */ UINT uMsg; /* message */ WPARAM wParam; /* first message parameter */ LPARAM lParam; /* second message parameter */ { HDC hdc; /* device context (DC) for window */ RECT rcTmp; /* temporary rectangle */ PAINTSTRUCT ps; /* paint data for Begin/EndPaint */ POINT ptClientUL; /* client area upper left corner */
POINT ptClientLR; /* client area lower right corner */ static HDC hdcCompat; /* DC for copying bitmap */ static POINT pt; /* x and y coordinates of cursor */ static RECT rcBmp; /* rectangle that encloses bitmap */ static RECT rcTarget; /* rectangle to receive bitmap */ static RECT rcClient; /* client-area rectangle */ static BOOL fDragRect; /* TRUE if bitmap rect. is dragged */
static HBITMAP hbmp; /* handle of bitmap to display */ static HBRUSH hbrBkgnd; /* handle of background-color brush */ static COLORREF crBkgnd; /* color of client-area background */ static HPEN hpenDot; /* handle of dotted pen */ switch (uMsg) { case WM_CREATE: /* Load the bitmap resource. */ hbmp = LoadBitmap(hinst, MAKEINTRESOURCE(1)); /* * Create a device context (DC) to hold the bitmap.
* The bitmap is copied from this DC to the window's DC * whenever it must be drawn. */ hdc = GetDC(hwnd); hdcCompat = CreateCompatibleDC(hdc); SelectObject(hdcCompat, hbmp); /* * Create a brush of the same color as the background * of the client area. The brush is used later to erase * the old bitmap before copying the bitmap into the
* target rectangle. */ crBkgnd = GetBkColor(hdc); hbrBkgnd = CreateSolidBrush(crBkgnd); ReleaseDC(hwnd, hdc); /* * Create a dotted pen. The pen is used to draw the * bitmap rectangle as the user drags it. */ hpenDot = CreatePen(PS_DOT, 1, RGB(0, 0, 0)); /* * Set the initial rectangle for the bitmap. Note that
* this application supports only a 32- by 32-pixel * bitmap. The rectangle is slightly larger than the * bitmap. */ SetRect(&rcBmp, 1, 1, 34, 34); return 0; case WM_PAINT: /* * Draw the bitmap rectangle and copy the bitmap into * it. The 32-pixel by 32-pixel bitmap is centered * in the rectangle by adding 1 to the left and top
* coordinates of the bitmap rectangle, and subtracting * 2 from the right and bottom coordinates. */ BeginPaint(hwnd, &ps); Rectangle(ps.hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); StretchBlt(ps.hdc, rcBmp.left + 1, rcBmp.top + 1, (rcBmp.right - rcBmp.left) - 2, (rcBmp.bottom - rcBmp.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
EndPaint(hwnd, &ps); break; case WM_MOVE: case WM_SIZE: /* * Convert the client coordinates of the client-area * rectangle to screen coordinates and save them in a * rectangle. The rectangle is passed to the ClipCursor * function during WM_LBUTTONDOWN processing. */ GetClientRect(hwnd, &rcClient); ptClientUL.x = rcClient.left;
ptClientUL.y = rcClient.top; ptClientLR.x = rcClient.right; ptClientLR.y = rcClient.bottom; ClientToScreen(hwnd, &ptClientUL); ClientToScreen(hwnd, &ptClientLR); SetRect(&rcClient, ptClientUL.x, ptClientUL.y, ptClientLR.x, ptClientLR.y); return 0; case WM_LBUTTONDOWN: /* * Restrict the mouse cursor to the client area. This
* ensures that the window receives a matching * WM_LBUTTONUP message. */ ClipCursor(&rcClient); /* Save the coordinates of the mouse cursor. */ pt.x = (LONG) LOWORD(lParam); pt.y = (LONG) HIWORD(lParam); /* * If the user has clicked the bitmap rectangle, redraw * it using the dotted pen. Set the fDragRect flag to * indicate that the user is about to drag the
* rectangle. */ if (PtInRect(&rcBmp, pt)) { hdc = GetDC(hwnd); SelectObject(hdc, hpenDot); Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); fDragRect = TRUE; ReleaseDC(hwnd, hdc); } return 0; case WM_MOUSEMOVE: /* * Draw a target rectangle or drag the bitmap
* rectangle, depending on the status of the fDragRect * flag. */ if ((wParam && MK_LBUTTON) && !fDragRect) { /* draw a target rectangle */ /* * Set the mix mode so that the pen color is the * inverse of the background color. The previous * rectangle can then be erased by drawing * another rectangle on top of it.
*/ hdc = GetDC(hwnd); SetROP2(hdc, R2_NOTXORPEN); /* * If a previous target rectangle exists, erase * it by drawing another rectangle on top of it. */ if (!IsRectEmpty(&rcTarget)) Rectangle(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); /*
* Save the coordinates of the target rectangle. * Avoid invalid rectangles by ensuring that the * value of the left coordinate is greater than * that of the right coordinate, and that the * value of the bottom coordinate is greater than * that of the top. */ if ((pt.x < (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam)))
SetRect(&rcTarget, pt.x, HIWORD(lParam), LOWORD(lParam), pt.y); else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y > (LONG) HIWORD(lParam))) SetRect(&rcTarget, LOWORD(lParam), HIWORD(lParam), pt.x, pt.y); else if ((pt.x > (LONG) LOWORD(lParam)) && (pt.y < (LONG) HIWORD(lParam))) SetRect(&rcTarget, LOWORD(lParam), pt.y,
pt.x, HIWORD(lParam)); else SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam), HIWORD(lParam)); /* Draw the new target rectangle. */ Rectangle(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); ReleaseDC(hwnd, hdc); } else if ((wParam && MK_LBUTTON) && fDragRect) { /* drag the bitmap rectangle */
/* * Set the mix mode so that the pen color is the * inverse of the background color. */ hdc = GetDC(hwnd); SetROP2(hdc, R2_NOTXORPEN); /* * Select the dotted pen into the DC and erase * the previous bitmap rectangle by drawing * another rectangle on top of it. */
SelectObject(hdc, hpenDot); Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); /* * Set the new coordinates of the bitmap * rectangle, then redraw it. */ OffsetRect(&rcBmp, LOWORD(lParam) - pt.x, HIWORD(lParam) - pt.y); Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom);
ReleaseDC(hwnd, hdc); /* Save the coordinates of the mouse cursor. */ pt.x = (LONG) LOWORD(lParam); pt.y = (LONG) HIWORD(lParam); } return 0; case WM_LBUTTONUP: /* * If the bitmap rectangle and target rectangle * intersect, copy the bitmap into the target * rectangle. Otherwise, copy the bitmap into the
* rectangle bitmap at its new location. */ if (IntersectRect(&rcTmp, &rcBmp, &rcTarget)) { /* * Erase the bitmap rectangle by filling it with * the background color. */ hdc = GetDC(hwnd); FillRect(hdc, &rcBmp, hbrBkgnd); /* * Redraw the target rectangle because the part * that intersected with the bitmap rectangle was
* erased by the call to FillRect. */ Rectangle(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); /* Copy the bitmap into the target rectangle. */ StretchBlt(hdc, rcTarget.left + 1, rcTarget.top + 1, (rcTarget.right - rcTarget.left) - 2, (rcTarget.bottom - rcTarget.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
/* * Copy the target rectangle to the bitmap * rectangle, set the coordinates of the target * rectangle to 0, then reset the fDragRect flag. */ CopyRect(&rcBmp, &rcTarget); SetRectEmpty(&rcTarget); ReleaseDC(hwnd, hdc); fDragRect = FALSE; } else if (fDragRect) { /*
* Draw the bitmap rectangle, copy the bitmap into * it, and reset the fDragRect flag. */ hdc = GetDC(hwnd); Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); StretchBlt(hdc, rcBmp.left + 1, rcBmp.top + 1, (rcBmp.right - rcBmp.left) - 2, (rcBmp.bottom - rcBmp.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
ReleaseDC(hwnd, hdc); fDragRect = FALSE; } /* Release the mouse cursor. */ ClipCursor((LPRECT) NULL); return 0; case WM_DESTROY: /* * Destroy the background brush, compatible bitmap, * and the bitmap. */ DeleteObject(hbrBkgnd); DeleteDC(hdcCompat); DeleteObject(hbmp);
PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return (LRESULT) NULL; }
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
| Пригласи друзей и счет твоего мобильника всегда будет положительным! |
Использование Прямоугольников
Пример в этой секции иллюстрирует как, чтобы использовать функции прямоугольника. Это состоит из основной процедуры окна из приложения, которое приспосабливается потребителя, чтобы перемещение и размер побитовое отображение.
Когда приложение начинается, оно делает 32- пикселем к 32-побитовому отображению пикселя в верхнем левом углу экрана. Потребитель может переместить побитовое отображение таща этому. В размер побитовое отображение, потребитель создает целевой прямоугольник таща мышь затем тащит побитовое отображение и "капли" это в целевом прямоугольнике. Приложение отвечает копируя побитовое отображение в целевой прямоугольник. Процедура окна, которая позволяет потребителя, чтобы перемещаться и размер побитовое отображение дано в следующем примере.
LRESULT CALLBACK MainWndProc(hwnd, uMsg, wParam, lParam) HWND hwnd; /* ручка окна */ UINT uMsg; /* сообщение */ WPARAM wParam; /* первый параметр сообщения */ LPARAM lParam; /* параметр сообщения секунды */ { hdc HDC; /* контекст устройства (DC) для окна */ RECT rcTmp; /* временный прямоугольник */ ps PAINTSTRUCT; /* закрасьте данные для Begin/EndPaint */ ТОЧКА ptClientUL; /* область клиента верхнего левого угла */
УКАЖИТЕ ptClientLR; /* область клиента правого нижнего угла */ статический HDC hdcCompat; /* DC ДЛЯ копирования побитового отображения */ статическая ТОЧКА пт; /* x и y координаты курсора */ статический RECT rcBmp; /* прямоугольник, который прилагает побитовое отображение */ статический RECT rcTarget; /* прямоугольник должен получать побитовое отображение */ статический RECT rcClient; /* клиент-область прямоугольника */ статический BOOL fDragRect; /* ИСТИНА если побитовое отображение rect. потащено */
статический HBITMAP hbmp; /* ручка побитового отображения, чтобы отображаться */ статический HBRUSH hbrBkgnd; /* ручка фон-цветной щетки */ статический COLORREF crBkgnd; /* цвет клиента-области фона */ статический HPEN hpenDot; /* ручка точечной ручки */ ключ (uMsg) { случай WM_CREATE: /* Загрузите побитовое отображение resource. */ hbmp = LoadBitmap(hinst, MAKEINTRESOURCE(1)); /* * Создайте контекст устройства (DC), чтобы держать побитовое отображение.
* Побитовое отображение скопировано от этого DC до окна DC * всякий раз, когда должно быть сделано. */ hdc = GetDC(hwnd); hdcCompat = CreateCompatibleDC(hdc); SelectObject(hdcCompat, hbmp); /* * Создайте щетку того же самого цвета как фон * области клиента. Щетка использована последующим, чтобы стирать * старое побитовое отображение перед копированием побитового отображения в the
* целевой прямоугольник. */ crBkgnd = GetBkColor(hdc); hbrBkgnd = CreateSolidBrush(crBkgnd); ReleaseDC(hwnd, hdc); /* * Создайте точечную ручку. Ручка использована, чтобы делать the * прямоугольник побитового отображения как помехи пользователя это. */ hpenDot = CreatePen(PS_DOT, 1, RGB(0, 0, 0)); /* * Установите начальный прямоугольник для побитового отображения. Отметьтесь, что
* это приложение поддерживается только 32- 32- пикселем * побитовое отображение. Прямоугольник немного больший чем the * побитовое отображение. */ SetRect(&rcBmp, 1, 1, 34, 34); возврат 0; случай WM_PAINT: /* * Сделайте прямоугольником побитового отображения и копируйте побитовое отображение в * это. 32- Пиксель к 32-побитовому отображению пикселя отцентрирован * в прямоугольнике добавляя 1 налево и верх
* координаты прямоугольника побитового отображения, и вычитание * 2 из права и нижних координат. */ BeginPaint(hwnd, &ps); Прямоугольник(ps.hdc, rcBmp.left, rcBmp.верх, rcBmp.right, rcBmp.bottom); StretchBlt(ps.hdc, rcBmp.left + 1, rcBmp.top + 1, (rcBmp.right - rcBmp.left) - 2, (rcBmp.bottom - rcBmp.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
EndPaint(hwnd, &ps); прерывание; случай WM_MOVE: случай WM_SIZE: /* * Преобразовайте координаты клиента клиента-области * прямоугольник, чтобы отгораживать координировать и сохранять им в a * прямоугольник. Прямоугольник пройден на ClipCursor * функция в течение обработки WM_LBUTTONDOWN. */ GetClientRect(hwnd, &rcClient); ptClientUL.x = rcClient.left;
ptClientUL.y = rcClient.top; ptClientLR.x = rcClient.right; ptClientLR.y = rcClient.bottom; ClientToScreen(hwnd, &ptClientUL); ClientToScreen(hwnd, &ptClientLR); SetRect(&rcClient, ptClientUL.x, ptClientUL.y, ptClientLR.x, ptClientLR.y); возврат 0; случай WM_LBUTTONDOWN: /* * Ограничьте курсор мыши в область клиента. Это
* проверяет, что окно получает сопоставление * сообщение WM_LBUTTONUP. */ ClipCursor(&rcClient); /* Сохраните координаты мыши cursor. */ pt.x = (ДОЛГО (ДЛИНОЙ)) LOWORD(lParam); pt.y = (ДОЛГО (ДЛИНОЙ)) HIWORD(lParam); /* * Если пользователь щелкнул бы прямоугольник побитового отображения, перерисовывать * это используя точечную ручку. Установите флаг fDragRect, чтобы * укажите, что пользователь собирается тащить the
* прямоугольник. */ если (PtInRect(&rcBmp, пт)) { hdc = GetDC(hwnd); SelectObject(hdc, hpenDot); Прямоугольник(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); fDragRect = ИСТИНА; ReleaseDC(hwnd, hdc); } возврат 0; случай WM_MOUSEMOVE: /* * Сделайте целевым прямоугольником или тащите побитовое отображение
* прямоугольник, в зависимости от статуса fDragRect * флаг. */ если ((wParam && MK_LBUTTON) && !fDragRect) { /* сделайте целевым прямоугольником */ /* * Установите режим смешивания чтобы цвет ручки являлся the * инверсия цвета фона. Предшествующий * прямоугольник может затем выстиран чертежом * другой прямоугольник на верхе этого.
*/ hdc = GetDC(hwnd); SetROP2(hdc, R2_NOTXORPEN); /* * Если предшествующий целевой прямоугольник существует, выстирайтесь * это рисуя другой прямоугольник на верхе этого. */ если (!IsRectEmpty ПРЯМОУГОЛЬНИКА(&rcTarget))(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); /*
* Сохраните координаты целевого прямоугольника. * Избегайте неправильных прямоугольников гарантируя это the * оцените левую координату больше, чем * та самая координата права, и это the * оцените нижнюю координату больше, чем * тот самый верх. */ если ((pt.x < (ДОЛГО (ДЛИНОЙ)) LOWORD(lParam)) && (pt.y > (ДОЛГО (ДЛИНОЙ)) HIWORD(lParam)))
SetRect(&rcTarget, pt.x, HIWORD(lParam), LOWORD(lParam), pt.y); еще если ((pt.x > (ДОЛГО (ДЛИНОЙ)) LOWORD(lParam)) && (pt.y > (ДОЛГО (ДЛИНОЙ)) HIWORD(lParam))) SetRect(&rcTarget, LOWORD(lParam), HIWORD(lParam), pt.x, pt.y); еще если ((pt.x > (ДОЛГО (ДЛИНОЙ)) LOWORD(lParam)) && (pt.y < (ДОЛГО (ДЛИНОЙ)) HIWORD(lParam))) SetRect(&rcTarget, LOWORD(lParam), pt.y,
pt.x, HIWORD(lParam)); еще SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam), HIWORD(lParam)); /* Сделайте новой целью rectangle. */ Прямоугольник(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); ReleaseDC(hwnd, hdc); } еще если ((wParam && MK_LBUTTON) && fDragRect) { /* потащите прямоугольник побитового отображения */
/* * Установите режим смешивания чтобы цвет ручки являлся the * инверсия цвета фона. */ hdc = GetDC(hwnd); SetROP2(hdc, R2_NOTXORPEN); /* * Выберитесь точечную ручку в DC и стирайте * предшествующий прямоугольник побитового отображения рисуя * другой прямоугольник на верхе этого. */
SelectObject(hdc, hpenDot); Прямоугольник(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); /* * Установите новые координаты побитового отображения * прямоугольник затем перерисовывает это. */ OffsetRect(&rcBmp, LOWORD(lParam) - pt.x, HIWORD(lParam) - pt.y); Прямоугольник(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom);
ReleaseDC(hwnd, hdc); /* Сохраните координаты мыши cursor. */ pt.x = (ДОЛГО (ДЛИНОЙ)) LOWORD(lParam); pt.y = (ДОЛГО (ДЛИНОЙ)) HIWORD(lParam); } возврат 0; случай WM_LBUTTONUP: /* * Если прямоугольник побитового отображения и целевого прямоугольника * пересекать, копирует побитовое отображение в цель * прямоугольник. В противном случае, копировать побитовое отображение в the
* побитовое отображение прямоугольника в своей новой позиции. */ если (IntersectRect(&rcTmp, &rcBmp, &rcTarget)) { /* * Выстирайте прямоугольник побитового отображения заполняя это с * цвет фона. */ hdc = GetDC(hwnd); FillRect(hdc, &rcBmp, hbrBkgnd); /* * Перерисовывать целевой прямоугольник поскольку часть * это intersected с прямоугольником побитового отображения было
* выстиранное вызовом на FillRect. */ Прямоугольник(hdc, rcTarget.left, rcTarget.top, rcTarget.right, rcTarget.bottom); /* Скопируйте побитовое отображение в цель rectangle. */ StretchBlt(hdc, rcTarget.left + 1, rcTarget.top + 1, (rcTarget.right - rcTarget.left) - 2, (rcTarget.bottom - rcTarget.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
/* * Скопируйте целевой прямоугольник в побитовое отображение * прямоугольник, устанавливает координаты цели * прямоугольник на 0 затем восстанавливает флаг fDragRect. */ CopyRect(&rcBmp, &rcTarget); SetRectEmpty(&rcTarget); ReleaseDC(hwnd, hdc); fDragRect = ЛОЖЬ; } еще если (fDragRect) { /*
* Сделайте прямоугольником побитового отображения, копируйте побитовое отображение в * это и восстанавливает флаг fDragRect. */ hdc = GetDC(hwnd); Прямоугольник(hdc, rcBmp.left, rcBmp.top, rcBmp.right, rcBmp.bottom); StretchBlt(hdc, rcBmp.left + 1, rcBmp.top + 1, (rcBmp.right - rcBmp.left) - 2, (rcBmp.bottom - rcBmp.top) - 2, hdcCompat, 0, 0, 32, 32, SRCCOPY);
ReleaseDC(hwnd, hdc); fDragRect = ЛОЖЬ; } /* Выпустите мышь cursor. */ ClipCursor((LPRECT) НЕДЕЙСТВИТЕЛЬНЫЙ); возврат 0; случай WM_DESTROY: /* * Уничтожьте щетку фона, совместимого побитового отображения, * и побитовое отображение. */ DeleteObject(hbrBkgnd); DeleteDC(hdcCompat); DeleteObject(hbmp);
PostQuitMessage(0); прерывание; умолчание: возвращайте DefWindowProc(hwnd, uMsg, wParam, lParam); } возврат (LRESULT) НЕДЕЙСТВИТЕЛЬНЫЙ; }
|
|
|
|
| |