Exemplo n.º 1
0
static INT_PTR CALLBACK plStealthMouseOverrideProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    IParamMap2 *map = (IParamMap2 *)GetWindowLongPtr( hWnd, GWLP_USERDATA );

    switch( msg )
    {
        case WM_LBUTTONDOWN:
        case WM_LBUTTONUP:
        case WM_MOUSEMOVE:
            {
                // We don't want the COREInterface to process our mouse messages with RollupMouseMessage;
                // rather, we want IMtlParams to do it just like it would if we could actually call
                // CreateChildMParamMap2
                IParamBlock2 *pb = map->GetParamBlock();
                if( pb != nil )
                {
                    plAnimStealthNode *stealth = (plAnimStealthNode *)pb->GetOwner();
                    if( stealth != nil )
                    {
                        plPassMtlBase *mtl = (plPassMtlBase *)stealth->GetParentMtl();
                        mtl->fIMtlParams->RollupMouseMessage( hWnd, msg, wParam, lParam );
                    }
                }
            return 0;
            }
    }

    if( sOldStealthDlgProc != nil )
        return CallWindowProc( sOldStealthDlgProc, hWnd, msg, wParam, lParam );
    else
        return 0;
}
Exemplo n.º 2
0
    BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        IParamBlock2 *pb = map->GetParamBlock();
        plRTLightBase *gl = (plRTLightBase *) pb->GetOwner();

        switch (msg)
        {
            case WM_COMMAND:
                if(LOWORD(wParam) == IDC_PROJ_MAPNAME )
                {
                    if( gl->ClassID() != RTOMNI_LIGHT_CLASSID )
//                  if(pb->GetInt(plRTLightBase::kLightType) != plRTLightBase::RT_OMNI)
                    
                    //  map->SetValue(plRTSpotLight::kProjMapTexButton, t, 
                        //gl->SetProjMap(
                        map->Invalidate(plRTSpotLight::kProjMapTexButton);
                    return false;
                }
                else if( LOWORD( wParam ) == IDC_LHOTSIZE || LOWORD( wParam ) == IDC_LFALLOFF )
                {
                    if( HIWORD( wParam ) == EN_CHANGE )
                        IValidateSpinners( t, wParam, pb, map );
                }
                break;

            case CC_SPINNER_CHANGE:      
                if( LOWORD( wParam ) == IDC_LHOTSIZESPINNER || LOWORD( wParam ) == IDC_LFALLOFFSPINNER )
                    IValidateSpinners( t, wParam, pb, map );
                break;
        }

        return plBaseLightProc::DlgProc( t, map, hWnd, msg, wParam, lParam );;
    }
Exemplo n.º 3
0
    BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_INITDIALOG:
            fPB = map->GetParamBlock();
            
            fNoteTrackDlgX.Init(GetDlgItem(hWnd, IDC_COMP_CLICK_DRAG_ANIMX),
                                nil,
                                kClickDragAnimX,
                                -1,
                                fPB,
                                fPB->GetOwner());

            fNoteTrackDlgX.Load();

            EnableWindow(GetDlgItem(hWnd, IDC_COMP_CLICK_DRAG_ANIMX), true);
            
            fNoteTrackDlgY.Init(GetDlgItem(hWnd, IDC_COMP_CLICK_DRAG_ANIM_Y),
                                nil,
                                kClickDragAnimY,
                                -1,
                                fPB,
                                fPB->GetOwner());

            fNoteTrackDlgY.Load();

            EnableWindow(GetDlgItem(hWnd, IDC_COMP_CLICK_DRAG_ANIM_Y), true);
            return TRUE;

        case WM_COMMAND:
            if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMP_CLICK_DRAG_ANIMX)
            {
                fNoteTrackDlgX.AnimChanged();
                return TRUE;
            }
            if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMP_CLICK_DRAG_ANIM_Y)
            {
                fNoteTrackDlgY.AnimChanged();
                return TRUE;
            }
            break;
        }
        return false;   
    }
void    plPassAnimDlgProc::IExposeStealthNode( HelperObject *node, IParamMap2 *thisMap )
{
    if( node->ClassID() != ANIMSTEALTH_CLASSID )
        return;

    // Get our stealth pointer
    plAnimStealthNode *stealth = (plAnimStealthNode *)node;

    // Create the paramMap-based dialog for us
    IParamBlock2 *pb = thisMap->GetParamBlock();
    plPassMtlBase *mtl = (plPassMtlBase *)pb->GetOwner();

    if( !stealth->CreateAndEmbedDlg( thisMap, mtl->fIMtlParams, GetDlgItem( fhWnd, IDC_PLACEHOLDER ) ) )
    {
    }
}
Exemplo n.º 5
0
        BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
        {
            IParamBlock2        *pb = map->GetParamBlock();
            plRTProjDirLight    *lite = (plRTProjDirLight *)pb->GetOwner();
            PBBitmap            *bitmap;
            plLayerTex          *layer = (plLayerTex *)lite->GetProjMap();
            ICustButton         *bmSelectBtn;


            switch( msg )
            {
                case WM_COMMAND:
                    if( LOWORD( wParam ) == IDC_PROJ_MAPNAME )
                    {
                        BOOL selectedNewBitmap = layer->HandleBitmapSelection();
                        if( selectedNewBitmap )
                        {
                            bmSelectBtn = GetICustButton( GetDlgItem( hWnd, IDC_PROJ_MAPNAME ) );
                            bitmap = layer->GetPBBitmap();
                            bmSelectBtn->SetText( bitmap != nil ? (TCHAR *)bitmap->bi.Filename() : "");
                            ReleaseICustButton( bmSelectBtn );
                        }
                        return false;
                    }
                    break;

                case WM_INITDIALOG:

                    // Set projection map bitmap name
                    bmSelectBtn = GetICustButton( GetDlgItem( hWnd, IDC_PROJ_MAPNAME ) );
                    if( bmSelectBtn != nil )
                    {
                        bitmap = ( layer == nil ) ? nil : layer->GetPBBitmap();
                        if( bitmap != nil )
                            bmSelectBtn->SetText( (TCHAR *)bitmap->bi.Filename() );
                        else
                            bmSelectBtn->SetText( _T( "<none>" ) );
                        ReleaseICustButton( bmSelectBtn );
                    }

                    break;
            }

            return plBaseLightProc::DlgProc( t, map, hWnd, msg, wParam, lParam );
        }
Exemplo n.º 6
0
    BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_INITDIALOG:
            {
                IParamBlock2 *pb = map->GetParamBlock();

                // Enable the min and max controls (that are only valid with stop points)
                // if at least one of the targets has a stop point
                plAnimComponent *comp = (plAnimComponent*)pb->GetOwner();
                int num = comp->NumTargets();
                bool stopPoints = false;
                for (int i = 0; i < num; i++)
                {
                    if (DoesHaveStopPoints(comp->GetTarget(i)))
                    {
                        stopPoints = true;
                        break;
                    }
                }
                EnableStopPoints(map, stopPoints);

                // If we're doing an ease, set the ease rollup to open
                if (pb->GetInt(kAnimEaseInType) != plAnimEaseTypes::kNoEase ||
                    pb->GetInt(kAnimEaseOutType) != plAnimEaseTypes::kNoEase)
                    PostMessage(hWnd, WM_ROLLOUT_OPEN, 0, 0);
            }
            return TRUE;

        // Max doesn't know about the rollup until after WM_CREATE, so we get
        // around it by posting a message
        case WM_ROLLOUT_OPEN:
            {
                IRollupWindow *rollup = GetCOREInterface()->GetCommandPanelRollup();
                int idx = rollup->GetPanelIndex(hWnd);
                rollup->SetPanelOpen(idx, TRUE);
            }
            return TRUE;
        }
        return FALSE;
    }
Exemplo n.º 7
0
plComponentBase *plMaxNodeBase::IRefMakerToComponent(ReferenceMaker *maker, bool all)
{
    if (!maker)
        return nil;

    // Is the refmaker a paramblock?  If so, it may be the
    // targets block of a component
    if (maker->SuperClassID() == PARAMETER_BLOCK2_CLASS_ID)
    {
        IParamBlock2 *pb = (IParamBlock2*)maker;
        ReferenceMaker *pbowner = pb->GetOwner();

        // Is the owner of the paramblock a helper object (component superclass)?
        if (pbowner && pbowner->SuperClassID() == HELPER_CLASS_ID)
        {
            Object *obj = (Object*)pbowner;
            // Is the owner of the paramblock a component?
            if (IsComponent(obj))
            {
                plComponentBase *comp = (plComponentBase*)obj;

                if (!all)
                {
                    // Does this component actually ref us? (A component can have other
                    // refs to a node, like a proxy object, so we want to make sure this
                    // node is actually in the target list.)
                    for (uint32_t i = 0; i < comp->NumTargets(); i++)
                    {
                        if (comp->GetTarget(i) == this)
                            return comp;
                    }
                }
                else
                    return comp;
            }
        }
    }

    return nil;
}
Exemplo n.º 8
0
BOOL plStealthDlgProc::DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    IParamBlock2 *pb = map->GetParamBlock();
    plAnimStealthNode *stealth = (plAnimStealthNode *)pb->GetOwner();

    switch (msg)
    {
        case WM_INITDIALOG:
        {
            // Install our override proc so we can capture mouse messages ourselves.
            // Note that the first time, we grab the old proc so we can restore with that
            // one every time after, since they should always be the same proc
            WNDPROC old = (WNDPROC)SetWindowLongPtr( hWnd, DWLP_DLGPROC, (LONG_PTR)plStealthMouseOverrideProc );
            if( sOldStealthDlgProc == nil )
                sOldStealthDlgProc = old;

            fhWnd = hWnd;
            IInitControls( stealth, pb );

            return TRUE;
        }

        case WM_DESTROY:
            // Restore our old proc
            SetWindowLongPtr( hWnd, DWLP_DLGPROC, (LONG_PTR)sOldStealthDlgProc );
            break;

        case WM_ENABLE:
            // The entire dialog was either enabled or disabled. 
            break;

    case WM_COMMAND:
        // Loop selection changed
        if( LOWORD( wParam ) == IDC_LOOPS && HIWORD( wParam ) == CBN_SELCHANGE )
        {
            // If a loop is selected, save it
            HWND hCombo = (HWND)lParam;
            int sel = SendMessage( hCombo, CB_GETCURSEL, 0, 0 );
            if( sel != CB_ERR )
            {
                if( SendMessage( hCombo, CB_GETITEMDATA, sel, 0 ) == kName )
                {
                    char buf[256];
                    SendMessage( hCombo, CB_GETLBTEXT, sel, (LPARAM)buf );
                    pb->SetValue( (ParamID)plAnimStealthNode::kPBLoopName, 0, buf );
                }
                else
                    pb->SetValue( (ParamID)plAnimStealthNode::kPBLoopName, 0, "" );
            }

            return TRUE;
        }

        // Auto-start or loop checkbox checked
        if( LOWORD( wParam ) == IDC_LOOP && HIWORD( wParam ) == BN_CLICKED )
        {
            BOOL checked = ( SendMessage( (HWND)lParam, BM_GETCHECK, 0, 0 ) == BST_CHECKED );

            pb->SetValue( plAnimStealthNode::kPBLoop, 0, checked );
            EnableWindow( GetDlgItem( hWnd, IDC_LOOPS ), checked );
            return TRUE;
        }

        // Refresh clicked
        else if( LOWORD( wParam ) == IDC_REFRESH_ANIMS && HIWORD( wParam ) == BN_CLICKED )
        {
            IInitControls( stealth, pb );
            return TRUE;
        }

        break;
    }

    return FALSE;
}
Exemplo n.º 9
0
    BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        int selection;
        HWND cbox = NULL;
        HWND hList = GetDlgItem(hWnd, IDC_COMP_LOD_AVATAR_BONELIST);

        switch (msg)
        {
        case WM_INITDIALOG:
            {
                int LodBeginState   = map->GetParamBlock()->GetInt(plLODAvatarComponent::kLODState);

                HWND LODCombo = GetDlgItem(hWnd, IDC_COMP_LOD_AVATAR_STATE);
    
                fMstrDlg = hWnd;
            
                fPB = map->GetParamBlock();
                fComp = (plLODAvatarComponent*) fPB->GetOwner();

                VCharArray Nilptr;
                ILoadComboBox(LODCombo, fComp->fLODLevels);
                SendMessage(LODCombo, CB_SETCURSEL, LodBeginState,  0); // select the right one

                int i;
                for (i = 0; i < plClothingMgr::kMaxGroup; i++)
                {
                    cbox = GetDlgItem(hWnd, IDC_COMP_AVATAR_CLOTHING_GROUP);
                    SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM)plClothingMgr::GroupStrings[i]);
                }
                selection = fPB->GetInt(ParamID(plLODAvatarComponent::kClothingGroup));
                SendMessage(cbox, CB_SETCURSEL, selection, 0);

                for (i = 0; i < plArmatureMod::kMaxBoneBase; i++)
                {
                    cbox = GetDlgItem(hWnd, IDC_COMP_AVATAR_SKELETON);
                    SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM)plArmatureMod::BoneStrings[i]);
                }
                selection = fPB->GetInt(ParamID(plLODAvatarComponent::kSkeleton));
                SendMessage(cbox, CB_SETCURSEL, selection, 0);

                Mtl *mat = fPB->GetMtl(plLODAvatarComponent::kMaterial);
                Button_SetText(GetDlgItem(hWnd, IDC_COMP_LOD_AVATAR_MTL), (mat ? mat->GetName() : "(none)"));

                UpdateBoneDisplay(map);
                return true;
            }

        case WM_COMMAND:
            if (LOWORD(wParam) == IDC_COMP_AVATAR_CLOTHING_GROUP)
            {
                selection = SendMessage(GetDlgItem(hWnd, IDC_COMP_AVATAR_CLOTHING_GROUP), CB_GETCURSEL, 0, 0);
                fPB->SetValue(ParamID(plLODAvatarComponent::kClothingGroup), t, selection);
                return TRUE;
            }
            else if (LOWORD(wParam) == IDC_COMP_AVATAR_SKELETON)
            {
                selection = SendMessage(GetDlgItem(hWnd, IDC_COMP_AVATAR_SKELETON), CB_GETCURSEL, 0, 0);
                fPB->SetValue(ParamID(plLODAvatarComponent::kSkeleton), t, selection);
                return TRUE;
            }
            else if (HIWORD(wParam) == BN_CLICKED)
            {
                if (LOWORD(wParam) == IDC_COMP_LOD_AVATAR_BONE_ADD)
                {
                    std::vector<Class_ID> cids;
                    cids.push_back(Class_ID(TRIOBJ_CLASS_ID, 0));
                    cids.push_back(Class_ID(EDITTRIOBJ_CLASS_ID, 0));
                    if (plPick::NodeRefKludge(fPB, plLODAvatarComponent::kLastPick, &cids, true, false))            
                        fComp->AddSelectedBone();

                    return TRUE;
                }
                // Remove the currently selected material
                else if (LOWORD(wParam) == IDC_COMP_LOD_AVATAR_BONE_REMOVE)
                {
                    int curSel = SendMessage(hList, LB_GETCURSEL, 0, 0);
                    if (curSel >= 0)
                        fComp->RemoveBone(curSel);

                    return TRUE;
                }
                else if (LOWORD(wParam) == IDC_COMP_LOD_AVATAR_MTL)
                {
                    Mtl *pickedMtl = plPickMaterialMap::PickMaterial(plMtlCollector::kPlasmaOnly);
                    fPB->SetValue(plLODAvatarComponent::kMaterial, 0, pickedMtl);
                    Button_SetText(GetDlgItem(hWnd, IDC_COMP_LOD_AVATAR_MTL), (pickedMtl ? pickedMtl->GetName() : "(none)"));

                    return TRUE;
                }
            }
            else 
            {
                int LodBeginState   = map->GetParamBlock()->GetInt(plLODAvatarComponent::kLODState);
                
                if(fPB->GetINode(plLODAvatarComponent::kMeshNodeAddBtn,t))
                    fPB->SetValue(plLODAvatarComponent::kMeshNodeTab, t, fPB->GetINode(plLODAvatarComponent::kMeshNodeAddBtn,t), LodBeginState);
                    
                if(LOWORD(wParam) == IDC_COMP_LOD_AVATAR_STATE && HIWORD(wParam) == CBN_SELCHANGE)
                {
                    int idx = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
                    fPB->SetValue(plLODAvatarComponent::kLODState, 0, idx);
                    
                    if(fPB->GetINode(plLODAvatarComponent::kMeshNodeTab, t, idx))
                        fPB->SetValue(plLODAvatarComponent::kMeshNodeAddBtn, t, fPB->GetINode(plLODAvatarComponent::kMeshNodeTab,t, idx));
                    else
                        fPB->Reset(plLODAvatarComponent::kMeshNodeAddBtn);
                    return true;
                }
            }

            break;

        case WM_CLOSE:
            {
                int LodBeginState   = map->GetParamBlock()->GetInt(plLODAvatarComponent::kLODState);

                if(fPB->GetINode(plLODAvatarComponent::kMeshNodeAddBtn,t))
                    fPB->SetValue(plLODAvatarComponent::kMeshNodeTab, t, fPB->GetINode(plLODAvatarComponent::kMeshNodeAddBtn,t), LodBeginState);

                return false;
            }
        }
            
        return false;
    }
BOOL plPassAnimDlgProc::DlgProc(TimeValue t, IParamMap2 *pMap, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if( fCurrParamMap != pMap )
    {
        if( fCurrParamMap != nil )
        {
            plPassMtlBase *mtl = (plPassMtlBase *)( fCurrParamMap->GetParamBlock()->GetOwner() );
            mtl->UnregisterChangeCallback( this );
        }

        fCurrParamMap = pMap;

        if( fCurrParamMap != nil )
        {
            plPassMtlBase *mtl = (plPassMtlBase *)( fCurrParamMap->GetParamBlock()->GetOwner() );
            mtl->RegisterChangeCallback( this );
        }
    }

    IParamBlock2 *pb = pMap->GetParamBlock();
    plPassMtlBase *mtl = (plPassMtlBase*)pb->GetOwner();
    HWND gWnd = GetDlgItem(hWnd, IDC_MTL_GLOBAL_NAME);  
    char buff[512];

    switch (msg)
    {
        case WM_DESTROY:
            if( fCurrParamMap != nil )
            {
                plPassMtlBase *mtl = (plPassMtlBase *)( fCurrParamMap->GetParamBlock()->GetOwner() );
                mtl->RegisterChangeCallback( this );
                fCurrParamMap = nil;
            }
            break;

        case WM_INITDIALOG:
            {
                fhWnd = hWnd;
                fCurrStealth = nil;
                IInitControls(mtl, pb);

                plAnimComponentProc::FillAgeGlobalComboBox(gWnd, pb->GetStr(ParamID(kPBAnimGlobalName)));                           
                plAnimComponentProc::SetBoxToAgeGlobal(gWnd, pb->GetStr(ParamID(kPBAnimGlobalName)));   
                IEnableGlobal(hWnd, pb->GetInt( (ParamID)kPBAnimUseGlobal ) );      

                bool stopPoints = false;
                if( DoesHaveStopPoints( pb->GetOwner() ) )
                {
                    stopPoints = true;
                    break;
                }
                
                IEnableEaseStopPoints( pMap, stopPoints );
            }
            return TRUE;

        case WM_COMMAND:
            // Anim name selection changed
            if (LOWORD(wParam) == IDC_NAMES && HIWORD(wParam) == CBN_SELCHANGE)
            {
                IUpdateSegmentSel( pMap );
                return TRUE;
            }
            // Refresh clicked
            else if (LOWORD(wParam) == IDC_REFRESH_ANIMS && HIWORD(wParam) == BN_CLICKED)
            {
                IInitControls(mtl, pb);
                return TRUE;
            }
            else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_MTL_GLOBAL_NAME)
            {
                ComboBox_GetLBText(gWnd, ComboBox_GetCurSel(gWnd), buff);
                pb->SetValue(ParamID(kPBAnimGlobalName), 0, _T(buff));
            }           
            else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_MTL_USE_GLOBAL)
            {
                IEnableGlobal(hWnd, pb->GetInt( (ParamID)kPBAnimUseGlobal ) );
            }

            break;
    }

    return FALSE;
}
BOOL plResponderProc::DlgProc(TimeValue t, IParamMap2 *pm, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static UINT dragListMsg = 0;

    if (dragListMsg != 0 && msg == dragListMsg)
        if (DragListProc(hWnd, (DRAGLISTINFO*)lParam))
            return TRUE;

    switch (msg)
    {
    case WM_INITDIALOG:
        {
            if (!fhMenu)
                ICreateMenu();

            fhDlg = hWnd;
            fhList = GetDlgItem(fhDlg, IDC_CMD_LIST);
            fCurState = 0;
            fCmdIdx = -1;
            
            fPB = pm->GetParamBlock();
            fComp = (plResponderComponent*)fPB->GetOwner();

            fComp->IFixOldPB();

            LoadState();
            
            // Make it so the user can drag commands to different positions
            dragListMsg = RegisterWindowMessage(DRAGLISTMSGSTRING);
            MakeDragList(GetDlgItem(hWnd, IDC_CMD_LIST));

            // Setup the State Name combo
            HWND hStateName = GetDlgItem(hWnd, IDC_STATE_COMBO);
            ComboBox_LimitText(hStateName, 256);

// I give up, Windows doesn't want to tell me the real font size
#if 0//def CUSTOM_DRAW
            // TEMP
            HDC hDC = GetDC(hStateName);
            HFONT sysFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
            HFONT oldFont = SelectFont(hDC, sysFont);

            TEXTMETRIC tm;
            GetTextMetrics(hDC, &tm);
            ComboBox_SetItemHeight(hStateName, 0, tm.tmHeight+2);

            DeleteFont(SelectFont(hDC, oldFont));
            ReleaseDC(hStateName, hDC);
#endif

            // Add the commands
            int idx = ComboBox_AddString(hStateName, "Add State");
            ComboBox_SetItemData(hStateName, idx, kStateAdd);
            idx = ComboBox_AddString(hStateName, "Remove Current State");
            ComboBox_SetItemData(hStateName, idx, kStateRemove);
            idx = ComboBox_AddString(hStateName, "Set Current as Default");
            ComboBox_SetItemData(hStateName, idx, kStateDefault);
            idx = ComboBox_AddString(hStateName, "Copy Current State");
            ComboBox_SetItemData(hStateName, idx, kStateCopy);

            HWND hSwitchCombo = GetDlgItem(hWnd, IDC_SWITCH_COMBO);

            int numStates = fPB->Count(kResponderStateName);
            for (int i = 0; i < numStates; i++)
            {
                const char *stateName = fPB->GetStr(kResponderStateName, 0, i);
                char buf[128];
                if (!stateName || *stateName == '\0')
                {
                    sprintf(buf, "State %d", i+1);
                    stateName = buf;
                }
                ComboBox_InsertString(hStateName, i, stateName);
                ComboBox_AddString(hSwitchCombo, stateName);
            }

            ComboBox_SetCurSel(hStateName, fCurState);

            ComboBox_SetCurSel(hSwitchCombo, fStatePB->GetInt(kStateCmdSwitch));
        }
        return TRUE;

#ifdef CUSTOM_DRAW
    case WM_DRAWITEM:
        if (wParam == IDC_STATE_COMBO)
        {
            IDrawComboItem((DRAWITEMSTRUCT*)lParam);
            return TRUE;
        }
        break;
#endif

    case WM_SETCURSOR:
        {
            if (HIWORD(lParam) == WM_RBUTTONDOWN && HWND(wParam) == GetDlgItem(hWnd, IDC_CMD_LIST))
            {
                ICmdRightClick(HWND(wParam));
                return TRUE;
            }
        }
        break;
    
    case WM_COMMAND:
        if (HIWORD(wParam) == BN_CLICKED)
        {
            if (LOWORD(wParam) == IDC_ADD_ACTIVATOR)
            {
                // Adding an activator.  Set it and refresh the UI to show it in our list.
                plPick::Activator(fPB, kResponderActivators, false);
                pm->Invalidate(kResponderActivators);
                return TRUE;
            }
            else if (LOWORD(wParam) == IDC_ADD_CMD)
            {
                AddCommand();
                return TRUE;
            }
            // Remove the currently selected condition
            else if (LOWORD(wParam) == IDC_REMOVE_CMD)
            {
                RemoveCurCommand();
                return TRUE;
            }
        }
        else if (HIWORD(wParam) == LBN_SELCHANGE && LOWORD(wParam) == IDC_CMD_LIST)
        {
            ICreateCmdRollups();
            return TRUE;
        }
        else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_SWITCH_COMBO)
        {
            int sel = ComboBox_GetCurSel((HWND)lParam);
            if (sel != CB_ERR)
                fStatePB->SetValue(kStateCmdSwitch, 0, sel);
        }
        else if (LOWORD(wParam) == IDC_STATE_COMBO)
        {
            HWND hCombo = (HWND)lParam;
            int code = HIWORD(wParam);

            // Disable accelerators when the combo has focus, so that new names can be typed in
            if (code == CBN_SETFOCUS)
            {
                plMaxAccelerators::Disable();
                return TRUE;
            }
            else if (code == CBN_KILLFOCUS)
            {
                plMaxAccelerators::Enable();
                return TRUE;
            }
            // State name changed, save it in the PB
            else if (code == CBN_EDITCHANGE)
            {
                char buf[256];
                ComboBox_GetText(hCombo, buf, sizeof(buf));
                const char *curName = fPB->GetStr(kResponderStateName, 0, fCurState);
                if (!curName || strcmp(buf, curName))
                {
                    HWND hSwitch = GetDlgItem(hWnd, IDC_SWITCH_COMBO);
                    int sel = ComboBox_GetCurSel(hSwitch);
                    ComboBox_DeleteString(hSwitch, fCurState);
                    ComboBox_InsertString(hSwitch, fCurState, buf);
                    ComboBox_SetCurSel(hSwitch, sel);
                    
                    fPB->SetValue(kResponderStateName, 0, buf, fCurState);
                    ComboBox_DeleteString(hCombo, fCurState);
                    ComboBox_InsertString(hCombo, fCurState, buf);
//                  ComboBox_SetCurSel(hCombo, fCurState);
                }

                return TRUE;
            }
            else if (code == CBN_SELCHANGE)
            {
                int sel = ComboBox_GetCurSel(hCombo);
                int type = ComboBox_GetItemData(hCombo, sel);

                if (type == kStateAdd)
                {
                    IParamBlock2 *pb = CreateParameterBlock2(&gStateBlock, nil);
                    fCurState = AddState(pb);
                    fCmdIdx = -1;
                }
                else if (type == kStateRemove)
                {
                    int count = fPB->Count(kResponderState);
                    // Don't let the user remove the last state
                    if (count == 1)
                    {
                        hsMessageBox("You must have at least one state.", "Error", hsMessageBoxNormal);
                        ComboBox_SetCurSel(hCombo, fCurState);
                        return TRUE;
                    }
                    // Verify that the user really wants to delete the state
                    else
                    {
                        int ret = hsMessageBox("Are you sure you want to remove this state?", "Verify Remove", hsMessageBoxYesNo);
                        if (ret == hsMBoxNo)
                        {
                            ComboBox_SetCurSel(hCombo, fCurState);
                            return TRUE;
                        }
                    }

                    fPB->Delete(kResponderState, fCurState, 1);
                    fPB->Delete(kResponderStateName, fCurState, 1);

                    ComboBox_DeleteString(hCombo, fCurState);
                    ComboBox_SetCurSel(hCombo, 0);

                    HWND hSwitch = GetDlgItem(hWnd, IDC_SWITCH_COMBO);
                    ComboBox_DeleteString(hSwitch, fCurState);

                    // If the deleted state was the default, set the default to the first
                    int defState = fPB->GetInt(kResponderStateDef);
                    if (fCurState == defState)
                        fPB->SetValue(kResponderStateDef, 0, 0);
                    else if (fCurState < defState)
                        fPB->SetValue(kResponderStateDef, 0, defState-1);

                    // Patch up the switch commands
                    for (int i = fCurState; i < fPB->Count(kResponderState); i++)
                    {
                        IParamBlock2 *pb = (IParamBlock2*)fPB->GetReferenceTarget(kResponderState, 0, i);

                        int switchState = pb->GetInt(kStateCmdSwitch);
                        // TODO: might want to warn about this
                        if (switchState == fCurState)
                            pb->SetValue(kStateCmdSwitch, 0, 0);
                        else if (switchState > fCurState)
                            pb->SetValue(kStateCmdSwitch, 0, switchState-1);
                    }

                    fCurState = 0;
                    fCmdIdx = -1;
                }
                else if (type == kStateDefault)
                {
                    // Set the current state as the default
                    fPB->SetValue(kResponderStateDef, 0, fCurState);
                    ComboBox_SetCurSel(hCombo, fCurState);
                }
                else if (type == kStateCopy)
                {
                    // Clone the state PB
                    IParamBlock2 *origPB = (IParamBlock2*)fPB->GetReferenceTarget(kResponderState, 0, fCurState);
                    IParamBlock2 *copyPB = (IParamBlock2*)origPB->Clone(gMyRemapDir);
                    fCurState = AddState(copyPB);
                    fCmdIdx = -1;
                }
                else
                {
                    fCurState = sel;
                    fCmdIdx = -1;
                }

                LoadState();

                return TRUE;
            }
        }
    }

    return FALSE;
}