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.
810 lines
20 KiB
810 lines
20 KiB
/****************************Module*Header******************************\
|
|
* Copyright (c) 1987 - 1991 Microsoft Corporation *
|
|
\***********************************************************************/
|
|
/********************************************************
|
|
* *
|
|
* file: ptools.c *
|
|
* system: PC Paintbrush for MS-Windows *
|
|
* descr: general tools for paintbrush *
|
|
* date: 12/19/89 @ 10:20 *
|
|
********************************************************/
|
|
|
|
#include "onlypbr.h"
|
|
|
|
#undef NOMB
|
|
#undef NOWINMESSAGES
|
|
#undef NORASTEROPS
|
|
#undef NOCLIPBOARD
|
|
#undef NOKEYSTATES
|
|
#undef NOKERNEL
|
|
#undef NOCTLMGR
|
|
#undef NOWINOFFSETS
|
|
#undef NOLFILEIO
|
|
#undef NOOPENFILE
|
|
#undef NOLSTRING
|
|
#undef NOMEMMGR
|
|
#undef NOMENUS
|
|
|
|
#undef NOATOM /* OLE */
|
|
#include <windows.h>
|
|
#include "port1632.h"
|
|
//#define NOEXTERN
|
|
#include "pbrush.h"
|
|
|
|
#include "pbserver.h" /* OLE */
|
|
extern RECT pickRect; /* OLE: Rectangle to copy to clip */
|
|
extern RECT imageView; /* OLE: Scroll bar displacements */
|
|
|
|
#define MAXPALETTE 256
|
|
#define PALVERSION 0x300
|
|
|
|
#define SWAP(a,b) ((a)^=(b)^=(a)^=(b))
|
|
|
|
/* define raster ops needed for MaskBlt */
|
|
#define DSx 0x00660046L
|
|
#define DSa 0x008800C6L
|
|
#define DSna 0x00220326L
|
|
|
|
extern HWND pbrushWnd[];
|
|
extern int horzDotsMM, vertDotsMM;
|
|
extern int imagePlanes, imagePixels;
|
|
extern DWORD *rgbColor;
|
|
extern int theBackg;
|
|
extern HDC monoDC;
|
|
extern HPALETTE hPalette;
|
|
|
|
static BYTE byColorTable[] = { 0, 0x48, 0x98, 0xb8, 0xd0, 0xe0, 0xf0, 0xff };
|
|
static int bluetable[] = { 0, 2, 4, 7 };
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CropBitmap (hbm,lprect) - Returns a bitmap croped to new size
|
|
----------------------------------------------------------------------------*/
|
|
HBITMAP PUBLIC CropBitmap (HBITMAP hbm, PRECT prc, BOOL fScale)
|
|
{
|
|
HDC hMemDCsrc;
|
|
HDC hMemDCdst;
|
|
HDC hdc;
|
|
HBITMAP hNewBm = NULL;
|
|
BITMAP bm;
|
|
int dx,dy; /* size of new bitmap */
|
|
|
|
if (!hbm)
|
|
goto error1;
|
|
|
|
GetObject(hbm, sizeof(BITMAP), (LPVOID) &bm);
|
|
dx = prc->right - prc->left;
|
|
dy = prc->bottom - prc->top;
|
|
|
|
hdc = GetDC(NULL);
|
|
if (!(hMemDCsrc = CreateCompatibleDC(hdc)))
|
|
goto error2;
|
|
if(!SelectObject(hMemDCsrc,hbm))
|
|
goto error3;
|
|
|
|
if (!(hMemDCdst = CreateCompatibleDC(hdc)))
|
|
goto error3;
|
|
if (!(hNewBm = CreateBitmap(dx,dy,bm.bmPlanes,bm.bmBitsPixel,NULL)))
|
|
goto error4;
|
|
if(!SelectObject(hMemDCdst,hNewBm)) {
|
|
DeleteObject(hNewBm);
|
|
hNewBm = NULL;
|
|
goto error4;
|
|
}
|
|
|
|
if (fScale) {
|
|
SetStretchBltMode(hMemDCdst,
|
|
bm.bmPlanes * bm.bmBitsPixel == 1 ? BLACKONWHITE : COLORONCOLOR);
|
|
|
|
StretchBlt(hMemDCdst,0,0,dx,dy,
|
|
hMemDCsrc,0,0,bm.bmWidth,bm.bmHeight,
|
|
SRCCOPY
|
|
);
|
|
}
|
|
else {
|
|
BitBlt(hMemDCdst,0,0,dx,dy,
|
|
hMemDCsrc,prc->left,prc->top,
|
|
SRCCOPY
|
|
);
|
|
}
|
|
|
|
error4:
|
|
DeleteDC(hMemDCdst);
|
|
|
|
error3:
|
|
DeleteDC(hMemDCsrc);
|
|
|
|
error2:
|
|
ReleaseDC(NULL,hdc);
|
|
|
|
error1:
|
|
return hNewBm;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
CopyBitmap (hbm) - Returns a copy of a given bitmap
|
|
----------------------------------------------------------------------------*/
|
|
HBITMAP PUBLIC CopyBitmap (HBITMAP hbm)
|
|
{
|
|
BITMAP bm;
|
|
RECT rc;
|
|
|
|
if (!hbm)
|
|
return NULL;
|
|
|
|
GetObject(hbm,sizeof(BITMAP),(LPVOID)&bm);
|
|
rc.left = 0;
|
|
rc.top = 0;
|
|
rc.right = bm.bmWidth;
|
|
rc.bottom = bm.bmHeight;
|
|
|
|
return CropBitmap(hbm,&rc,FALSE);
|
|
}
|
|
|
|
HPALETTE PUBLIC CopyPalette(HPALETTE hPal)
|
|
{
|
|
WORD wPalSize;
|
|
HPALETTE hNewPal = NULL;
|
|
LOGPALETTE *pPal;
|
|
|
|
if (!hPal)
|
|
goto cleanup;
|
|
|
|
GetObject(hPal, sizeof(wPalSize), (LPVOID) &wPalSize);
|
|
|
|
pPal = (LOGPALETTE *) LocalAlloc(LPTR, sizeof(LOGPALETTE) +
|
|
wPalSize * sizeof(PALETTEENTRY));
|
|
|
|
if (!pPal)
|
|
goto cleanup;
|
|
|
|
if (GetPaletteEntries(hPal, 0, wPalSize, pPal->palPalEntry) == wPalSize) {
|
|
pPal->palNumEntries = wPalSize;
|
|
pPal->palVersion = PALVERSION;
|
|
|
|
hNewPal = CreatePalette(pPal);
|
|
}
|
|
LocalFree((HANDLE) pPal);
|
|
|
|
cleanup:
|
|
return hNewPal;
|
|
}
|
|
|
|
BOOL PUBLIC DumpBitmapToClipboard(HDC hDC, UINT msg, RECT Rect)
|
|
{
|
|
HBITMAP hTempBM, hBitmap, hCopy;
|
|
HPALETTE hPal;
|
|
WORD error = IDSNoMemAvail;
|
|
HDC hMemDC;
|
|
BITMAP myBM;
|
|
HCURSOR oldCur;
|
|
|
|
oldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
if (!(hTempBM = CreateBitmap(1, 1, 1, 1, 0L)))
|
|
goto Error1;
|
|
if (!(hBitmap = SelectObject(hDC, hTempBM)))
|
|
goto Error2;
|
|
if (!(hCopy = CopyBitmap(hBitmap)))
|
|
goto Error3;
|
|
if (hPalette && !(hPal = CopyPalette(hPalette)))
|
|
goto Error4;
|
|
|
|
if (!(hMemDC = CreateCompatibleDC(NULL)))
|
|
goto Error5;
|
|
GetObject(hCopy, sizeof(BITMAP), (LPVOID)&myBM);
|
|
MSetBitmapDimension(hCopy,
|
|
(int)((long)myBM.bmWidth *254/GetDeviceCaps(hMemDC, LOGPIXELSX)),
|
|
(int)((long)myBM.bmHeight*254/GetDeviceCaps(hMemDC, LOGPIXELSY)));
|
|
|
|
error = IDSNoClipboard;
|
|
if (!OpenClipboard(pbrushWnd[PAINTid]))
|
|
goto Error6;
|
|
if (!EmptyClipboard())
|
|
goto Error7;
|
|
|
|
SetClipboardData(CF_BITMAP, hCopy);
|
|
if (hPalette)
|
|
SetClipboardData(CF_PALETTE, hPal);
|
|
|
|
if (fOLE) { /* OLE: Copy Native, Links to clipboard */
|
|
RECT rc;
|
|
|
|
rc = Rect;
|
|
OffsetRect(&rc, imageView.left, imageView.top);
|
|
CutCopyObjectFormats(hDC, hBitmap, rc, msg);
|
|
}
|
|
|
|
error = FALSE;
|
|
|
|
Error7:
|
|
CloseClipboard();
|
|
Error6:
|
|
DeleteDC(hMemDC);
|
|
Error5:
|
|
if (hPalette && error)
|
|
DeleteObject(hPal);
|
|
Error4:
|
|
if (error)
|
|
DeleteObject(hCopy);
|
|
Error3:
|
|
SelectObject(hDC, hBitmap);
|
|
Error2:
|
|
DeleteObject(hTempBM);
|
|
Error1:
|
|
if (error)
|
|
PbrushOkError(error, MB_ICONEXCLAMATION);
|
|
|
|
SetCursor(oldCur);
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
HWND hWnd;
|
|
|
|
/* Force Clipboard to update its window */
|
|
hWnd = FindWindow(TEXT("Clipboard"), NULL);
|
|
if (hWnd) {
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
UpdateWindow(hWnd);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return(!error);
|
|
}
|
|
|
|
HBITMAP PUBLIC CreatePatternBM(HDC hDC, DWORD color)
|
|
{
|
|
HDC patDC;
|
|
HBRUSH brush, hOldBrush;
|
|
HBITMAP patBM = NULL, hOldBM;
|
|
|
|
if(!(patDC = CreateCompatibleDC(hDC)))
|
|
goto Error1;
|
|
if(hPalette) {
|
|
SelectPalette(patDC, hPalette, 0);
|
|
RealizePalette(patDC);
|
|
}
|
|
if(!(brush = CreateSolidBrush(color)))
|
|
goto Error2;
|
|
if(!(hOldBrush = SelectObject(patDC, brush)))
|
|
goto Error2a;
|
|
if(!(patBM = CreateBitmap(8, 8, (BYTE)imagePlanes, (BYTE)imagePixels, NULL)))
|
|
goto Error3;
|
|
if(!(hOldBM = SelectObject(patDC, patBM))) {
|
|
DeleteObject(patBM);
|
|
patBM = NULL;
|
|
goto Error3;
|
|
}
|
|
|
|
PatBlt(patDC, 0, 0, 8, 8, PATCOPY);
|
|
|
|
SelectObject(patDC, hOldBM);
|
|
Error3:
|
|
SelectObject(patDC, hOldBrush);
|
|
Error2a:
|
|
DeleteObject(brush);
|
|
Error2:
|
|
DeleteDC(patDC);
|
|
Error1:
|
|
|
|
return(patBM);
|
|
}
|
|
|
|
void PUBLIC ConstrainBrush(LPRECT lprBounds, WPARAM wParam, int *dir)
|
|
{
|
|
int dx, dy;
|
|
|
|
if(wParam & MK_SHIFT) {
|
|
if(!(*dir)) {
|
|
dx = abs(lprBounds->right - lprBounds->left);
|
|
dy = abs(lprBounds->bottom - lprBounds->top);
|
|
|
|
if(dx > dy)
|
|
*dir = HORIZdir;
|
|
else if(dy > dx)
|
|
*dir = VERTdir;
|
|
}
|
|
|
|
if(*dir == HORIZdir)
|
|
lprBounds->bottom = lprBounds->top;
|
|
else if(*dir == VERTdir)
|
|
lprBounds->right = lprBounds->left;
|
|
} else
|
|
*dir = 0;
|
|
}
|
|
|
|
void PUBLIC ConstrainRect(LPRECT lprBounds, LPRECT lprConst, WPARAM wParam)
|
|
{
|
|
int dx, dy;
|
|
|
|
if(wParam & MK_SHIFT) {
|
|
dx = abs(lprBounds->right - lprBounds->left);
|
|
dy = abs(lprBounds->bottom - lprBounds->top);
|
|
|
|
if((long)horzDotsMM * dy < (long)vertDotsMM * dx) {
|
|
dy = (int)((long)(lprBounds->bottom<lprBounds->top ? -dx : dx)
|
|
*vertDotsMM/horzDotsMM);
|
|
dx = lprBounds->right - lprBounds->left;
|
|
} else {
|
|
dx = (int)((long)(lprBounds->right<lprBounds->left ? -dy : dy)
|
|
*horzDotsMM/vertDotsMM);
|
|
dy = lprBounds->bottom - lprBounds->top;
|
|
}
|
|
} else {
|
|
dx = lprBounds->right - lprBounds->left;
|
|
dy = lprBounds->bottom - lprBounds->top;
|
|
}
|
|
|
|
lprBounds->right = lprBounds->left + dx;
|
|
lprBounds->bottom = lprBounds->top + dy;
|
|
|
|
|
|
NormalizeRect(lprBounds);
|
|
|
|
if(lprConst)
|
|
IntersectRect(lprBounds, lprBounds, lprConst);
|
|
}
|
|
|
|
int PUBLIC DoDialog(int id, HWND hwnd, WNDPROC theProc)
|
|
{
|
|
int f = -1;
|
|
|
|
#ifdef BLOCKONMSG
|
|
EnterMsgMode();
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
if(!(theProc = MakeProcInstance (theProc, hInst)))
|
|
goto Error1;
|
|
f = DialogBox (hInst, (LPTSTR) MAKEINTRESOURCE(id), hwnd, (WNDPROC)theProc);
|
|
FreeProcInstance (theProc);
|
|
#else
|
|
f = DialogBox (hInst, (LPTSTR) MAKEINTRESOURCE(id), hwnd, theProc);
|
|
#endif
|
|
|
|
//Error1:
|
|
return(f);
|
|
}
|
|
|
|
void PUBLIC CenterWindow(HWND hWnd)
|
|
{
|
|
RECT deskRect, winRect;
|
|
POINT pos;
|
|
|
|
GetWindowRect(GetDesktopWindow(), &deskRect);
|
|
GetWindowRect(hWnd, &winRect);
|
|
|
|
pos.x = (deskRect.right - deskRect.left - winRect.right + winRect.left) >> 1;
|
|
pos.y = (deskRect.bottom - deskRect.top - winRect.bottom + winRect.top) >> 1;
|
|
SetWindowPos(hWnd, NULL, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
#ifdef WIN16
|
|
int PUBLIC changeDiskDir(LPTSTR newDir)
|
|
{
|
|
TCHAR c;
|
|
TCHAR szDir[4];
|
|
int nRet;
|
|
|
|
if (newDir[1] == TEXT(':')) /* select new drive */
|
|
{
|
|
c = newDir[0];
|
|
if (_istlower(c))
|
|
c = _totupper(c);
|
|
SetCurrentDrive (c - TEXT('A'));
|
|
}
|
|
|
|
/* To avoid overwriting stack on newDir larger than szDir. */
|
|
if (lstrlen(newDir) == 2) {
|
|
lstrcpy(szDir, newDir);
|
|
lstrcat(szDir, TEXT("\\"));
|
|
return _chdir(szDir); /* change to correct directory */
|
|
} else {
|
|
AnsiToOem (newDir, newDir);
|
|
nRet = _chdir(newDir);
|
|
OemToAnsi(newDir, newDir);
|
|
return (nRet);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
BOOL PUBLIC bFileExists(LPTSTR lpFilename)
|
|
{
|
|
HANDLE fh;
|
|
WIN32_FIND_DATA FileInfo;
|
|
|
|
fh = FindFirstFile(lpFilename, &FileInfo);
|
|
FindClose (fh);
|
|
|
|
return (fh != INVALID_HANDLE_VALUE);
|
|
}
|
|
#if 0 // 15-Sep-1993 JonPa - this functions is never called
|
|
BOOL PUBLIC bValidFilename(LPTSTR lpFilename)
|
|
{
|
|
HANDLE fh;
|
|
WIN32_FIND_DATA FileInfo;
|
|
|
|
fh = FindFirstFile(lpFilename, &FileInfo);
|
|
FindClose (fh);
|
|
|
|
return (fh != INVALID_HANDLE_VALUE);
|
|
}
|
|
#endif
|
|
|
|
/* ** Enable ok button in a dialog box if and only if edit item
|
|
contains text. Edit item must have id of idEditSave */
|
|
void PUBLIC DlgCheckOkEnable(HWND hwnd, int idEdit, UINT message)
|
|
{
|
|
if (message == EN_CHANGE)
|
|
EnableWindow(GetDlgItem(hwnd, IDOK),
|
|
(BOOL) (SendMessage(GetDlgItem(hwnd, idEdit),
|
|
WM_GETTEXTLENGTH, 0, 0L)));
|
|
}
|
|
|
|
void PUBLIC MakeValidFilename(LPTSTR s, LPTSTR lpszDefExtension)
|
|
{
|
|
LPTSTR pszSrc;
|
|
LPTSTR pszDst;
|
|
LPTSTR pszDot;
|
|
LPTSTR pszFileName;
|
|
LPTSTR pszLastNonWhite;
|
|
|
|
/*
|
|
* Strip out '"'s and find the last
|
|
* '.' and '\'.
|
|
*/
|
|
pszLastNonWhite = pszFileName = pszDot = pszDst = s;
|
|
for( pszSrc = s; *pszSrc; pszSrc++ ) {
|
|
if (*pszSrc != TEXT('"') ) {
|
|
*pszDst = *pszSrc;
|
|
|
|
if (IsPathSep(*pszDst))
|
|
pszFileName = pszDst;
|
|
|
|
if (*pszDst == TEXT('.'))
|
|
pszDot = pszDst;
|
|
|
|
if (*pszDst != TEXT(' ') && *pszDst != TEXT('\t'))
|
|
pszLastNonWhite = pszDst;
|
|
|
|
pszDst++;
|
|
}
|
|
}
|
|
|
|
pszDst = pszLastNonWhite+1;
|
|
*pszDst = TEXT('\0');
|
|
|
|
if (IsPathSep(*pszFileName))
|
|
pszFileName++;
|
|
|
|
/*
|
|
* There was not a '.' in the filename, append
|
|
* the default extention to it.
|
|
*/
|
|
if (*pszDot != TEXT('.') || pszDot < pszFileName) {
|
|
lstrcpy( pszDst, lpszDefExtension);
|
|
}
|
|
}
|
|
|
|
BOOL PUBLIC IsReadOnly(LPTSTR lpFilename)
|
|
{
|
|
HANDLE fh;
|
|
|
|
fh = MyOpenFile(lpFilename, NULL, 1);
|
|
if (fh != INVALID_HANDLE_VALUE)
|
|
{
|
|
MyCloseFile(fh);
|
|
return FALSE;
|
|
}
|
|
|
|
fh = MyOpenFile(lpFilename, NULL, 0);
|
|
if (fh != INVALID_HANDLE_VALUE)
|
|
MyCloseFile(fh);
|
|
|
|
return (fh != INVALID_HANDLE_VALUE);
|
|
}
|
|
|
|
/* How big is the palette? if bits per pel not 24
|
|
** no of bytes to read is 6 for 1 bit, 48 for 4 bits
|
|
** 256*3 for 8 bits and 0 for 24 bits
|
|
*/
|
|
WORD PUBLIC PaletteSize(VOID FAR * pv)
|
|
{
|
|
#define lpbi ((LPBITMAPINFOHEADER) pv)
|
|
|
|
WORD NumColors;
|
|
|
|
NumColors = DibNumColors(lpbi);
|
|
|
|
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
|
|
return (WORD)(NumColors * sizeof(RGBTRIPLE));
|
|
else
|
|
return (WORD)(NumColors * sizeof(RGBQUAD));
|
|
|
|
#undef lpbi
|
|
#undef lpbc
|
|
}
|
|
|
|
/*
|
|
** CreateDibPalette()
|
|
**
|
|
** Given a Global HANDLE to a BITMAPINFO Struct
|
|
** will create a GDI palette object from the color table.
|
|
**
|
|
** NOTES only works with "new" format DIB's
|
|
**
|
|
*/
|
|
HPALETTE PUBLIC CreateDibPalette(HANDLE hbi)
|
|
{
|
|
HPALETTE hpal;
|
|
|
|
if (!hbi)
|
|
return NULL;
|
|
|
|
hpal = CreateBIPalette((LPBITMAPINFOHEADER) GlobalLock(hbi));
|
|
GlobalUnlock(hbi);
|
|
return hpal;
|
|
}
|
|
|
|
/*
|
|
** CreateBIPalette()
|
|
**
|
|
** Given a Pointer to a BITMAPINFO struct will create a
|
|
** a GDI palette object from the color table.
|
|
**
|
|
** NOTES only works with "new" format DIB's
|
|
**
|
|
*/
|
|
HPALETTE PUBLIC CreateBIPalette(LPBITMAPINFOHEADER lpbi)
|
|
{
|
|
LOGPALETTE *pPal;
|
|
HPALETTE hpal = NULL;
|
|
WORD nNumColors;
|
|
BYTE red;
|
|
BYTE green;
|
|
BYTE blue;
|
|
WORD i;
|
|
RGBQUAD FAR *pRgb;
|
|
RGBQUAD FAR *pColor;
|
|
|
|
if (!lpbi)
|
|
return NULL;
|
|
|
|
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
|
|
goto exit;
|
|
|
|
pRgb = (RGBQUAD FAR *) ((LPBYTE) lpbi + (WORD) lpbi->biSize);
|
|
pColor = (RGBQUAD FAR *) rgbColor;
|
|
nNumColors = DibNumColors(lpbi);
|
|
|
|
if (nNumColors) {
|
|
// BUG 8035: make sure user can't write invalid colors into the DIB
|
|
// by adding all of the rgbColor[] entries (the available brush
|
|
// colors) to the logical palette we "receive" from the DIB.
|
|
//
|
|
|
|
pPal = (LOGPALETTE *) LocalAlloc(LPTR, sizeof(LOGPALETTE) +
|
|
(nNumColors+MAXcolors) * sizeof(PALETTEENTRY));
|
|
|
|
if (!pPal)
|
|
goto exit;
|
|
|
|
pPal->palNumEntries = nNumColors + MAXcolors;
|
|
pPal->palVersion = PALVERSION;
|
|
|
|
for (i = 0; i < nNumColors; i++) {
|
|
pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
|
|
pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
|
|
pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
|
|
pPal->palPalEntry[i].peFlags = (BYTE) 0;
|
|
}
|
|
|
|
for (i = 0; i < MAXcolors; i++) {
|
|
pPal->palPalEntry[i+nNumColors].peRed = pColor[i].rgbRed;
|
|
pPal->palPalEntry[i+nNumColors].peGreen = pColor[i].rgbGreen;
|
|
pPal->palPalEntry[i+nNumColors].peBlue = pColor[i].rgbBlue;
|
|
pPal->palPalEntry[i+nNumColors].peFlags = (BYTE) 0;
|
|
}
|
|
|
|
hpal = CreatePalette(pPal);
|
|
LocalFree((HANDLE)pPal);
|
|
} else if (lpbi->biBitCount == 24) {
|
|
nNumColors = MAXPALETTE;
|
|
pPal = (LOGPALETTE *) LocalAlloc(LPTR, sizeof(LOGPALETTE) +
|
|
nNumColors * sizeof(PALETTEENTRY));
|
|
|
|
if (!pPal)
|
|
goto exit;
|
|
|
|
pPal->palNumEntries = nNumColors;
|
|
pPal->palVersion = PALVERSION;
|
|
|
|
i = 0;
|
|
for (red = 0; red < 8; ++red)
|
|
for (green = 0; green < 8; ++green)
|
|
for (blue = 0; blue < 4; ++blue) {
|
|
pPal->palPalEntry[i].peRed = byColorTable[red];
|
|
pPal->palPalEntry[i].peGreen = byColorTable[green];
|
|
pPal->palPalEntry[i].peBlue = byColorTable[bluetable[blue]];
|
|
pPal->palPalEntry[i].peFlags = (BYTE) 0;
|
|
++i;
|
|
}
|
|
|
|
hpal = CreatePalette(pPal);
|
|
LocalFree((HANDLE)pPal);
|
|
}
|
|
|
|
exit:
|
|
return hpal;
|
|
}
|
|
|
|
/* How Many colors does this DIB have?
|
|
** this will work on both PM and Windows bitmap info structures.
|
|
*/
|
|
WORD PUBLIC DibNumColors(VOID FAR *pv)
|
|
{
|
|
#define lpbi ((LPBITMAPINFOHEADER) pv)
|
|
#define lpbc ((LPBITMAPCOREHEADER) pv)
|
|
|
|
int bits;
|
|
|
|
/*
|
|
** with the new format headers, the size of the palette is in biClrUsed
|
|
** else is dependent on bits per pixel
|
|
*/
|
|
if (lpbi->biSize != sizeof(BITMAPCOREHEADER)) {
|
|
if (lpbi->biClrUsed != 0)
|
|
return (WORD) lpbi->biClrUsed;
|
|
|
|
bits = lpbi->biBitCount;
|
|
} else
|
|
bits = lpbc->bcBitCount;
|
|
|
|
switch (bits) {
|
|
case 1:
|
|
return 2;
|
|
|
|
case 4:
|
|
return 16;
|
|
|
|
case 8:
|
|
return 256;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
#undef lpbi
|
|
#undef lpbc
|
|
}
|
|
|
|
void PUBLIC TripleToQuad(LPBITMAPINFO lpDIBinfo, BOOL bSwap)
|
|
{
|
|
BYTE FAR *lpNewRGB, FAR *lpOldRGB, FAR *lpSentinel;
|
|
DWORD dwNumColors;
|
|
BYTE t;
|
|
|
|
if (!(dwNumColors = lpDIBinfo->bmiHeader.biClrUsed))
|
|
dwNumColors = (1L << lpDIBinfo->bmiHeader.biBitCount);
|
|
|
|
/* need to convert 24-bit palette to 32-bit palette */
|
|
lpOldRGB = lpNewRGB = lpSentinel = (BYTE FAR *) lpDIBinfo->bmiColors;
|
|
lpOldRGB += 3 * dwNumColors - 1;
|
|
lpNewRGB += sizeof(RGBQUAD) * dwNumColors - 1;
|
|
|
|
while (lpOldRGB > lpSentinel) {
|
|
/* swap assumes order is r g b and needs to be b g r */
|
|
if (bSwap) {
|
|
t = lpOldRGB[0];
|
|
lpOldRGB[0] = lpOldRGB[-2];
|
|
lpOldRGB[-2] = t;
|
|
}
|
|
|
|
*lpNewRGB-- = 0;
|
|
*lpNewRGB-- = *lpOldRGB--;
|
|
*lpNewRGB-- = *lpOldRGB--;
|
|
*lpNewRGB-- = *lpOldRGB--;
|
|
}
|
|
}
|
|
|
|
HPALETTE PUBLIC MakeImagePalette(HPALETTE hPal, HANDLE hDIBinfo, UINT FAR *wUsage)
|
|
{
|
|
HPALETTE hNewPal;
|
|
LPBITMAPINFO lpDIBinfo;
|
|
DWORD dwNumColors;
|
|
BYTE FAR *bp;
|
|
WORD FAR *wp;
|
|
DWORD FAR *dp;
|
|
WORD i;
|
|
|
|
*wUsage = DIB_RGB_COLORS;
|
|
|
|
lpDIBinfo = (LPBITMAPINFO) GlobalLock(hDIBinfo);
|
|
|
|
if (!(dwNumColors = lpDIBinfo->bmiHeader.biClrUsed))
|
|
dwNumColors = (1L << lpDIBinfo->bmiHeader.biBitCount);
|
|
|
|
/* 24 bit image w/o palette so use RGB color translation */
|
|
if (dwNumColors > 256L) {
|
|
hNewPal = hPal ? hPal : CreateDibPalette(hDIBinfo);
|
|
goto cleanup1;
|
|
}
|
|
|
|
if (!hPal) {
|
|
/* no palette so create it ... */
|
|
hNewPal = CreateDibPalette(hDIBinfo);
|
|
if (hNewPal) {
|
|
for (i = 0, wp = (WORD FAR *) lpDIBinfo->bmiColors;
|
|
i < (WORD) dwNumColors;)
|
|
*wp++ = i++;
|
|
} else
|
|
goto cleanup1;
|
|
} else {
|
|
/* get closest match for each color /w respect to current palette */
|
|
for (i = 0, wp = (WORD FAR *) lpDIBinfo->bmiColors,
|
|
dp = (DWORD FAR *) lpDIBinfo->bmiColors;
|
|
i < (WORD) dwNumColors; ++i) {
|
|
bp = (BYTE FAR *) dp;
|
|
SWAP(bp[0],bp[2]);
|
|
*wp++ = (WORD)GetNearestPaletteIndex(hPal, *dp++);
|
|
}
|
|
hNewPal = hPal;
|
|
}
|
|
|
|
*wUsage = DIB_PAL_COLORS;
|
|
|
|
cleanup1:
|
|
GlobalUnlock(hDIBinfo);
|
|
return hNewPal;
|
|
}
|
|
|
|
void PUBLIC NormalizeRect(LPRECT lpRect)
|
|
{
|
|
int t;
|
|
|
|
if (lpRect->left > lpRect->right) {
|
|
t = lpRect->left;
|
|
lpRect->left = lpRect->right;
|
|
lpRect->right = t;
|
|
}
|
|
|
|
if (lpRect->top > lpRect->bottom) {
|
|
t = lpRect->top;
|
|
lpRect->top = lpRect->bottom;
|
|
lpRect->bottom = t;
|
|
}
|
|
}
|
|
|
|
/* copy hbm to hDC, using hbmMask as a mask.
|
|
** if mask bit = 0 then leave destination unchanged
|
|
** if mask bit = 1 then copy from source
|
|
** if hbmMask is NULL, this becomes a straight BitBlt (all bits 1)
|
|
*/
|
|
BOOL PUBLIC MaskStretchBlt(HDC hDCD, int x, int y, int dx, int dy,
|
|
HDC hDCS, HDC hDCSMask, int x0, int y0,
|
|
int dx0, int dy0)
|
|
{
|
|
DWORD rgbBk, rgbFg;
|
|
|
|
if (!hDCSMask)
|
|
return StretchBlt(hDCD, x, y, dx, dy, hDCS, x0, y0, dx0, dy0, SRCCOPY);
|
|
|
|
rgbBk = SetBkColor(hDCD, RGB(255,255,255));
|
|
rgbFg = SetTextColor(hDCD, RGB(0,0,0));
|
|
|
|
StretchBlt(hDCD, x, y, dx, dy, hDCS, x0, y0, dx0, dy0, DSx);
|
|
StretchBlt(hDCD, x, y, dx, dy, hDCSMask, x0, y0, dx0, dy0, DSna);
|
|
StretchBlt(hDCD, x, y, dx, dy, hDCS, x0, y0, dx0, dy0, DSx);
|
|
|
|
SetBkColor(hDCD, rgbBk);
|
|
SetTextColor(hDCD, rgbFg);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void PUBLIC EnableMenuItems(HMENU hMenu, UINT MenuItems[], UINT wFlags)
|
|
{
|
|
while(*MenuItems != -1) {
|
|
EnableMenuItem(hMenu, *MenuItems++, wFlags);
|
|
}
|
|
}
|