mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
950 lines
31 KiB
950 lines
31 KiB
/****************************************************************************
|
|
ASSOC.C
|
|
|
|
$Log: S:\products\wangview\oiwh\display\assoc.c_v $
|
|
*
|
|
* Rev 1.24 18 Apr 1996 11:21:22 BEG06016
|
|
* Added CheckError2 for error handling.
|
|
*
|
|
* Rev 1.23 02 Jan 1996 09:56:36 BLJ
|
|
* Changed alot of UINTs to ints.
|
|
* Changed IMG structure to include the image data.
|
|
* Changed lp prefix to p.
|
|
*
|
|
* Rev 1.22 22 Dec 1995 11:13:08 BLJ
|
|
* Added a parameter for zero init'ing to some memory manager calls.
|
|
*
|
|
* Rev 1.21 06 Dec 1995 11:01:02 BLJ
|
|
* Fixed 5521 Indefinite repaint.
|
|
*
|
|
* Rev 1.20 02 Nov 1995 10:14:22 BLJ
|
|
* Adding Undo functionality.
|
|
*
|
|
* Rev 1.19 12 Oct 1995 13:01:40 BLJ
|
|
* Fixed deleting of brushes.
|
|
*
|
|
* Rev 1.18 07 Sep 1995 13:22:18 BLJ
|
|
* Modified scaling to allow for proper rotation of fax images.
|
|
*
|
|
* Rev 1.17 05 Sep 1995 09:30:04 BLJ
|
|
* Took out the call to IsRegWnd.
|
|
*
|
|
* Rev 1.16 02 Aug 1995 12:34:58 BLJ
|
|
* An attempt at returning an error if the associated window is
|
|
* already displaying an image.
|
|
*
|
|
* Rev 1.15 12 Jul 1995 14:41:04 BLJ
|
|
* Removed obsolete code.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "privdisp.h"
|
|
|
|
//
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: IMGNavIsHere
|
|
|
|
PURPOSE: This function informs seqfile that the navigation DLL is
|
|
loaded and running. Therefore, seqfile is to start calling
|
|
navigation during repaint.
|
|
This is a navigation specific api that is called by the
|
|
navigation DLL only. It is not public.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI IMGNavIsHere(void){
|
|
|
|
int nStatus = 0;
|
|
|
|
Start();
|
|
|
|
bCallNavigation = TRUE;
|
|
|
|
End();
|
|
return(nStatus);
|
|
}
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: IMGCalcViewRect
|
|
|
|
PURPOSE: This function calculates the scale and offset needed to
|
|
display a given rectangle of image data, and the resulting
|
|
view rect formed by it.
|
|
This is a navigation specific api that is called by the
|
|
navigation DLL only. It is not public.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI IMGCalcViewRect(HWND hWndNavigation, HWND hWndPrincipal,
|
|
UINT uRelativeScaleFactor, LPLRECT plRect, PUINT puScaleFactor,
|
|
long *plHOffset, long *plVOffset, int nFlags){
|
|
|
|
int nStatus;
|
|
|
|
PWINDOW pWindowNav;
|
|
PANO_IMAGE pAnoImageNav;
|
|
PIMAGE pImageNav;
|
|
|
|
PWINDOW pWindowPrin;
|
|
PANO_IMAGE pAnoImagePrin;
|
|
PIMAGE pImagePrin;
|
|
|
|
int nHeight;
|
|
int nWidth;
|
|
RECT ClientRect;
|
|
LRECT lScaledImageRect;
|
|
int nWndWidth;
|
|
int nWndHeight;
|
|
LRECT lrCurrentViewRect;
|
|
|
|
|
|
CheckError2(Init(hWndPrincipal, &pWindowPrin, &pAnoImagePrin, FALSE, TRUE))
|
|
pImagePrin = pAnoImagePrin->pBaseImage;
|
|
|
|
CheckError2(Init(hWndNavigation, &pWindowNav, &pAnoImageNav, FALSE, TRUE))
|
|
pImageNav = pAnoImageNav->pBaseImage;
|
|
|
|
if (!plRect || !puScaleFactor || !plHOffset || !plVOffset){
|
|
nStatus = Error(DISPLAY_NULLPOINTERINVALID);
|
|
goto Exit;
|
|
}
|
|
|
|
// Translate rectangle that was passed in to fullsize navigation coords.
|
|
if (nFlags & PARM_SCALED){
|
|
if (plRect->left < 0){
|
|
plRect->right -= plRect->left;
|
|
plRect->left = 0;
|
|
}
|
|
if (plRect->top < 0){
|
|
plRect->bottom -= plRect->top;
|
|
plRect->top = 0;
|
|
}
|
|
CheckError2(ConvertRect(pWindowNav, plRect, CONV_SCALED_TO_FULLSIZE))
|
|
}else if (nFlags & PARM_WINDOW){
|
|
CheckError2(ConvertRect(pWindowNav, plRect, CONV_WINDOW_TO_SCALED))
|
|
if (plRect->left < 0){
|
|
plRect->right -= plRect->left;
|
|
plRect->left = 0;
|
|
}
|
|
if (plRect->top < 0){
|
|
plRect->bottom -= plRect->top;
|
|
plRect->top = 0;
|
|
}
|
|
CheckError2(ConvertRect(pWindowNav, plRect, CONV_SCALED_TO_FULLSIZE))
|
|
}
|
|
|
|
if (plRect->left < 0){
|
|
plRect->right -= plRect->left;
|
|
plRect->left = 0;
|
|
}
|
|
if (plRect->top < 0){
|
|
plRect->bottom -= plRect->top;
|
|
plRect->top = 0;
|
|
}
|
|
|
|
if (plRect->right < 0 || plRect->bottom < 0
|
|
|| plRect->right - plRect->left <= 0
|
|
|| plRect->bottom - plRect->top <= 0){
|
|
nStatus = Error(DISPLAY_INVALIDRECT);
|
|
goto Exit;
|
|
}
|
|
|
|
// Translate rectangle that was passed in to fullsize principal coords.
|
|
|
|
plRect->left = ((plRect->left * 1000) / uRelativeScaleFactor);
|
|
plRect->top = ((plRect->top * 1000) / uRelativeScaleFactor);
|
|
plRect->right = ((plRect->right * 1000) / uRelativeScaleFactor);
|
|
plRect->bottom = ((plRect->bottom * 1000) / uRelativeScaleFactor);
|
|
|
|
|
|
// Adjust scroll for incoming rect.
|
|
|
|
if ( plRect->right >= pImagePrin->nWidth){
|
|
plRect->left = lmax(0, plRect->left - (plRect->right - (pImagePrin->nWidth - 1)));
|
|
plRect->right = pImagePrin->nWidth - 1;
|
|
}
|
|
if ( plRect->bottom >= pImagePrin->nHeight){
|
|
plRect->top = lmax(0, plRect->top - (plRect->bottom - (pImagePrin->nHeight - 1)));
|
|
plRect->bottom = pImagePrin->nHeight - 1;
|
|
}
|
|
|
|
// Calculate new scale.
|
|
|
|
CheckError2(GetViewRect(hWndPrincipal, pWindowNav, pImageNav, pWindowPrin, pImagePrin,
|
|
uRelativeScaleFactor, &lrCurrentViewRect, pWindowPrin->nScale,
|
|
pWindowPrin->lHOffset, pWindowPrin->lVOffset, PARM_FULLSIZE))
|
|
if ((lrCurrentViewRect.right - lrCurrentViewRect.left) == (plRect->right - plRect->left)
|
|
&& (lrCurrentViewRect.bottom - lrCurrentViewRect.top) == (plRect->bottom - plRect->top)){
|
|
*puScaleFactor = pWindowPrin->nScale;
|
|
}else{
|
|
nWidth = (plRect->right - plRect->left);
|
|
nHeight = (plRect->bottom - plRect->top);
|
|
|
|
GetEntireClientRect(hWndPrincipal, pWindowPrin, &ClientRect);
|
|
if (nHeight < (pImagePrin->nHeight - 1) && pWindowPrin->bScrollBarsEnabled){
|
|
ClientRect.bottom -= (GetSystemMetrics(SM_CYHSCROLL) - 1);
|
|
}
|
|
if (nWidth < (pImagePrin->nWidth - 1) && pWindowPrin->bScrollBarsEnabled){
|
|
ClientRect.right -= (GetSystemMetrics(SM_CXVSCROLL) - 1);
|
|
}
|
|
|
|
nWndWidth = ClientRect.right - ClientRect.left;
|
|
nWndHeight = ClientRect.bottom - ClientRect.top;
|
|
|
|
if (nWidth && nWndWidth && nHeight && nWndHeight){
|
|
*puScaleFactor = max(20, min(65000,
|
|
min(((SCALE_DENOMINATOR * nWndWidth) / nWidth),
|
|
((SCALE_DENOMINATOR * nWndHeight) / ((( nHeight)
|
|
* pImagePrin->nHRes) / pImagePrin->nVRes)))));
|
|
}else{
|
|
*puScaleFactor = SCALE_DENOMINATOR;
|
|
}
|
|
}
|
|
|
|
// Calculate new scroll offsets and adjust them if needed.
|
|
ConvertRect2(plRect, CONV_FULLSIZE_TO_SCALED,
|
|
*puScaleFactor, ((*puScaleFactor * pImagePrin->nHRes) / pImagePrin->nVRes),
|
|
0, 0);
|
|
|
|
lScaledImageRect.left = 0;
|
|
lScaledImageRect.top = 0;
|
|
lScaledImageRect.right = pImagePrin->nWidth - 1;
|
|
lScaledImageRect.bottom = pImagePrin->nHeight - 1;
|
|
ConvertRect2(&lScaledImageRect, CONV_FULLSIZE_TO_SCALED,
|
|
*puScaleFactor, ((*puScaleFactor * pImagePrin->nHRes) / pImagePrin->nVRes),
|
|
0, 0);
|
|
|
|
if (plRect->right > lScaledImageRect.right){
|
|
plRect->left -= min(plRect->left,
|
|
lScaledImageRect.right - plRect->right);
|
|
plRect->right = plRect->left + ClientRect.right;
|
|
}
|
|
if (plRect->bottom > lScaledImageRect.bottom){
|
|
plRect->top -= min(plRect->top,
|
|
lScaledImageRect.bottom - plRect->bottom);
|
|
plRect->bottom = plRect->top + ClientRect.bottom;
|
|
}
|
|
*plHOffset = plRect->left;
|
|
*plVOffset = plRect->top;
|
|
|
|
|
|
// Calculate resulting view rect.
|
|
CheckError2(GetViewRect(hWndPrincipal, pWindowNav, pImageNav, pWindowPrin, pImagePrin,
|
|
uRelativeScaleFactor, plRect, *puScaleFactor, *plHOffset, *plVOffset, nFlags))
|
|
|
|
Exit:
|
|
DeInit(FALSE, TRUE);
|
|
DeInit(FALSE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: IMGGetViewRect
|
|
|
|
PURPOSE: This function calculates the scale and offset needed to
|
|
display a given rectangle of image data, and the resulting
|
|
view rect formed by it.
|
|
This is a navigation specific api that is called by the
|
|
navigation DLL only. It is not public.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI IMGGetViewRect(HWND hWndNavigation, HWND hWndPrincipal,
|
|
UINT uRelativeScaleFactor, LPLRECT plRect, int nFlags){
|
|
|
|
int nStatus;
|
|
|
|
PWINDOW pWindowNav;
|
|
PANO_IMAGE pAnoImageNav;
|
|
PIMAGE pImageNav;
|
|
|
|
PWINDOW pWindowPrin;
|
|
PANO_IMAGE pAnoImagePrin;
|
|
PIMAGE pImagePrin;
|
|
|
|
|
|
CheckError2(Init(hWndPrincipal, &pWindowPrin, &pAnoImagePrin, FALSE, TRUE))
|
|
pImagePrin = pAnoImagePrin->pBaseImage;
|
|
|
|
CheckError2(Init(hWndNavigation, &pWindowNav, &pAnoImageNav, FALSE, TRUE))
|
|
pImageNav = pAnoImageNav->pBaseImage;
|
|
|
|
CheckError2(GetViewRect(hWndPrincipal, pWindowNav, pImageNav, pWindowPrin, pImagePrin,
|
|
uRelativeScaleFactor, plRect, pWindowPrin->nScale,
|
|
pWindowPrin->lHOffset, pWindowPrin->lVOffset, nFlags))
|
|
|
|
Exit:
|
|
DeInit(FALSE, TRUE);
|
|
DeInit(FALSE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: GetViewRect
|
|
|
|
PURPOSE: This function calculates the scale and offset needed to
|
|
display a given rectangle of image data, and the resulting
|
|
view rect formed by it.
|
|
This is a navigation specific api that is called by the
|
|
navigation DLL only. It is not public.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI GetViewRect(HWND hWndPrincipal,
|
|
PWINDOW pWindowNav, PIMAGE pImageNav,
|
|
PWINDOW pWindowPrin, PIMAGE pImagePrin,
|
|
int uRelativeScaleFactor, LPLRECT plRect,
|
|
int nScale, long lHOffset, long lVOffset, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
RECT ClientRect;
|
|
|
|
|
|
if (!plRect){
|
|
nStatus = Error(DISPLAY_NULLPOINTERINVALID);
|
|
goto Exit;
|
|
}
|
|
|
|
GetEntireClientRect(hWndPrincipal, pWindowPrin, &ClientRect);
|
|
if (pImagePrin->nHeight > ClientRect.bottom
|
|
&& pWindowPrin->bScrollBarsEnabled){
|
|
ClientRect.bottom -= (GetSystemMetrics(SM_CYHSCROLL) - 1);
|
|
}
|
|
if (pImagePrin->nWidth > ClientRect.right
|
|
&& pWindowPrin->bScrollBarsEnabled){
|
|
ClientRect.right -= (GetSystemMetrics(SM_CXVSCROLL) - 1);
|
|
}
|
|
|
|
CopyRect(*plRect, ClientRect);
|
|
ConvertRect2(plRect, CONV_WINDOW_TO_FULLSIZE,
|
|
nScale, ((nScale * pImagePrin->nHRes) / pImagePrin->nVRes),
|
|
lHOffset, lVOffset);
|
|
|
|
// Translate rectangle to fullsize navigation coords.
|
|
plRect->left = ((plRect->left * uRelativeScaleFactor) / 1000);
|
|
plRect->top = ((plRect->top * uRelativeScaleFactor) / 1000);
|
|
plRect->right = ((plRect->right * uRelativeScaleFactor) / 1000);
|
|
plRect->bottom = ((plRect->bottom * uRelativeScaleFactor) / 1000);
|
|
|
|
// Convert rect to appropriate coords
|
|
if (nFlags & PARM_SCALED){
|
|
ConvertRect(pWindowNav, plRect, CONV_FULLSIZE_TO_SCALED);
|
|
}else if (nFlags & PARM_WINDOW){
|
|
ConvertRect(pWindowNav, plRect, CONV_FULLSIZE_TO_WINDOW);
|
|
}
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: IMGAssociateWindow
|
|
|
|
PURPOSE: This function associates 2 windows.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI IMGAssociateWindow(HWND hWnd, HWND hWndSource, int nFlags){
|
|
|
|
int nStatus;
|
|
PWINDOW pWindow;
|
|
PWINDOW pWindowSource;
|
|
|
|
int nLoop;
|
|
int nCount;
|
|
HWND hAssociatedWnd[MAX_ASSOCIATED_WINDOWS];
|
|
|
|
|
|
CheckError2(Init(hWnd, &pWindow, 0, FALSE, TRUE))
|
|
CheckError2(Init(hWndSource, &pWindowSource, 0, FALSE, TRUE))
|
|
|
|
if (pWindow->hImageWnd != hWnd || pWindow->pDisplay->pAnoImage){
|
|
nStatus = Error(DISPLAY_CANT_ASSOCIATE_WINDOW);
|
|
goto Exit;
|
|
}
|
|
|
|
for (nLoop = 0; nLoop < MAX_ASSOCIATED_PER_WINDOW; nLoop++){
|
|
if (!pWindowSource->hDisplayWnd[nLoop]){
|
|
break;
|
|
}
|
|
}
|
|
if (nLoop == MAX_ASSOCIATED_PER_WINDOW){
|
|
nStatus = Error(DISPLAY_CANT_ASSOCIATE_WINDOW);
|
|
goto Exit;
|
|
}
|
|
|
|
pWindow->hImageWnd = hWndSource;
|
|
pWindowSource->hDisplayWnd[nLoop] = hWnd;
|
|
|
|
// Check for infinite loop.
|
|
nCount = 0;
|
|
if (nStatus = GetAssociatedWndList(0, pWindow, &hAssociatedWnd[0],
|
|
&nCount, MAX_ASSOCIATED_WINDOWS)){
|
|
pWindow->hImageWnd = hWnd;
|
|
pWindowSource->hDisplayWnd[nLoop] = 0;
|
|
goto Exit;
|
|
}
|
|
CheckError2(SetAllPImages(hWnd, pWindow))
|
|
CheckError2(IMGRepaintDisplay(hWnd, (PRECT) -1))
|
|
|
|
|
|
Exit:
|
|
DeInit(FALSE, TRUE);
|
|
DeInit(FALSE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/*****************************************************************************
|
|
|
|
FUNCTION: IMGUnassociateWindow
|
|
|
|
PURPOSE: This function nnassociates 2 or more windows.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI IMGUnassociateWindow(HWND hWnd, int nFlags){
|
|
|
|
int nStatus;
|
|
PWINDOW pWindow;
|
|
|
|
HWND hWndSource;
|
|
PWINDOW pWindow2;
|
|
PANO_IMAGE pAnoImage;
|
|
int nCount;
|
|
HWND hAssociatedWnd[MAX_ASSOCIATED_WINDOWS];
|
|
int nLoop;
|
|
|
|
|
|
CheckError2(Init(hWnd, &pWindow, 0, FALSE, TRUE))
|
|
hWndSource = pWindow->hImageWnd;
|
|
nCount = 0;
|
|
CheckError2(GetAssociatedWndList(0, pWindow, &hAssociatedWnd[0],
|
|
&nCount, MAX_ASSOCIATED_WINDOWS))
|
|
if (nFlags & OI_UNASSOC_ALL){
|
|
for (nLoop = 0; nLoop < nCount; nLoop++){
|
|
if (!hAssociatedWnd[nLoop]){
|
|
break;
|
|
}
|
|
pWindow2 = 0;
|
|
if (nStatus = GetPWindow(hAssociatedWnd[nLoop], &pWindow2)){
|
|
continue;
|
|
}
|
|
pWindow2->hImageWnd = hAssociatedWnd[nLoop];
|
|
memset(pWindow2->hDisplayWnd, 0, MAX_ASSOCIATED_WINDOWS * sizeof(HWND));
|
|
}
|
|
}else{
|
|
if(nFlags & OI_UNASSOC_AS_SOURCE){
|
|
for (nLoop = 0; nLoop < MAX_ASSOCIATED_PER_WINDOW; nLoop++){
|
|
if (pWindow->hDisplayWnd[nLoop]){
|
|
pWindow2 = 0;
|
|
if (nStatus = GetPWindow(hAssociatedWnd[nLoop],&pWindow2)){
|
|
continue;
|
|
}
|
|
pWindow2->hImageWnd = hAssociatedWnd[nLoop];
|
|
}
|
|
}
|
|
}
|
|
if((nFlags & OI_UNASSOC_AS_ASSOC) || !(nFlags & OI_UNASSOC_AS_SOURCE)){
|
|
pWindow->hImageWnd = hWnd;
|
|
pWindow2 = 0;
|
|
CheckError2(GetPWindow(hWndSource, &pWindow2))
|
|
for (nLoop = 0; nLoop < MAX_ASSOCIATED_PER_WINDOW; nLoop++){
|
|
if (pWindow2->hDisplayWnd[nLoop] == hWnd){
|
|
if (nLoop < MAX_ASSOCIATED_PER_WINDOW - 1){
|
|
for (;nLoop < MAX_ASSOCIATED_PER_WINDOW - 1; nLoop++){
|
|
pWindow2->hDisplayWnd[nLoop] = pWindow2->hDisplayWnd[nLoop + 1];
|
|
}
|
|
}
|
|
pWindow2->hDisplayWnd[MAX_ASSOCIATED_PER_WINDOW] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CheckError2(SetAllPImages(hWnd, pWindow))
|
|
|
|
if (nCount > 1){
|
|
if((nFlags & OI_UNASSOC_ALL) || (nFlags & OI_UNASSOC_AS_ASSOC)
|
|
|| !(nFlags & OI_UNASSOC_AS_SOURCE)){
|
|
pAnoImage = pWindow2->pDisplay->pAnoImage;
|
|
if (pAnoImage){
|
|
for (nLoop = 0; nLoop < nCount; nLoop++){
|
|
pWindow->pDisplay->pAnoImage = pWindow2->pDisplay->pAnoImage;
|
|
// if the window handle is not that of the current window but of
|
|
// an associated window, save it in the temporary assoc list
|
|
if (hAssociatedWnd[nLoop] != hWndSource){
|
|
CheckError2(ReAllocateMemory(sizeof(HWND) * (pAnoImage->nhWnd + 1),
|
|
(PPSTR) &pAnoImage->phWnd, ZERO_INIT))
|
|
pAnoImage->phWnd[pAnoImage->nhWnd++] = hAssociatedWnd[nLoop];
|
|
pAnoImage->nLockCount++; //this is because the lock count
|
|
// is 1 even if the same image is displayed in 2 assoc
|
|
// windows. Now that the association is broken, the
|
|
// lock count must reflect it
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if((nFlags & OI_UNASSOC_ALL) || (nFlags & OI_UNASSOC_AS_SOURCE)){
|
|
for (nLoop = 0; nLoop < nCount; nLoop++){
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
if (!pAnoImage){
|
|
break;
|
|
}
|
|
// no need to do a display file in the source window again
|
|
if (hWndSource != hAssociatedWnd[nLoop]){
|
|
if (nStatus = GetPWindow(hAssociatedWnd[nLoop], &pWindow2)){
|
|
continue;
|
|
}
|
|
pWindow2->pDisplay->pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
}
|
|
if (hWnd != hWndSource){
|
|
CheckError2(ReAllocateMemory(sizeof(HWND) * (pAnoImage->nhWnd + 1),
|
|
(PPSTR) &pAnoImage->phWnd, ZERO_INIT))
|
|
pAnoImage->phWnd[pAnoImage->nhWnd++] = hAssociatedWnd[nLoop];
|
|
pAnoImage->nLockCount++; //this is because the lock count
|
|
// is 1 even if the same image is displayed in 2 assoc
|
|
// windows. Now that the association is broken, the
|
|
// lock count must reflect it
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (nLoop = 0; nLoop < nCount; nLoop++){
|
|
IMGRepaintDisplay(hAssociatedWnd[nLoop], (PRECT) -1);
|
|
}
|
|
|
|
|
|
Exit:
|
|
DeInit(FALSE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: Init
|
|
|
|
PURPOSE: Initializes pWindow, and pAnoImage to 0.
|
|
Then gets the image information based on the
|
|
window handle passed in, sets the cursor busy (if desired),
|
|
and returns nStatus accordingly.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI Init(HWND hWnd, PWINDOW *ppWindow,
|
|
PANO_IMAGE *ppAnoImage, BOOL bSetBusy, BOOL bPreventMultiprocessing){
|
|
|
|
int nStatus = 0;
|
|
|
|
PWINDOW pWindow = 0;
|
|
PANO_IMAGE pAnoImage = 0;
|
|
|
|
|
|
Start();
|
|
|
|
CheckError2(IntSeqfileInit())
|
|
|
|
if (bSetBusy){
|
|
BusyOn();
|
|
}
|
|
|
|
// Prevent Multiprocessing in this code.
|
|
if (bPreventMultiprocessing){
|
|
CheckError2(LockMutex())
|
|
}
|
|
|
|
CheckError2(GetPWindow(hWnd, &pWindow))
|
|
|
|
if (ppAnoImage && !pWindow->pDisplay->pAnoImage){
|
|
nStatus = Error2(DISPLAY_IHANDLEINVALID);
|
|
goto Exit;
|
|
}
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
|
|
Exit:
|
|
if (ppWindow){
|
|
*ppWindow = pWindow;
|
|
}
|
|
if (ppAnoImage){
|
|
*ppAnoImage = pAnoImage;
|
|
}
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: GetPWindow
|
|
|
|
PURPOSE: Gets the Window information based on the information passed in.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI GetPWindow(HWND hWnd, PWINDOW *ppWindow){
|
|
|
|
int nStatus = 0;
|
|
PWINDOW pWindow = 0;
|
|
|
|
long OIWinClass;
|
|
int nWindowIndex;
|
|
BOOL bAllocatingMemory = FALSE;
|
|
//DWORD dwProcessId;
|
|
|
|
|
|
if (!hWnd){
|
|
nStatus = Error(DISPLAY_WHANDLEINVALID);
|
|
goto Exit;
|
|
}
|
|
|
|
// This is taken out with Rita's permission.
|
|
// if (nStatus = IMGIsRegWnd(hWnd)){
|
|
// Error2(nStatus);
|
|
// goto Exit;
|
|
// }
|
|
|
|
// dwProcessId = GetCurrentProcessId();
|
|
|
|
for (nWindowIndex = 0; nWindowIndex < MAX_WINDOWS; nWindowIndex++){
|
|
if (pSubSegMemory->WindowTable[nWindowIndex].hWnd == hWnd){
|
|
// && pSubSegMemory->WindowTable[nWindowIndex].dwProcessId == dwProcessId){
|
|
pWindow = pSubSegMemory->WindowTable[nWindowIndex].pWindow;
|
|
break;
|
|
}
|
|
if (!pSubSegMemory->WindowTable[nWindowIndex].hWnd){
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!pWindow){
|
|
bAllocatingMemory = TRUE;
|
|
CheckError2(AllocateMemory(sizeof(WINDOW), (PPSTR) &pWindow, ZERO_INIT))
|
|
CheckError2(AllocateMemory(sizeof(MARK), (PPSTR) &pWindow->pUserMark, ZERO_INIT))
|
|
CheckError2(AllocateMemory(sizeof(DISPLAY), (PPSTR) &pWindow->pDisplay, ZERO_INIT))
|
|
|
|
pSubSegMemory->WindowTable[nWindowIndex].hWnd = hWnd;
|
|
// pSubSegMemory->WindowTable[nWindowIndex].dwProcessId = dwProcessId;
|
|
pSubSegMemory->WindowTable[nWindowIndex].pWindow = pWindow;
|
|
|
|
pWindow->hImageWnd = hWnd;
|
|
pWindow->WinClass = OIWinClass = GetClassLong(hWnd, GCL_STYLE);
|
|
OIWinClass &= (~(CS_HREDRAW | CS_VREDRAW));
|
|
SetClassLong(hWnd, GCL_STYLE, OIWinClass);
|
|
CheckError2(IMGGetParmsCgbw(hWnd, PARM_SCALE, &pWindow->nWndDefScale, PARM_SYSTEM_DEFAULT))
|
|
pWindow->nScale = SCALE_DENOMINATOR;
|
|
memset(&pWindow->nWndDefScaleAlgorithm, 0, sizeof(IMG_TYPE_UINT));
|
|
|
|
IMGGetParmsCgbw(hWnd, PARM_MAX_UNDO, &pWindow->nWndDefMaxULUndos, PARM_SYSTEM_DEFAULT);
|
|
|
|
CheckError2(ResetDisplayParms(hWnd, pWindow))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (ppWindow){
|
|
*ppWindow = pWindow;
|
|
}
|
|
if (nStatus){
|
|
if (bAllocatingMemory && pWindow){
|
|
if (pWindow->pUserMark){
|
|
FreeMemory((PPSTR) &pWindow->pUserMark);
|
|
}
|
|
if (pWindow->pDisplay){
|
|
FreeMemory((PPSTR) &pWindow->pDisplay);
|
|
}
|
|
FreeMemory((PPSTR) &pWindow);
|
|
}
|
|
}
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DeInit
|
|
|
|
PURPOSE: Unlocks the display and image parameters, and reset the
|
|
cursor.
|
|
|
|
*****************************************************************************/
|
|
|
|
void WINAPI DeInit(BOOL bClearBusy, BOOL bPreventMultiprocessing){
|
|
|
|
if (bClearBusy){
|
|
BusyOff();
|
|
}
|
|
|
|
// Allow Multiprocessing again.
|
|
if (bPreventMultiprocessing){
|
|
UnlockMutex();
|
|
}
|
|
|
|
End();
|
|
return;
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: InvalidateAllDisplayRects
|
|
|
|
PURPOSE: Invalidates all or part of the display rect for all windows
|
|
displaying this image. If plRect = NULL, then it will
|
|
invalidate the entire display rect, else it will invalidate
|
|
the part specified in plRect.
|
|
|
|
INPUTS: pWindow - A pointer to the display buffer of any window
|
|
that is displaying this image.
|
|
plRect - A pointer to the rectangle the you wish to have
|
|
invalidated. It is specified in fullsize pixels.
|
|
NULL pointer = all.
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI InvalidateAllDisplayRects(PWINDOW pWindow, PIMAGE pImage,
|
|
LPLRECT plrRect, BOOL bInvalidateDisplayBuffer){
|
|
|
|
int nStatus = 0;
|
|
|
|
PWINDOW pWindow2;
|
|
PDISPLAY pDisplay2;
|
|
|
|
int nLoop;
|
|
LRECT lrFullsize;
|
|
LRECT lrScaled;
|
|
BOOL bInvalidateAll;
|
|
int nCount;
|
|
HWND hAssociatedWnd[MAX_ASSOCIATED_WINDOWS];
|
|
|
|
|
|
nCount = 0;
|
|
CheckError2(GetAssociatedWndListAll(0, pWindow, &hAssociatedWnd[0],
|
|
&nCount, MAX_ASSOCIATED_WINDOWS))
|
|
|
|
if (plrRect){
|
|
bInvalidateAll = FALSE;
|
|
lrFullsize = *plrRect;
|
|
}else{
|
|
bInvalidateAll = TRUE;
|
|
}
|
|
|
|
for (nLoop = 0; nLoop < nCount; nLoop++){
|
|
if (!hAssociatedWnd[nLoop]){
|
|
goto Exit;
|
|
}
|
|
CheckError2(GetPWindow(hAssociatedWnd[nLoop], &pWindow2))
|
|
pWindow2->bRepaintClientRect = TRUE;
|
|
if (bInvalidateDisplayBuffer){
|
|
pDisplay2 = pWindow2->pDisplay;
|
|
|
|
if (pDisplay2->pDisplay){
|
|
if (bInvalidateAll){
|
|
FreeImgBuf(&pDisplay2->pDisplay);
|
|
pWindow2->bRepaintClientRect = TRUE;
|
|
SetLRect(pDisplay2->lrScDisplayRect, 0, 0, 0, 0);
|
|
SetLRect(pWindow2->lrInvalidDisplayRect, 0, 0, 0, 0);
|
|
}else{
|
|
CopyRect(lrScaled, lrFullsize);
|
|
CheckError2(ConvertRect(pWindow2, &lrScaled, CONV_FULLSIZE_TO_SCALED))
|
|
if ((lrScaled.left < pDisplay2->lrScDisplayRect.right)
|
|
&& (lrScaled.right > pDisplay2->lrScDisplayRect.left)
|
|
&& (lrScaled.top < pDisplay2->lrScDisplayRect.bottom)
|
|
&& (lrScaled.bottom > pDisplay2->lrScDisplayRect.top)){
|
|
if (((pWindow2->lrInvalidDisplayRect.right -
|
|
pWindow2->lrInvalidDisplayRect.left) == 0
|
|
|| (pWindow2->lrInvalidDisplayRect.bottom -
|
|
pWindow2->lrInvalidDisplayRect.top) == 0)){
|
|
pWindow2->lrInvalidDisplayRect = lrScaled;
|
|
}else{
|
|
pWindow2->lrInvalidDisplayRect.left =
|
|
lmax(pDisplay2->lrScDisplayRect.left,
|
|
min(pWindow2->lrInvalidDisplayRect.left,
|
|
lrScaled.left));
|
|
pWindow2->lrInvalidDisplayRect.right =
|
|
min(pDisplay2->lrScDisplayRect.right,
|
|
lmax(pWindow2->lrInvalidDisplayRect.right,
|
|
lrScaled.right));
|
|
pWindow2->lrInvalidDisplayRect.top =
|
|
lmax(pDisplay2->lrScDisplayRect.top,
|
|
min(pWindow2->lrInvalidDisplayRect.top,
|
|
lrScaled.top));
|
|
pWindow2->lrInvalidDisplayRect.bottom =
|
|
min(pDisplay2->lrScDisplayRect.bottom,
|
|
lmax(pWindow2->lrInvalidDisplayRect.bottom,
|
|
lrScaled.bottom));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: GetImageWnd
|
|
|
|
PURPOSE: This is the starter routine. It finds the main image
|
|
window.
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
int WINAPI GetImageWnd(HWND hWnd, PWINDOW pWindow, PWINDOW * ppImageWindow){
|
|
|
|
int nStatus = 0;
|
|
|
|
HANDLE hImageWnd = 0;
|
|
HANDLE hImageWnd2;
|
|
|
|
|
|
if (!pWindow){
|
|
CheckError2(GetPWindow(hWnd, &pWindow))
|
|
}
|
|
|
|
hImageWnd2 = pWindow->hImageWnd;
|
|
while(hImageWnd != pWindow->hImageWnd){
|
|
hImageWnd = pWindow->hImageWnd;
|
|
CheckError2(GetPWindow(hImageWnd, &pWindow))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (ppImageWindow){
|
|
*ppImageWindow = pWindow;
|
|
}
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: GetAssociatedWndList
|
|
|
|
PURPOSE: Adds to a list of window handles, all the
|
|
window handles that are associated to this window.
|
|
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI GetAssociatedWndList(HWND hWnd, PWINDOW pWindow,
|
|
PHANDLE phAssociatedWnd, int *pnCount, int nMaxCount){
|
|
|
|
int nStatus;
|
|
|
|
|
|
CheckError2(GetImageWnd(hWnd, pWindow, &pWindow))
|
|
|
|
memset(phAssociatedWnd, 0, nMaxCount * sizeof(HWND));
|
|
CheckError2(GetAssociatedWndList2(pWindow->hImageWnd,
|
|
phAssociatedWnd, pnCount, nMaxCount))
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: GetAssociatedWndList2
|
|
|
|
PURPOSE: Adds to a list of window handles, this window and all the
|
|
window handles that are associated to this window.
|
|
|
|
THIS ROUTINE IS RECURSIVE!!!
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI GetAssociatedWndList2(HWND hWnd, PHANDLE phAssociatedWnd,
|
|
int *pnCount, int nMaxCount){
|
|
|
|
int nStatus;
|
|
|
|
int nLoop;
|
|
PWINDOW pWindow;
|
|
|
|
|
|
CheckError2(GetPWindow(hWnd, &pWindow))
|
|
if (*pnCount >= nMaxCount){
|
|
nStatus = Error(DISPLAY_CANT_ASSOCIATE_WINDOW);
|
|
goto Exit;
|
|
}
|
|
phAssociatedWnd[(*pnCount)++] = hWnd;
|
|
|
|
for (nLoop = 0; nLoop < MAX_ASSOCIATED_PER_WINDOW; nLoop++){
|
|
if (pWindow->hDisplayWnd[nLoop]){
|
|
CheckError2(GetAssociatedWndList2(pWindow->hDisplayWnd[nLoop],
|
|
phAssociatedWnd, pnCount, nMaxCount))
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SetAllPImages
|
|
|
|
PURPOSE: Sets the pImage for all associated windows.
|
|
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SetAllPImages(HWND hWnd, PWINDOW pWindow){
|
|
|
|
int nStatus;
|
|
PANO_IMAGE pAnoImage;
|
|
|
|
HWND hAssocWnds[MAX_ASSOCIATED_WINDOWS + 1];
|
|
int nCount;
|
|
int nLoop;
|
|
|
|
|
|
CheckError2(GetImageWnd(hWnd, 0, &pWindow))
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
nCount = 0;
|
|
memset(&hAssocWnds[0], 0, (MAX_ASSOCIATED_WINDOWS + 1) * sizeof(HWND));
|
|
CheckError2(GetAssociatedWndList(hWnd, pWindow,
|
|
&hAssocWnds[0], &nCount, MAX_ASSOCIATED_WINDOWS))
|
|
for (nLoop = 0; nCount; nCount--, nLoop++){
|
|
if (GetPWindow(hAssocWnds[nLoop], &pWindow)){
|
|
continue;
|
|
}
|
|
pWindow->pDisplay->pAnoImage = pAnoImage;
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: GetAssociatedWndListAll
|
|
|
|
PURPOSE: Gets a list of all windows that are associated to this
|
|
window or are displaying the same image
|
|
****************************************************************************/
|
|
|
|
int WINAPI GetAssociatedWndListAll(HWND hWnd, PWINDOW pWindow,
|
|
PHANDLE phAssociatedWnd, int *pnCount, int nMaxCount){
|
|
|
|
int nStatus;
|
|
PANO_IMAGE pAnoImage;
|
|
int nWindowIndex;
|
|
|
|
|
|
CheckError2(GetImageWnd(hWnd, pWindow, &pWindow))
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
for (nWindowIndex = 0; nWindowIndex < pAnoImage->nhWnd; nWindowIndex++){
|
|
CheckError2(GetAssociatedWndList2(pAnoImage->phWnd[nWindowIndex],
|
|
phAssociatedWnd, pnCount, nMaxCount))
|
|
}
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|