STATUS.C


/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1993 - 1998 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

/****************************** Module Header *******************************
* Module Name: status.c
*
* Support for the Status window.
*
* Functions:
*
* StatusDlgProc()
* StatusApplyChanges()
* StatusFillSymbolList()
* StatusSetCoords()
* StatusUpdate()
* StatusSetEnable()
* StatusInit()
* StatusProcessCommand()
* ValidateNewName()
* ValidateNewID()
* ApplyNewName()
* ApplyNewID()
* ApplyNewText()
* StatusSetText()
* StatusSetTextLabels()
* StatusSetID()
* StatusSetName()
* StatusSetNameID()
* StatusClearID()
* StatusClearName()
* StatusClear()
* StatusShowFields()
*
* Comments:
*
****************************************************************************/

#include "dlgedit.h"
#include "dlgfuncs.h"
#include "dlgextrn.h"
#include "dialogs.h"

STATICFN BOOL StatusInit(HWND hwnd);
STATICFN VOID StatusProcessCommand(HWND hwnd, INT idCtrl,
INT NotifyCode);
STATICFN BOOL ValidateNewName(NPCTYPE npc, LPTSTR pszName,
LPTSTR pszID, LPTSTR pszSym, PINT pidNew, BOOL *pfAddLabel);
STATICFN BOOL ValidateNewID(NPCTYPE npc, LPTSTR pszSym, LPTSTR pszID,
PINT pidNew, BOOL *pfAddLabel);
STATICFN BOOL ApplyNewName(NPCTYPE npc, LPTSTR pszName,
BOOL fAddLabel, LPTSTR pszSym, INT idNew);
STATICFN BOOL ApplyNewID(NPCTYPE npc, INT idNew, BOOL fAddLabel,
LPTSTR pszSym);
STATICFN BOOL ApplyNewText(NPCTYPE npc, LPTSTR pszNewText);
STATICFN VOID StatusSetText(LPTSTR pszText, INT Type);
STATICFN VOID StatusSetTextLabels(INT Type, BOOL fIsOrd);
STATICFN VOID StatusSetID(INT id, BOOL fSymAlso);
STATICFN VOID StatusSetName(LPTSTR pszName, INT Type);
STATICFN VOID StatusSetNameID(INT id, INT Type);
STATICFN VOID StatusClearID(VOID);
STATICFN VOID StatusClearName(VOID);
STATICFN VOID StatusClear(VOID);
STATICFN VOID StatusShowFields(INT Type);

/*
* TRUE if the user has changed the entry fields in the status window.
* This will be reset to FALSE whenever new information is placed
* into the fields.
*/
static BOOL gfStatusChanged = FALSE;

/*
* These globals save the window positions of the upper and lower
* combo boxes and edit controls. This is used to position them
* depending on what type of control is selected.
*/
static RECT grcTopCombo;
static RECT grcBottomCombo;
static RECT grcTopEdit;
static RECT grcBottomEdit;



/************************************************************************
* StatusDlgProc
*
* This is the dialog procedure for the Status ribbon window.
*
************************************************************************/

DIALOGPROC StatusDlgProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
return StatusInit(hwnd);

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 + gcyStatus) - gcyBorder - 1, NULL);
LineTo(hdc, rc.right, (rc.top + gcyStatus) - gcyBorder - 1);

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

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

break;

case WM_CTLCOLORDLG:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORSTATIC:
switch ((WORD)(msg - WM_CTLCOLORMSGBOX)) {
case CTLCOLOR_DLG:
case CTLCOLOR_LISTBOX:
return (BOOL)GetStockObject(LTGRAY_BRUSH);

case CTLCOLOR_STATIC:
SetBkColor((HDC)(wParam),
LIGHTGRAY);
return (BOOL)GetStockObject(LTGRAY_BRUSH);
}

return (BOOL)NULL;

case WM_COMMAND:
StatusProcessCommand(hwnd,
LOWORD(wParam),
HIWORD(wParam));
break;

default:
return FALSE;
}

return FALSE;
}



/************************************************************************
* StatusInit
*
* Initializes the Status ribbon window.
*
* Arguments:
* HWND hwnd = The window handle.
*
* Returns:
*
* TRUE
*
************************************************************************/

STATICFN BOOL StatusInit(
HWND hwnd)
{
/*
* Set this global right away. Other routines that will be called
* before CreateDialog returns depend on this global.
*/
hwndStatus = hwnd;

GetChildRect(GetDlgItem(hwnd, DID_STATUSSYM), &grcTopCombo);
GetChildRect(GetDlgItem(hwnd, DID_STATUSSYMID), &grcTopEdit);
GetChildRect(GetDlgItem(hwnd, DID_STATUSNAME), &grcBottomCombo);
GetChildRect(GetDlgItem(hwnd, DID_STATUSNAMEID), &grcBottomEdit);

SendDlgItemMessage(hwnd, DID_STATUSSYM, EM_LIMITTEXT, CCHTEXTMAX, 0L);
SendDlgItemMessage(hwnd, DID_STATUSNAME, EM_LIMITTEXT, CCHTEXTMAX, 0L);
SendDlgItemMessage(hwnd, DID_STATUSSYMID, EM_LIMITTEXT, CCHIDMAX, 0L);
SendDlgItemMessage(hwnd, DID_STATUSNAMEID, EM_LIMITTEXT, CCHIDMAX, 0L);
SendDlgItemMessage(hwnd, DID_STATUSTEXT, EM_LIMITTEXT, CCHTEXTMAX, 0L);

StatusFillSymbolList(plInclude);
StatusUpdate();
StatusSetEnable();

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



/************************************************************************
* StatusProcessCommand
*
* Function that processes commands sent to the status window.
*
* 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.
*
*
************************************************************************/

STATICFN VOID StatusProcessCommand(
HWND hwnd,
INT idCtrl,
INT NotifyCode)
{
TCHAR szSym[CCHTEXTMAX];
TCHAR szID[CCHIDMAX + 1];
NPLABEL npLabel;
INT id;
INT nIndex;
LPTSTR pszOldName;

switch (idCtrl) {
case DID_STATUSSYM:
/*
* Did the symbol edit field change and is
* something selected?
*/
if (gnpcSel && (NotifyCode == CBN_EDITCHANGE ||
NotifyCode == CBN_SELCHANGE)) {
/*
* Get the symbol and begin looking for it.
*/
if (NotifyCode == CBN_EDITCHANGE) {
/*
* The edit field was typed into. Get the
* new text from there.
*/
GetDlgItemText(hwnd, DID_STATUSSYM, szSym, CCHTEXTMAX);
}
else {
/*
* A new string was selected from the list
* box. Get it from the list box, because
* at this point the new text is not yet set
* into the edit control!
*/
nIndex = (INT)SendDlgItemMessage(hwnd,
DID_STATUSSYM, CB_GETCURSEL, 0, 0L);

if (nIndex != CB_ERR)
SendDlgItemMessage(hwnd, DID_STATUSSYM, CB_GETLBTEXT,
nIndex, (DWORD)szSym);
else
*szSym = CHAR_NULL;
}

/*
* Convert the symbol field to the associated id value,
* taking into account the special IDOK values, etc.
*/
if (!LabelToID(szSym, &id)) {
/*
* The symbol was not found.
* If the symbol is not blank, and the
* id of the control is already taken
* by another label, fill the id field
* with the next available id. Otherwise,
* fill the id field with the controls
* id value. It is assumed here that the
* dialog cannot be selected if the symbol
* field was able to be changed.
*/
if (*szSym && FindID(gnpcSel->id, plInclude))
id = NextID(NEXTID_CONTROL, plInclude, 0);
else
id = gnpcSel->id;
}

StatusSetID(id, FALSE);

gfStatusChanged = TRUE;
}

break;

case DID_STATUSNAME:
/*
* Did the name edit field change and is
* something selected?
*/
if (gnpcSel && (NotifyCode == CBN_EDITCHANGE ||
NotifyCode == CBN_SELCHANGE)) {
/*
* Get the symbol and begin looking for it.
*/
if (NotifyCode == CBN_EDITCHANGE) {
/*
* The edit field was typed into. Get the
* new text from there.
*/
GetDlgItemText(hwnd, DID_STATUSNAME, szSym, CCHTEXTMAX);
}
else {
/*
* A new string was selected from the list
* box. Get it from the list box, because
* at this point the new text is not yet set
* into the edit control!
*/
nIndex = (INT)SendDlgItemMessage(hwnd,
DID_STATUSNAME, CB_GETCURSEL, 0, 0L);

if (nIndex != CB_ERR)
SendDlgItemMessage(hwnd, DID_STATUSNAME, CB_GETLBTEXT,
nIndex, (DWORD)szSym);
else
*szSym = CHAR_NULL;
}

/*
* Try and convert the name to an ordinal.
*/
StrToNameOrd(szSym, (gnpcSel->pwcd->iType == W_DIALOG) ?
TRUE : FALSE);

/*
* Was the name converted to an ordinal?
*/
if (IsOrd(szSym)) {
id = OrdID(szSym);
}
/*
* Is it an existing label?
*/
else if (npLabel = FindLabel(szSym, plInclude)) {
id = npLabel->id;
}
else {
/*
* Get a pointer to the original name.
*/
pszOldName = (gnpcSel->pwcd->iType == W_DIALOG) ?
gcd.pszDlgName : gnpcSel->text;

/*
* If the old name was originally an ordinal, and
* there was no corresponding label for it,
* assume that the user is trying to enter a
* define for it and leave it alone. Otherwise,
* pick the next available id. But if the user
* completely blanks out the field, leave it
* alone also (this is a benign case).
*/
if (IsOrd(pszOldName) &&
(!*szSym || !FindID(OrdID(pszOldName), plInclude)))
id = OrdID(pszOldName);
else
id = NextID((gnpcSel->pwcd->iType == W_DIALOG) ?
NEXTID_DIALOG : NEXTID_CONTROL, plInclude, 0);
}

StatusSetNameID(id, gnpcSel->pwcd->iType);

/*
* Change the labels to reflect that the entered name
* is an ID instead of a name.
*/
StatusSetTextLabels(gnpcSel->pwcd->iType, TRUE);

gfStatusChanged = TRUE;
}

break;

case DID_STATUSSYMID:
case DID_STATUSNAMEID:
case DID_STATUSTEXT:
if (!gnpcSel)
break;

if (NotifyCode == EN_CHANGE)
gfStatusChanged = TRUE;

if (idCtrl == DID_STATUSNAMEID) {
GetDlgItemText(hwnd, DID_STATUSNAME, szSym, CCHTEXTMAX);
GetDlgItemText(hwnd, DID_STATUSNAMEID, szID, CCHIDMAX + 1);
StrToNameOrd(szSym, (gnpcSel->pwcd->iType == W_DIALOG) ?
TRUE : FALSE);

/*
* Change the labels to reflect whether the entered name
* is an ID or a name. It is considered an id if the
* edit field has something in it, or if the name field
* is a valid label, or if the name field represents an
* ordinal (it is numeric).
*/
StatusSetTextLabels(gnpcSel->pwcd->iType,
(IsOrd(szSym) || *szID ||
FindLabel(szSym, plInclude)) ? TRUE : FALSE);
}

break;

case IDOK:
if (StatusApplyChanges())
SetFocus(ghwndMain);

break;

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



/************************************************************************
* StatusApplyChanges
*
* Processes the Enter command from the "Status" bar window to apply
* the current value of the fields to the current control.
*
* Returns:
*
* TRUE is successful; otherwise, FALSE is returned.
*
************************************************************************/

BOOL StatusApplyChanges(VOID)
{
TCHAR szText[CCHTEXTMAX];
TCHAR szSym[CCHTEXTMAX];
TCHAR szName[CCHTEXTMAX];
TCHAR szSymID[CCHIDMAX + 1];
TCHAR szNameID[CCHIDMAX + 1];
TCHAR szNameSym[CCHTEXTMAX];
INT idSymNew;
INT idNameNew;
BOOL fAddSymLabel;
BOOL fAddNameLabel;
BOOL fSuccess = FALSE;

/*
* Quit if nothing is selected, or if nothing was changed.
*/
if (!gnpcSel || !gfStatusChanged)
return TRUE;

idSymNew = gnpcSel->id;

switch (gnpcSel->pwcd->iType) {
case W_DIALOG:
GetDlgItemText(hwndStatus, DID_STATUSNAME, szName, CCHTEXTMAX);
GetDlgItemText(hwndStatus, DID_STATUSNAMEID, szNameID, CCHIDMAX + 1);
GetDlgItemText(hwndStatus, DID_STATUSTEXT, szText, CCHTEXTMAX);
if (!ValidateNewName(gnpcSel, szName, szNameID, szNameSym,
&idNameNew, &fAddNameLabel))
return FALSE;

if (ApplyNewName(gnpcSel, szName, fAddNameLabel,
szNameSym, idNameNew) &&
ApplyNewText(gnpcSel, szText))
fSuccess = TRUE;

break;

case W_ICON:
GetDlgItemText(hwndStatus, DID_STATUSNAME, szName, CCHTEXTMAX);
GetDlgItemText(hwndStatus, DID_STATUSNAMEID, szNameID, CCHIDMAX + 1);
GetDlgItemText(hwndStatus, DID_STATUSSYM, szSym, CCHTEXTMAX);
GetDlgItemText(hwndStatus, DID_STATUSSYMID, szSymID, CCHIDMAX + 1);
if (!ValidateNewName(gnpcSel, szName, szNameID, szNameSym,
&idNameNew, &fAddNameLabel) ||
!ValidateNewID(gnpcSel, szSym, szSymID,
&idSymNew, &fAddSymLabel))
return FALSE;

if (ApplyNewID(gnpcSel, idSymNew, fAddSymLabel, szSym) &&
ApplyNewName(gnpcSel, szName, fAddNameLabel,
szNameSym, idNameNew))
fSuccess = TRUE;

break;

default:
GetDlgItemText(hwndStatus, DID_STATUSSYM, szSym, CCHTEXTMAX);
GetDlgItemText(hwndStatus, DID_STATUSSYMID, szSymID, CCHIDMAX + 1);
GetDlgItemText(hwndStatus, DID_STATUSTEXT, szText, CCHTEXTMAX);
#ifdef JAPAN
{
TCHAR szTmp[CCHTEXTMAX];

KKExpandCopy(szTmp, szText, CCHTEXTMAX);
lstrcpy(szText, szTmp);
}
#endif
if (!ValidateNewID(gnpcSel, szSym, szSymID, &idSymNew, &fAddSymLabel))
return FALSE;

if (ApplyNewID(gnpcSel, idSymNew, fAddSymLabel, szSym) &&
ApplyNewText(gnpcSel, szText))
fSuccess = TRUE;

break;
}

if (fSuccess) {
ShowFileStatus(FALSE);
StatusUpdate();
}

return fSuccess;
}



/************************************************************************
* ValidateNewName
*
* Validates the new name from the processing of the OK command
* from the Status ribbon window.
*
* The name is considered valid if it does not have any blanks in it,
* it is not already used by another dialog in the resource file, and
* it is not an empty string.
*
* Arguments:
* NPCTYPE npc - Pointer to the control.
* LPTSTR pszName - The new name.
* LPTSTR pszID - The ID.
* LPTSTR pszSym - The symbol.
* PINT pidNew - Where to return the new ID if successful.
* BOOL *pfAddLabel - Set to TRUE if this symbol/id should be added
* to the include list. Not touched otherwise.
*
* Returns:
* TRUE if the new name is valid, FALSE otherwise.
*
************************************************************************/

STATICFN BOOL ValidateNewName(
NPCTYPE npc,
LPTSTR pszName,
LPTSTR pszID,
LPTSTR pszSym,
PINT pidNew,
BOOL *pfAddLabel)
{
NPLABEL npLabel;
BOOL fIDEmpty = FALSE;
BOOL fNameEmpty = FALSE;
BOOL fAddLabel = FALSE;
INT idNew;
TCHAR szIDTemp[CCHIDMAX + 1];

/*
* Start by assuming that the label will NOT be added.
*/
*pfAddLabel = FALSE;

/*
* Is the ID field non-blank?
*/
if (*pszID) {
/*
* Is the id valid?
*/
if (!IsValue(pszID)) {
Message(MSG_BADSYMBOLID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAMEID));
return FALSE;
}

idNew = valtoi(pszID);
}
else {
/*
* The id field is blank.
*/
fIDEmpty = TRUE;
}

/*
* Is the name field blank?
*/
if (!(*pszName))
fNameEmpty = TRUE;

if (fNameEmpty) {
if (fIDEmpty) {
Message((npc->pwcd->iType == W_DIALOG) ?
MSG_NODLGNAME : MSG_NOICONNAME);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAME));
return FALSE;
}
else {
WriteOrd((PORDINAL)pszName, idNew);
}
}
else {
/*
* Error if there are imbedded blanks.
*/
if (HasBlanks(pszName)) {
Message((npc->pwcd->iType == W_DIALOG) ?
MSG_DLGNAMEHASBLANKS : MSG_ICONNAMEHASBLANKS);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAME));
return FALSE;
}

/*
* Convert the name to an ordinal, if appropriate.
*/
StrToNameOrd(pszName, (npc->pwcd->iType == W_DIALOG) ? TRUE : FALSE);

/*
* If the name was translated to an ordinal, we are done.
* Otherwise, keep trying to figure out whether it is a
* name or a define.
*/
if (!IsOrd(pszName)) {
/*
* Is the name a symbol in the current include list?
*/
if (npLabel = FindLabel(pszName, plInclude)) {
/*
* Yes. If the id field was blank, just assume they
* wanted the corresponding id.
*/
if (fIDEmpty)
idNew = npLabel->id;

/*
* If they somehow entered a valid define but tried to
* give it a different id value, show an error.
*/
if (npLabel->id != idNew) {
Myitoa(npLabel->id, szIDTemp);
Message(MSG_IDSYMMISMATCH, szIDTemp);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAMEID));
return FALSE;
}

/*
* Make the name field into an ordinal.
*/
WriteOrd((PORDINAL)pszName, idNew);
}
else {
/*
* The name was not found as a label. Is the id field
* empty?
*/
if (fIDEmpty) {
/*
* Since the id field is empty, we can assume that
* what they entered is a name (not a define)
* and we are done.
*/
}
else {
/*
* At this point we know the name field is not empty,
* and there is an id entered along with it. We also
* know that the name (which we can now assume is
* a symbol) is not already found in the include file.
* We will check it for validity, copy it to the
* pszSym buffer, translate the name to an ordinal
* and set a flag saying that the sym/id pair should
* be added to the include list.
*/
if (!IsSymbol(pszName)) {
Message(MSG_BADSYMBOLID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAME));
return FALSE;
}

/*
* Pass back the values.
*/
lstrcpy(pszSym, pszName);
WriteOrd((PORDINAL)pszName, idNew);
*pidNew = idNew;

fAddLabel = TRUE;
}
}
}
}

/*
* Inform caller whether they should add this id/symbol
* as a label to the include list.
*/
*pfAddLabel = fAddLabel;

/*
* Return success.
*/
return TRUE;
}



/************************************************************************
* ValidateNewID
*
* Validates the new ID from the processing of the OK command from
* the Status ribbon window. It will return the new id in *pidNew.
* Note that the control is not actually updated by this routine. This
* is so that if other validations fail nothing will have been done to the
* control. It is assumed that ApplyNewID will be called later to do
* the actual update of the control.
*
* Arguments:
* NPCTYPE npc = Pointer to the control.
* LPTSTR pszSym = The symbol.
* LPTSTR pszID = The ID.
* PINT pidNew = Where to return the new ID if successful.
* BOOL *pfAddLabel = Set to TRUE if this symbol/id should be added
* to the include list. Not touched otherwise.
*
* Returns:
* TRUE if successful, FALSE otherwise. If TRUE is returned and they
* changed the id, the new id will have been placed in *pidNew.
*
************************************************************************/

STATICFN BOOL ValidateNewID(
NPCTYPE npc,
LPTSTR pszSym,
LPTSTR pszID,
PINT pidNew,
BOOL *pfAddLabel)
{
NPLABEL npLabel;
BOOL fIDEmpty = FALSE;
BOOL fIDChanged = FALSE;
BOOL fSymEmpty = FALSE;
BOOL fSymChanged = FALSE;
BOOL fAddLabel = FALSE;
INT idNew;
TCHAR szIDTemp[CCHIDMAX + 1];

/*
* Start by assuming that the label will NOT be added.
*/
*pfAddLabel = FALSE;

/*
* If in translate mode, they cannot change the symbol or id,
* and so it should not be validated. Even if there was a
* problem, they could not fix it.
*/
if (gfTranslateMode)
return TRUE;

/*
* Special case if they selected the "unused" label.
* Blank out the symbol so it doesn't cause trouble
* later, force the id to be zero, and then check if
* the id was changed.
*/
if (lstrcmp(pszSym, ids(IDS_UNUSED)) == 0) {
pszSym = szEmpty;
idNew = IDUNUSED;
if (idNew != npc->id)
fIDChanged = TRUE;
}
else if (lstrcmp(pszSym, ids(IDS_IDOK)) == 0 &&
!FindLabel(ids(IDS_IDOK), plInclude)) {
pszSym = szEmpty;
idNew = IDOK;
if (idNew != npc->id)
fIDChanged = TRUE;
}
else if (lstrcmp(pszSym, ids(IDS_IDCANCEL)) == 0 &&
!FindLabel(ids(IDS_IDCANCEL), plInclude)) {
pszSym = szEmpty;
idNew = IDCANCEL;
if (idNew != npc->id)
fIDChanged = TRUE;
}
/*
* Is the ID field non-blank?
*/
else if (*pszID) {
/*
* Is the id valid?
*/
if (!IsValue(pszID)) {
Message(MSG_BADSYMBOLID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYMID));
return FALSE;
}

/*
* Did they change the id value?
*/
idNew = valtoi(pszID);
if (idNew != npc->id)
fIDChanged = TRUE;
}
else {
/*
* The id field is blank. This implies they changed it.
*/
fIDEmpty = TRUE;
fIDChanged = TRUE;
}

/*
* Is the symbol field blank?
*/
if (!(*pszSym))
fSymEmpty = TRUE;

/*
* Determine if they have changed the symbol.
* Did the original id have a symbol associated with it?
*/
if (npLabel = FindID(npc->id, plInclude)) {
if (lstrcmp(npLabel->pszLabel, pszSym) != 0)
fSymChanged = TRUE;
}
else {
/*
* Since the original id did not have a symbol, if they
* have entered a symbol it is changed.
*/
if (!fSymEmpty)
fSymChanged = TRUE;
}

/*
* Quit if nothing changed.
*/
if (!fSymChanged && !fIDChanged)
return TRUE;

/*
* Is the symbol field empty?
*/
if (fSymEmpty) {
/*
* If the id field is empty also, return an error.
*/
if (fIDEmpty) {
Message(MSG_BADSYMBOLID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYMID));
return FALSE;
}
else {
/*
* Otherwise, go on to the final test. It doesn't matter
* if this new id has a symbol or not.
*/
goto CheckForDups;
}
}

/*
* At this point we know the symbol field is not empty.
* Is it a valid symbol?
*/
if (!IsSymbol(pszSym)) {
Message(MSG_BADSYMBOLID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYM));
return FALSE;
}

/*
* Does this symbol already exist?
*/
if (npLabel = FindLabel(pszSym, plInclude)) {
/*
* Since the symbol exists, if they blanked the id field
* be friendly and assume they want the matching id value.
*/
if (fIDEmpty)

idNew = npLabel->id; 

/*
* Does the id that is in the id field match the id of the
* symbol they entered?
*/
if (npLabel->id == idNew) {
/*
* Yes, go on to the final test.
*/
goto CheckForDups;
}
else {
/*
* No, give them an error message saying that it has to.
*/
Myitoa(npLabel->id, szIDTemp);
Message(MSG_IDSYMMISMATCH, szIDTemp);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYMID));
return FALSE;
}
}
else {
/*
* Since the symbol doesn't exist, if they left the id field
* blank, assume they want the next available id.
*/
if (fIDEmpty)
idNew = NextID(NEXTID_CONTROL, plInclude, 0);

/*
* They should add this id/symbol as a label to the
* include list.
*/
fAddLabel = TRUE;
goto CheckForDups;
}

CheckForDups:
/*
* If the id changed, it is not the special "unused" id,
* and it is a duplicate of another id, don't allow it.
*/
if (idNew != npc->id && !IsUniqueID(idNew)) {
Message(MSG_CTRLDUPID);
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYM));
return FALSE;
}
else {
/*
* Pass back the new id value.
*/
*pidNew = idNew;

/*
* Inform caller whether they should add this id/symbol
* as a label to the include list.
*/
*pfAddLabel = fAddLabel;

/*
* Return success.
*/
return TRUE;
}
}



/************************************************************************
* ApplyNewName
*
* Updates an icon control's or dialog's name with a new name.
*
* If fAddLabel is TRUE, pszSym is assumed to be a string that is
* the symbol to be added and idNew contains the value associated with
* it. This will cause a new define to be added to the current include
* file. In either event, pszName will contain either a new name or
* an ordinal that is to be the name. For dialogs, the dialog name will
* be updated. For icon controls, the icon's text is updated with the
* name/ordinal.
*
* Arguments:
* NPCTYPE npc = Pointer to the control.
* LPTSTR pszName = New name. A string or ordinal.
* BOOL fAddLabel = TRUE if a new label for this id/name should be added.
* LPTSTR pszSym = The new symbol to add (only valid if fAddLabel is TRUE).
* INT idNew = The new ID (only valid if fAddLabel is TRUE).
*
* Returns:
*
* TRUE if successful; otherwise, FALSE is returned.
*
************************************************************************/

STATICFN BOOL ApplyNewName(
NPCTYPE npc,
LPTSTR pszName,
BOOL fAddLabel,
LPTSTR pszSym,
INT idNew)
{
LPTSTR psz;

if (fAddLabel) {
/*
* Go ahead and quietly add the label for them.
*/
if (AddLabel(pszSym, idNew, FPOS_MAX, 0, &plInclude,
&plDelInclude, NULL, NULL)) {
/*
* Return the controls new id, update the status
* windows symbol combo box, mark the fact that
* we have changed the include file, and return
* success.
*/
gfIncChged = TRUE;
StatusFillSymbolList(plInclude);
}
else {
/*
* An error occurred on the AddLabel. The most likely
* cause of this is if they are trying to add a symbol
* with a duplicate id.
*/
SetFocus(GetDlgItem(hwndStatus, DID_STATUSNAMEID));
return FALSE;
}
}

switch (npc->pwcd->iType) {
case W_ICON:
/*
* The resource name for an icon is stored in it's text.
*/
ApplyNewText(npc, pszName);
break;

case W_DIALOG:
/*
* We are done if the name was not changed.
*/
if (NameOrdCmp(gcd.pszDlgName, pszName) == 0)
break;

/*
* Allocate room for the new name (it can be an ordinal!).
*/
if (!(psz = MyAlloc(NameOrdLen(pszName))))
return FALSE;

NameOrdCpy(psz, pszName);

if (gcd.pszDlgName)
MyFree(gcd.pszDlgName);

gcd.pszDlgName = psz;

/*
* If the new name is an ordinal, update the base id of
* the dialog with it.
*/
if (IsOrd(gcd.pszDlgName))
gcd.npc->id = OrdID(gcd.pszDlgName);

/*
* Finally, set the "changed" flag.
*/
gfResChged = gfDlgChanged = TRUE;

break;
}

return TRUE;
}



/************************************************************************
* ApplyNewID
*
* Updates the control with the new id.
*
* Arguments:
* NPCTYPE npc = Pointer to the control.
* INT idNew = The ID.
* BOOL fAddLabel = TRUE if a new label for this id/symbol should be added.
* LPTSTR pszSym = Symbol to add if fAddLabel is TRUE.
*
* Returns:
*
* TRUE if successful; otherwise, FALSE is returned.
*
************************************************************************/

STATICFN BOOL ApplyNewID(
NPCTYPE npc,
INT idNew,
BOOL fAddLabel,
LPTSTR pszSym)
{
if (fAddLabel) {
/*
* Go ahead and quietly add the label for them.
*/
if (AddLabel(pszSym, idNew, FPOS_MAX, 0, &plInclude,
&plDelInclude, NULL, NULL)) {
/*
* Return the controls new id, update the status
* windows symbol combo box, mark the fact that
* we have changed the include file, and return
* success.
*/
gfIncChged = TRUE;
StatusFillSymbolList(plInclude);
}
else {
/*
* An error occurred on the AddLabel. The most likely
* cause of this is if they are trying to add a symbol
* with a duplicate id.
*/
SetFocus(GetDlgItem(hwndStatus, DID_STATUSSYMID));
return FALSE;
}
}

/*
* Return if the id wasn't changed.
*/
if (npc->id == idNew)
return TRUE;

/*
* Update the controls id and set the resource changed flag.
*/
npc->id = idNew;
gfResChged = gfDlgChanged = TRUE;
return TRUE;
}



/************************************************************************
* ApplyNewText
*
* Sets the new text from the processing of the OK command from
* the Status ribbon window. If the text was changed, the selected
* control will have its text updated.
*
* Arguments:
* NPCTYPE npc = Pointer to the control.
* LPTSTR pszNewText = The new text.
*
* Returns:
*
* TRUE if successful, FALSE otherwise.
*
************************************************************************/

STATICFN BOOL ApplyNewText(
NPCTYPE npc,
LPTSTR pszNewText)
{
INT cb;
LPTSTR psz;

/*
* Did the text change?
*/
if ((npc->text == NULL && *pszNewText) ||
(npc->text != NULL && NameOrdCmp(npc->text, pszNewText) != 0)) {
if (*pszNewText) {
cb = NameOrdLen(pszNewText);

if (npc->text == NULL)
psz = MyAlloc(cb);
else
psz = MyRealloc(npc->text, cb);

if (psz == NULL) {
return FALSE;
}
else {
NameOrdCpy(psz, pszNewText);
npc->text = psz;
}
}
else {
if (npc->text) {
MyFree(npc->text);
npc->text = NULL;
}
}

/*
* Change the text of the control, except for W_ICON controls
* because they have resource names. In that case, we don't
* want to change the text of the actual control because
* the resource would probably not be found.
*/
if (npc->pwcd->iType != W_ICON) {
SetWindowText(npc->hwnd, pszNewText);

/*
* Redraw the control after the text changed. This is
* necessary because changing the text probably caused
* the drag handles to get overwritten.
*/
if (npc->pwcd->iType == W_DIALOG)
/*
* Redraw the frame, which just overwrote the drag
* handles when the text was changed.
*/
SetWindowPos(npc->hwnd, NULL, 0, 0, 0, 0,
SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOMOVE |
SWP_NOSIZE | SWP_NOZORDER);
else
/*
* Redraw the control(s).
*/
RedrawSelection();
}

gfResChged = gfDlgChanged = TRUE;
}

return TRUE;
}



/************************************************************************
* StatusFillSymbolList
*
* This function fills the Symbol and Name combo boxes with
* the given list of labels.
*
* Arguments:
* NPLABEL plHead - pointer to the list of labels.
*
************************************************************************/

VOID StatusFillSymbolList(
NPLABEL plHead)
{
NPLABEL npLabel;
HWND hwndSymCB;
HWND hwndNameCB;
HCURSOR hcurSave;

hcurSave = SetCursor(hcurWait);

/*
* Get the handles to the combo boxes and clear out all items.
*/
hwndSymCB = GetDlgItem(hwndStatus, DID_STATUSSYM);
hwndNameCB = GetDlgItem(hwndStatus, DID_STATUSNAME);
SendMessage(hwndSymCB, CB_RESETCONTENT, 0, 0L);
SendMessage(hwndNameCB, CB_RESETCONTENT, 0, 0L);

/*
* Fill the combo boxes with the items.
*/
for (npLabel = plHead; npLabel; npLabel = npLabel->npNext) {
SendMessage(hwndSymCB, CB_ADDSTRING, 0, (DWORD)npLabel->pszLabel);
SendMessage(hwndNameCB, CB_ADDSTRING, 0, (DWORD)npLabel->pszLabel);
}

/*
* Put some special entries into the symbol combo. Note that we allow
* the user to have defined IDOK and IDCANCEL to be something else,
* in which case we will NOT add these special entries after all.
*/
SendMessage(hwndSymCB, CB_ADDSTRING, 0, (DWORD)ids(IDS_UNUSED));

if (!FindLabel(ids(IDS_IDOK), plInclude))
SendMessage(hwndSymCB, CB_ADDSTRING, 0, (DWORD)ids(IDS_IDOK));

if (!FindLabel(ids(IDS_IDCANCEL), plInclude))
SendMessage(hwndSymCB, CB_ADDSTRING, 0, (DWORD)ids(IDS_IDCANCEL));

SetCursor(hcurSave);
}



/************************************************************************
* StatusSetCoords
*
* This function sets the coordinates in the status display
* to the given rectangle.
*
* Arguments:
* PRECT prc - coordinates.
*
************************************************************************/

VOID StatusSetCoords(
PRECT prc)
{
static INT xSave = 0x7FFF;
static INT ySave = 0x7FFF;
static INT cxSave = 0x7FFF;
static INT cySave = 0x7FFF;
static INT x2Save = 0x7FFF;
static INT y2Save = 0x7FFF;
TCHAR szBuf[CCHTEXTMAX];

if (prc) {
if (prc->bottom - prc->top != cySave) {
/*
* Save it for the next time.
*/
cySave = prc->bottom - prc->top;

wsprintf(szBuf, ids(IDS_CYFMTSTR), cySave);
SetDlgItemText(hwndStatus, DID_STATUSCY, szBuf);
}

if (prc->right != x2Save || prc->bottom != y2Save) {
/*
* Save them for the next time.
*/
x2Save = prc->right;
y2Save = prc->bottom;

wsprintf(szBuf, L"(%d, %d)", x2Save, y2Save);
SetDlgItemText(hwndStatus, DID_STATUSX2Y2, szBuf);
}

if (prc->left != xSave || prc->top != ySave) {
/*
* Save them for the next time.
*/
xSave = prc->left;
ySave = prc->top;

wsprintf(szBuf, L"(%d, %d)", xSave, ySave);
SetDlgItemText(hwndStatus, DID_STATUSXY, szBuf);
}

if (prc->right - prc->left != cxSave) {
/*
* Save it for the next time.
*/
cxSave = prc->right - prc->left;

wsprintf(szBuf, ids(IDS_CXFMTSTR), cxSave);
SetDlgItemText(hwndStatus, DID_STATUSCX, szBuf);
}
}
else {
/*
* Clear the fields.
*/
SetDlgItemText(hwndStatus, DID_STATUSXY, szEmpty);
SetDlgItemText(hwndStatus, DID_STATUSX2Y2, szEmpty);
SetDlgItemText(hwndStatus, DID_STATUSCX, szEmpty);
SetDlgItemText(hwndStatus, DID_STATUSCY, szEmpty);

/*
* Reset the cache variables so that the next "set" of
* the coords is sure to update the display fields.
*/
xSave =
ySave =
cxSave =
cySave =
x2Save =
y2Save = 0x7FFF;
}
}



/************************************************************************
* StatusSetText
*
* This function sets the "Text" field in the status display
* to the given text.
*
* Arguments:
* LPTSTR pszText - The text to display. This can be NULL.
* INT Type - Type of control. One of the W_* constants.
*
************************************************************************/

STATICFN VOID StatusSetText(
LPTSTR pszText,
INT Type)
{
/*
* Protect against getting a null value.
*/
if (!pszText)
pszText = szEmpty;

/*
* If this is an icon control, set the name instead (the text
* of an icon is really a resource name).
*/
if (Type == W_ICON)
StatusSetName(pszText, Type);
else
#ifdef JAPAN
{
TCHAR szTmp[CCHTEXTMAX];

KDExpandCopy(szTmp, pszText, CCHTEXTMAX);
SetDlgItemText(hwndStatus, DID_STATUSTEXT, szTmp);
}
#else
SetDlgItemText(hwndStatus, DID_STATUSTEXT, pszText);
#endif
}



/************************************************************************
* StatusSetTextLabels
*
* This function sets the labels of the descriptive text fields in
* Status window based on the type of control that is selected.
*
* Arguments:
* INT Type - Type of control. One of the W_* constants.
* BOOL fIsOrd - TRUE if the name is an ordinal. This is ignored
* unless Type is W_DIALOG or W_ICON.
*
************************************************************************/

STATICFN VOID StatusSetTextLabels(
INT Type,
BOOL fIsOrd)
{
WORD ids1;
WORD ids2;

switch (Type) {
case W_DIALOG:
ids1 = (WORD)(fIsOrd ? IDS_DLGIDLABEL : IDS_DLGNAMELABEL);
ids2 = IDS_CAPTIONLABEL;
break;

case W_ICON:
ids1 = IDS_SYMBOLLABEL;
ids2 = (WORD)(fIsOrd ? IDS_ICONIDLABEL : IDS_ICONNAMELABEL);
break;

default:
ids1 = IDS_SYMBOLLABEL;
ids2 = IDS_TEXTLABEL;
break;
}

SetDlgItemText(hwndStatus, DID_STATUSLABEL1, ids(ids1));
SetDlgItemText(hwndStatus, DID_STATUSLABEL2, ids(ids2));
}



/************************************************************************
* StatusSetID
*
* Updates the id field of the given label.
*
* Arguments:
* INT id = The id.
* BOOL fSymAlso = Find the corresponding label and update the
* symbol field also.
*
************************************************************************/

STATICFN VOID StatusSetID(
INT id,
BOOL fSymAlso)
{
TCHAR szValue[CCHIDMAX + 1];
NPLABEL npLabel;
LPTSTR pszLabel;

Myitoa(id, szValue);
SetDlgItemText(hwndStatus, DID_STATUSSYMID, szValue);

if (fSymAlso) {
/*
* If a matching label is found, the text is used.
* Otherwise, if the id is zero, we use the "unused"
* label. Otherwise, we just use an empty string.
*/
if (npLabel = FindID(id, plInclude))
pszLabel = npLabel->pszLabel;
else if (id == IDUNUSED)
pszLabel = ids(IDS_UNUSED);
else if (id == IDOK && !FindLabel(ids(IDS_IDOK), plInclude))
pszLabel = ids(IDS_IDOK);
else if (id == IDCANCEL && !FindLabel(ids(IDS_IDCANCEL), plInclude))
pszLabel = ids(IDS_IDCANCEL);
else
pszLabel = szEmpty;

SetDlgItemText(hwndStatus, DID_STATUSSYM, pszLabel);
}
}



/************************************************************************
* StatusSetName
*
* This function sets the "Res. Name" field in the status display
* to the given text.
*
* Arguments:
*
* LPTSTR pszName - The name to display. NULL values and ordinals
* are handled properly.
* INT Type - Type of control. One of the W_* constants.
*
************************************************************************/

STATICFN VOID StatusSetName(
LPTSTR pszName,
INT Type)
{
NPLABEL npLabel;

/*
* Protect against getting a null value.
*/
if (!pszName)
pszName = szEmpty;

/*
* Does the name represent an ordinal? If so, set the nameid
* field to the value and fill in the name field with the
* associated symbol, if there is one.
*
* Note that this does NOT produce a hex value in Hex Mode for
* dialog names, because rc.exe does not parse hex ordinals
* for dialog names.
*/
if (IsOrd(pszName)) {
StatusSetNameID(OrdID(pszName), Type);

if (npLabel = FindID(OrdID(pszName), plInclude))
pszName = npLabel->pszLabel;
else
pszName = szEmpty;
}
else {
SetDlgItemText(hwndStatus, DID_STATUSNAMEID, szEmpty);
}

SetDlgItemText(hwndStatus, DID_STATUSNAME, pszName);
}



/************************************************************************
* StatusSetNameID
*
* This function sets the id edit field associated with the
* "Res. Name" field in the status display
*
* Arguments:
*
* INT id - The id to set into the field.
* INT Type - Type of control. One of the W_* constants.
*
************************************************************************/

STATICFN VOID StatusSetNameID(
INT id,
INT Type)
{
TCHAR szValue[CCHIDMAX + 1];

/*
* If the current control is a dialog, do NOT produce a hex
* value, even if the hex mode is on. RC.Exe doesn't recognize
* hex values for the dialog name as ordinals.
*/
if (Type == W_DIALOG)
itoaw(id, szValue, 10);
else
Myitoa(id, szValue);

SetDlgItemText(hwndStatus, DID_STATUSNAMEID, szValue);
}



/************************************************************************
* StatusClearID
*
* Clears the id of the status window..
*
************************************************************************/

STATICFN VOID StatusClearID(VOID)
{
SetDlgItemText(hwndStatus, DID_STATUSSYM, szEmpty);
SetDlgItemText(hwndStatus, DID_STATUSSYMID, szEmpty);
}



/************************************************************************
* StatusClearName
*
* Clears the name of the status window.
*
************************************************************************/

STATICFN VOID StatusClearName(VOID)
{
SetDlgItemText(hwndStatus, DID_STATUSNAME, szEmpty);
SetDlgItemText(hwndStatus, DID_STATUSNAMEID, szEmpty);
}



/************************************************************************
* StatusClear
*
* Clears the status window.
*
************************************************************************/

STATICFN VOID StatusClear(VOID)
{
StatusSetCoords(NULL);
StatusSetText(NULL, W_NOTHING);
StatusShowFields(W_NOTHING);
StatusClearID();
StatusClearName();
gfStatusChanged = FALSE;
}



/************************************************************************
* StatusUpdate
*
* Updates the status window to the current selection.
*
************************************************************************/

VOID StatusUpdate(VOID)
{
if (gnpcSel) {
StatusSetCoords(&gnpcSel->rc);
StatusSetText(gnpcSel->text, gnpcSel->pwcd->iType);

if (gfDlgSelected)
StatusSetName(gcd.pszDlgName, W_DIALOG);
else
StatusSetID(gnpcSel->id, TRUE);

StatusShowFields(gnpcSel->pwcd->iType);

gfStatusChanged = FALSE;
}
else {
StatusClear();
}
}



/************************************************************************
* StatusShowFields
*
* This function shows and hides fields in the Status ribbon based on
* whether the dialog is currently selected or not. This is necessary
* because dialogs have a name, whereas controls do not, and controls
* have an id that dialogs do not have, etc.
*
* It will also call StatusSetTextLabels to set the text for the
* descriptive labels in front of the fields.
*
* This function should be called whenever it is possible that the current
* selection has been changed.
*
* Arguments:
* INT Type - Type of control that is selected (W_* constant).
*
************************************************************************/

STATICFN VOID StatusShowFields(
INT Type)
{
/*
* This static caches the type of the selected control.
*/
static INT TypeSave = W_NOTHING;

/*
* We only have special cases for the dialog and for icon controls.
* All other types are treated the same (we use W_CHECKBOX arbitrarily).
* This prevents some repainting when switching between controls that
* have the same layout of fields in the status window.
*/
if (Type != W_DIALOG && Type != W_ICON)
Type = W_CHECKBOX;

if (Type != TypeSave) {
switch (Type) {
case W_DIALOG:
MoveWindow(GetDlgItem(hwndStatus, DID_STATUSNAME),
grcTopCombo.left, grcTopCombo.top,
grcTopCombo.right - grcTopCombo.left,
grcTopCombo.bottom - grcTopCombo.top, TRUE);
MoveWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID),
grcTopEdit.left, grcTopEdit.top,
grcTopEdit.right - grcTopEdit.left,
grcTopEdit.bottom - grcTopEdit.top, TRUE);

ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAME), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSTEXT), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYM), SW_HIDE);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYMID), SW_HIDE);

StatusSetTextLabels(Type, IsOrd(gcd.pszDlgName));

break;

case W_ICON:
MoveWindow(GetDlgItem(hwndStatus, DID_STATUSNAME),
grcBottomCombo.left, grcBottomCombo.top,
grcBottomCombo.right - grcBottomCombo.left,
grcBottomCombo.bottom - grcBottomCombo.top, TRUE);
MoveWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID),
grcBottomEdit.left, grcBottomEdit.top,
grcBottomEdit.right - grcBottomEdit.left,
grcBottomEdit.bottom - grcBottomEdit.top, TRUE);

ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAME), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYM), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYMID), SW_SHOW);

StatusSetTextLabels(Type,
gnpcSel->text ? IsOrd(gnpcSel->text) : FALSE);

break;

default:
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSTEXT), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYM), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSSYMID), SW_SHOW);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAME), SW_HIDE);
ShowWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID), SW_HIDE);

StatusSetTextLabels(Type, FALSE);

break;
}

TypeSave = Type;
}
}



/************************************************************************
* StatusSetEnable
*
* This routine sets the enable state of the editable controls in the
* status window based on various state globals.
*
* The controls will be disabled on the following conditions:
*
* 1. Nothing is selected.
* 2. We are in Test mode.
* 3. One of the editors own dialogs is up (gfDisabled == TRUE).
*
* In addition, some controls will always be disabled if in Translate
* mode, and the text field will be disabled if this control cannot
* have text.
*
************************************************************************/

VOID StatusSetEnable(VOID)
{
BOOL fEnableText = TRUE;
BOOL fEnableSym = TRUE;
BOOL fEnableName = TRUE;

if (!gnpcSel || gfTestMode || gfDisabled)
fEnableText = fEnableSym = fEnableName = FALSE;

/*
* Disable the text field if this control cannot have text.
*/
if (gnpcSel && !gnpcSel->pwcd->fHasText)
fEnableText = FALSE;

/*
* If the dialog is selected and the style does not include
* a caption, disable the text field.
*/
if (gfDlgSelected && (gnpcSel->flStyle & WS_CAPTION) != WS_CAPTION)
fEnableText = FALSE;

/*
* Always disable the symbol and name fields if Translating.
*/
if (gfTranslateMode)
fEnableSym = fEnableName = FALSE;

EnableWindow(GetDlgItem(hwndStatus, DID_STATUSTEXT), fEnableText);

EnableWindow(GetDlgItem(hwndStatus, DID_STATUSSYM), fEnableSym);
EnableWindow(GetDlgItem(hwndStatus, DID_STATUSSYMID), fEnableSym);

EnableWindow(GetDlgItem(hwndStatus, DID_STATUSNAME), fEnableName);
EnableWindow(GetDlgItem(hwndStatus, DID_STATUSNAMEID), fEnableName);
}
#ifdef JAPAN
/************************************************************************
* Copy strings to the buffer. text strings "\036" and "\037" are expanded to
* Codes \036 and \037 respectively.
************************************************************************/

VOID KKExpandCopy(LPTSTR pszDest, LPTSTR pszSrc, WORD wLimit)
{
int i;
LPTSTR p = pszSrc;
#if defined(DBCS) && !defined(UNICODE)
#define wcsncmp strncmp
#endif

wLimit--;
for (i = 0; i < wLimit && p && *p; i++) {
if (*p == TEXT('\\')) {
if(!wcsncmp(p+1, TEXT("036"), 3)) {
pszDest[i] = 036;
p+=4;
continue;
}
else if(!wcsncmp(p+1, TEXT("037"), 3)) {
pszDest[i] = 037;
p+=4;
continue;
}
}
pszDest[i] = *p;
if (IsDBCSLeadByte((BYTE)*p)) {
if (i == wLimit - 1) {
break;
}
pszDest[++i] = *(p+1);
}
p = CharNext(p);
}
pszDest[i] = '\0';
}
#endif