windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/wb/bmpobj.cpp
2020-09-26 16:20:57 +08:00

1449 lines
32 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// BitmapObj.CPP
// Bitmap objects:
//
// Copyright Microsoft 1998-
//
#include "precomp.h"
#include "NMWbObj.h"
BitmapObj::BitmapObj (BitmapCreatePDU * pbitmapCreatePDU)
{
ResetAttrib();
SetType(bitmapCreatePDU_chosen);
SetPenThickness(0);
SetMyWorkspace(NULL);
m_lpTransparencyMask = NULL;
m_lpbiImage = NULL;
m_lpBitMask = NULL;
m_hSaveBitmap = NULL;
m_hOldBitmap = NULL;
m_hIcon = NULL;
m_fMoreToFollow = TRUE;
//
// Created remotely, not selected, not editing or deleting.
//
ClearCreationFlags();
ClearSelectionFlags();
ClearEditionFlags();
ClearDeletionFlags();
if(pbitmapCreatePDU->bitmapFormatHeader.choice != bitmapHeaderNonStandard_chosen)
{
ERROR_OUT(("Only Handle uncompresed bitmaps"));
return;
}
SetThisObjectHandle(pbitmapCreatePDU->bitmapHandle);
UINT workspaceHandle;
UINT planeID;
m_ToolType = GetBitmapDestinationAddress(&pbitmapCreatePDU->destinationAddress, &workspaceHandle, &planeID);
SetWorkspaceHandle(workspaceHandle);
SetPlaneID(planeID);
//
// Get bitmap attributes
//
if(pbitmapCreatePDU->bit_mask & BitmapCreatePDU_attributes_present)
{
GetBitmapAttrib(pbitmapCreatePDU->attributes);
}
//
// Get bitmap anchor point
//
if(pbitmapCreatePDU->bit_mask & BitmapCreatePDU_anchorPoint_present)
{
SetAnchorPoint(pbitmapCreatePDU->anchorPoint.xCoordinate, pbitmapCreatePDU->anchorPoint.yCoordinate);
}
//
// Get bitmap size
//
m_bitmapSize.x = pbitmapCreatePDU->bitmapSize.width;
m_bitmapSize.y = pbitmapCreatePDU->bitmapSize.height;
RECT rect;
rect.top = pbitmapCreatePDU->anchorPoint.yCoordinate;
rect.left = pbitmapCreatePDU->anchorPoint.xCoordinate;
rect.bottom = pbitmapCreatePDU->anchorPoint.yCoordinate + m_bitmapSize.y;
rect.right = pbitmapCreatePDU->anchorPoint.xCoordinate + m_bitmapSize.x;
SetRect(&rect);
//
// Get bitmap region of interest
//
if(pbitmapCreatePDU->bit_mask & bitmapRegionOfInterest_present)
{
m_bitmapRegionOfInterest.left = pbitmapCreatePDU->bitmapRegionOfInterest.upperLeft.xCoordinate;
m_bitmapRegionOfInterest.top = pbitmapCreatePDU->bitmapRegionOfInterest.upperLeft.yCoordinate;
m_bitmapRegionOfInterest.right = pbitmapCreatePDU->bitmapRegionOfInterest.lowerRight.xCoordinate;
m_bitmapRegionOfInterest.bottom = pbitmapCreatePDU->bitmapRegionOfInterest.lowerRight.yCoordinate;
}
//
// Get the bitmap pixel aspect ration
//
m_pixelAspectRatio = pbitmapCreatePDU->pixelAspectRatio.choice;
if(pbitmapCreatePDU->bit_mask & BitmapCreatePDU_scaling_present)
{
m_scaling.x = pbitmapCreatePDU->scaling.xCoordinate;
m_scaling.y = pbitmapCreatePDU->scaling.yCoordinate;
}
//
// Non standard bitmap
//
if((pbitmapCreatePDU->bit_mask & BitmapCreatePDU_nonStandardParameters_present) &&
pbitmapCreatePDU->nonStandardParameters->value.nonStandardIdentifier.choice == h221nonStandard_chosen)
{
m_bitmapData.m_length = pbitmapCreatePDU->nonStandardParameters->value.data.length;
m_lpbiImage = (LPBITMAPINFOHEADER)::GlobalAlloc(GPTR, m_bitmapData.m_length);
memcpy(m_lpbiImage, // pColor is now pointing to the begining of the bitmap bits
pbitmapCreatePDU->nonStandardParameters->value.data.value,
m_bitmapData.m_length);
}
m_fMoreToFollow = pbitmapCreatePDU->moreToFollow;
// Create a memory DC compatible with the display
m_hMemDC = ::CreateCompatibleDC(NULL);
//
// If this is a remote pointer
//
if(m_ToolType == TOOLTYPE_REMOTEPOINTER)
{
CreateColoredIcon(0, m_lpbiImage, m_lpTransparencyMask);
CreateSaveBitmap();
}
}
void BitmapObj::Continue (BitmapCreateContinuePDU * pbitmapCreateContinuePDU)
{
//
// Get the continuation bitmap data
//
BYTE * pNewBitmapBuffer = NULL;
ULONG length = 0;
BYTE* pSentBuff;
//
// Allocate a buffer for the previous data and the one we just got, copy the old data in the new buffer
//
if(pbitmapCreateContinuePDU->bit_mask == BitmapCreateContinuePDU_nonStandardParameters_present)
{
length = pbitmapCreateContinuePDU->nonStandardParameters->value.data.length;
pSentBuff = pbitmapCreateContinuePDU->nonStandardParameters->value.data.value;
}
else
{
return;
}
//
// Copy the old data
//
pNewBitmapBuffer = (BYTE *)::GlobalAlloc(GPTR, m_bitmapData.m_length + length);
if(pNewBitmapBuffer == NULL)
{
TRACE_DEBUG(("Could not allocate memory size = %d)", m_bitmapData.m_length + length));
return;
}
memcpy(pNewBitmapBuffer, m_lpbiImage, m_bitmapData.m_length);
TRACE_DEBUG(("BitmapObj::Continue length = %d moreToFollow = %d)", length, pbitmapCreateContinuePDU->moreToFollow));
//
// Copy the new data
//
memcpy(pNewBitmapBuffer + m_bitmapData.m_length, pSentBuff, length);
//
// delete the old buffer
//
::GlobalFree((HGLOBAL)m_lpbiImage);
//
// Update bitmap data info
//
m_lpbiImage = (LPBITMAPINFOHEADER)pNewBitmapBuffer;
m_bitmapData.m_length += length;
m_lpbiImage->biSizeImage += length;
m_fMoreToFollow = pbitmapCreateContinuePDU->moreToFollow;
}
BitmapObj::BitmapObj (UINT toolType)
{
SetType(bitmapCreatePDU_chosen);
ResetAttrib();
SetOwnerID(g_MyMemberID);
SetMyWorkspace(NULL);
m_ToolType = toolType;
m_lpTransparencyMask = NULL;
m_lpbiImage = NULL;
m_lpBitMask = NULL;
m_hSaveBitmap = NULL;
m_hOldBitmap = NULL;
m_fMoreToFollow = FALSE;
//
// Created locally, not selected, not editing or deleting.
//
CreatedLocally();
ClearSelectionFlags();
ClearEditionFlags();
ClearDeletionFlags();
SetPenThickness(0);
//
// Set it to 0 so it boundsRect == rect
//
RECT rect;
::SetRectEmpty(&rect);
SetRect(&rect);
SetWorkspaceHandle(g_pCurrentWorkspace == NULL ? 0 : g_pCurrentWorkspace->GetWorkspaceHandle());
SetPlaneID(1);
SetViewState(unselected_chosen);
SetZOrder(front);
SetAnchorPoint(0,0);
if(m_ToolType == TOOLTYPE_REMOTEPOINTER)
{
// We haven't yet created our mem DC
m_hSaveBitmap = NULL;
m_hOldBitmap = NULL;
// Set the bounding rectangle of the object
rect.left = 0;
rect.top = 0;
rect.right = ::GetSystemMetrics(SM_CXICON);
rect.bottom = ::GetSystemMetrics(SM_CYICON);
SetRect(&rect);
}
// 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);
}
BitmapObj::~BitmapObj( void )
{
RemoveObjectFromResendList(this);
RemoveObjectFromRequestHandleList(this);
if(GetMyWorkspace() != NULL && WasDeletedLocally())
{
OnObjectDelete();
}
::GlobalFree((HGLOBAL)m_lpbiImage);
DeleteSavedBitmap();
if (m_hMemDC != NULL)
{
::DeleteDC(m_hMemDC);
m_hMemDC = NULL;
}
if(g_pMain && g_pMain->m_pLocalRemotePointer == this)
{
GetAnchorPoint(&g_pMain->m_localRemotePointerPosition);
g_pMain->m_pLocalRemotePointer = NULL;
g_pMain->m_TB.PopUp(IDM_REMOTE);
}
if(m_lpTransparencyMask)
{
delete m_lpTransparencyMask;
m_lpTransparencyMask = NULL;
}
if(m_hIcon)
{
::DestroyIcon(m_hIcon);
}
}
void BitmapObj::BitmapEditObj (BitmapEditPDU * pbitmapEditPDU )
{
RECT rect;
POSITION pos;
POINT anchorPoint;
LONG deltaX = 0;
LONG deltaY = 0;
TRACE_MSG(("bitmapHandle = %d", pbitmapEditPDU->bitmapHandle ));
//
// Was edited remotely
//
ClearEditionFlags();
//
// Read attributes
//
if(pbitmapEditPDU->bit_mask & BitmapEditPDU_attributeEdits_present)
{
GetBitmapAttrib((PBitmapCreatePDU_attributes)pbitmapEditPDU->attributeEdits);
}
//
// Change the anchor point
//
GetAnchorPoint(&anchorPoint);
if(pbitmapEditPDU->bit_mask & BitmapEditPDU_anchorPointEdit_present)
{
TRACE_DEBUG(("Old anchor point (%d,%d)", anchorPoint.x, anchorPoint.y));
TRACE_DEBUG(("New anchor point (%d,%d)",
pbitmapEditPDU->anchorPointEdit.xCoordinate, pbitmapEditPDU->anchorPointEdit.yCoordinate));
//
// Get the delta from previous anchor point
//
deltaX = pbitmapEditPDU->anchorPointEdit.xCoordinate - anchorPoint.x;
deltaY = pbitmapEditPDU->anchorPointEdit.yCoordinate - anchorPoint.y;
TRACE_DEBUG(("Delta (%d,%d)", deltaX , deltaY));
//
// Was edited remotely
//
ClearEditionFlags();
//
// Set new anchor point
//
anchorPoint.x = pbitmapEditPDU->anchorPointEdit.xCoordinate;
anchorPoint.y = pbitmapEditPDU->anchorPointEdit.yCoordinate;
SetAnchorPoint(anchorPoint.x, anchorPoint.y);
GetRect(&rect);
::OffsetRect(&rect, deltaX, deltaY);
SetRect(&rect);
}
// if(pbitmapEditPDU->bit_mask & BitmapEditPDU_nonStandardParameters_present)
// {
// ; // Do the non Standard Edit PDU NYI
// }
if(HasAnchorPointChanged())
{
g_pDraw->EraseInitialDrawFinal(0 - deltaX,0 - deltaY, FALSE, (T126Obj*)this);
GetBoundsRect(&rect);
g_pDraw->InvalidateSurfaceRect(&rect,TRUE);
}
else if(HasZOrderChanged())
{
if(GetZOrder() == front)
{
g_pDraw->BringToTopSelection(FALSE, this);
}
else
{
g_pDraw->SendToBackSelection(FALSE, this);
}
}
//
// If it just select/unselected it
//
else if(HasViewStateChanged())
{
}
else
{
Draw();
}
//
// Reset all the attributes
//
ResetAttrib();
}
void BitmapObj::GetBitmapAttrib(PBitmapCreatePDU_attributes pAttribPDU)
{
PBitmapCreatePDU_attributes attributes;
attributes = (PBitmapCreatePDU_attributes)pAttribPDU;
while(attributes)
{
switch(attributes->value.choice)
{
case(BitmapAttribute_viewState_chosen):
{
if((attributes->value.u.viewState).choice != nonStandardViewState_chosen)
{
SetViewState(attributes->value.u.viewState.choice);
//
// If the other node is selecting the drawing or unselecting
//
if(attributes->value.u.viewState.choice == selected_chosen)
{
SelectedRemotely();
}
else if(attributes->value.u.viewState.choice == unselected_chosen)
{
ClearSelectionFlags();
}
TRACE_MSG(("Attribute viewState %d", attributes->value.u.viewState.choice));
}
else
{
// Do the non Standard view state
;
}
break;
}
case(BitmapAttribute_zOrder_chosen):
{
SetZOrder(attributes->value.u.zOrder);
TRACE_MSG(("Attribute zOrder %d", attributes->value.u.zOrder));
break;
}
case(BitmapAttribute_transparencyMask_chosen):
{
TRACE_MSG(("Attribute transparencyMask"));
if(attributes->value.u.transparencyMask.bitMask.choice == uncompressed_chosen)
{
m_SizeOfTransparencyMask = attributes->value.u.transparencyMask.bitMask.u.uncompressed.length;
DBG_SAVE_FILE_LINE
m_lpTransparencyMask = new BYTE[m_SizeOfTransparencyMask];
memcpy(m_lpTransparencyMask, attributes->value.u.transparencyMask.bitMask.u.uncompressed.value, m_SizeOfTransparencyMask);
//
// Asn wants it top bottom left right
//
// BYTE swapByte;
// for (UINT i=0; i <m_SizeOfTransparencyMask ; i++)
// {
// swapByte = attributes->value.u.transparencyMask.bitMask.u.uncompressed.value[i];
// m_lpTransparencyMask [i] = ~(((swapByte >> 4) & 0x0f) | ((swapByte << 4)));
// }
}
break;
}
case(DrawingAttribute_nonStandardAttribute_chosen):
{
break; // NYI
}
default:
WARNING_OUT(("Invalid attributes choice"));
break;
}
attributes = attributes->next;
}
}
void BitmapObj::CreateNonStandard24BitBitmap(BitmapCreatePDU * pBitmapCreatePDU)
{
pBitmapCreatePDU->bit_mask |= BitmapCreatePDU_nonStandardParameters_present;
//
// Create the bitmpa header because it is not optional
//
pBitmapCreatePDU->bitmapFormatHeader.choice = bitmapHeaderNonStandard_chosen;
pBitmapCreatePDU->bitmapFormatHeader.u.bitmapHeaderNonStandard.nonStandardIdentifier.choice = bitmapHeaderNonStandard_chosen;
CreateNonStandardPDU(&pBitmapCreatePDU->bitmapFormatHeader.u.bitmapHeaderNonStandard, NonStandard24BitBitmapID);
pBitmapCreatePDU->bitmapFormatHeader.u.bitmapHeaderNonStandard.data.length = 0;
pBitmapCreatePDU->bitmapFormatHeader.u.bitmapHeaderNonStandard.data.value = NULL;
DBG_SAVE_FILE_LINE
pBitmapCreatePDU->nonStandardParameters = new BitmapCreatePDU_nonStandardParameters;
pBitmapCreatePDU->nonStandardParameters->next = NULL;
CreateNonStandardPDU(&pBitmapCreatePDU->nonStandardParameters->value, NonStandard24BitBitmapID);
}
void BitmapObj::CreateBitmapCreatePDU(CWBOBLIST * pCreatePDUList)
{
if(m_lpbiImage == NULL)
{
TRACE_MSG(("We dont have a bitmap structure to sent"));
return;
}
SIPDU *sipdu = NULL;
DBG_SAVE_FILE_LINE
sipdu = (SIPDU *) new BYTE[sizeof(SIPDU)];
if(!sipdu)
{
TRACE_MSG(("Failed to create sipdu"));
::PostMessage(g_pMain->m_hwnd, WM_USER_DISPLAY_ERROR, WBFE_RC_WINDOWS, 0);
return;
}
//
// This is the first bitmap create pdu
//
sipdu->choice = bitmapCreatePDU_chosen;
BitmapCreatePDU *pCreatePDU = &sipdu->u.bitmapCreatePDU;
pCreatePDU->bit_mask = 0;
pCreatePDU->nonStandardParameters = NULL;
//
// Pass the bitmap Handle
//
pCreatePDU->bitmapHandle = GetThisObjectHandle();
//
// Pass the destination adress
//
if( m_ToolType == TOOLTYPE_REMOTEPOINTER)
{
pCreatePDU->destinationAddress.choice = softCopyPointerPlane_chosen;
pCreatePDU->destinationAddress.u.softCopyPointerPlane.workspaceHandle = GetMyWorkspace()->GetWorkspaceHandle();
}
else
{
pCreatePDU->destinationAddress.choice = BitmapDestinationAddress_softCopyImagePlane_chosen;
pCreatePDU->destinationAddress.u.softCopyImagePlane.workspaceHandle = GetMyWorkspace()->GetWorkspaceHandle();
pCreatePDU->destinationAddress.u.softCopyImagePlane.plane = (DataPlaneID)GetPlaneID();
}
//
// Pass the bitmap attributes
//
pCreatePDU->bit_mask |=BitmapCreatePDU_attributes_present;
SetBitmapAttrib(&pCreatePDU->attributes);
//
// Pass the anchor point
//
pCreatePDU->bit_mask |=BitmapCreatePDU_anchorPoint_present;
POINT point;
GetAnchorPoint(&point);
pCreatePDU->anchorPoint.xCoordinate = point.x;
pCreatePDU->anchorPoint.yCoordinate = point.y;
//
// Pass the bitmap size
//
pCreatePDU->bitmapSize.width = m_bitmapSize.x;
pCreatePDU->bitmapSize.height = m_bitmapSize.y;
//
// Pass bitmap region of interest
//
pCreatePDU->bit_mask |=bitmapRegionOfInterest_present;
BitmapRegion bitmapRegionOfInterest;
//
// Pass pixel aspect ratio
//
pCreatePDU->pixelAspectRatio.choice = PixelAspectRatio_square_chosen;
//
// Pass scaling factor
//
// pCreatePDU->bit_mask |=BitmapCreatePDU_scaling_present;
// pCreatePDU->scaling.xCoordinate = 0;
// pCreatePDU->scaling.yCoordinate = 0;
//
// Pass check points
//
// pCreatePDU->bit_mask |=checkpoints_present;
// pCreatePDU->checkpoints;
//
// JOSEF If we want > 8 have to recalculate to 24
//
LPSTR pDIB_bits;
LPBITMAPINFOHEADER lpbi8 = m_lpbiImage;
HDC hdc = NULL;
HBITMAP hbmp = NULL;
DWORD sizeOfBmpData = 0;
if(!g_pNMWBOBJ->CanDo24BitBitmaps())
{
hdc = GetDC(NULL);
BITMAPINFOHEADER lpbmih;
if(lpbi8->biBitCount > MAX_BITS_PERPIXEL)
{
lpbmih.biSize = sizeof(BITMAPINFOHEADER);
lpbmih.biWidth = lpbi8->biWidth;
lpbmih.biHeight = lpbi8->biHeight;
lpbmih.biPlanes = 1;
lpbmih.biBitCount = MAX_BITS_PERPIXEL;
lpbmih.biCompression = lpbi8->biCompression;
lpbmih.biSizeImage = lpbi8->biSizeImage;
lpbmih.biXPelsPerMeter = lpbi8->biXPelsPerMeter;
lpbmih.biYPelsPerMeter = lpbi8->biYPelsPerMeter;
lpbmih.biClrUsed = lpbi8->biClrUsed;
lpbmih.biClrImportant = lpbi8->biClrImportant;
hbmp = CreateDIBitmap(hdc, &lpbmih, CBM_INIT, DIB_Bits(lpbi8),(LPBITMAPINFO)lpbi8, DIB_RGB_COLORS);
lpbi8 = DIB_FromBitmap(hbmp, NULL, FALSE, FALSE);
}
}
pDIB_bits = (LPSTR)lpbi8;
sizeOfBmpData = DIB_TotalLength(lpbi8);
//
// Sending data
//
BOOL bMoreToFollow = FALSE;
DWORD length = sizeOfBmpData;
pCreatePDU->bitmapData.bit_mask = 0;
if(sizeOfBmpData > MAX_BITMAP_DATA)
{
length = MAX_BITMAP_DATA;
bMoreToFollow = TRUE;
}
pCreatePDU->moreToFollow = (ASN1bool_t)bMoreToFollow;
//
// Pass the bitmap info
//
pCreatePDU->bit_mask |= BitmapCreatePDU_nonStandardParameters_present;
CreateNonStandard24BitBitmap(&sipdu->u.bitmapCreatePDU);
pCreatePDU->nonStandardParameters->value.data.length = length;
pCreatePDU->nonStandardParameters->value.data.value = (ASN1octet_t *)pDIB_bits;
//
// We are not passing it into the data field
//
pCreatePDU->bitmapData.bit_mask = 0;
pCreatePDU->bitmapData.data.length = 1;
pCreatePDUList->AddTail(sipdu);
BitmapCreateContinuePDU * pCreateContinuePDU;
while(bMoreToFollow)
{
//
// Advance the pointer
//
pDIB_bits += MAX_BITMAP_DATA;
sizeOfBmpData-= MAX_BITMAP_DATA;
if(sizeOfBmpData > MAX_BITMAP_DATA)
{
length = MAX_BITMAP_DATA;
}
else
{
length = sizeOfBmpData;
bMoreToFollow = FALSE;
}
//
// Create a new BitmapCreateContinuePDU
//
sipdu = NULL;
DBG_SAVE_FILE_LINE
sipdu = (SIPDU *) new BYTE[sizeof(SIPDU)];
if(!sipdu)
{
TRACE_MSG(("Failed to create sipdu"));
::PostMessage(g_pMain->m_hwnd, WM_USER_DISPLAY_ERROR, WBFE_RC_WINDOWS, 0);
return;
}
sipdu->choice = bitmapCreateContinuePDU_chosen;
pCreateContinuePDU = &sipdu->u.bitmapCreateContinuePDU;
pCreateContinuePDU->bit_mask = 0;
pCreateContinuePDU->nonStandardParameters = NULL;
//
// Pass the bitmap Handle
//
pCreateContinuePDU->bitmapHandle = GetThisObjectHandle();
//
// Pass the data
//
pCreateContinuePDU->bit_mask |= BitmapCreateContinuePDU_nonStandardParameters_present;
//
// Pass the bitmap info
//
DBG_SAVE_FILE_LINE
pCreateContinuePDU->nonStandardParameters = new BitmapCreateContinuePDU_nonStandardParameters;
pCreateContinuePDU->nonStandardParameters->next = NULL;
CreateNonStandardPDU(&pCreateContinuePDU->nonStandardParameters->value, NonStandard24BitBitmapID);
pCreateContinuePDU->nonStandardParameters->value.data.length = length;
pCreateContinuePDU->nonStandardParameters->value.data.value = (ASN1octet_t *)pDIB_bits;
//
// We are not passing it into the data field
//
pCreateContinuePDU->bitmapData.bit_mask = 0;
pCreateContinuePDU->bitmapData.data.length = 1;
pCreateContinuePDU->moreToFollow = (ASN1bool_t) bMoreToFollow;
pCreatePDUList->AddTail(sipdu);
}
if(hbmp)
{
DeleteObject(hbmp);
}
if(hdc)
{
ReleaseDC(NULL, hdc);
}
}
void BitmapObj::CreateBitmapEditPDU(BitmapEditPDU *pEditPDU)
{
pEditPDU->bit_mask = (ASN1uint16_t) GetPresentAttribs();
//
// Pass the anchor point
//
if(HasAnchorPointChanged())
{
POINT point;
GetAnchorPoint(&point);
pEditPDU->anchorPointEdit.xCoordinate = point.x;
pEditPDU->anchorPointEdit.yCoordinate = point.y;
}
//
// JOSEF Pass Region of interest (FEATURE)
//
//
// JOSEF Pass scaling (FEATURE)
//
//
// Pass all the changed attributes, if any.
//
pEditPDU->attributeEdits = NULL;
if(pEditPDU->bit_mask & BitmapEditPDU_attributeEdits_present)
{
SetBitmapAttrib((PBitmapCreatePDU_attributes *)&pEditPDU->attributeEdits);
}
pEditPDU->bitmapHandle = GetThisObjectHandle();
}
void BitmapObj::CreateBitmapDeletePDU(BitmapDeletePDU *pDeletePDU)
{
pDeletePDU->bit_mask = 0;
pDeletePDU->bitmapHandle = GetThisObjectHandle();
}
void BitmapObj::AllocateAttrib(PBitmapCreatePDU_attributes *pAttributes)
{
DBG_SAVE_FILE_LINE
PBitmapCreatePDU_attributes pAttrib = (PBitmapCreatePDU_attributes)new BYTE[sizeof(BitmapCreatePDU_attributes)];
if(*pAttributes == NULL)
{
*pAttributes = pAttrib;
pAttrib->next = NULL;
}
else
{
((PBitmapCreatePDU_attributes)pAttrib)->next = *pAttributes;
*pAttributes = pAttrib;
}
}
void BitmapObj::SetBitmapAttrib(PBitmapCreatePDU_attributes *pattributes)
{
PBitmapCreatePDU_attributes attributes = NULL;
//
// Do the viewState
//
if(HasViewStateChanged())
{
AllocateAttrib(&attributes);
attributes->value.choice = BitmapAttribute_viewState_chosen;
attributes->value.u.viewState.choice = (ASN1choice_t)GetViewState();
}
//
// Do the zOrder
//
if(HasZOrderChanged())
{
AllocateAttrib(&attributes);
attributes->value.choice = BitmapAttribute_zOrder_chosen;
attributes->value.u.zOrder = GetZOrder();
}
//
// Do the Transparency
//
if(HasTransparencyMaskChanged())
{
AllocateAttrib(&attributes);
attributes->value.choice = BitmapAttribute_transparencyMask_chosen;
attributes->value.u.transparencyMask.bit_mask = 0;
attributes->value.u.transparencyMask.bitMask.choice = uncompressed_chosen;
attributes->value.u.transparencyMask.bitMask.u.uncompressed.length = m_SizeOfTransparencyMask;
attributes->value.u.transparencyMask.bitMask.u.uncompressed.value = m_lpTransparencyMask;
}
//
// End of attributes
//
*pattributes = attributes;
}
void BitmapObj::Draw(HDC hDC, BOOL bForcedDraw, BOOL bPrinting)
{
if(!bPrinting)
{
//
// Don't draw anything if we don't belong in this workspace
//
if(GetWorkspaceHandle() != g_pCurrentWorkspace->GetThisObjectHandle())
{
return;
}
}
RECT clipBox;
RECT rect;
GetRect(&rect);
if(hDC == NULL)
{
hDC = g_pDraw->m_hDCCached;
}
MLZ_EntryOut(ZONE_FUNCTION, "BitmapObj::Draw");
// Only draw anything if the bounding rectangle intersects
// the current clip box.
if (::GetClipBox(hDC, &clipBox) == ERROR)
{
WARNING_OUT(("Failed to get clip box"));
}
else if (!::IntersectRect(&clipBox, &clipBox, &rect))
{
TRACE_MSG(("No clip/bounds intersection"));
return;
}
if(m_ToolType == TOOLTYPE_FILLEDBOX)
{
if(m_fMoreToFollow)
{
return;
}
// Set the stretch mode to be used so that scan lines are deleted
// rather than combined. This will tend to preserve color better.
int iOldStretchMode = ::SetStretchBltMode(hDC, STRETCH_DELETESCANS);
// Draw the bitmap
::StretchDIBits(hDC,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
0,
0,
(UINT) m_lpbiImage->biWidth,
(UINT) m_lpbiImage->biHeight,
(VOID FAR *) DIB_Bits(m_lpbiImage),
(LPBITMAPINFO)m_lpbiImage,
DIB_RGB_COLORS,
SRCCOPY);
// Restore the stretch mode
::SetStretchBltMode(hDC, iOldStretchMode);
}
else
{
// Create the save bitmap if necessary
CreateSaveBitmap();
// Draw the icon
::DrawIcon(hDC, rect.left, rect.top, m_hIcon);
}
}
//
//
// Function: BitmapObj::::FromScreenArea
//
// Purpose: Set the content of the object from an area of the screen
//
//
void BitmapObj::FromScreenArea(LPCRECT lprcScreen)
{
m_lpbiImage = DIB_FromScreenArea(lprcScreen);
if (m_lpbiImage == NULL)
{
::Message(NULL, (UINT)IDS_MSG_CAPTION, (UINT)IDS_CANTGETBMP, (UINT)MB_OK );
}
else
{
m_bitmapSize.x = m_lpbiImage->biWidth;
m_bitmapSize.y = m_lpbiImage->biHeight;
RECT rect;
GetBoundsRect(&rect);
// Calculate the bounding rectangle from the size of the bitmap
rect.right = rect.left + m_lpbiImage->biWidth;
rect.bottom = rect.top + m_lpbiImage->biHeight;
SetRect(&rect);
}
}
UINT GetBitmapDestinationAddress(BitmapDestinationAddress *destinationAddress, PUINT workspaceHandle, PUINT planeID)
{
UINT toolType = TOOLTYPE_FILLEDBOX;
//
// Get the destination address
//
switch(destinationAddress->choice)
{
case(BitmapDestinationAddress_softCopyImagePlane_chosen):
{
*workspaceHandle = (destinationAddress->u.softCopyImagePlane.workspaceHandle);
*planeID = (destinationAddress->u.softCopyImagePlane.plane);
break;
}
case(BitmapDestinationAddress_softCopyAnnotationPlane_chosen):
{
*workspaceHandle = (destinationAddress->u.softCopyAnnotationPlane.workspaceHandle);
*planeID = (destinationAddress->u.softCopyAnnotationPlane.plane);
break;
}
case(softCopyPointerPlane_chosen):
{
*workspaceHandle = (destinationAddress->u.softCopyPointerPlane.workspaceHandle);
*planeID = (0);
toolType = TOOLTYPE_REMOTEPOINTER;
break;
}
// case(BitmapDestinationAddress_nonStandardDestination_chosen):
// {
// break;
// }
default:
ERROR_OUT(("Invalid destinationAddress"));
break;
}
return toolType;
}
//
// UI Edited the Bitmap Object
//
void BitmapObj::OnObjectEdit(void)
{
g_bContentsChanged = TRUE;
SIPDU *sipdu = NULL;
DBG_SAVE_FILE_LINE
sipdu = (SIPDU *) new BYTE[sizeof(SIPDU)];
if(sipdu)
{
sipdu->choice = bitmapEditPDU_chosen;
CreateBitmapEditPDU(&sipdu->u.bitmapEditPDU);
T120Error rc = SendT126PDU(sipdu);
if(rc == T120_NO_ERROR)
{
SIPDUCleanUp(sipdu);
}
}
else
{
TRACE_MSG(("Failed to create sipdu"));
::PostMessage(g_pMain->m_hwnd, WM_USER_DISPLAY_ERROR, WBFE_RC_WINDOWS, 0);
}
}
//
// UI Deleted the Bitmap Object
//
void BitmapObj::OnObjectDelete(void)
{
SIPDU *sipdu = NULL;
DBG_SAVE_FILE_LINE
sipdu = (SIPDU *) new BYTE[sizeof(SIPDU)];
if(sipdu)
{
sipdu->choice = bitmapDeletePDU_chosen;
CreateBitmapDeletePDU(&sipdu->u.bitmapDeletePDU);
T120Error rc = SendT126PDU(sipdu);
if(rc == T120_NO_ERROR)
{
SIPDUCleanUp(sipdu);
}
}
else
{
TRACE_MSG(("Failed to create sipdu"));
::PostMessage(g_pMain->m_hwnd, WM_USER_DISPLAY_ERROR, WBFE_RC_WINDOWS, 0);
}
}
void BitmapObj::GetEncodedCreatePDU(ASN1_BUF *pBuf)
{
pBuf->length = DIB_TotalLength(m_lpbiImage);
pBuf->value = (PBYTE)m_lpbiImage;
}
//
// UI Created a new Bitmap Object
//
void BitmapObj::SendNewObjectToT126Apps(void)
{
SIPDU *sipdu = NULL;
CWBOBLIST BitmapContinueCreatePDUList;
BitmapContinueCreatePDUList.EmptyList();
CreateBitmapCreatePDU(&BitmapContinueCreatePDUList);
T120Error rc = T120_NO_ERROR;
WBPOSITION pos = BitmapContinueCreatePDUList.GetHeadPosition();
while (pos != NULL)
{
sipdu = (SIPDU *) BitmapContinueCreatePDUList.GetNext(pos);
TRACE_DEBUG(("Sending Bitmap >> Bitmap handle = %d", sipdu->u.bitmapCreatePDU.bitmapHandle ));
if(g_bSavingFile && GraphicTool() == TOOLTYPE_REMOTEPOINTER)
{
; // Don't send Remote pointers to disk
}
else
{
if(!m_fMoreToFollow)
{
rc = SendT126PDU(sipdu);
}
}
if(rc == T120_NO_ERROR)
{
SIPDUCleanUp(sipdu);
}
}
BitmapContinueCreatePDUList.EmptyList();
}
//
//
// Function: CreateColoredIcon
//
// Purpose: Create an icon of the correct color for this pointer.
//
//
HICON BitmapObj::CreateColoredIcon(COLORREF color, LPBITMAPINFOHEADER lpbInfo, LPBYTE pMaskBits)
{
HICON hColoredIcon = NULL;
HBRUSH hBrush = NULL;
HBRUSH hOldBrush;
HBITMAP hImage = NULL;
HBITMAP hOldBitmap;
HBITMAP hMask = NULL;
COLOREDICON *pColoredIcon;
ICONINFO ii;
UINT i;
LPSTR pBits;
LPBITMAPINFOHEADER lpbi;
BYTE swapByte;
color = SET_PALETTERGB(color);
MLZ_EntryOut(ZONE_FUNCTION, "RemotePointerObject::CreateColoredIcon");
//
// Create the mask for the icon with the data sent through T126
//
if(pMaskBits && lpbInfo)
{
hMask = CreateBitmap(lpbInfo->biWidth, lpbInfo->biHeight, 1, 1, m_lpTransparencyMask);
}
//
// Create the local mask
//
else
{
// Load the mask bitmap
hMask = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(REMOTEPOINTERANDMASK));
if (!hMask)
{
TRACE_MSG(("Could not load mask bitmap"));
goto CreateIconCleanup;
}
}
//
// Create a bitmap with the data that sent through T126
//
if(lpbInfo)
{
VOID *ppvBits;
hImage = CreateDIBSection(m_hMemDC, (LPBITMAPINFO)lpbInfo, DIB_RGB_COLORS, &ppvBits, NULL, 0);
if(!ppvBits)
{
TRACE_MSG(("CreateColoredIcon failed calling CreateDIBSection error = %d", GetLastError()));
goto CreateIconCleanup;
}
pBits = DIB_Bits(lpbInfo);
::GetDIBits(m_hMemDC, hImage, 0, (WORD) lpbInfo->biHeight, NULL,(LPBITMAPINFO)lpbInfo, DIB_RGB_COLORS);
memcpy(ppvBits, pBits, lpbInfo->biSizeImage);
if(!hMask)
{
hMask = CreateBitmap(lpbInfo->biWidth, lpbInfo->biHeight, 1, 1, NULL);
}
}
//
// Create a local bitmap
//
else
{
// Load the image bitmap
hImage = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(REMOTEPOINTERXORDATA));
if (!hImage)
{
TRACE_MSG(("Could not load pointer bitmap"));
goto CreateIconCleanup;
}
hBrush = ::CreateSolidBrush(color);
if (!hBrush)
{
TRACE_MSG(("Couldn't create color brush"));
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);
if(!hOldBitmap)
{
ERROR_OUT(("DeleteSavedBitmap - Could not select old bitmap"));
}
// Fill the image bitmap with color
::FloodFill(m_hMemDC, ::GetSystemMetrics(SM_CXICON) / 2, ::GetSystemMetrics(SM_CYICON) / 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);
//
// Create the internal format if we were created locally
//
if(m_lpbiImage == NULL)
{
m_lpbiImage = DIB_FromBitmap(hImage, NULL, FALSE, FALSE, TRUE);
}
if(m_lpTransparencyMask == NULL)
{
ChangedTransparencyMask();
lpbi = DIB_FromBitmap(hMask,NULL,FALSE, TRUE);
pBits = DIB_Bits(lpbi);
m_SizeOfTransparencyMask = lpbi->biSizeImage;
DBG_SAVE_FILE_LINE
m_lpTransparencyMask = new BYTE[m_SizeOfTransparencyMask];
memcpy(m_lpTransparencyMask, pBits, m_SizeOfTransparencyMask );
::GlobalFree(lpbi);
}
if (m_lpbiImage == NULL)
{
::Message(NULL, (UINT)IDS_MSG_CAPTION, (UINT)IDS_CANTGETBMP, (UINT)MB_OK );
}
else
{
m_bitmapSize.x = m_lpbiImage->biWidth;
m_bitmapSize.y = m_lpbiImage->biHeight;
RECT rect;
GetBoundsRect(&rect);
// Calculate the bounding rectangle from the size of the bitmap
rect.right = rect.left + m_lpbiImage->biWidth;
rect.bottom = rect.top + m_lpbiImage->biHeight;
SetRect(&rect);
SetAnchorPoint(rect.left, rect.top);
}
CreateIconCleanup:
// Free the image bitmap
if (hImage != NULL)
{
::DeleteBitmap(hImage);
}
// Free the mask bitmap
if (hMask != NULL)
{
::DeleteBitmap(hMask);
}
if (hBrush != NULL)
{
::DeleteBrush(hBrush);
}
m_hIcon = hColoredIcon;
return(hColoredIcon);
}
//
//
// Function: BitmapObj::CreateSaveBitmap()
//
// Purpose: Create a bitmap for saving the bits under the pointer.
//
//
void BitmapObj::CreateSaveBitmap()
{
MLZ_EntryOut(ZONE_FUNCTION, "BitmapObj::CreateSaveBitmap");
// If we already have a save bitmap, exit immediately
if (m_hSaveBitmap != NULL)
{
TRACE_MSG(("Already have save bitmap"));
return;
}
// 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.
RECT rect;
RECT rcVis;
POINT point;
POINT delta;
HDC hDC = NULL;
g_pDraw->GetVisibleRect(&rcVis);
GetRect(&rect);
delta.x = rect.right - rect.left;
delta.y = rect.bottom - rect.top;
point.x = rect.left - rcVis.left;
point.y = rect.top - rcVis.top;
ClientToScreen (g_pDraw->m_hwnd, &point);
rect.left = point.x;
rect.top = point.y;
rect.right = rect.left + delta.x;
rect.bottom = rect.top + delta.y;
//
// Create the bitmap
//
m_hSaveBitmap = FromScreenAreaBmp(&rect);
}
//
//
// Function: BitmapObj::Undraw()
//
// Purpose: Draw the marker object
//
//
void BitmapObj::UnDraw(void)
{
if(GraphicTool() == TOOLTYPE_REMOTEPOINTER)
{
// Create the save bitmap if necessary
CreateSaveBitmap();
//
// Select the saved area
//
if(m_hSaveBitmap)
{
m_hOldBitmap = SelectBitmap(m_hMemDC, m_hSaveBitmap);
if(!m_hOldBitmap)
{
ERROR_OUT(("DeleteSavedBitmap - Could not select old bitmap"));
}
}
// Copy the saved bits onto the screen
UndrawScreen();
}
else
{
RECT rect;
GetBoundsRect(&rect);
g_pDraw->InvalidateSurfaceRect(&rect,TRUE);
}
}
//
//
// Function: BitmapObj::UndrawScreen()
//
// Purpose: Copy the saved bits under the pointer to the screen.
//
//
BOOL BitmapObj::UndrawScreen()
{
BOOL bResult = FALSE;
RECT rcUpdate;
MLZ_EntryOut(ZONE_FUNCTION, "DCWbGraphicPointer::UndrawScreen");
GetRect(&rcUpdate);
// We are undrawing - copy the saved bits to the DC passed
bResult = ::BitBlt(g_pDraw->m_hDCCached, 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"));
}
else
{
DeleteSavedBitmap();
}
return(bResult);
}
void BitmapObj::DeleteSavedBitmap(void)
{
// Restore the original bitmap to the memory DC
if (m_hOldBitmap != NULL)
{
if(!SelectBitmap(m_hMemDC, m_hOldBitmap))
{
ERROR_OUT(("DeleteSavedBitmap - Could not select old bitmap"));
}
// if(!DeleteBitmap(m_hOldBitmap))
// {
// ERROR_OUT(("DeleteSavedBitmap - Could not delete old bitmap"));
// }
m_hOldBitmap = NULL;
}
if (m_hSaveBitmap != NULL)
{
if(!DeleteBitmap(m_hSaveBitmap))
{
ERROR_OUT(("DeleteSavedBitmap - Could not delete bitmap"));
}
m_hSaveBitmap = NULL;
}
}