windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx7/diquick/diqvbool.c
2020-09-26 16:20:57 +08:00

246 lines
6 KiB
C

/*****************************************************************************
*
* diqvbool.c
*
* VList plug-in that does BOOLs.
*
*****************************************************************************/
#include "diquick.h"
#pragma BEGIN_CONST_DATA
/*****************************************************************************
*
* VLISTBOOL
*
* BOOL-specific goo.
*
* When we PreDisplay a control, we stash the VLISTBOOL into the
* DWL_USER. We can't use the GWLP_USERDATA, because the vlist
* manager uses that.
*
*****************************************************************************/
typedef struct VLISTBOOL {
VLISTITEM item;
DIPROPDWORD dipdw;
/*
* If non-NULL, then this is a read/write control.
*/
PROPUPDATEPROC Update;
PV pvRef1;
PV pvRef2;
} VLISTBOOL, *PVLISTBOOL;
/*****************************************************************************
*
* VBool_PreDisplay
*
* Check the Yes or No, accordingly.
*
* Note that there is no such thing as a read-only radio button.
* We have to disable it.
*
*****************************************************************************/
void INTERNAL
VBool_PreDisplay(HWND hdlg, PV pv)
{
PVLISTBOOL pvbool = pv;
/*
* Need to do this early so our subclass procedure knows who
* we're talking about.
*/
SetDialogPtr(hdlg, pvbool);
CheckRadioButton(hdlg, IDC_VBOOL_YES, IDC_VBOOL_NO,
pvbool->dipdw.dwData ? IDC_VBOOL_YES
: IDC_VBOOL_NO);
ShowWindow(GetDlgItem(hdlg, IDC_VBOOL_APPLY),
pvbool->Update ? SW_SHOW : SW_HIDE);
}
/*****************************************************************************
*
* VBool_Destroy
*
* Nothing to clean up.
*
*****************************************************************************/
void INTERNAL
VBool_Destroy(PV pv)
{
PVLISTBOOL pvbool = pv;
}
/*****************************************************************************
*
* VBool_Button_SubclassProc
*
* Procedure we install that subclasses our radio buttons.
*
* If we are in R/O mode, then we return DLGC_STATIC so the
* dialog manager won't include us in the TAB order.
*
*****************************************************************************/
LRESULT CALLBACK
VBool_Button_SubclassProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
switch (wm) {
case WM_GETDLGCODE:
{
PVLISTBOOL pvbool = GetDialogPtr(GetParent(hwnd));
if (pvbool && !pvbool->Update) {
return DLGC_STATIC;
}
}
break;
}
return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA),
hwnd, wm, wp, lp);
}
/*****************************************************************************
*
* VBool_OnInitDialog
*
* Subclas our buttons so they act "dumb".
*
*****************************************************************************/
BOOL INTERNAL
VBool_OnInitDialog(HWND hdlg)
{
WNDPROC wp;
HWND hwnd;
hwnd = GetDlgItem(hdlg, IDC_VBOOL_YES);
wp = SubclassWindow(hwnd, VBool_Button_SubclassProc);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (INT_PTR)wp);
hwnd = GetDlgItem(hdlg, IDC_VBOOL_NO);
wp = SubclassWindow(hwnd, VBool_Button_SubclassProc);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (INT_PTR)wp);
return TRUE;
}
/*****************************************************************************
*
* VBool_OnApply
*
* Let the owner know.
*
*****************************************************************************/
void INTERNAL
VBool_OnApply(HWND hdlg)
{
HRESULT hres;
PVLISTBOOL pvbool = GetDialogPtr(hdlg);
pvbool->dipdw.dwData = IsDlgButtonChecked(hdlg, IDC_VBOOL_YES);
hres = pvbool->Update(&pvbool->dipdw.diph, pvbool->pvRef1, pvbool->pvRef2);
if (FAILED(hres)) {
MessageBoxV(hdlg, IDS_ERR_HRESULT, hres);
}
}
/*****************************************************************************
*
* VBool_OnCommand
*
* If they clicked one of the options, change it back if we are R/O.
*
* If they pressed Apply, then apply it.
*
*****************************************************************************/
BOOL INLINE
VBool_OnCommand(HWND hdlg, int id, UINT codeNotify)
{
switch (id) {
case IDC_VBOOL_APPLY:
VBool_OnApply(hdlg);
return TRUE;
}
return FALSE;
}
/*****************************************************************************
*
* VBool_DlgProc
*
* Nothing really happens here. The real work is done externally.
*
*****************************************************************************/
INT_PTR CALLBACK
VBool_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
{
switch (wm) {
case WM_INITDIALOG: return VBool_OnInitDialog(hdlg);
case WM_COMMAND:
return VBool_OnCommand(hdlg,
(int)GET_WM_COMMAND_ID(wp, lp),
(UINT)GET_WM_COMMAND_CMD(wp, lp));
}
return FALSE;
}
/*****************************************************************************
*
* c_vvtblBool
*
* Our vtbl.
*
*****************************************************************************/
const VLISTVTBL c_vvtblBool = {
VBool_PreDisplay,
VBool_Destroy,
IDD_VAL_BOOL,
VBool_DlgProc,
};
/*****************************************************************************
*
* VBool_Create
*
* Make a vlist item that tracks a BOOL.
*
*****************************************************************************/
PVLISTITEM EXTERNAL
VBool_Create(LPDIPROPDWORD pdipdw, PROPUPDATEPROC Update, PV pvRef1, PV pvRef2)
{
PVLISTBOOL pvbool = LocalAlloc(LPTR, cbX(VLISTBOOL));
if (pvbool) {
pvbool->item.pvtbl = &c_vvtblBool;
pvbool->dipdw = *pdipdw;
pvbool->Update = Update;
pvbool->pvRef1 = pvRef1;
pvbool->pvRef2 = pvRef2;
}
return (PV)pvbool;
}