예제 #1
0
ComboFrameEx::ComboFrameEx(Frame* parent, int id, int style)
  : WindowFrame(parent)
{
  boxHeight = 500;
  create(L"ComboBox", L"", style | WS_CHILD | CBS_OWNERDRAWFIXED | WS_TABSTOP | WS_VSCROLL, 0);
  setFont(FontSys::getSysFont());
  setId(id);
  ComboBox_SetItemHeight(hWnd, -1, 16);
  setHeight(21);
}
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;
}