File:  [WindowsNT SDKs] / mstools / samples / sdktools / imagedit / util.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:24:28 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-nov-1993, ntsdk-jul-1993, HEAD
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993

/****************************************************************************/
/*                                                                          */
/*                         Microsoft Confidential                           */
/*                                                                          */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
/****************************** Module Header *******************************
* Module Name: util.c
*
* Contains miscellaneous utility functions for ImagEdit.
*
* History:
*
****************************************************************************/

#include "imagedit.h"

#include <stdio.h>
#include <stdarg.h>

#define CBOVERHEAD      (sizeof(INT)+sizeof(INT)+sizeof(INT))
#define MEMSIGHEAD      0x1234
#define MEMSIGTAIL      0x5678



/****************************************************************************
* MyAlloc
*
*
*
* History:
*  25-Jul-1989   - Created
****************************************************************************/

VOID *MyAlloc(
    INT cbAlloc)
{
    register HANDLE hMem;

    if (hMem = LocalAlloc(LMEM_FIXED, cbAlloc)) {
        return (VOID *)hMem;
    }
    else {
        MessageBeep(0);
        Message(MSG_OUTOFMEMORY);

        return NULL;
    }
}



/****************************************************************************
* MyRealloc
*
*
*
* History:
*  25-Jul-1989   - Created
****************************************************************************/

VOID *MyRealloc(
    VOID *npMem,
    INT cbNewAlloc)
{
    npMem = (VOID *)LocalReAlloc((HANDLE)npMem, cbNewAlloc, LMEM_MOVEABLE);

    if (!npMem) {
        MessageBeep(0);
        Message(MSG_OUTOFMEMORY);

        return NULL;
    }

    return npMem;
}



/****************************************************************************
* MyFree
*
*
* History:
*  25-Jul-1989   - Created
****************************************************************************/

VOID *MyFree(
    VOID *npMem)
{
    if (LocalFree((HANDLE)npMem)) {
        MessageBeep(0);
        Message(MSG_MEMERROR);

        return npMem;
    }

    return NULL;
}



/************************************************************************
* Message
*
* This function puts up a message box.  The message is described in
* the gamdMessages table.
*
* Arguments:
*   UINT idMsg - Index to the message.
*   ...        - Optional arguments.
*
* Returns:
*     What MessageBox returns.
*
************************************************************************/

INT Message(
    UINT idMsg,
    ...)
{
    va_list marker;
    INT RetCode;
    CHAR szT[CCHTEXTMAX];

    va_start(marker, idMsg);
    vsprintf(szT, ids(gamdMessages[idMsg].ids), marker);

    RetCode = MessageBox(NULL, szT, ids(IDS_PGMTITLE),
            gamdMessages[idMsg].fMessageBox | MB_TASKMODAL);

    va_end(marker);

    return RetCode;
}



/************************************************************************
* CenterWindow
*
* This function centers the given window over its owner.  It ensures
* that the window is entirely within the visible screen, however.
* If the window does not have an owner, it is centered over the
* desktop.
*
* Arguments:
*   HWND hwnd - The window to center.
*
* History:
*
************************************************************************/

VOID CenterWindow(
    HWND hwnd)
{
    RECT rc;
    RECT rcOwner;
    RECT rcCenter;
    HWND hwndOwner;

    GetWindowRect(hwnd, &rc);

    if (!(hwndOwner = GetWindow(hwnd, GW_OWNER)))
        hwndOwner = GetDesktopWindow();

    GetWindowRect(hwndOwner, &rcOwner);

    /*
     *  Calculate the starting x,y for the new
     *  window so that it would be centered.
     */
    rcCenter.left = rcOwner.left +
            (((rcOwner.right - rcOwner.left) -
            (rc.right - rc.left))
            / 2);

    rcCenter.top = rcOwner.top +
            (((rcOwner.bottom - rcOwner.top) -
            (rc.bottom - rc.top))
            / 2);

    rcCenter.right = rcCenter.left + (rc.right - rc.left);
    rcCenter.bottom = rcCenter.top + (rc.bottom - rc.top);

    FitRectToScreen(&rcCenter);

    SetWindowPos(hwnd, NULL, rcCenter.left, rcCenter.top, 0, 0,
            SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
}



/************************************************************************
* FitRectToScreen
*
* This function ensures that the given rectangle is entirely within
* the visible screen, adjusting it if necessary.
*
* Arguments:
*   PRECT prc - The rectangle.
*
* History:
*
************************************************************************/

VOID FitRectToScreen(
    PRECT prc)
{
    INT cxScreen;
    INT cyScreen;
    INT delta;

    cxScreen = GetSystemMetrics(SM_CXSCREEN);
    cyScreen = GetSystemMetrics(SM_CYSCREEN);

    if (prc->right > cxScreen) {
        delta = prc->right - prc->left;
        prc->right = cxScreen;
        prc->left = prc->right - delta;
    }

    if (prc->left < 0) {
        delta = prc->right - prc->left;
        prc->left = 0;
        prc->right = prc->left + delta;
    }

    if (prc->bottom > cyScreen) {
        delta = prc->bottom - prc->top;
        prc->bottom = cyScreen;
        prc->top = prc->bottom - delta;
    }

    if (prc->top < 0) {
        delta = prc->bottom - prc->top;
        prc->top = 0;
        prc->bottom = prc->top + delta;
    }
}



/************************************************************************
* ids
*
* This function will return a string, given the string id.  If this is
* the first time that the string has been retrieved, memory will be
* allocated for it and it will be loaded.  After it is loaded once, it
* is then cached in a PSTR array and is available for later without
* having to load it again.
*
* Arguments:
*   UINT idString - String ID of the string to retrieve.
*
* History:
*
************************************************************************/

PSTR ids(
    UINT idString)
{
    static PSTR apstr[CSTRINGS];        // String resource array cache.
    PSTR pstr;
    INT cch;

    if (apstr[idString])
        return apstr[idString];

    if (!(pstr = MyAlloc(CCHTEXTMAX)))
        return "";

    if (!(cch = LoadString(ghInst, idString, pstr, CCHTEXTMAX))) {
        MyFree(pstr);
        return "";
    }

    apstr[idString] = pstr = MyRealloc(pstr, cch + 1);

    return (pstr ? pstr : "");
}



/************************************************************************
* MyCreateBitmap
*
*
*
* Arguments:
*
* History:
*
************************************************************************/

HBITMAP MyCreateBitmap(
    HDC hdc,
    INT cx,
    INT cy,
    INT nColors)
{
    BITMAPINFOHEADER bmih;

    if (nColors == 2) {
        return CreateBitmap(cx, cy, 1, 1, NULL);
    }
    else {
        bmih.biSize = sizeof(BITMAPINFOHEADER);
        bmih.biWidth = cx;
        bmih.biHeight = cy;
        bmih.biPlanes = 1;              // 1 plane, 4 bpp is
        bmih.biBitCount = 4;            // 16 colors.

        bmih.biCompression =
        bmih.biSizeImage =
        bmih.biXPelsPerMeter =
        bmih.biYPelsPerMeter =
        bmih.biClrUsed =
        bmih.biClrImportant = 0;

        return CreateDIBitmap(hdc, &bmih, 0L, NULL, NULL, 0);
    }
}



#if defined(DBG) && defined(WIN16)
/****************************************************************************
* DBGStackReport
*
* This debugging function reports how much stack is used by a program.
* To use it, call it with fInit == TRUE right at the beginning of the
* program and then with fInit == FALSE just before the program exits.
* The stack space used during the current run of the program will be
* displayed on the debug terminal.
*
* It is implemented by filling the stack with a certain value down to
* the bottom of the stack (if fInit is TRUE).  When it is called with
* fInit == FALSE, it starts at the bottom of the stack and looks for
* where this "signature" value has been overwritten with data, then
* does a little math to compute the used stack.
*
* Arguments:
*   BOOL fInit - TRUE if the stack should be initialized, FALSE to
*                print out the report.
*
* History:
*  28-Aug-1990  - Created
****************************************************************************/

/*
 * This signature byte will be used to fill the stack.
 */
#define STACKSIG    'A'

/*
 * This is a C runtime global that is always at the very end of the
 * global data.  Taking its address is a way that the "bottom" of the
 * stack can be found.
 */
extern CHAR end;

VOID DBGStackReport(
    BOOL fInit)
{
    static PBYTE pbStackTop;
    PBYTE pb;
    BYTE bDummy;

    if (fInit) {
        /*
         * The address of one of this functions local variables is
         * taken and considered the "top" of the stack.  This means
         * that it will work best when it is called first thing in
         * the program.
         */
        pbStackTop = pb = &bDummy;

        /*
         * Fill the stack up.
         */
        while (pb > &end)
            *pb-- = STACKSIG;
    }
    else {
        /*
         * Start at the bottom of the stack and search upwards.
         */
        pb = &end;
        while (*(++pb) == STACKSIG && pb < pbStackTop)
            ;

        /*
         * Display the results.
         */
        DBGprintf("ImagEdit stack used: %d bytes.", pbStackTop - pb);
    }
}
#endif



#ifdef DBG
/****************************************************************************
* DBGBltImage
*
* This debugging function blits out the given image in the specified
* DC to the screen.  Every time that it is called, it will blit the
* image to the right of the last one, starting at the top of the
* screen.  It assumes that each image is 32x32 pixels.
*
* Arguments:
*   HDC hdc - The DC with the image to blit.  If this is NULL, the
*             current XOR and AND images are blit'd, with the AND
*             image below the XOR image.
*
* History:
*  16-Sep-1991  - Created
****************************************************************************/

VOID DBGBltImage(
    HDC hdc)
{
    static INT x;
    HDC hdcScreen;

    hdcScreen = GetDC(NULL);

    if (hdc) {
        BitBlt(hdcScreen, x, 0, 32, 32, hdc, 0, 0, SRCCOPY);
    }
    else {
        BitBlt(hdcScreen, x, 0, 32, 32, ghdcImage, 0, 0, SRCCOPY);
        BitBlt(hdcScreen, x, 32 + 1, 32, 32, ghdcANDMask, 0, 0, SRCCOPY);
    }

    ReleaseDC(NULL, hdcScreen);
    x += 32 + 1;
}



/****************************************************************************
* DBGprintf
*
* This debugging function prints out a string to the debug output.
* An optional set of substitutional parameters can be specified,
* and the final output will be the processed result of these combined
* with the format string, just like printf.  A newline is always
* output after every call to this function.
*
* Arguments:
*   PSTR fmt - Format string (printf style).
*   ...      - Variable number of arguments.
*
* History:
*  28-Aug-1990  - Created
****************************************************************************/

VOID DBGprintf(PSTR fmt, ...)
{
    va_list marker;
    CHAR szBuf[CCHTEXTMAX];

    va_start(marker, fmt);
    vsprintf(szBuf, fmt, marker);
    va_end(marker);

    OutputDebugString(szBuf);
    OutputDebugString("\r\n");
}
#endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.