Tengo una barra de tareas con tareas que necesito habilitar y deshabilitar dinámicamente. Por ahora lo estoy haciendo por CMFCTasksPane :: ShowTask, sin embargo, eso también oculta / muestra la tarea, idealmente me gustaría atenuar la tarea cuando no está habilitada. Noté que ocurre el mismo comportamiento cuando asigno un comando de tarea que no está registrado usando la macro ON_COMMAND, luego está atenuado. Sin embargo, no veo cómo controlar este comportamiento dinámicamente más adelante. ¿Cómo se puede hacer esto? (idealmente utilizando lo que ya se proporciona, pero no necesariamente si no hay otra forma, por supuesto).

Aquí hay un ejemplo mínimo para demostrarlo. En CMainFrame agregué:

// CMainFrame class definition
CMFCTasksPane pane;
afx_msg void OnCommand1() {};
afx_msg void OnCommand2() {};

// constants
int TASKBAR_ID = 33333;
int TASK_ID1 = 34000;
int TASK_ID2 = 34001;

// BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
ON_COMMAND(TASK_ID1, &CMainFrame::OnCommand1)
ON_COMMAND(TASK_ID2, &CMainFrame::OnCommand2)

// CMainFrame::OnCreate
pane.Create("Pane", this, 500, FALSE, TASKBAR_ID);
pane.AddGroup("Group1");
pane.AddTask(0, "Task1", -1, TASK_ID1);
pane.AddTask(0, "Task2", -1, TASK_ID2);
pane.EnableGroupCollapse(FALSE);
pane.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&pane);

Entonces el botón de tareas está visible / se puede hacer clic:

enter image description here

Si, por ejemplo, elimino las macros ON_COMMAND, entonces no se puede hacer clic (que es algo que me gustaría habilitar / deshabilitar dinámicamente):

enter image description here

Si uso el ShowTask, está completamente oculto (como se esperaba, pero no es lo que quiero):

pane.ShowTask(0, 0, FALSE);

enter image description here

Estaré agradecido por cualquier sugerencia.

Editar: Creo que encontré una manera, aunque es un truco. Básicamente para deshabilitar el botón que hago:

CMFCTasksPaneTask* task = pane.GetTask(0, 0);
task->m_uiCommandID = 1;

Y para volver a habilitarlo hago:

CMFCTasksPaneTask* task = pane.GetTask(0, 0);
task->m_uiCommandID = TASK_ID1;

Parece estar funcionando como se esperaba, por supuesto, si hay una forma más adecuada de hacerlo, me alegraré.

1
Sil 23 ago. 2020 a las 23:48

1 respuesta

La mejor respuesta

La razón que causa esto es la participación del Mecanismo de actualización de la interfaz de usuario . Y aunque la clase CMFCTasksPane parece no tener miembros públicos que puedan habilitar / deshabilitar los elementos de la tarea, el mecanismo de actualización de la interfaz de usuario los cambiaría incluso si lo hicieran.

De hecho, tener un controlador ON_COMMAND para el elemento de la interfaz de usuario (menú, barra de herramientas / botón de armadura, etc.) en una de sus instancias de clase activa hace que el elemento esté habilitado, mientras que no tener uno lo deshabilita. Esto se puede ver fácilmente en un proyecto MDI con el controlador ON_COMMAND implementado en la clase Document o View; si cierra todas las vistas (y posteriormente todos los documentos), el elemento del menú o el botón de la barra de herramientas se desactivará automáticamente.

Al utilizar un controlador ON_UPDATE_COMMAND_UI, puede cambiar el comportamiento predeterminado anterior y especificar la condición de activación / desactivación en función de otros criterios, por ejemplo, los datos seleccionados actualmente. El mecanismo de actualización de la interfaz de usuario es una característica muy poderosa de MFC, que permite tener la condición para actualizar su elemento de la interfaz de usuario en un solo punto de su código, en lugar de tener que evaluarlo explícitamente (y actualizar el elemento) en cada punto que podría cambiarlo (por ejemplo, cuando el usuario selecciona un comando, cambia el estado de un control, selecciona un conjunto diferente de datos, etc., etc.). Los controladores ON_UPDATE_COMMAND_UI se ejecutan durante el procesamiento en tiempo de inactividad, por lo que no debe colocar operaciones largas allí. Simplemente agregue un comando de pitido corto (por ejemplo, Beep(500,30);) para averiguar con qué frecuencia se llaman.

Vea más detalles y código de muestra en mis publicaciones anteriores aquí y aquí.

1
Constantine Georgiou 26 ago. 2020 a las 00:30