PROPBAR.C

/****************************************************************************/ 
/* */
/* Copyright (C) 1987-1996 Microsoft Corp. */
/* All Rights Reserved */
/* */
/****************************************************************************/
/****************************** Module Header *******************************
* Module Name: propbar.c
*
* Support for the Properties Bar.
*
* History:
*
****************************************************************************/

#include "imagedit.h"
#include "dialogs.h"

#include <windowsx.h>

#define IMPOSSIBLEVALUE 0x7FFF

STATICFN VOID NEAR PropBarProcessCommand(HWND hwnd, INT idCtrl,
INT NotifyCode);

/*
* Cache variables. These cache the values of some displayed fields.
* The field is updated only if the value changes, which avoids flicker.
* They are initialized to a large value so that the first "set" to
* any value will always cause the field to be updated.
*/
static INT xSave = IMPOSSIBLEVALUE;
static INT ySave = IMPOSSIBLEVALUE;
static INT cxSave = IMPOSSIBLEVALUE;
static INT cySave = IMPOSSIBLEVALUE;
static INT xHotSpotSave = IMPOSSIBLEVALUE;
static INT yHotSpotSave = IMPOSSIBLEVALUE;



/************************************************************************
* PropBarDlgProc
*
* This is the dialog procedure for the PropBar ribbon window.
*
* History:
*
************************************************************************/

DIALOGPROC PropBarDlgProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
/*
* Set this global right away. Other routines that
* might be called before CreateDialog returns depend
* on this global.
*/
ghwndPropBar = hwnd;

PropBarUpdate();

/*
* Return TRUE so that the dialog manager does NOT
* set the focus for me. This prevents the PropBar
* window from initially having the focus when the
* editor is started.
*/
return TRUE;

case WM_PAINT:
{
HDC hdc;
RECT rc;
PAINTSTRUCT ps;
HPEN hpenWindowFrame;

/*
* Draw our border lines.
*/
GetClientRect(hwnd, &rc);
hdc = BeginPaint(hwnd, &ps);

SelectObject(hdc, GetStockObject(WHITE_PEN));
MoveToEx(hdc, rc.left, rc.top, NULL);
LineTo(hdc, rc.right, rc.top);

SelectObject(hdc, hpenDarkGray);
MoveToEx(hdc, rc.left, (rc.top + gcyPropBar) - gcyBorder - 1, NULL);
LineTo(hdc, rc.right, (rc.top + gcyPropBar) - gcyBorder - 1);

hpenWindowFrame = CreatePen(PS_SOLID, gcyBorder,
GetSysColor(COLOR_WINDOWFRAME));
SelectObject(hdc, hpenWindowFrame);
MoveToEx(hdc, rc.left, (rc.top + gcyPropBar) - gcyBorder, NULL);
LineTo(hdc, rc.right, (rc.top + gcyPropBar) - gcyBorder);

EndPaint(hwnd, &ps);
DeleteObject(hpenWindowFrame);
}

break;

case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORSTATIC:
switch (GET_WM_CTLCOLOR_TYPE(wParam, lParam, msg)) {
case CTLCOLOR_BTN:
case CTLCOLOR_DLG:
case CTLCOLOR_LISTBOX:
return (BOOL)GetStockObject(LTGRAY_BRUSH);

case CTLCOLOR_STATIC:
SetBkColor(GET_WM_CTLCOLOR_HDC(wParam, lParam, msg),
RGB_LIGHTGRAY);
return (BOOL)GetStockObject(LTGRAY_BRUSH);
}

return (BOOL)NULL;

case WM_COMMAND:
PropBarProcessCommand(hwnd,
GET_WM_COMMAND_ID(wParam, lParam),
GET_WM_COMMAND_CMD(wParam, lParam));
break;

case WM_DESTROY:
/*
* Null out the global window handle for the prop bar
* for safety's sake.
*/
ghwndPropBar = NULL;

break;

default:
return FALSE;
}

return FALSE;
}



/************************************************************************
* PropBarProcessCommand
*
*
* Arguments:
* HWND hwnd - The window handle.
* INT idCtrl - The id of the control the WM_COMMAND is for.
* INT NotifyCode - The control's notification code.
*
* History:
*
************************************************************************/

STATICFN VOID NEAR PropBarProcessCommand(
HWND hwnd,
INT idCtrl,
INT NotifyCode)
{
INT iSelect;
PIMAGEINFO pImage;

switch (idCtrl) {
case DID_PROPBARIMAGE:
if (NotifyCode == CBN_SELCHANGE) {
if ((iSelect = (INT)SendDlgItemMessage(hwnd,
DID_PROPBARIMAGE, CB_GETCURSEL, 0, 0L)) != CB_ERR) {
/*
* Get a pointer to the selected image (stored in the
* listbox items data field).
*/
pImage = (PIMAGEINFO)SendDlgItemMessage(hwnd,
DID_PROPBARIMAGE, CB_GETITEMDATA, iSelect, 0L);

/*
* Open the image. If it fails, be sure to set the
* combobox selection back to the current image.
*/
if (!ImageOpen(pImage)) {
PropBarSetImage(gpImageCur);
break;
}

SetFocus(ghwndMain);
}
}

break;

case IDOK:
case IDCANCEL:
SetFocus(ghwndMain);
break;
}
}



/************************************************************************
* PropBarUpdate
*
* This function updates the Properties Bar for the selection of a
* new image or file. It fills the Image combo with the names of
* the images in the current file and shows/hides the HotSpot display.
*
* History:
*
************************************************************************/

VOID PropBarUpdate(VOID)
{
HWND hwndCombo;
PIMAGEINFO pImage;
INT idLabel;
INT i;

if (gpImageCur || gpszFileName) {
switch (giType) {
case FT_BITMAP:
idLabel = IDS_BITMAPIMAGELABEL;
break;

case FT_ICON:
idLabel = IDS_ICONIMAGELABEL;
break;

case FT_CURSOR:
idLabel = IDS_CURSORIMAGELABEL;
break;
}
}
else {
idLabel = IDS_NULL;
}

SetDlgItemText(ghwndPropBar, DID_PROPBARIMAGELABEL, ids(idLabel));

/*
* Get the handle to the combo box and clear out all items.
*/
hwndCombo = GetDlgItem(ghwndPropBar, DID_PROPBARIMAGE);
SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);

/*
* Fill the combo box with the images.
*/
for (pImage = gpImageHead; pImage; pImage = pImage->pImageNext) {
i = (INT)SendMessage(hwndCombo, CB_INSERTSTRING, (WPARAM)-1,
pImage->pDevice ?
(DWORD)(LPSTR)pImage->pDevice->szDesc :
(DWORD)(LPSTR)ids(IDS_UNKNOWNIMAGEFORMAT));

SendMessage(hwndCombo, CB_SETITEMDATA, i, (DWORD)(LPSTR)pImage);
}

/*
* Select the current image.
*/
PropBarSetImage(gpImageCur);

/*
* Show/Hide the HotSpot info depending on whether this is
* a cursor or not.
*/
if (giType == FT_CURSOR) {
if (gpImageCur)
PropBarSetHotSpot(gpImageCur->iHotspotX, gpImageCur->iHotspotY);
else
PropBarClearHotSpot();

PropBarShowHotSpot(TRUE);
}
else {
PropBarShowHotSpot(FALSE);
}
}



/************************************************************************
* PropBarSetImage
*
*
* History:
*
************************************************************************/

VOID PropBarSetImage(
PIMAGEINFO pImage)
{
if (pImage)
SendDlgItemMessage(ghwndPropBar, DID_PROPBARIMAGE, CB_SELECTSTRING,
(WPARAM)-1, (DWORD)(LPSTR)pImage->pDevice->szDesc);
else
SendDlgItemMessage(ghwndPropBar, DID_PROPBARIMAGE, CB_SETCURSEL,
(WPARAM)-1, 0);
}



/************************************************************************
* PropBarSetPos
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarSetPos(
INT x,
INT y)
{
CHAR szBuf[CCHTEXTMAX];

if (x != xSave || y != ySave) {
wsprintf(szBuf, "%d, %d", x, y);
SetDlgItemText(ghwndPropBar, DID_PROPBARPOS, szBuf);

/*
* Save them for the next time.
*/
xSave = x;
ySave = y;
}
}



/************************************************************************
* PropBarClearPos
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarClearPos(VOID)
{
SetDlgItemText(ghwndPropBar, DID_PROPBARPOS, "");

/*
* Reset the cache variables so that the next "set" of
* the position is sure to update the display fields.
*/
xSave = IMPOSSIBLEVALUE;
ySave = IMPOSSIBLEVALUE;
}



/************************************************************************
* PropBarSetSize
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarSetSize(
POINT pt1,
POINT pt2)
{
CHAR szBuf[CCHTEXTMAX];
INT cx;
INT cy;

NormalizePoints(&pt1, &pt2);
cx = ((pt2.x - pt1.x) / gZoomFactor) + 1;
cy = ((pt2.y - pt1.y) / gZoomFactor) + 1;

if (cx != cxSave || cy != cySave) {
wsprintf(szBuf, "%dx%d", cx, cy);
SetDlgItemText(ghwndPropBar, DID_PROPBARSIZE, szBuf);

/*
* Save them for the next time.
*/
cxSave = cx;
cySave = cy;
}
}



/************************************************************************
* PropBarClearSize
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarClearSize(VOID)
{
SetDlgItemText(ghwndPropBar, DID_PROPBARSIZE, "");

/*
* Reset the cache variables so that the next "set" of
* the position is sure to update the display fields.
*/
cxSave = IMPOSSIBLEVALUE;
cySave = IMPOSSIBLEVALUE;
}



/************************************************************************
* PropBarSetHotSpot
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarSetHotSpot(
INT xHotSpot,
INT yHotSpot)
{
CHAR szBuf[CCHTEXTMAX];

if (xHotSpot != xHotSpotSave || yHotSpot != yHotSpotSave) {
wsprintf(szBuf, "%d, %d", xHotSpot, yHotSpot);
SetDlgItemText(ghwndPropBar, DID_PROPBARHOTSPOT, szBuf);

/*
* Save them for the next time.
*/
xHotSpotSave = xHotSpot;
yHotSpotSave = yHotSpot;
}
}



/************************************************************************
* PropBarClearHotSpot
*
*
* Arguments:
*
* History:
*
************************************************************************/

VOID PropBarClearHotSpot(VOID)
{
SetDlgItemText(ghwndPropBar, DID_PROPBARHOTSPOT, "");

/*
* Reset the cache variables so that the next "set" of
* the hotspot is sure to update the display fields.
*/
xHotSpotSave = IMPOSSIBLEVALUE;
yHotSpotSave = IMPOSSIBLEVALUE;
}



/************************************************************************
* PropBarShowHotSpot
*
*
* Arguments:
*
* History:
*
************************************************************************/
VOID PropBarShowHotSpot(
BOOL fShow)
{
ShowWindow(GetDlgItem(ghwndPropBar, DID_PROPBARHOTSPOTLABEL),
fShow ? SW_SHOWNA : SW_HIDE);
ShowWindow(GetDlgItem(ghwndPropBar, DID_PROPBARHOTSPOT),
fShow ? SW_SHOWNA : SW_HIDE);
}