397 lines
9.7 KiB
C
397 lines
9.7 KiB
C
|
/*
|
||
|
**************************************************************************
|
||
|
*
|
||
|
* dispfram.c
|
||
|
*
|
||
|
* DispFrame Control DLL defines a bitmap display control to be used
|
||
|
* by any windows application.
|
||
|
*
|
||
|
* Copyright 1991-3, Microsoft Corporation
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* In Sik Rhee - 7/15/91 (original slider.dll)
|
||
|
* Ben Mejia - 1/22/92 (made display.dll)
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
#pragma warning(disable:4704)
|
||
|
#include <windows.h>
|
||
|
#include <custcntl.h>
|
||
|
#include <commctrl.h>
|
||
|
#include "draw.h"
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* global static variables
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
UINT gwPm_DispFrame;
|
||
|
extern HINSTANCE ghInstance;
|
||
|
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* prototypes
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
|
||
|
LONG PASCAL dfPaint (HWND hWnd);
|
||
|
LONG PASCAL dfSetBitmap (HWND hWnd, HBITMAP hBmpNew, HPALETTE
|
||
|
hPalNew);
|
||
|
BOOL PASCAL RegSndCntrlClass (LPCTSTR lpszSndCntrlClass);
|
||
|
LRESULT PASCAL dfDispFrameWndFn (HWND hWnd, UINT wMessage, WPARAM wParam,
|
||
|
LPARAM lParam);
|
||
|
BOOL dfDrawRect (HDC hdcRect, RECT rFrame);
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* RegSndCntrlClass
|
||
|
*
|
||
|
* Description: Registers the SndCntrlClass, must be called in LibMain
|
||
|
*
|
||
|
* Arguments:
|
||
|
* LPTSTR lpszSndCntrlClass
|
||
|
*
|
||
|
* Returns: BOOL
|
||
|
* TRUE if RegisterClass succeeds, else FALSE
|
||
|
*
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
BOOL PASCAL RegSndCntrlClass(LPCTSTR lpszSndCntrlClass)
|
||
|
{
|
||
|
|
||
|
extern UINT gwPm_DispFrame;
|
||
|
|
||
|
/* local variables */
|
||
|
WNDCLASS ClassStruct;
|
||
|
|
||
|
/* check to see if class already exists; if so, simply return TRUE */
|
||
|
if (GetClassInfo(ghInstance, lpszSndCntrlClass, &ClassStruct))
|
||
|
return TRUE;
|
||
|
|
||
|
/* define dispfram class attributes */
|
||
|
ClassStruct.lpszClassName = (LPTSTR)DISPFRAMCLASS;
|
||
|
ClassStruct.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||
|
ClassStruct.lpszMenuName = (LPTSTR)NULL;
|
||
|
ClassStruct.style = CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS;
|
||
|
ClassStruct.lpfnWndProc = dfDispFrameWndFn;
|
||
|
ClassStruct.hInstance = ghInstance;
|
||
|
ClassStruct.hIcon = NULL;
|
||
|
ClassStruct.cbWndExtra = DF_DISP_EXTRA;
|
||
|
ClassStruct.cbClsExtra = 0;
|
||
|
ClassStruct.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1 );
|
||
|
|
||
|
/* register display frame window class */
|
||
|
if (!RegisterClass(&ClassStruct))
|
||
|
return FALSE;
|
||
|
gwPm_DispFrame = RegisterWindowMessage((LPTSTR) DF_WMDISPFRAME);
|
||
|
|
||
|
if (!gwPm_DispFrame) /* failed to create message */
|
||
|
return FALSE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* dfDispFrameWndFn
|
||
|
*
|
||
|
* Description: Window function for display frame control.
|
||
|
*
|
||
|
* Arguments:
|
||
|
* HWND hWnd - handle to control window.
|
||
|
* UINT wMessage - the message
|
||
|
* WPARAM wParam
|
||
|
* LPARAM lParam
|
||
|
* Returns: LONG
|
||
|
* result of message processing... depends on message sent.
|
||
|
*
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
|
||
|
LRESULT PASCAL dfDispFrameWndFn(HWND hWnd, UINT wMessage, WPARAM wParam,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
HBITMAP hBmp;
|
||
|
|
||
|
switch (wMessage)
|
||
|
{
|
||
|
case WM_CREATE:
|
||
|
DF_SET_BMPHANDLE(0);
|
||
|
DF_SET_BMPPAL(0);
|
||
|
return 0;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
/* Free up stored bitmap and palette, if any.
|
||
|
*/
|
||
|
hBmp = (HBITMAP)DF_GET_BMPHANDLE;
|
||
|
if (hBmp)
|
||
|
DeleteObject(hBmp);
|
||
|
return 0;
|
||
|
|
||
|
case WM_SYSCOLORCHANGE:
|
||
|
InvalidateRect(hWnd, NULL, TRUE);
|
||
|
return 0;
|
||
|
|
||
|
case WM_PAINT:
|
||
|
return dfPaint(hWnd);
|
||
|
|
||
|
/* Custom Control Messages */
|
||
|
case DF_PM_SETBITMAP:
|
||
|
return dfSetBitmap(hWnd, (HBITMAP)wParam, (HPALETTE)lParam);
|
||
|
}
|
||
|
return DefWindowProc(hWnd, wMessage, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* dfDrawRect
|
||
|
*
|
||
|
* Description: Draws background of control window.
|
||
|
*
|
||
|
* Params:
|
||
|
* HWND hWnd - handle to control window.
|
||
|
* RECT rFrame - bounding rectangle.
|
||
|
*
|
||
|
* Returns: BOOL
|
||
|
* Pass/Fail indicator 0 indicates failure.
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
BOOL dfDrawRect(HDC hdcRect, RECT rFrame)
|
||
|
{
|
||
|
HANDLE hBrush;
|
||
|
HANDLE hOldBrush;
|
||
|
HANDLE hPen;
|
||
|
HANDLE hOldPen;
|
||
|
HANDLE hPen3DHILIGHT;
|
||
|
|
||
|
/* Get DC's pen and brush for frame redraw
|
||
|
*/
|
||
|
hBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
|
||
|
if (!hBrush)
|
||
|
return FALSE;
|
||
|
hPen = CreatePen(PS_SOLID, 2, GetSysColor(COLOR_WINDOWFRAME));
|
||
|
|
||
|
if (!hPen)
|
||
|
{
|
||
|
DeleteObject(hBrush);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hPen3DHILIGHT = CreatePen(PS_SOLID, 2, GetSysColor(COLOR_3DHILIGHT));
|
||
|
|
||
|
if (!hPen3DHILIGHT)
|
||
|
{
|
||
|
DeleteObject(hBrush);
|
||
|
DeleteObject(hPen);
|
||
|
return FALSE;
|
||
|
}
|
||
|
hOldBrush = SelectObject(hdcRect, hBrush);
|
||
|
//hOldPen = SelectObject(hdcRect, hPen);
|
||
|
hOldPen = SelectObject(hdcRect, hPen3DHILIGHT);
|
||
|
|
||
|
/* paint the window.
|
||
|
*/
|
||
|
//Rectangle(hdcRect, rFrame.left, rFrame.top, rFrame.right,
|
||
|
// rFrame.bottom);
|
||
|
MoveToEx(hdcRect, rFrame.left,rFrame.bottom, NULL);
|
||
|
LineTo(hdcRect, rFrame.right,rFrame.bottom);
|
||
|
LineTo(hdcRect, rFrame.right,rFrame.top);
|
||
|
SelectObject(hdcRect, hPen);
|
||
|
LineTo(hdcRect, rFrame.left,rFrame.top);
|
||
|
LineTo(hdcRect, rFrame.left,rFrame.bottom);
|
||
|
SelectObject(hdcRect, hOldPen);
|
||
|
SelectObject(hdcRect, hOldBrush);
|
||
|
|
||
|
/*clean up brush and pen */
|
||
|
//DeleteObject();
|
||
|
DeleteObject(hBrush);
|
||
|
DeleteObject(hPen3DHILIGHT);
|
||
|
DeleteObject(hPen);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* dfPaint
|
||
|
*
|
||
|
* Description: Paints background and bitmap, if any.
|
||
|
*
|
||
|
* Params:
|
||
|
* HWND hWnd - handle to control window
|
||
|
*
|
||
|
* Returns: LONG
|
||
|
* 0 if OK, -1 otherwise. (for windproc return)
|
||
|
*
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
LONG PASCAL dfPaint(HWND hWnd)
|
||
|
{
|
||
|
HBITMAP hBmp;
|
||
|
HBITMAP hPrev;
|
||
|
RECT rFrame;
|
||
|
PAINTSTRUCT ps;
|
||
|
HDC hdcMem;
|
||
|
BITMAP bmp;
|
||
|
int x, y, dx, dy;
|
||
|
|
||
|
/* Setup to do the painting
|
||
|
*/
|
||
|
if(!GetUpdateRect(hWnd,NULL,FALSE))
|
||
|
return 0L;
|
||
|
BeginPaint(hWnd, &ps);
|
||
|
GetClientRect(hWnd, &rFrame);
|
||
|
hBmp = (HBITMAP)DF_GET_BMPHANDLE;
|
||
|
if (hBmp)
|
||
|
{
|
||
|
hdcMem = CreateCompatibleDC(ps.hdc);
|
||
|
if (!hdcMem)
|
||
|
{
|
||
|
EndPaint(hWnd, &ps);
|
||
|
return -1L;
|
||
|
}
|
||
|
hPrev = SelectObject(hdcMem, hBmp);
|
||
|
|
||
|
/* Get the size of the bitmap to center it in the frame.
|
||
|
*/
|
||
|
GetObject(hBmp, sizeof(BITMAP), (LPTSTR)&bmp);
|
||
|
if (bmp.bmWidth > (rFrame.right-rFrame.left))
|
||
|
{
|
||
|
x = 0;
|
||
|
dx = rFrame.right-rFrame.left;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
x = ((rFrame.right-rFrame.left - bmp.bmWidth) >> 1);
|
||
|
dx = bmp.bmWidth;
|
||
|
}
|
||
|
if (bmp.bmHeight > (rFrame.bottom-rFrame.top))
|
||
|
{
|
||
|
y = 0;
|
||
|
dy = rFrame.bottom-rFrame.top;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
y = ((rFrame.bottom-rFrame.top - bmp.bmHeight) >> 1);
|
||
|
dy = bmp.bmHeight;
|
||
|
}
|
||
|
|
||
|
/* Draw the frame & background, then blt in the bitmap.
|
||
|
*/
|
||
|
dfDrawRect(ps.hdc, rFrame);
|
||
|
BitBlt(ps.hdc, x, y, dx, dy, hdcMem, 0, 0, SRCCOPY);
|
||
|
|
||
|
/* Cleanup and exit.
|
||
|
*/
|
||
|
SelectObject(hdcMem, hPrev);
|
||
|
DeleteDC(hdcMem);
|
||
|
}
|
||
|
else
|
||
|
/* if no bitmap, just repaint the background.
|
||
|
*/
|
||
|
dfDrawRect(ps.hdc, rFrame);
|
||
|
|
||
|
EndPaint(hWnd, &ps);
|
||
|
return 0L;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
**************************************************************************
|
||
|
* dfSetBitmap
|
||
|
*
|
||
|
* Description: Load a new bitmap into the control.
|
||
|
*
|
||
|
* Arguments:
|
||
|
* HWND hWnd - handle to control window.
|
||
|
* HBITMAP hBmpNew - handle to new bitmap.
|
||
|
* HPALETTE hPalNew - handle to new bitmap's palette (Optional).
|
||
|
* Returns: LONG
|
||
|
* 0 for success; -1 if fails (for return by wndproc).
|
||
|
*
|
||
|
**************************************************************************
|
||
|
*/
|
||
|
LONG PASCAL dfSetBitmap(HWND hWnd, HBITMAP hBmpNew, HPALETTE hPalNew)
|
||
|
{
|
||
|
HBITMAP hBmp;
|
||
|
HANDLE hPrev;
|
||
|
HANDLE hPrevNew;
|
||
|
HDC hdcMem;
|
||
|
HDC hdcNew;
|
||
|
HDC hDC;
|
||
|
RECT rFrame;
|
||
|
int dx, dy;
|
||
|
BITMAP bmp;
|
||
|
|
||
|
/* Cleanup any existing bitmap & palette
|
||
|
*/
|
||
|
hBmp = (HBITMAP)DF_GET_BMPHANDLE;
|
||
|
if (hBmp)
|
||
|
DeleteObject(hBmp);
|
||
|
DF_SET_BMPHANDLE(0);
|
||
|
DF_SET_BMPPAL(0);
|
||
|
InvalidateRect(hWnd, NULL, TRUE);
|
||
|
|
||
|
/* Copy the displayable portion of the bitmap into a private copy.
|
||
|
*/
|
||
|
if (hBmpNew)
|
||
|
{
|
||
|
/* get all the req'd DC's etc.
|
||
|
*/
|
||
|
hDC = GetDC(hWnd);
|
||
|
hdcMem = CreateCompatibleDC(hDC);
|
||
|
if (!hdcMem)
|
||
|
{
|
||
|
ReleaseDC(hWnd, hDC);
|
||
|
return -1L;
|
||
|
}
|
||
|
hdcNew = CreateCompatibleDC(hDC);
|
||
|
if (!hdcNew)
|
||
|
{
|
||
|
ReleaseDC(hWnd, hDC);
|
||
|
return -1L;
|
||
|
}
|
||
|
GetObject(hBmpNew, sizeof(BITMAP), (LPTSTR)&bmp);
|
||
|
hBmp = CreateCompatibleBitmap(hDC, bmp.bmWidth, bmp.bmHeight);
|
||
|
if (!hBmp)
|
||
|
{
|
||
|
DeleteDC(hdcMem);
|
||
|
DeleteDC(hdcNew);
|
||
|
ReleaseDC(hWnd, hDC);
|
||
|
return -1L;
|
||
|
}
|
||
|
hPrevNew = SelectObject(hdcNew, hBmpNew);
|
||
|
hPrev = SelectObject(hdcMem, hBmp);
|
||
|
|
||
|
/* figure out how much of the bitmap we need to copy.
|
||
|
*/
|
||
|
GetClientRect(hWnd, &rFrame);
|
||
|
if (bmp.bmWidth > (rFrame.right-rFrame.left))
|
||
|
dx = rFrame.right-rFrame.left;
|
||
|
else
|
||
|
dx = bmp.bmWidth;
|
||
|
if (bmp.bmHeight > (rFrame.bottom-rFrame.top))
|
||
|
dy = rFrame.bottom-rFrame.top;
|
||
|
else
|
||
|
dy = bmp.bmHeight;
|
||
|
|
||
|
/* copy the bitmap.
|
||
|
*/
|
||
|
BitBlt(hdcMem, 0, 0, dx, dy, hdcNew, 0 , 0, SRCCOPY);
|
||
|
|
||
|
/* cleanup
|
||
|
*/
|
||
|
hBmp = SelectObject(hdcMem, hPrev);
|
||
|
DF_SET_BMPHANDLE(hBmp);
|
||
|
DeleteDC(hdcMem);
|
||
|
SelectObject(hdcNew, hPrevNew);
|
||
|
DeleteDC(hdcNew);
|
||
|
ReleaseDC(hWnd, hDC);
|
||
|
|
||
|
/* if a palette is handed in, store it too.
|
||
|
*/
|
||
|
DF_SET_BMPPAL(hPalNew);
|
||
|
}
|
||
|
return 0L;
|
||
|
}
|
||
|
|