home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
On Hand
/
On_Hand_From_Softbank_1994_Release_2_Disc_2_1994.iso
/
00202
/
s
/
disk1
/
pal.c_
/
pal.bin
Wrap
Text File
|
1993-04-28
|
13KB
|
486 lines
//---------------------------------------------------------------------------
// Copyright (C) 1992-93 Microsoft Corporation
//
// You have a royalty-free right to use, modify, reproduce and distribute
// the Sample Custom Control Files (and/or any modified version) in any way
// you find useful, provided that you agree that Microsoft has no warranty,
// obligation or liability for any Custom Control File.
//---------------------------------------------------------------------------
// Pal.c
//---------------------------------------------------------------------------
// PALette Control
//---------------------------------------------------------------------------
#include <windows.h>
#include <string.h>
#include <vbapi.h>
#include "pal.h"
extern MODEL modelPal;
VOID PaintPalette(HCTL hctl, HWND hwnd, HDC hdc);
HPALETTE CopyPalette(HPALETTE hpal);
HANDLE hmodDLL; // Module handle for the DLL
#define ERR_OOM 7 // Out of memory error
//---------------------------------------------------------------------------
// PAL control function
//---------------------------------------------------------------------------
LONG _export FAR PASCAL PalCtlProc
(
HCTL hctl,
HWND hwnd,
USHORT msg,
USHORT wp,
LONG lp
)
{
LONG lResult;
// Message pre-processing
switch(msg)
{
case WM_NCCREATE:
// For convenience, mark this control as always using a palette,
// but for windowed controls this will only take effect if we later
// also set CTLFLG_HASPALETTE.
VBSetControlFlags(hctl, CTLFLG_USESPALETTE, CTLFLG_USESPALETTE);
break;
case WM_PAINT:
if (wp)
// Handle "subclass paint", where wp == hdc
PaintPalette(hctl, hwnd, (HDC)wp);
else
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
PaintPalette(hctl, hwnd, ps.hdc);
EndPaint(hwnd, &ps);
}
break;
case VBM_GETPALETTE:
// Return the palette we want realized.
// Turning off our palette awareness with VBSetControlFlags()
// when we have no palette will prevent us from returning NULL here.
return PALDEREF(hctl)->hpal;
case VBM_GETPROPERTY:
switch (wp)
{
case IPROP_PAL_PICTURE:
// For the Picture property we build an HPIC value composed
// of a 0 by 0 bitmap and a copy of our current HPALETTE
{
PPAL ppal;
PIC pic;
HPIC hpic;
HPALETTE hpal;
HBITMAP hbmp;
HDC hdcScr;
ppal = PALDEREF(hctl);
if (!ppal->hpal)
{
// No palette - no picture
*(HPIC FAR *)lp = HPIC_NULL;
return 0;
}
// Make a copy of the palette we're using
hpal = CopyPalette(ppal->hpal);
if (!hpal)
return ERR_OOM;
// Create a 1x1 bitmap to go with the palette
hdcScr = GetDC(NULL);
hbmp = CreateBitmap(1, 1,
(BYTE)GetDeviceCaps(hdcScr, PLANES),
(BYTE)GetDeviceCaps(hdcScr, BITSPIXEL),
NULL);
ReleaseDC(NULL, hdcScr);
if (!hbmp)
{
DeleteObject(hpal);
return ERR_OOM;
}
// Create HPIC from HBMP and HPAL
pic.picType = PICTYPE_BITMAP;
pic.picData.bmp.hbitmap = hbmp;
pic.picData.bmp.hpal = hpal;
hpic = VBAllocPicEx(&pic, VB_VERSION);
if (!hpic)
{
DeleteObject(hpal);
DeleteObject(hbmp);
return ERR_OOM;
}
// Return the HPIC but don't call VBRefPic because we're
// not holding a reference to this picture
*(HPIC FAR *)lp = hpic;
return 0;
}
case IPROP_PAL_LENGTH:
// The Length property just returns the palette length
{
PPAL ppal;
HPALETTE hpal;
SHORT palNumEntries;
ppal = PALDEREF(hctl);
hpal = ppal->hpal;
if (!hpal)
// Fall back to the default palette
hpal = GetStockObject(DEFAULT_PALETTE);
GetObject((HANDLE)hpal, sizeof(WORD), (LPSTR)&palNumEntries);
*(SHORT FAR *)lp = palNumEntries;
return 0;
}
case IPROP_PAL_ENTRY:
// The Entry array property returns the color RGB value
// of the palette entry at the given index
{
PPAL ppal;
HPALETTE hpal;
PALETTEENTRY palentry;
LPDATASTRUCT pds = (LPDATASTRUCT)lp;
SHORT index = (SHORT)(pds->index[0].data);
ppal = PALDEREF(hctl);
hpal = ppal->hpal;
if (!hpal)
hpal = GetStockObject(DEFAULT_PALETTE);
if (!GetPaletteEntries(hpal, index, 1, &palentry))
return VBSetErrorMessage(32000, "invalid palette index");
pds->data = RGB(palentry.peRed, palentry.peGreen, palentry.peBlue);
return 0;
}
}
break;
case VBM_SETPROPERTY:
switch (wp)
{
case IPROP_PAL_PICTURE:
// For the Picture we just copy the palette from the HPIC
{
PIC pic;
PPAL ppal;
ppal = PALDEREF(hctl);
// Get the picture information and validate the type
VBGetPicEx((HPIC)lp, &pic, VB_VERSION);
switch (pic.picType)
{
case PICTYPE_NONE:
case PICTYPE_BITMAP:
// Free old HPAL
if (ppal->hpal)
DeleteObject(ppal->hpal);
if (pic.picType == PICTYPE_NONE)
ppal->hpal = NULL;
else
ppal->hpal = CopyPalette(pic.picData.bmp.hpal);
InvalidateRect(hwnd, NULL, TRUE);
VBSetControlFlags(hctl, CTLFLG_HASPALETTE,
(ppal->hpal != NULL) ? CTLFLG_HASPALETTE : 0);
return 0;
}
return VBSetErrorMessage(32001, "bitmaps only");
}
case IPROP_PAL_LENGTH:
// The Length property causes the palette to be extended
// (with black entries) or truncated to a specific length
{
PPAL ppal;
HPALETTE hpal;
ppal = PALDEREF(hctl);
hpal = ppal->hpal;
if (!hpal)
{
// Fall back to the default palette
hpal = CopyPalette(GetStockObject(DEFAULT_PALETTE));
if (!hpal)
return ERR_OOM;
ppal->hpal = hpal;
}
// Windows does all the real work here!!
if (!ResizePalette(hpal, (WORD)lp))
return VBSetErrorMessage(32002, "can't resize palette");
InvalidateRect(hwnd, NULL, TRUE);
VBSetControlFlags(hctl, CTLFLG_HASPALETTE, CTLFLG_HASPALETTE);
return 0;
}
case IPROP_PAL_ENTRY:
// The Entry array property sets the color RGB value
// of the palette entry at the given index
{
PPAL ppal;
HPALETTE hpal;
PALETTEENTRY palentry;
LPDATASTRUCT pds = (LPDATASTRUCT)lp;
SHORT index = (SHORT)(pds->index[0].data);
// Use RGBCOLOR macro to translate SysColors
COLOR color = RGBCOLOR(pds->data);
ppal = PALDEREF(hctl);
hpal = ppal->hpal;
if (!hpal)
{
// Fall back to the default palette
hpal = CopyPalette(GetStockObject(DEFAULT_PALETTE));
if (!hpal)
return ERR_OOM;
ppal->hpal = hpal;
}
// Build an entry and set it
palentry.peRed = GetRValue(color);
palentry.peGreen = GetGValue(color);
palentry.peBlue = GetBValue(color);
palentry.peFlags = 0;
if (!SetPaletteEntries(hpal, index, 1, &palentry))
return VBSetErrorMessage(32003, "invalid palette index");
InvalidateRect(hwnd, NULL, TRUE);
VBSetControlFlags(hctl, CTLFLG_HASPALETTE, CTLFLG_HASPALETTE);
return 0;
}
}
break;
}
// Default processing:
lResult = VBDefControlProc(hctl, hwnd, msg, wp, lp);
// Message post-processing:
switch (msg)
{
case WM_DESTROY:
{
PPAL ppal;
ppal = PALDEREF(hctl);
// Free old HPAL
if (ppal->hpal)
{
DeleteObject(ppal->hpal);
ppal->hpal = NULL;
}
}
break;
}
return lResult;
}
//---------------------------------------------------------------------------
// Handle the painting of the window.
//---------------------------------------------------------------------------
VOID PaintPalette
(
HCTL hctl,
HWND hwnd,
HDC hdc
)
{
RECT rect;
HPALETTE hpal;
HPALETTE hpalOld;
int i;
int stripe;
HBRUSH hbr;
int palNumEntries;
hpal = PALDEREF(hctl)->hpal;
if (!hpal)
hpal = GetStockObject(DEFAULT_PALETTE);
GetClientRect(hwnd, &rect);
hpalOld = SelectPalette(hdc, hpal, TRUE);
RealizePalette(hdc);
GetObject((HANDLE)hpal, sizeof(WORD), (LPSTR)&palNumEntries);
stripe = rect.right / (int)palNumEntries;
if (stripe == 0)
stripe = 1;
++stripe;
for (i = 0; i < palNumEntries; i++)
{
// A palette-relative brush is used for drawing.
hbr = CreateSolidBrush(PALETTEINDEX(i));
if (hbr)
{
hbr = SelectObject(hdc, hbr);
PatBlt(hdc, i*stripe, 0, stripe, rect.bottom, PATCOPY);
hbr = SelectObject(hdc, hbr);
DeleteObject(hbr);
}
}
SelectPalette(hdc, hpalOld, TRUE);
RealizePalette(hdc);
}
//---------------------------------------------------------------------------
// Makes a copy of a GDI logical palette. Returns a handle to the new
// palette.
//---------------------------------------------------------------------------
HPALETTE CopyPalette
(
HPALETTE hpal
)
{
PLOGPALETTE ppal;
int nNumEntries;
if (!hpal)
return NULL;
GetObject(hpal,sizeof(int),(LPSTR)&nNumEntries);
if (nNumEntries == 0)
return NULL;
ppal = (PLOGPALETTE)LocalAlloc(LPTR, (WORD)(sizeof(LOGPALETTE) +
nNumEntries * sizeof(PALETTEENTRY)));
if (!ppal)
return NULL;
ppal->palVersion = 0x300;
ppal->palNumEntries = (WORD)nNumEntries;
GetPaletteEntries(hpal,0, (WORD)nNumEntries, ppal->palPalEntry);
hpal = CreatePalette(ppal);
LocalFree((HANDLE)ppal);
return hpal;
}
//---------------------------------------------------------------------------
// Register custom control. This routine is called by VB when the custom
// control DLL is loaded for use.
//---------------------------------------------------------------------------
BOOL FAR PASCAL _export VBINITCC
(
USHORT usVersion,
BOOL fRuntime
)
{
// Avoid warnings on unused (but required) formal parameters
fRuntime = fRuntime;
// Avoid loading under earlier version of VB
if (usVersion < VB200_VERSION)
{
MessageBox(NULL,
"Requires Visual Basic 2.0",
"Palette Control",
MB_OK | MB_TASKMODAL);
return FALSE;
}
// Register control(s)
return VBRegisterModel(hmodDLL, &modelPal);
}
//---------------------------------------------------------------------------
// Provide custom control model information to host environment.
//---------------------------------------------------------------------------
LPMODELINFO FAR PASCAL _export VBGetModelInfo
(
USHORT usVersion
)
{
// Avoid warnings on unused (but required) formal parameters
usVersion = usVersion;
return &modelinfoPal;
}
//---------------------------------------------------------------------------
// Initialize library. This routine is called when the first client loads
// the DLL.
//---------------------------------------------------------------------------
int FAR PASCAL LibMain
(
HANDLE hModule,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine
)
{
// Avoid warnings on unused (but required) formal parameters
wDataSeg = wDataSeg;
cbHeapSize = cbHeapSize;
lpszCmdLine = lpszCmdLine;
hmodDLL = hModule;
return 1;
}
//---------------------------------------------------------------------------
// WEP
//---------------------------------------------------------------------------
// C7 and QCWIN provide default a WEP:
//---------------------------------------------------------------------------
#if (_MSC_VER < 610)
int FAR PASCAL WEP(int fSystemExit);
//---------------------------------------------------------------------------
// For Windows 3.0 it is recommended that the WEP function reside in a
// FIXED code segment and be exported as RESIDENTNAME. This is
// accomplished using the alloc_text pragma below and the related EXPORTS
// and SEGMENTS directives in the .DEF file.
//
// Read the comments section documenting the WEP function in the Windows
// 3.1 SDK "Programmers Reference, Volume 2: Functions" before placing
// any additional code in the WEP routine for a Windows 3.0 DLL.
//---------------------------------------------------------------------------
#pragma alloc_text(WEP_TEXT,WEP)
//---------------------------------------------------------------------------
// Performs cleanup tasks when the DLL is unloaded. WEP() is
// called automatically by Windows when the DLL is unloaded (no
// remaining tasks still have the DLL loaded). It is strongly
// recommended that a DLL have a WEP() function, even if it does
// nothing but returns success (1), as in this example.
//---------------------------------------------------------------------------
int FAR PASCAL WEP
(
int fSystemExit
)
{
// Avoid warnings on unused (but required) formal parameters
fSystemExit = fSystemExit;
return 1;
}
#endif // C6
//---------------------------------------------------------------------------