|
|
//
// GRPTR.CPP
// More Graphic Objects
//
// Copyright Microsoft 1998-
//
//
// The remote pointer is handled by blitting to and from the screen to a
// memory bitmap rather than letting Windows draw it. This is to get a
// reasonably continuous tracking of the pointer.
//
// In order to do this we create a memory bitmap that is the pointer size
// times 2 by 3. The top left square of the 2*3 array is used to hold the
// screen contents before the pointer is written. It may be used at any
// time to remove the pointer from the screen. The lower 2*2 square is
// used to hold the currently displayed pointer plus surrounding screen
// bits. The pointer may be anywhere within the 2*2 sector, as defined by
// "offset".
//
// ------------------
// | | |
// | | |
// | saved | unused |
// | | |
// | | |
// |----------------|
// | |
// | -------- |
// | | | |
// | | rem | |
// | | ptr | |
// | | | |
// | | | |
// | -------- |
// | |
// ------------------
//
// Operations consist of
//
// If there is no pointer there currently then
//
// 1. Copy lower 2*2 segment from the screen
// 2. Save the remote pointer square to the saved area
// 3. Draw the icon into rem ptr square
// 4. Blit the 2*2 back to the screen
//
// If there is an old rem ptr and the new one lies within the same 2*2 area
// then as above but copy "saved" to "old rem ptr" before step 2 to remove
// it.
//
// If the new pointer lies off the old square then copy "saved" back to the
// display before proceeding as in the no pointer case.
//
//
// PRECOMP
#include "precomp.h"
//
// Runtime class information
//
//
// Local defines
//
#define DRAW 1
#define UNDRAW 2
//
//
// Function: ~DCWbColorToIconMap
//
// Purpose: Destructor
//
//
DCWbColorToIconMap::~DCWbColorToIconMap(void) { // Delete all the objects in the user map and release the icon handles
HICON hIcon;
POSITION position = GetHeadPosition(); COLOREDICON * pColoredIcon; while (position) { pColoredIcon = (COLOREDICON *)GetNext(position);
// Destroy the icon
if (pColoredIcon != NULL) { ::DestroyIcon(pColoredIcon->hIcon); delete pColoredIcon; } } EmptyList(); }
//
//
// Function: DCWbGraphicPointer::DCWbGraphicPointer
//
// Purpose: Constructor for remote pointer objects
//
//
DCWbGraphicPointer::DCWbGraphicPointer(WbUser* _pUser) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::DCWbGraphicPointer");
// We haven't yet created our mem DC
m_hSaveBitmap = NULL; m_hOldBitmap = NULL;
// Save the user pointer
ASSERT(_pUser != NULL); m_pUser = _pUser;
// Set the bounding rectangle of the object
m_uiIconWidth = ::GetSystemMetrics(SM_CXICON); m_uiIconHeight = ::GetSystemMetrics(SM_CYICON);
m_boundsRect.left = 0; m_boundsRect.top = 0; m_boundsRect.right = m_uiIconWidth; m_boundsRect.bottom = m_uiIconHeight;
// Show that the object is not drawn
m_bDrawn = FALSE; ::SetRectEmpty(&m_rectLastDrawn);
// Show that we do not have an icon for drawing yet
m_hIcon = NULL;
// Create a memory DC compatible with the display
m_hMemDC = ::CreateCompatibleDC(NULL); }
//
//
// Function: DCWbGraphicPointer::~DCWbGraphicPointer
//
// Purpose: Destructor for remote pointer objects
//
//
DCWbGraphicPointer::~DCWbGraphicPointer(void) { // Restore the original bitmap to the memory DC
if (m_hOldBitmap != NULL) { SelectBitmap(m_hMemDC, m_hOldBitmap); m_hOldBitmap = NULL; }
if (m_hSaveBitmap != NULL) { DeleteBitmap(m_hSaveBitmap); m_hSaveBitmap = NULL; }
if (m_hMemDC != NULL) { ::DeleteDC(m_hMemDC); m_hMemDC = NULL; }
if(g_pMain) { g_pMain->RemoveGraphicPointer(this); }
}
//
//
// Function: Color
//
// Purpose: Set the color of the pointer. An icon of the appropriate
// color is created if necessary.
//
//
void DCWbGraphicPointer::SetColor(COLORREF newColor) { newColor = SET_PALETTERGB( newColor ); // make it use color matching
// If this is a color change
if (m_clrPenColor != newColor) {
COLOREDICON* pColoredIcon; POSITION position = g_pUsers->GetHeadPosition(); BOOL found = FALSE; while (position && !found) { pColoredIcon = (COLOREDICON *)g_pIcons->GetNext(position); if (newColor == pColoredIcon->color) { found = TRUE; } }
if(!found) { m_hIcon = CreateColoredIcon(newColor); }
// Set the color
m_clrPenColor = newColor; } }
//
//
// Function: CreateSaveBitmap
//
// Purpose: Create a bitmap for saving the bits under the pointer.
//
//
void DCWbGraphicPointer::CreateSaveBitmap(WbDrawingArea * pDrawingArea) { HBITMAP hImage = NULL; HBITMAP hOld = NULL;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::CreateSaveBitmap");
// If we already have a save bitmap, exit immediately
if (m_hSaveBitmap != NULL) { TRACE_MSG(("Already have save bitmap")); return; }
// Load the pointer bitmap
hImage = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(REMOTEPOINTERXORDATA)); if (!hImage) { ERROR_OUT(("Could not load pointer bitmap")); goto CleanupSaveBitmap; }
// Select the pointer bitmap into the memory DC. We do this to
// allow creation of a compatible bitmap (otherwise we would get
// a default monochrome format when calling CreateCompatibleBitmap).
hOld = SelectBitmap(m_hMemDC, hImage); if (hOld == NULL) { ERROR_OUT(("Could not select bitmap into DC")); goto CleanupSaveBitmap; }
// Create a bitmap to save the bits under the icon. This bitmap is
// created with space for building the new screen image before
// blitting it to the screen.
m_hSaveBitmap = ::CreateCompatibleBitmap(m_hMemDC, 2 * m_uiIconWidth * pDrawingArea->ZoomOption(), 3 * m_uiIconHeight * pDrawingArea->ZoomOption()); if (!m_hSaveBitmap) { ERROR_OUT(("Could not create save bitmap")); goto CleanupSaveBitmap; }
// Select in the save bits bitmap
m_hOldBitmap = hOld; hOld = NULL; SelectBitmap(m_hMemDC, m_hSaveBitmap);
// Default zoom factor is 1
m_iZoomSaved = 1;
CleanupSaveBitmap: if (hOld != NULL) { // Put back the original bitmap--we failed to create the save bmp
SelectBitmap(m_hMemDC, hOld); }
if (hImage != NULL) { ::DeleteBitmap(hImage); } }
//
//
// Function: CreateColoredIcon
//
// Purpose: Create an icon of the correct color for this pointer. The
// DCWbGraphicPointer class keeps a static list of icons
// created previously. These are re-used as necessary.
//
//
HICON DCWbGraphicPointer::CreateColoredIcon(COLORREF color) { HICON hColoredIcon = NULL; HBRUSH hBrush = NULL; HBRUSH hOldBrush; HBITMAP hImage = NULL; HBITMAP hOldBitmap; HBITMAP hMask = NULL; COLOREDICON *pColoredIcon; ICONINFO ii;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::CreateColoredIcon");
hBrush = ::CreateSolidBrush(color); if (!hBrush) { TRACE_MSG(("Couldn't create color brush")); goto CreateIconCleanup; }
// Load the mask bitmap
hMask = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(REMOTEPOINTERANDMASK)); if (!hMask) { TRACE_MSG(("Could not load mask bitmap")); goto CreateIconCleanup; }
// Load the image bitmap
hImage = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(REMOTEPOINTERXORDATA)); if (!hImage) { TRACE_MSG(("Could not load pointer bitmap")); goto CreateIconCleanup; }
// Select in the icon color
hOldBrush = SelectBrush(m_hMemDC, hBrush);
// Select the image bitmap into the memory DC
hOldBitmap = SelectBitmap(m_hMemDC, hImage);
// Fill the image bitmap with color
::FloodFill(m_hMemDC, m_uiIconWidth / 2, m_uiIconHeight / 2, RGB(0, 0, 0));
SelectBitmap(m_hMemDC, hOldBitmap); SelectBrush(m_hMemDC, hOldBrush);
//
// Now use the image and mask bitmaps to create an icon
//
ii.fIcon = TRUE; ii.xHotspot = 0; ii.yHotspot = 0; ii.hbmMask = hMask; ii.hbmColor = hImage;
// Create a new icon from the data and mask
hColoredIcon = ::CreateIconIndirect(&ii);
// Add the new icon to the static list
ASSERT(g_pIcons); pColoredIcon = new COLOREDICON; if (!pColoredIcon) { ERROR_OUT(("Failed to allocate COLORICON object")); DestroyIcon(hColoredIcon); hColoredIcon = NULL; } else { pColoredIcon->color = color; pColoredIcon->hIcon = hColoredIcon; g_pIcons->AddTail(pColoredIcon); }
CreateIconCleanup:
// Free the image bitmap
if (hImage != NULL) { ::DeleteBitmap(hImage); }
// Free the mask bitmap
if (hMask != NULL) { ::DeleteBitmap(hMask); }
if (hBrush != NULL) { ::DeleteBrush(hBrush); }
return(hColoredIcon); }
//
//
// Function: GetPage
//
// Purpose: Return the page of the pointer. An invalid page is returned
// if the pointer is not active.
//
//
WB_PAGE_HANDLE DCWbGraphicPointer::GetPage(void) const { // If this pointer is active, return its actual page
if (m_bActive == TRUE) return(m_hPage); else return(WB_PAGE_HANDLE_NULL); }
void DCWbGraphicPointer::SetPage(WB_PAGE_HANDLE hNewPage) { m_hPage = hNewPage; }
//
//
// Function: DrawnRect
//
// Purpose: Return the rectangle where the pointer was last drawn
//
//
void DCWbGraphicPointer::GetDrawnRect(LPRECT lprc) { ::SetRectEmpty(lprc);
if (m_bDrawn) { *lprc = m_rectLastDrawn; } }
//
//
// Function: IsLocalPointer
//
// Purpose: Return TRUE if this is the local user's pointer
//
//
BOOL DCWbGraphicPointer::IsLocalPointer(void) const { ASSERT(m_pUser != NULL); return m_pUser->IsLocalUser(); }
//
//
// Function: operator==
//
// Purpose: Return TRUE if the specified remote pointer is the same as
// this one.
//
//
BOOL DCWbGraphicPointer::operator==(const DCWbGraphicPointer& pointer) const { return (m_pUser == pointer.m_pUser); }
//
//
// Function: operator!=
//
// Purpose: Return FALSE if the specified pointer is the same as this
//
//
BOOL DCWbGraphicPointer::operator!=(const DCWbGraphicPointer& pointer) const { return (!((*this) == pointer)); }
//
//
// Function: DCWbGraphicPointer::Draw
//
// Purpose: Draw the pointer object without saving the bits under it
//
//
void DCWbGraphicPointer::Draw(HDC hDC, WbDrawingArea * pDrawingArea) { RECT rcUpdate;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::Draw");
rcUpdate = m_boundsRect;
// Check that we have an icon to draw
if (m_hIcon == NULL) { WARNING_OUT(("Icon not found")); return; }
if (pDrawingArea == NULL) { ERROR_OUT(("No drawing area passed in")); return; }
// Create the save bitmap if necessary
CreateSaveBitmap(pDrawingArea);
PointerDC(hDC, pDrawingArea, &rcUpdate, pDrawingArea->ZoomFactor());
// Draw the icon to the DC passed
::DrawIcon(hDC, rcUpdate.left, rcUpdate.top, m_hIcon);
SurfaceDC(hDC, pDrawingArea);
}
//
//
// Function: DCWbGraphicPointer::DrawSave
//
// Purpose: Draw the pointer object after saving the bits under it
//
//
void DCWbGraphicPointer::DrawSave(HDC hDC, WbDrawingArea * pDrawingArea) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::DrawSave");
// Pretend that we are not drawn
m_bDrawn = FALSE;
// Call the redraw member
Redraw(hDC, pDrawingArea); }
//
//
// Function: DCWbGraphicPointer::Redraw
//
// Purpose: Draw the pointer in its current position after erasing it
// from the DC using the saved version.
//
//
void DCWbGraphicPointer::Redraw(HDC hDC, WbDrawingArea * pDrawingArea) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::Redraw");
RECT clipBox;
::GetClipBox(hDC, &clipBox);
// Create the save bitmap if necessary
CreateSaveBitmap(pDrawingArea);
// If we are not yet drawn, we must copy data from the screen
// to initialize the save bitmaps.
if (!m_bDrawn) { TRACE_MSG(("Pointer not yet drawn"));
// Only do anything if the pointer will be visible
if (::IntersectRect(&clipBox, &clipBox, &m_boundsRect)) { // Pretend that we were drawn at the same place and copy the screen
// bits into memory to build the image.
GetBoundsRect(&m_rectLastDrawn); CopyFromScreen(hDC, pDrawingArea);
// Save the bits under the pointer
SaveMemory();
// Draw the pointer
DrawMemory();
// Copy the new image to the screen
CopyToScreen(hDC, pDrawingArea);
// Show that the pointer is now drawn
m_bDrawn = TRUE; } } else { TRACE_MSG(("Pointer already drawn at %d %d", m_rectLastDrawn.left, m_rectLastDrawn.top));
// Calculate the update rectangle
RECT rcUpdate;
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn);
// Check whether any of the update is visible
if (::IntersectRect(&clipBox, &clipBox, &rcUpdate)) { // Check whether we can do better by drawing in memory before
// going to the screen.
GetBoundsRect(&rcUpdate); if (::IntersectRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn)) { TRACE_MSG(("Drawing in memory first"));
// The old and new positions of the pointers overlap. We can
// reduce flicker by building the new image in memory and
// blitting to the screen.
// Copy overlap rectangle to memory
CopyFromScreen(hDC, pDrawingArea);
// Undraw the pointer from the overlap rectangle
UndrawMemory();
// Save the bits under the new pointer position (from memory)
SaveMemory();
// Draw the new pointer into memory
DrawMemory();
// Copy the new image to the screen
CopyToScreen(hDC, pDrawingArea); } else { TRACE_MSG(("No overlap - remove and redraw"));
// The old and new pointer positions do not overlap. We can remove
// the old pointer and draw the new in the usual way.
// Copy the saved bits under the pointer to the screen
UndrawScreen(hDC, pDrawingArea);
// Pretend that we were drawn at the same place and copy the screen
// bits into memory to build the image.
GetBoundsRect(&m_rectLastDrawn); CopyFromScreen(hDC, pDrawingArea);
// Save the bits under the pointer
SaveMemory();
// Draw the pointer
DrawMemory();
// Copy the new image to the screen
CopyToScreen(hDC, pDrawingArea); }
// Show that the pointer is now drawn
m_bDrawn = TRUE; } }
// If the pointer was drawn, save the rectangle in which it was drawn
if (m_bDrawn) { GetBoundsRect(&m_rectLastDrawn); } }
//
//
// Function: DCWbGraphicPointer::Undraw
//
// Purpose: Draw the marker object
//
//
void DCWbGraphicPointer::Undraw(HDC hDC, WbDrawingArea * pDrawingArea) { // If we are not drawn, do nothing
if (m_bDrawn) { // Create the save bitmap if necessary
CreateSaveBitmap(pDrawingArea);
// Copy the saved bits onto the screen
UndrawScreen(hDC, pDrawingArea);
// Show that we are no longer drawn
m_bDrawn = FALSE; } }
//
//
// Function: CopyFromScreen
//
// Purpose: Save the bits around the old and new pointer positions
// to memory.
//
//
BOOL DCWbGraphicPointer::CopyFromScreen(HDC hDC, WbDrawingArea * pDrawingArea) { BOOL bResult = FALSE; RECT rcUpdate;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::CopyFromScreen");
// Get the update rectangle needed
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn);
PointerDC(hDC, pDrawingArea, &rcUpdate, pDrawingArea->ZoomFactor());
// Copy the bits
bResult = ::BitBlt(m_hMemDC, 0, m_uiIconHeight * m_iZoomSaved, rcUpdate.right - rcUpdate.left, rcUpdate.bottom - rcUpdate.top, hDC, rcUpdate.left, rcUpdate.top, SRCCOPY); if (!bResult) { WARNING_OUT(("CopyFromScreen - Could not copy to bitmap")); }
SurfaceDC(hDC, pDrawingArea);
return(bResult); }
//
//
// Function: CopyToScreen
//
// Purpose: Copy the saved bits around the old and new pointers back
// to the screen.
//
//
BOOL DCWbGraphicPointer::CopyToScreen(HDC hDC, WbDrawingArea * pDrawingArea) { BOOL bResult = FALSE; RECT rcUpdate;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::CopyToScreen");
// Get the update rectangle needed
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn);
PointerDC(hDC, pDrawingArea, &rcUpdate);
bResult = ::BitBlt(hDC, rcUpdate.left, rcUpdate.top, rcUpdate.right - rcUpdate.left, rcUpdate.bottom - rcUpdate.top, m_hMemDC, 0, m_uiIconHeight * m_iZoomSaved, SRCCOPY); if (!bResult) { WARNING_OUT(("CopyToScreen - Could not copy from bitmap")); }
SurfaceDC(hDC, pDrawingArea);
return(bResult); }
//
//
// Function: UndrawMemory
//
// Purpose: Copy the saved bits under the pointer to the memory copy of
// the screen, thus erasing the pointer from the image.
//
//
BOOL DCWbGraphicPointer::UndrawMemory() { BOOL bResult = FALSE; RECT rcUpdate; SIZE offset;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::UndrawMemory");
// Get the update rectangle needed
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn); offset.cx = m_rectLastDrawn.left - rcUpdate.left; offset.cy = m_rectLastDrawn.top - rcUpdate.top;
bResult = ::BitBlt(m_hMemDC, offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved, m_uiIconWidth * m_iZoomSaved, m_uiIconHeight * m_iZoomSaved, m_hMemDC, 0, 0, SRCCOPY); if (bResult == FALSE) { WARNING_OUT(("UndrawMemory - Could not copy from bitmap")); } TRACE_MSG(("Copied to memory %d,%d from memory %d,%d size %d,%d", offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved, 0, 0, m_uiIconWidth * m_iZoomSaved, m_uiIconHeight * m_iZoomSaved));
return(bResult); }
//
//
// Function: SaveMemory
//
// Purpose: Copy the area of the memory image that will be under the
// pointer to the save area.
//
//
BOOL DCWbGraphicPointer::SaveMemory(void) { BOOL bResult = FALSE; RECT rcUpdate; SIZE offset;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::SaveMemory");
// Get the update rectangle needed
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn); offset.cx = m_boundsRect.left - rcUpdate.left; offset.cy = m_boundsRect.top - rcUpdate.top;
bResult = ::BitBlt(m_hMemDC, 0, 0, m_uiIconWidth * m_iZoomSaved, m_uiIconHeight * m_iZoomSaved, m_hMemDC, offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved, SRCCOPY); if (bResult == FALSE) { TRACE_MSG(("SaveMemory - Could not copy from bitmap")); } TRACE_MSG(("Copied to memory %d,%d from memory %d,%d size %d,%d", 0, 0, offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved, m_uiIconWidth * m_iZoomSaved, m_uiIconHeight * m_iZoomSaved));
return(bResult); }
//
//
// Function: DrawMemory
//
// Purpose: Draw the pointer onto the memory image copy.
//
//
BOOL DCWbGraphicPointer::DrawMemory(void) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::DrawMemory");
BOOL bResult = FALSE;
// Check that we have an icon to draw
if (m_hIcon == NULL) { WARNING_OUT(("No icon to draw")); } else { RECT rcUpdate; SIZE offset;
// Get the update rectangle needed
GetBoundsRect(&rcUpdate); ::UnionRect(&rcUpdate, &rcUpdate, &m_rectLastDrawn); offset.cx = m_boundsRect.left - rcUpdate.left; offset.cy = m_boundsRect.top - rcUpdate.top;
// Draw the icon to the DC passed
bResult = ::DrawIcon(m_hMemDC, offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved + (m_uiIconHeight * (m_iZoomSaved - 1))/2, m_hIcon);
if (bResult == FALSE) { WARNING_OUT(("DrawMemory - Could not draw icon")); } TRACE_MSG(("Write pointer to memory at %d,%d", offset.cx * m_iZoomSaved, (m_uiIconHeight + offset.cy) * m_iZoomSaved + (m_uiIconHeight * (m_iZoomSaved - 1))/2)); }
return(bResult); }
//
//
// Function: UndrawScreen
//
// Purpose: Copy the saved bits under the pointer to the screen.
//
//
BOOL DCWbGraphicPointer::UndrawScreen(HDC hDC, WbDrawingArea * pDrawingArea) { BOOL bResult = FALSE; RECT rcUpdate;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::UndrawScreen");
rcUpdate = m_rectLastDrawn;
PointerDC(hDC, pDrawingArea, &rcUpdate);
// We are undrawing - copy the saved bits to the DC passed
bResult = ::BitBlt(hDC, rcUpdate.left, rcUpdate.top, rcUpdate.right - rcUpdate.left, rcUpdate.bottom - rcUpdate.top, m_hMemDC, 0, 0, SRCCOPY); if (!bResult) { WARNING_OUT(("UndrawScreen - Could not copy from bitmap")); }
SurfaceDC(hDC, pDrawingArea);
return(bResult); }
//
//
// Function: Update
//
// Purpose: Update the pointer information stored in the user
// information.
//
//
void DCWbGraphicPointer::Update(void) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::Update");
// Only do the update if we have been changed
if (m_bChanged) { // Make the update (the pointer information is held in the associated
// user object)
ASSERT(m_pUser != NULL); m_pUser->Update();
// Show that we have not changed since the last update
m_bChanged = FALSE; } }
//
//
// Function: SetActive
//
// Purpose: Update the pointer information to show that the pointer
// is now active.
//
//
void DCWbGraphicPointer::SetActive(WB_PAGE_HANDLE hPage, POINT point) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::SetActive");
// Set the member variables
MoveTo(point.x, point.y); m_hPage = hPage; m_bActive = TRUE; m_bChanged = TRUE;
// Distribute the update
Update(); }
//
//
// Function: SetInactive
//
// Purpose: Update the pointer information to show that the pointer
// is no longer active.
//
//
void DCWbGraphicPointer::SetInactive(void) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::SetInactive");
// Set the member variables
m_bActive = FALSE; m_bChanged = TRUE;
// Distribute the update
Update(); }
//
//
// Function: PointerDC
//
// Purpose: Scale the DC to 1:1, set a zero origin and convert the
// supplied rectangle into window coordinates. This is because
// we have to do the zoom mapping ourselves when we are doing
// remote pointer blitting, otherwise the system does
// stretchblits and screws up. Note that the SurfaceToClient
// function gives us a client rectangle (ie it is 3 * as big
// when we are zoomed)
//
//
void DCWbGraphicPointer::PointerDC ( HDC hDC, WbDrawingArea * pDrawingArea, LPRECT lprc, int zoom ) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::PointerDC");
// default zoom to be the saved value
if (zoom == 0) { zoom = m_iZoomSaved; } else { m_iZoomSaved = zoom; }
// If we are currently zoomed then do the scaling
if (zoom != 1) { ::ScaleViewportExtEx(hDC, 1, zoom, 1, zoom, NULL); TRACE_MSG(("Scaled screen viewport down by %d", zoom));
pDrawingArea->SurfaceToClient(lprc); ::SetWindowOrgEx(hDC, 0, 0, NULL); } }
//
//
// Function: SurfaceDC
//
// Purpose: Scale the DC back to the correct zoom factor and reset the
// origin to the surface offset
//
//
void DCWbGraphicPointer::SurfaceDC(HDC hDC, WbDrawingArea * pDrawingArea) { MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::SurfaceDC");
if (m_iZoomSaved != 1) { POINT pt;
::ScaleViewportExtEx(hDC, m_iZoomSaved, 1, m_iZoomSaved, 1, NULL); TRACE_MSG(("Scaled screen viewport up by %d", m_iZoomSaved));
pDrawingArea->GetOrigin(&pt); ::SetWindowOrgEx(hDC, pt.x, pt.y, NULL); } }
|