void plResponderProc::ICreateCmdRollups()
{
    // Get the index of the current command
    HWND hCmds = GetDlgItem(fhDlg, IDC_CMD_LIST);
    int cmdIdx = ListBox_GetCurSel(hCmds);

    if (cmdIdx != LB_ERR && cmdIdx != fCmdIdx)
    {
        fCmdIdx = cmdIdx;
        fIgnoreNextDrop = true;

        // Save the current scroll position and reset it at the end, so the panels
        // won't always jerk back up to the top
        IRollupWindow *rollup = GetCOREInterface()->GetCommandPanelRollup();
        int scrollPos = rollup->GetScrollPos();

        // Destroy the last command's rollups
        IRemoveCmdRollups();

        // Create the rollup for the current command
        IParamBlock2 *pb = (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdParams, 0, fCmdIdx);
        fCmdMap = ICreateMap(pb);

        ResponderWait::InitDlg(fStatePB, fCmdIdx, GetDlgItem(fhDlg, IDC_CMD_LIST));
        pb = (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdWait, 0, fCmdIdx);
        fWaitMap = ICreateMap(pb);

        rollup->SetScrollPos(scrollPos);
    }
}
void plResponderProc::MoveCommand(int oldIdx, int newIdx)
{
    // Move data
    int insertIdx = (newIdx > oldIdx) ? newIdx+1 : newIdx;
    int deleteIdx = (newIdx < oldIdx) ? oldIdx+1 : oldIdx;

    ReferenceTarget *targ = fStatePB->GetReferenceTarget(kStateCmdParams, 0, oldIdx);
    fStatePB->Insert(kStateCmdParams, insertIdx, 1, &targ);
    fStatePB->Delete(kStateCmdParams, deleteIdx, 1);

    ReferenceTarget *wait = fStatePB->GetReferenceTarget(kStateCmdWait, 0, oldIdx);
    fStatePB->Insert(kStateCmdWait, insertIdx, 1, &wait);
    fStatePB->Delete(kStateCmdWait, deleteIdx, 1);

    BOOL oldEnabled = fStatePB->GetInt(kStateCmdEnabled, 0, oldIdx);
    BOOL newEnabled = fStatePB->GetInt(kStateCmdEnabled, 0, newIdx);
    fStatePB->SetValue(kStateCmdEnabled, 0, oldEnabled, newIdx);
    fStatePB->SetValue(kStateCmdEnabled, 0, newEnabled, oldIdx);

    ResponderWait::CmdMoved(fStatePB, oldIdx, newIdx);

    LoadList();

    // Reselect item
    // (This doesn't send the LBN_SELCHANGE message so we do that manually)
    ListBox_SetCurSel(fhList, newIdx);
    ICreateCmdRollups();
}
const char* plResponderProc::GetCommandName(int cmdIdx)
{
    static char buf[256];

    if (fStatePB->Count(kStateCmdParams) > cmdIdx)
    {
        buf[0] = '\0';

        BOOL enabled = fStatePB->GetInt(kStateCmdEnabled, 0, cmdIdx);
        if (!enabled)
            strcat(buf, "[D]");

        IParamBlock2 *cmdPB = (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdParams, 0, cmdIdx);
        plResponderCmd *cmd = plResponderCmd::Find(cmdPB);

        IParamBlock2 *waitPB = (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdWait, 0, cmdIdx);
        int waitingOn = ResponderWait::GetWaitingOn(waitPB);
        if (waitingOn != -1)
        {
            char num[10];
            sprintf(num, "(%d)", waitingOn+1);
            strcat(buf, num);
        }

        strcat(buf, cmd->GetInstanceName(cmdPB));

        return buf;
    }

    hsAssert(0, "Bad index to GetCommandName");
    return nil;
}
void plResponderComponent::ISetupDefaultWait(plMaxNode* node, plErrorMsg* pErrMsg,
                                             int state, CmdIdxs& cmdIdxs, int &numCallbacks)
{
    IParamBlock2 *statePB = (IParamBlock2*)fCompPB->GetReferenceTarget(kResponderState, 0, state);
    plResponderModifier *responder = IGetResponderMod(node);
    hsTArray<plResponderModifier::plResponderCmd>& cmds = responder->fStates[state].fCmds;

    int numCmds = cmds.Count();
    for (int i = 0; i < numCmds; i++)
    {
        IParamBlock2 *waitPB = GetWaitBlk(statePB, i);
        ResponderWait::FixupWaitBlock(waitPB);

        // If we're supposed to wait for this command, and it converted, create a callback
        if (ResponderWait::GetWaitOnMe(waitPB) && cmdIdxs.find(i) != cmdIdxs.end())
        {
            int convertedIdx = cmdIdxs[i];

            ResponderWaitInfo waitInfo;
            waitInfo.responderName = plString::FromUtf8(GetINode()->GetName());
            waitInfo.receiver = responder->GetKey();
            waitInfo.callbackUser = numCallbacks++;
            waitInfo.msg = cmds[convertedIdx].fMsg;
            waitInfo.point = plString::Null;

            IParamBlock2 *pb = (IParamBlock2*)statePB->GetReferenceTarget(kStateCmdParams, 0, i);
            plResponderCmd *cmd = plResponderCmd::Find(pb);

            cmd->CreateWait(node, pErrMsg, pb, waitInfo);
        }
    }
}
void plResponderProc::LoadState()
{
    fStatePB = (IParamBlock2*)fPB->GetReferenceTarget(kResponderState, 0, fCurState);

    IRemoveCmdRollups();
    LoadList();

    HWND hSwitchCombo = GetDlgItem(fhDlg, IDC_SWITCH_COMBO);
    ComboBox_SetCurSel(hSwitchCombo, fStatePB->GetInt(kStateCmdSwitch));
}
void plResponderComponent::IConvertCmds(plMaxNode* node, plErrorMsg* pErrMsg, int state, CmdIdxs& cmdIdxs)
{
    IParamBlock2 *statePB = (IParamBlock2*)fCompPB->GetReferenceTarget(kResponderState, 0, state);
    plResponderModifier *responder = IGetResponderMod(node);

    // Add the messages to the logic modifier
    for (int i = 0; i < statePB->Count(kStateCmdParams); i++)
    {
        plMessage *msg = nil;

        BOOL enabled = statePB->GetInt(kStateCmdEnabled, 0, i);
        if (!enabled)
            continue;

        IParamBlock2 *cmdPB = (IParamBlock2*)statePB->GetReferenceTarget(kStateCmdParams, 0, i);

        try
        {
            plResponderCmd *cmd = plResponderCmd::Find(cmdPB);
            if (cmd)
                msg = cmd->CreateMsg(node, pErrMsg, cmdPB);
        }
        catch (char *reason)
        {
            char buf[512];

            char stateName[128];
            const char *curStateName = fCompPB->GetStr(kResponderStateName, 0, state);
            if (curStateName && *curStateName != '\0')
                strcpy(stateName, fCompPB->GetStr(kResponderStateName, 0, state));
            else
                sprintf(stateName, "State %d", state+1);

            sprintf(buf,
                "A responder command failed to export.\n\nResponder:\t%s\nState:\t\t%s\nCommand:\t%d\n\nReason: %s",
                GetINode()->GetName(), stateName, i+1, reason);

            pErrMsg->Set(true, "Responder Warning", buf).Show();
            pErrMsg->Set(false);
        }

        if (msg)
        {
            msg->SetSender(responder->GetKey());
            responder->AddCommand(msg, state);
            int idx = responder->fStates[state].fCmds.Count()-1;
            cmdIdxs[i] = idx;
        }
    }
}
hsBool plResponderComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
    int numStates = fCompPB->Count(kResponderState);
    for (int i = 0; i < numStates; i++)
    {
        IParamBlock2 *statePB = (IParamBlock2*)fCompPB->GetReferenceTarget(kResponderState, 0, i);

        for (int j = 0; j < statePB->Count(kStateCmdParams); j++)
        {
            IParamBlock2 *cmdPB = (IParamBlock2*)statePB->GetReferenceTarget(kStateCmdParams, 0, j);
            plResponderCmd *cmd = plResponderCmd::Find(cmdPB);
            cmd->SetupProperties(node, pErrMsg, cmdPB);
        }
    }

    return true;
}
void plResponderComponent::IConvertCmdWaits(plMaxNode* node, plErrorMsg* pErrMsg,
                                            int state, CmdIdxs& cmdIdxs, int &numCallbacks)
{
    IParamBlock2 *statePB = (IParamBlock2*)fCompPB->GetReferenceTarget(kResponderState, 0, state);
    plResponderModifier *responder = IGetResponderMod(node);
    hsTArray<plResponderModifier::plResponderCmd>& cmds = responder->fStates[state].fCmds;

    int numWaits = statePB->Count(kStateCmdWait);
    for (int i = 0; i < numWaits; i++)
    {
        IParamBlock2 *waitPB = GetWaitBlk(statePB, i);

        int wait = ResponderWait::GetWaitingOn(waitPB);

        // If the waiter and waitee both converted, create the callback
        if (cmdIdxs.find(wait) != cmdIdxs.end() && cmdIdxs.find(i) != cmdIdxs.end())
        {
            int convertedIdx = cmdIdxs[wait];

            ResponderWaitInfo waitInfo;
            waitInfo.responderName = plString::FromUtf8(GetINode()->GetName());
            waitInfo.receiver = responder->GetKey();
            waitInfo.callbackUser = numCallbacks++;
            waitInfo.msg = cmds[convertedIdx].fMsg;
            waitInfo.point = ResponderWait::GetWaitPoint(waitPB);

            responder->AddCallback(state, convertedIdx, waitInfo.callbackUser);
            cmds[cmdIdxs[i]].fWaitOn = waitInfo.callbackUser;

            IParamBlock2 *pb = (IParamBlock2*)statePB->GetReferenceTarget(kStateCmdParams, 0, wait);
            plResponderCmd *cmd = plResponderCmd::Find(pb);

            cmd->CreateWait(node, pErrMsg, pb, waitInfo);
        }
    }
}
Beispiel #9
0
void plResponderWaitProc::LoadPoint(bool force)
{
    int who = fWaitPB->GetInt(kWaitWho);
    const char *point = fWaitPB->GetStr(kWaitPoint);
    if (point && *point == '\0')
        point = nil;

    CheckRadioButton(fhDlg, IDC_RADIO_FINISH, IDC_RADIO_POINT, point || force ? IDC_RADIO_POINT : IDC_RADIO_FINISH);

    BOOL enableAll = (who != -1);
    EnableWindow(GetDlgItem(fhDlg, IDC_RADIO_FINISH), enableAll);
    EnableWindow(GetDlgItem(fhDlg, IDC_RADIO_POINT), enableAll);

    BOOL enablePoint = ((point != nil) || force) && enableAll;
    EnableWindow(GetDlgItem(fhDlg, IDC_WAIT_POINT), enablePoint);
    ComboBox_ResetContent(GetDlgItem(fhDlg, IDC_WAIT_POINT));

    if (enableAll)
    {
        IParamBlock2 *pb = (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdParams, 0, who);
        plResponderCmd *cmd = plResponderCmd::Find(pb);

        // KLUDGE - stupid one-shot needs editable box
        if (cmd == &(plResponderCmdOneShot::Instance()))
        {
            ShowWindow(GetDlgItem(fhDlg, IDC_WAIT_POINT), SW_HIDE);

            HWND hEdit = GetDlgItem(fhDlg, IDC_MARKER_EDIT);
            ShowWindow(hEdit, SW_SHOW);
            ICustEdit *custEdit = GetICustEdit(hEdit);
            custEdit->SetText(point ? (char*)point : "");
        }
        else
        {
            ShowWindow(GetDlgItem(fhDlg, IDC_WAIT_POINT), SW_SHOW);

            HWND hEdit = GetDlgItem(fhDlg, IDC_MARKER_EDIT);
            ShowWindow(hEdit, SW_HIDE);

            plResponderCmd::WaitPoints waitPoints;
            cmd->GetWaitPoints(pb, waitPoints);

            HWND hCombo = GetDlgItem(fhDlg, IDC_WAIT_POINT);
            ComboBox_ResetContent(hCombo);

            if (waitPoints.size() == 0)
            {
                EnableWindow(GetDlgItem(fhDlg, IDC_RADIO_POINT), FALSE);
                EnableWindow(GetDlgItem(fhDlg, IDC_WAIT_POINT), FALSE);
            }
            else
            {
                for (int i = 0; i < waitPoints.size(); i++)
                {
                    const char *marker = waitPoints[i].c_str();
                    int idx = ComboBox_AddString(hCombo, marker);
                    if (point && !strcmp(point, marker))
                        ComboBox_SetCurSel(hCombo, idx);
                }
            }
        }
    }
}
Beispiel #10
0
IParamBlock2 *plResponderWaitProc::GetCmdParams(int cmdIdx)
{
    return (IParamBlock2*)fStatePB->GetReferenceTarget(kStateCmdParams, 0, cmdIdx);
}
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;
}
Beispiel #12
0
BOOL plPythonFileComponentProc::DlgProc(TimeValue t, IParamMap2 *pmap, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_INITDIALOG:
        {
            IParamBlock2 *pb = pmap->GetParamBlock();

            HWND hCombo = GetDlgItem(hWnd, IDC_PYTHON_FILE);
            ComboBox_ResetContent(hCombo);

            SetDlgItemText(hWnd, IDC_VER_TEXT, "");

            IParamBlock2 *pythonPB = (IParamBlock2*)pb->GetReferenceTarget(kPythonFilePB);
            plAutoUIBlock *pythonBlock = FindAutoUI(pythonPB);

            int numPythonFiles = gAutoUIBlocks.size();
            for (int i = 0; i < numPythonFiles; i++)
            {
                plAutoUIBlock *block = gAutoUIBlocks[i];
                const char *name = block->GetName();

                int idx = ComboBox_AddString(hCombo, name);
                ComboBox_SetItemData(hCombo, idx, i);
                if (block == pythonBlock)
                {
                    ComboBox_SetCurSel(hCombo, idx);
                    SetDlgItemInt(hWnd, IDC_VER_TEXT, block->GetVersion(), TRUE);
                }
            }

            // Crappy hack, see WM_LOAD_AUTO_UI
            PostMessage(hWnd, WM_LOAD_AUTO_UI, 0, 0);
        }
        return TRUE;

    // Crappy hack.  If we put up the python file UI before returning from WM_INITDIALOG
    // it will show up ABOVE the main UI.  To get around this we post a message that won't
    // get processed until after the main UI is put up.
    case WM_LOAD_AUTO_UI:
        {
            IParamBlock2 *pb = pmap->GetParamBlock();

            IParamBlock2 *pythonPB = (IParamBlock2*)pb->GetReferenceTarget(kPythonFilePB);
            plAutoUIBlock *pythonBlock = FindAutoUI(pythonPB);

            if (pythonBlock && pythonPB)
                CreateAutoUI(pythonBlock, pythonPB);
        }
        return TRUE;

    case WM_COMMAND:
        if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_PYTHON_FILE)
        {
            HWND hCombo = (HWND)lParam;
            int sel = ComboBox_GetCurSel(hCombo);

            int type = ComboBox_GetItemData(hCombo, sel);

            plAutoUIBlock *block = gAutoUIBlocks[type];
            IParamBlock2 *autoPB = block->CreatePB();

            CreateAutoUI(block, autoPB);

            IParamBlock2 *pb = pmap->GetParamBlock();
            pb->SetValue(kPythonFilePB, 0, (ReferenceTarget*)autoPB);

            SetDlgItemInt(hWnd, IDC_VER_TEXT, block->GetVersion(), TRUE);

            return TRUE;
        }
        break;
    }
    
    return FALSE;   
}