Category : C Source Code
Archive   : FADE.ZIP
Filename : OPTIONS.C

 
Output of file : OPTIONS.C contained in archive : FADE.ZIP
//***********************************************************************
// File: options.c
//
// Purpose: Routines to read, write and modify the current options
// and to modify a DIB to conform to those options.
//
// Functions:
// ReadOptions - reads settings from .ini file
// WriteOptions - saves settings to .ini file
// OptionsDlgProc - dialog procedure to modify size & color options
// StepDlgProc - dialog procedure to change the number of animations steps
// SizeDIB - resizes a DIB according to the size and options given
//
// Development Team:
// Jeff Saathoff
//
// Written by Microsoft Product Support Services, Windows Developer Support
// COPYRIGHT:
//
// (C) Copyright Microsoft Corp. 1993. All rights reserved.
//
// You have a royalty-free right to use, modify, reproduce and
// distribute the Sample Files (and/or any modified version) in
// any way you find useful, provided that you agree that
// Microsoft has no warranty obligations or liability for any
// Sample Application Files which are modified.
//
//***********************************************************************

#include
#include
#include
#include "options.h"
#include "dib.h"
#include "file.h"

static char szIniFile[] = "fade.ini";
static char szDefault[] = "";

//***********************************************************************
// Function: ReadInt, ReadBool, ReadString, WriteInt, WriteString
//
// Purpose: Local helper functions called by ReadOptions and WriteOptions
//
// Parameters: varies
//
// Returns: varies
//
// Comments:
//
// History: Date Author Reason
//
//***********************************************************************

static __inline int ReadInt(char *szOpt, int nDefault, int nMin, int nMax)
{
return max(nMin, min(nMax,
(int) GetPrivateProfileInt("Fade", szOpt, nDefault, szIniFile) ) );
}

#define ReadBool(szOpt, nDefault) ReadInt(szOpt, nDefault, 0, 1)

static __inline int ReadString(char *szOpt, char *szRet)
{
return GetPrivateProfileString("Fade", szOpt, szDefault, szRet, strlen(szRet), szIniFile);
}

static __inline BOOL WriteInt(char *szOpt, int nVal)
{
char szVal[10];

wsprintf(szVal, "%d", nVal);

return WritePrivateProfileString("Fade", szOpt, szVal, szIniFile);
}

static __inline BOOL WriteString(char *szOpt, char *szVal)
{
return WritePrivateProfileString("Fade", szOpt, szVal, szIniFile);
}

//***********************************************************************
// Function: ReadOptions
//
// Purpose: Called at app startup to get current settings.
//
// Parameters:
// pOptions == pointer to OPTIONS structure
//
// Returns: No return
//
// Comments:
//
// History: Date Author Reason
// 8/30/92 JMS Created
//***********************************************************************

void ReadOptions(OPTIONS *pOptions)
{
char szMethod[16];

pOptions->wFlags = IDB_SIZEFIRST + ReadInt("Size", 0, 0, IDB_SIZELAST-IDB_SIZEFIRST+1);

ReadString("Method", szMethod);
if (!_stricmp(szMethod, "Tile"))
pOptions->wFlags |= IDB_TILE;
else if (!_stricmp(szMethod, "Stretch"))
pOptions->wFlags |= IDB_STRETCH;
else
pOptions->wFlags |= IDB_FILL;

if (ReadInt("Colors", 15, 15, 16) == 15)
pOptions->wFlags |= IDB_15COLORS;
else
pOptions->wFlags |= IDB_16COLORS;

pOptions->nWidth = ReadInt("Width", 0, 0, 32767);
pOptions->nHeight = ReadInt("Height", 0, 0, 32767);

pOptions->nSteps = ReadInt("Steps", 16, 2, 99);
}

//***********************************************************************
// Function: WriteOptions
//
// Purpose: Called at app termination to save current settings.
//
// Parameters:
// pOptions == pointer to OPTIONS structure
//
// Returns: No return
//
// Comments:
//
// History: Date Author Reason
// 8/30/92 JMS Created
//***********************************************************************

void WriteOptions(OPTIONS *pOptions)
{
WriteInt("Size", LOBYTE(pOptions->wFlags)-IDB_SIZEFIRST);

if (pOptions->wFlags&IDB_TILE)
WriteString("Method", "Tile");
else if (pOptions->wFlags&IDB_STRETCH)
WriteString("Method", "Stretch");
else
WriteString("Method", "Fill");

WriteInt("Colors", (pOptions->wFlags&IDB_15COLORS ? 15 : 16));

WriteInt("Width", pOptions->nWidth);
WriteInt("Height", pOptions->nHeight);

WriteInt("Steps", pOptions->nSteps);

// Clear update bit.
pOptions->wFlags &= ~OPTIONSCHANGED;
}

//***********************************************************************
// Function: OptionsDlgProc (HWND, WORD, WORD, LONG)
//
// Purpose: Window procedure for the BM2 Options dialog box.
//
// Returns: TRUE if the message was processed.
// FALSE if the system needs to process the message.
//
// Comments:
//
// History: Date Author Reason
// 8/6/92 JMS Created
//***********************************************************************

BOOL FAR PASCAL OptionsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static LPOPTIONS lpOptions;

switch (msg)
{
case WM_INITDIALOG:
// save pointer to options struct
lpOptions = (LPOPTIONS) lParam;

// Initialize the controls to the current options.

if ((LOBYTE(lpOptions->wFlags) < IDB_SIZEFIRST)
|| (LOBYTE(lpOptions->wFlags) > IDB_SIZELAST))
lpOptions->wFlags = (lpOptions->wFlags&0xFF00) | IDB_SIZEFIRST;

SendDlgItemMessage(hDlg, LOBYTE(lpOptions->wFlags), BM_SETCHECK, TRUE, 0L);
SetDlgItemInt(hDlg, IDE_WIDTH, lpOptions->nWidth, FALSE);
SetDlgItemInt(hDlg, IDE_HEIGHT, lpOptions->nHeight, FALSE);

if (lpOptions->wFlags&IDB_STRETCH)
SendDlgItemMessage(hDlg, IDB_STRETCH, BM_SETCHECK, TRUE, 0L);
else if (lpOptions->wFlags&IDB_TILE)
SendDlgItemMessage(hDlg, IDB_TILE, BM_SETCHECK, TRUE, 0L);
else // IDB_FILL is default
SendDlgItemMessage(hDlg, IDB_FILL, BM_SETCHECK, TRUE, 0L);

if (lpOptions->wFlags&IDB_15COLORS)
SendDlgItemMessage(hDlg, IDB_15COLORS, BM_SETCHECK, TRUE, 0L);
else // IDB_16COLORS is default
SendDlgItemMessage(hDlg, IDB_16COLORS, BM_SETCHECK, TRUE, 0L);

// If the custom size option is selected, we need to enable
// the associated edit controls, otherwise disable them.
if (LOBYTE(lpOptions->wFlags) == IDB_CUSTOM)
{
EnableWindow(GetDlgItem(hDlg, IDC_WIDTH), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_HEIGHT), TRUE);
EnableWindow(GetDlgItem(hDlg, IDE_WIDTH), TRUE);
EnableWindow(GetDlgItem(hDlg, IDE_HEIGHT), TRUE);
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_WIDTH), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_HEIGHT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDE_WIDTH), FALSE);
EnableWindow(GetDlgItem(hDlg, IDE_HEIGHT), FALSE);
}
return TRUE;

case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
EndDialog(hDlg, FALSE);
return TRUE;

case IDOK:
{
WORD wID;
UINT nWidth, nHeight;

// Get ID of currently checked option

for ( wID=IDB_SIZEFIRST;
wID<=IDB_SIZELAST, !SendDlgItemMessage(hDlg, wID, BM_GETCHECK, 0, 0L);
wID++ ) ; // No loop body

if (wID == IDB_CUSTOM) // Get new width & height
{
BOOL bNoError;

nWidth = GetDlgItemInt(hDlg, IDE_WIDTH, &bNoError, FALSE);
if (!bNoError || !nWidth)
{
MessageBox(hDlg, "Invalid Width", NULL, MB_ICONSTOP | MB_OK);
SetFocus(GetDlgItem(hDlg, IDE_WIDTH));
return TRUE;
}

nHeight = GetDlgItemInt(hDlg, IDE_HEIGHT, &bNoError, FALSE);
if (!bNoError || !nHeight)
{
MessageBox(hDlg, "Invalid Height", NULL, MB_ICONSTOP | MB_OK);
SetFocus(GetDlgItem(hDlg, IDE_HEIGHT));
return TRUE;
}

lpOptions->nWidth = nWidth;
lpOptions->nHeight = nHeight;
}

// Save new options and EndDialog

lpOptions->wFlags = wID;

if (SendDlgItemMessage(hDlg, IDB_STRETCH, BM_GETCHECK, 0, 0L))
lpOptions->wFlags |= IDB_STRETCH;
else if (SendDlgItemMessage(hDlg, IDB_TILE, BM_GETCHECK, 0, 0L))
lpOptions->wFlags |= IDB_TILE;
else
lpOptions->wFlags |= IDB_FILL;

if (SendDlgItemMessage(hDlg, IDB_15COLORS, BM_GETCHECK, 0, 0L))
lpOptions->wFlags |= IDB_15COLORS;
else
lpOptions->wFlags |= IDB_16COLORS;

// Hack! Set the high bit of the flags to indicate
// that we've changed the options settings.
lpOptions->wFlags |= OPTIONSCHANGED;

EndDialog(hDlg, TRUE);
return TRUE;
}

case IDB_LARGER:
case IDB_SMALLER:
case IDB_SIZE1:
case IDB_SIZE2:
case IDB_CUSTOM:
// If the custom size option is selected, we need to enable
// the associated edit controls, otherwise disable them.
if (HIWORD(lParam) == BN_CLICKED)
{
if (SendDlgItemMessage(hDlg, IDB_CUSTOM, BM_GETCHECK, 0, 0L))
{
EnableWindow(GetDlgItem(hDlg, IDC_WIDTH), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_HEIGHT), TRUE);
EnableWindow(GetDlgItem(hDlg, IDE_WIDTH), TRUE);
EnableWindow(GetDlgItem(hDlg, IDE_HEIGHT), TRUE);
}
else
{
EnableWindow(GetDlgItem(hDlg, IDC_WIDTH), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_HEIGHT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDE_WIDTH), FALSE);
EnableWindow(GetDlgItem(hDlg, IDE_HEIGHT), FALSE);
}
}
return TRUE;
}
break;
}
return FALSE;
}


//***********************************************************************
// Function: StepDlgProc
//
// Purpose: Called when the user wants a custom Step-size.
//
// Parameters:
// hDlg == Handle to _this_ window.
// message == Message to process.
// wParam == WORD parameter -- depends on message
// lParam == LONG parameter -- depends on message
//
// Returns: Depends on message.
//
// Comments:
//
// History: Date Author Reason
// 8/14/92 JMS Created
//***********************************************************************

BOOL FAR PASCAL StepDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
SetDlgItemInt(hDlg, IDE_STEPS, (UINT) lParam, FALSE);
SendDlgItemMessage(hDlg, IDE_STEPS, EM_SETSEL, 0, MAKELPARAM(0,-1));
return (TRUE);

case WM_COMMAND:
switch (wParam)
{
case IDOK: // "OK" box selected?
{
BOOL bNoError;
int nSteps;

nSteps = GetDlgItemInt(hDlg, IDE_STEPS, &bNoError, FALSE);

if (bNoError && (nSteps >= 2) && (nSteps <= 99))
EndDialog(hDlg, nSteps);
else
MessageBox(hDlg, "Invalid number of steps.", NULL, MB_ICONEXCLAMATION|MB_OK);

return (TRUE);
}

case IDCANCEL:
EndDialog(hDlg, 0); // Exits the dialog box
return (TRUE);
}
}

return FALSE; // Didn't process message
}

//***********************************************************************
// Function: SizeDIB
//
// Purpose: Given a handle to a CF_DIB and the desired width and
// and height, re-sizes the DIB to the new size.
// Returns TRUE for success and FALSE for failure.
//
// Parms: phdib == Pointer to handle of source DIB
// dwWidth == Desired width in pixels
// dwHeight == Desired height in pixels
// wMode == IDB_STRETCH, IDB_FILL, or IDB_TILE
//
// History: Date Author Reason
// 8/6/92 JMS Created
//***********************************************************************

BOOL SizeDIB(HGLOBAL *phdib, PALETTEENTRY *pe, LONG lWidth, LONG lHeight, WORD wMode)
{
LPBITMAPINFOHEADER lpbi;
HPBYTE hpBits;
HPALETTE hpal=NULL;
PLOGPALETTE ppal;
HBITMAP hbm;
HDC hdc, hdcMem;
DWORD dwSize;
int dx, dy, dw, dh, sx, sy, sw, sh;

// Get pointer to DIB

lpbi = (LPBITMAPINFOHEADER) GlobalLock(*phdib);

// See if there's anything to do...

if ((lpbi->biWidth == lWidth) && (lpbi->biHeight == lHeight))
{
GlobalUnlock(*phdib);
return TRUE;
}

// Re-alloc memory if we don't have enough

dwSize = (DWORD) sizeof(BITMAPINFOHEADER) + PaletteSize((LPSTR) lpbi)
+ WIDTHBYTES(lWidth * lpbi->biBitCount) * lHeight;

if (dwSize > GlobalSize(*phdib))
{
HGLOBAL h;

GlobalUnlock(*phdib);

if (h = GlobalReAlloc(*phdib, dwSize, 0))
{
*phdib = h;
lpbi = (LPBITMAPINFOHEADER) GlobalLock(*phdib);
}
else
return FALSE;
}

// Save pointer to bits to use later

hpBits = FindDIBBits((LPSTR) lpbi);

// Get a DC to work with
hdc = GetDC(NULL);
hdcMem = CreateCompatibleDC(hdc);

// Need the palette for converting the DIB
if (ppal = (PLOGPALETTE) LocalAlloc(LPTR, 2*sizeof(WORD) + 16*sizeof(PALETTEENTRY)))
{
ppal->palVersion = PALVERSION;
ppal->palNumEntries = 16;

for (dx=0; dx<16; dx++, pe++)
ppal->palPalEntry[dx] = *pe;

hpal = CreatePalette(ppal);

LocalFree((HLOCAL) ppal);
}

if (!hpal)
hpal = GetStockObject(DEFAULT_PALETTE);
hpal = SelectPalette(hdcMem, hpal, FALSE);
RealizePalette(hdcMem);

// Create temporary bitmap
if (!(hbm = CreateCompatibleBitmap(hdc, (int) lWidth, (int) lHeight)))
{
DeleteObject(SelectPalette(hdcMem, hpal, FALSE));
DeleteDC(hdcMem);
ReleaseDC(NULL, hdc);
GlobalUnlock(*phdib);
return FALSE;
}
hbm = SelectObject(hdcMem, hbm);

// Don't need hdc anymore (but still need hdcMem)
ReleaseDC(NULL, hdc);

// Initialize bitmap to black
PatBlt(hdcMem, 0, 0, (int) lWidth, (int) lHeight, BLACKNESS);

// Set up coordinates for StretchDIBits
if (wMode&IDB_STRETCH)
{ // Use full width & height for both src and dst
dx = dy = 0;
dw = (int) lWidth;
dh = (int) lHeight;
sx = sy = 0;
sw = (int) lpbi->biWidth;
sh = (int) lpbi->biHeight;
}
else if (wMode&IDB_TILE)
{ // All source and destination coordinates are the same
dx = dy = sx = sy = 0;
dw = sw = (int) lpbi->biWidth;
dh = sh = (int) lpbi->biHeight;
}
else // IDB_FILL (default)
{ // No stretching, want intersection instead
sw = dw = (int) min(lWidth, lpbi->biWidth);
sh = dh = (int) min(lHeight, lpbi->biHeight);

sy = 0;
dy = (int) ((lHeight - lpbi->biHeight) >> 1);
if (dy < 0)
{
sy = -dy;
dy = 0;
}

sx = 0;
dx = (int) ((lWidth - lpbi->biWidth) >> 1);
if (dx < 0)
{
sx = -dx;
dx = 0;
}
}

StretchDIBits(hdcMem, dx, dy, dw, dh, sx, sy, sw, sh, hpBits,
(LPBITMAPINFO) lpbi, DIB_PAL_COLORS, SRCCOPY);

if (wMode&IDB_TILE)
{
// Copy from the upper left corner across the top of the bitmap.

for ( dw = (int) lpbi->biWidth;
dw < (int) lWidth;
dw += (int) lpbi->biWidth )
BitBlt(hdcMem, dw, 0, (int)lpbi->biWidth, (int)lpbi->biHeight, hdcMem, 0, 0, SRCCOPY);

// Copy the new 'top row' of the bitmap down to the rest of the bitmap.

for ( dw = (int) lpbi->biHeight;
dw < (int) lHeight;
dw += (int) lpbi->biHeight )
BitBlt(hdcMem, 0, dw, (int)lWidth, (int)lpbi->biHeight, hdcMem, 0, 0, SRCCOPY);
}

// Make sure bitmap isn't selected into a DC for GetDIBits
hbm = SelectObject(hdcMem, hbm);

// Set new width & height in BITMAPINFOHEADER
lpbi->biWidth = lWidth;
lpbi->biHeight = lHeight;

// Get device independent bits from bitmap
if (!GetDIBits(hdcMem, hbm, 0, (UINT) lHeight, hpBits,
(LPBITMAPINFO) lpbi, DIB_PAL_COLORS))
{
DeleteObject(SelectPalette(hdcMem, hpal, FALSE));
DeleteObject(hbm);
DeleteDC(hdcMem);
GlobalUnlock(*phdib);
return FALSE;
}

// Clean up and we're done
DeleteObject(SelectPalette(hdcMem, hpal, FALSE));
DeleteObject(hbm);
DeleteDC(hdcMem);
GlobalUnlock(*phdib);

return TRUE; // success
}


  3 Responses to “Category : C Source Code
Archive   : FADE.ZIP
Filename : OPTIONS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/