Clase CWinThread

Representa un subproceso de ejecución dentro de una aplicación.

Sintaxis

class CWinThread : public CCmdTarget

Miembros

Constructores públicos

Nombre Descripción
CWinThread::CWinThread Construye un objeto CWinThread.

Métodos públicos

Nombre Descripción
CWinThread::CreateThread Inicia la ejecución de un objeto CWinThread.
CWinThread::ExitInstance Invalidar para limpiar cuando finalice el subproceso.
CWinThread::GetMainWnd Recupera un puntero a la ventana principal del subproceso.
CWinThread::GetThreadPriority Obtiene la prioridad del subproceso actual.
CWinThread::InitInstance Invalidar para realizar la inicialización de la instancia del subproceso.
CWinThread::IsIdleMessage Comprueba si hay mensajes especiales.
CWinThread::OnIdle Invalidar para realizar el procesamiento de los tiempos de inactividad específicos del subproceso.
CWinThread::PostThreadMessage Publica un mensaje en otro objeto CWinThread.
CWinThread::PreTranslateMessage Filtra los mensajes antes de enviarlos a las funciones TranslateMessage y DispatchMessage de Windows.
CWinThread::ProcessMessageFilter Intercepta determinados mensajes antes de que lleguen a la aplicación.
CWinThread::ProcessWndProcException Intercepta todas las excepciones no controladas producidas por el mensaje y los controladores de comandos del subproceso.
CWinThread::PumpMessage Contiene el bucle de mensajes del subproceso.
CWinThread::ResumeThread Disminuye el recuento de suspensiones de un subproceso.
CWinThread::Run Función de control para subprocesos con suministro de mensajes. Invalidar para personalizar el bucle de mensajes predeterminado.
CWinThread::SetThreadPriority Establece la prioridad del subproceso actual.
CWinThread::SuspendThread Incrementa el recuento de suspensiones de un subproceso.

Operadores públicos

Nombre Descripción
CWinThread::operator HANDLE Recupera el manipulador del objeto CWinThread.

Miembros de datos públicos

Nombre Descripción
CWinThread::m_bAutoDelete Especifica si se va a destruir el objeto en la finalización del subproceso.
CWinThread::m_hThread Manipulador del subproceso actual.
CWinThread::m_nThreadID Identificador del subproceso actual.
CWinThread::m_pActiveWnd Puntero a la ventana principal de la aplicación contenedora cuando un servidor OLE está activo en contexto.
CWinThread::m_pMainWnd Contiene un puntero a la ventana principal de la aplicación.

Comentarios

El subproceso principal de ejecución normalmente lo proporciona un objeto derivado de CWinApp; CWinApp se deriva de CWinThread. Los objetos CWinThread adicionales permiten varios subprocesos dentro de una aplicación determinada.

CWinThread admite dos tipos generales de subprocesos: subprocesos de trabajo y subprocesos de interfaz de usuario. Los subprocesos de trabajo no tienen suministro de mensajes: por ejemplo, un subproceso que realiza cálculos en segundo plano en una aplicación de hoja de cálculo. Los subprocesos de interfaz de usuario tienen suministro de mensajes y procesan los mensajes recibidos del sistema. CWinApp y las clases derivadas de él son ejemplos de subprocesos de interfaz de usuario. También se pueden derivar directamente de CWinThread otros subprocesos de interfaz de usuario.

Los objetos de la clase CWinThread normalmente existen durante la duración del subproceso. Si quiere modificar este comportamiento, establezca m_bAutoDelete en FALSE.

La clase CWinThread es necesaria para que su código y MFC sean totalmente seguros para subprocesos. Los objetos CWinThread administran los datos locales del subproceso utilizados por el marco de trabajo para mantener información específica del subproceso. Debido a esta dependencia de CWinThread para controlar los datos locales del subproceso, MFC debe crear cualquier subproceso que use MFC. Por ejemplo, en un subproceso creado por la función en tiempo de ejecución _beginthread, _beginthreadex no puede usar ninguna de las API de MFC.

Para crear un subproceso, llame a AfxBeginThread. Hay dos formas, dependiendo de si desea un subproceso de interfaz de usuario o de trabajo. Si desea un subproceso de interfaz de usuario, pase a AfxBeginThread un puntero al elemento CRuntimeClass de la clase derivada de CWinThread. Si desea crear un subproceso de trabajo, pase a AfxBeginThread un puntero a la función de control y el parámetro a la función de control. En el caso de los subprocesos de trabajo y los subprocesos de interfaz de usuario, puede especificar parámetros opcionales que modifiquen la prioridad, el tamaño de la pila, las marcas de creación y los atributos de seguridad. AfxBeginThread devolverá un puntero al nuevo objeto CWinThread.

En lugar de llamar a AfxBeginThread, puede construir un objeto derivado de CWinThread y, a continuación, llamar a CreateThread. Este método de construcción de dos fases es útil si desea reutilizar el objeto CWinThread entre creaciones y finalizaciones sucesivas de las ejecuciones del subproceso.

Para obtener más información sobre CWinThread, consulte los artículos Multithreading con C++ y MFC, Multithreading: creación de subprocesos de interfaz de usuario, Multithreading: creación de subprocesos de trabajo en MFC y Multithreading: uso de las clases de sincronización de MFC.

Jerarquía de herencia

CObject

CCmdTarget

CWinThread

Requisitos

Encabezadoafxwin.h:

CWinThread::CreateThread

Crea un subproceso que se va a ejecutar dentro del espacio de direcciones del proceso que realiza la llamada.

BOOL CreateThread(
    DWORD dwCreateFlags = 0,
    UINT nStackSize = 0,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

Parámetros

dwCreateFlags
Especifica una marca adicional que controla la creación del subproceso. Esta marca puede contener uno de estos dos valores:

  • CREATE_SUSPENDED Iniciar el subproceso con un recuento de suspensiones de uno. Use CREATE_SUSPENDED si quiere inicializar los datos de miembro del objeto CWinThread, como m_bAutoDelete o cualquier miembro de la clase derivada, antes de que el subproceso empiece a ejecutarse. Una vez que se complete la inicialización, use CWinThread::ResumeThread para iniciar la ejecución del subproceso. El subproceso no se ejecutará hasta que se llame a CWinThread::ResumeThread.

  • 0 Iniciar el subproceso inmediatamente después de la creación.

nStackSize
Especifica el tamaño en bytes de la pila del subproceso nuevo. Si es 0, el tamaño de la pila tiene como valor predeterminado el mismo tamaño que el del subproceso principal del proceso.

lpSecurityAttrs
Apunta a una estructura SECURITY_ATTRIBUTES que especifica los atributos de seguridad del subproceso.

Valor devuelto

Distinto de cero si el subproceso se crea correctamente; de lo contrario, 0.

Comentarios

Use AfxBeginThread para crear un objeto de subproceso y ejecutarlo en un paso. Use CreateThread si desea reutilizar el objeto de subproceso entre creaciones y finalizaciones sucesivas de las ejecuciones del subproceso.

CWinThread::CWinThread

Construye un objeto CWinThread.

CWinThread();

Comentarios

Para comenzar la ejecución del subproceso, llame a la función miembro CreateThread. Normalmente, creará subprocesos llamando a AfxBeginThread, que llamará a este constructor y a CreateThread.

CWinThread::ExitInstance

Lo llama el marco de trabajo desde la función miembro Run (que se invalida con poca frecuencia) para salir de esta instancia del subproceso o si se produce un error en una llamada a InitInstance.

virtual int ExitInstance();

Valor devuelto

Código de salida del subproceso; 0 indica que no hay errores y los valores mayores que 0 indican un error. Este valor se puede recuperar mediante una llamada a GetExitCodeThread.

Comentarios

No llame a esta función miembro desde ningún otro lugar que no sea desde dentro de la función miembro Run. Esta función miembro solo se usa en subprocesos de interfaz de usuario.

La implementación predeterminada de esta función elimina el objeto CWinThread si m_bAutoDelete es TRUE. Invalide esta función si desea realizar una limpieza adicional cuando finalice el subproceso. Su implementación de ExitInstance debe llamar a la versión de la clase base después de ejecutar su código.

CWinThread::GetMainWnd

Si la aplicación es un servidor OLE, llame a esta función para recuperar un puntero a la ventana principal activa de la aplicación en lugar de hacer referencia directamente al miembro m_pMainWnd del objeto de aplicación.

virtual CWnd* GetMainWnd();

Valor devuelto

Esta función devuelve un puntero a uno de los dos tipos de ventanas. Si el subproceso forma parte de un servidor OLE y tiene un objeto activo en funcionamiento dentro de un contenedor activo, esta función devuelve el miembro de datos CWinApp::m_pActiveWnd del objeto CWinThread.

Si no hay ningún objeto activo en funcionamiento dentro de un contenedor o la aplicación no es un servidor OLE, esta función devuelve el miembro de datos m_pMainWnd del objeto de subproceso.

Comentarios

En el caso de los subprocesos de interfaz de usuario, esto equivale a hacer referencia directamente al miembro m_pActiveWnd del objeto de aplicación.

Si la aplicación no es un servidor OLE, llamar a esta función equivale a hacer referencia directamente al miembro m_pMainWnd del objeto de aplicación.

Invalide esta función para modificar el comportamiento predeterminado.

CWinThread::GetThreadPriority

Obtiene el nivel de prioridad de subproceso actual de este subproceso.

int GetThreadPriority();

Valor devuelto

Nivel de prioridad de subproceso actual dentro de su clase de prioridad. El valor devuelto será uno de los siguientes, enumerados de la prioridad más alta a la más baja:

  • THREAD_PRIORITY_TIME_CRITICAL

  • THREAD_PRIORITY_HIGHEST

  • THREAD_PRIORITY_ABOVE_NORMAL

  • THREAD_PRIORITY_NORMAL

  • THREAD_PRIORITY_BELOW_NORMAL

  • THREAD_PRIORITY_LOWEST

  • THREAD_PRIORITY_IDLE

Para obtener más información sobre estas prioridades, consulte SetThreadPriority en Windows SDK.

CWinThread::InitInstance

Se debe invalidar InitInstance para inicializar cada nueva instancia de un subproceso de interfaz de usuario.

virtual BOOL InitInstance();

Valor devuelto

Valor distinto de cero si la inicialización se lleva a cabo correctamente; de lo contrario, es 0.

Comentarios

Normalmente, se invalida InitInstance para realizar las tareas que se deben completar cuando se crea un subproceso por primera vez.

Esta función miembro solo se usa en subprocesos de interfaz de usuario. Realice la inicialización de los subprocesos de trabajo en la función de control que se pasa a AfxBeginThread.

CWinThread::IsIdleMessage

Invalide esta función para evitar que se llame a OnIdle después de que se generen mensajes específicos.

virtual BOOL IsIdleMessage(MSG* pMsg);

Parámetros

pMsg
Apunta al mensaje actual que se está procesando.

Valor devuelto

Distinto de cero si se debe llamar a OnIdle después de procesar el mensaje; en caso contrario, 0.

Comentarios

La implementación predeterminada no llama a OnIdle después de mensajes redundantes del mouse y mensajes generados por símbolos de inserción intermitentes.

Si una aplicación ha creado un temporizador breve, se llamará a OnIdle con frecuencia, lo que provocará problemas de rendimiento. Para mejorar el rendimiento de una aplicación de este tipo, invalide IsIdleMessage en la clase derivada de CWinApp de la aplicación para comprobar si hay mensajes WM_TIMER de la siguiente manera:

BOOL CMyWinApp::IsIdleMessage(MSG* pMsg)
{
   if (!CWinApp::IsIdleMessage(pMsg) || pMsg->message == WM_TIMER)
      return FALSE;
   else
      return TRUE;
}

Controlar WM_TIMER de esta manera mejorará el rendimiento de las aplicaciones que usan temporizadores breves.

CWinThread::m_bAutoDelete

Especifica si el objeto CWinThread se debe eliminar automáticamente cuando finalice el subproceso.

BOOL m_bAutoDelete;

Comentarios

El miembro de datos m_bAutoDelete es una variable pública de tipo BOOL.

El valor de m_bAutoDelete no afecta a cómo se cierra el manipulador del subproceso subyacente, pero afecta al momento del cierre del manipulador. El identificador de subproceso siempre se cierra cuando se destruye el objeto CWinThread.

CWinThread::m_hThread

Manipulador del subproceso asociado a este objeto CWinThread.

HANDLE m_hThread;

Comentarios

El miembro de datos m_hThread es una variable pública de tipo HANDLE. Solo es válido si el objeto de subproceso del kernel subyacente existe actualmente y el manipulador aún no se ha cerrado.

El destructor de CWinThread llama a CloseHandle en m_hThread. Si m_bAutoDelete es TRUE cuando finaliza el subproceso, se destruye el objeto CWinThread, que invalida los punteros al objeto CWinThread y a sus variables miembro. Es posible que necesite el miembro m_hThread para comprobar el valor de salida del subproceso o para esperar una señal. Para mantener el objeto CWinThread y su miembro m_hThread durante la ejecución del subproceso y después de que finalice, establezca m_bAutoDelete en FALSE antes de permitir que continúe la ejecución del subproceso. De lo contrario, el subproceso puede terminar, destruir el objeto CWinThread y cerrar el manipulador antes de que pueda intentar usarlo. Si usa esta técnica, es responsable de eliminar el objeto CWinThread.

CWinThread::m_nThreadID

Identificador del subproceso asociado a este objeto CWinThread.

DWORD m_nThreadID;

Comentarios

El miembro de datos m_nThreadID es una variable pública de tipo DWORD. Solo es válido si el objeto de subproceso del kernel subyacente existe actualmente. Consulte también los comentarios sobre la vigencia de m_hThread.

Ejemplo

Vea el ejemplo de AfxGetThread.

CWinThread::m_pActiveWnd

Use este miembro de datos para almacenar un puntero al objeto de la ventana activa del subproceso.

CWnd* m_pActiveWnd;

Comentarios

La biblioteca MFC (Microsoft Foundation Class) finalizará automáticamente el subproceso cuando se cierre la ventana a la que hace referencia m_pActiveWnd. Si este subproceso es el subproceso principal de una aplicación, la aplicación también se finalizará. Si este miembro de datos es NULL, se heredará la ventana activa del objeto CWinApp de la aplicación. m_pActiveWnd es una variable pública de tipo CWnd*.

Normalmente, se establece esta variable miembro al invalidar InitInstance. En un subproceso de trabajo, el valor de este miembro de datos se hereda de su subproceso primario.

CWinThread::m_pMainWnd

Use este miembro de datos para almacenar un puntero al objeto de la ventana principal del subproceso.

CWnd* m_pMainWnd;

Comentarios

La biblioteca MFC (Microsoft Foundation Class) finalizará automáticamente el subproceso cuando se cierre la ventana a la que hace referencia m_pMainWnd. Si este subproceso es el subproceso principal de una aplicación, la aplicación también se finalizará. Si este miembro de datos es NULL, se usará la ventana principal del objeto CWinApp de la aplicación para determinar cuándo finalizar el subproceso. m_pMainWnd es una variable pública de tipo CWnd*.

Normalmente, se establece esta variable miembro al invalidar InitInstance. En un subproceso de trabajo, el valor de este miembro de datos se hereda de su subproceso primario.

CWinThread::OnIdle

Invalide esta función miembro para realizar el procesamiento de tiempo de inactividad.

virtual BOOL OnIdle(LONG lCount);

Parámetros

lCount
Contador que se incrementa cada vez que se llama a OnIdle cuando la cola de mensajes del subproceso está vacía. Este recuento se restablece en 0 cada vez que se procesa un nuevo mensaje. Puede usar el parámetro lCount para determinar el tiempo relativo que ha estado inactivo el subproceso sin procesar un mensaje.

Valor devuelto

Distinto de cero para recibir más tiempo de procesamiento de inactividad; 0 si no se necesita más tiempo de procesamiento de inactividad.

Comentarios

Se llama a OnIdle en el bucle de mensajes predeterminado cuando la cola de mensajes del subproceso está vacía. Use su invalidación para llamar a sus propias tareas de controlador de inactividad en segundo plano.

OnIdle debe devolver 0 para indicar que no se requiere ningún tiempo de procesamiento de inactividad adicional. El parámetro lCount se incrementa cada vez que se llama a OnIdle cuando la cola de mensajes está vacía y se restablece en 0 cada vez que se procesa un mensaje nuevo. Puede llamar a las diferentes rutinas inactivas en función de este recuento.

La implementación predeterminada de esta función miembro libera objetos temporales y bibliotecas de vínculos dinámicos sin usar de la memoria.

Esta función miembro solo se usa en subprocesos de interfaz de usuario.

Dado que la aplicación no puede procesar mensajes hasta que vuelve de OnIdle, no realice tareas largas en esta función.

CWinThread::operator HANDLE

Recupera el manipulador del objeto CWinThread.

operator HANDLE() const;

Valor devuelto

Si se ejecuta correctamente, el manipulador del objeto de subproceso; de lo contrario, NULL.

Comentarios

Use el manipulador para llamar directamente a las API de Windows.

CWinThread::PostThreadMessage

Se le llama para publicar un mensaje definido por el usuario en otro objeto CWinThread.

BOOL PostThreadMessage(
    UINT message,
    WPARAM wParam,
    LPARAM lParam);

Parámetros

message
Identificador del mensaje definido por el usuario.

wParam
Primer parámetro del mensaje.

lParam
Segundo parámetro del mensaje.

Valor devuelto

Si es correcta, su valor es distinto de cero. En caso contrario, es cero.

Comentarios

El mensaje publicado se asigna al controlador de mensajes adecuado mediante la macro de asignación de mensajes ON_THREAD_MESSAGE.

Nota:

Cuando se llama a PostThreadMessage, el mensaje se coloca en la cola de mensajes del subproceso. Sin embargo, dado que los mensajes publicados de esta manera no están asociados a una ventana, MFC no los enviará a los controladores de mensajes o de comandos. Para controlar estos mensajes, invalide la función PreTranslateMessage() de la clase derivada de CWinApp y controle los mensajes manualmente.

CWinThread::PreTranslateMessage

Invalide esta función para filtrar los mensajes de ventana antes de enviarlos a las funciones TranslateMessage y DispatchMessage de Windows.

virtual BOOL PreTranslateMessage(MSG* pMsg);

Parámetros

pMsg
Apunta a una estructura MSG que contiene el mensaje que se va a procesar.

Valor devuelto

Distinto de cero si el mensaje se procesó por completo en PreTranslateMessage y no se debe procesar más. Cero si el mensaje se debe procesar de la manera normal.

Comentarios

Esta función miembro solo se usa en subprocesos de interfaz de usuario.

CWinThread::ProcessMessageFilter

La función de enlace del marco llama a esta función miembro para filtrar y responder a determinados mensajes de Windows.

virtual BOOL ProcessMessageFilter(
    int code,
    LPMSG lpMsg);

Parámetros

code
Especifica un código de enlace. Esta función miembro usa el código para determinar cómo procesar lpMsg.

lpMsg
Puntero a una estructura MSG de Windows.

Valor devuelto

Distinto de cero si se procesa el mensaje; de lo contrario, 0.

Comentarios

Una función de enlace procesa los eventos antes de enviarlos al procesamiento de mensajes normal de la aplicación.

Si invalida esta característica avanzada, asegúrese de llamar a la versión de clase base para mantener el procesamiento del enlace del marco.

CWinThread::ProcessWndProcException

El marco de trabajo llama a esta función miembro cada vez que el controlador no detecta una excepción iniciada en uno de los controladores de comandos o de mensajes del subproceso.

virtual LRESULT ProcessWndProcException(
    CException* e,
    const MSG* pMsg);

Parámetros

e
Apunta a una excepción no controlada.

pMsg
Apunta a una estructura MSG que contiene información sobre el mensaje de Windows que hizo que el marco de trabajo iniciara una excepción.

Valor devuelto

-1 si se genera una excepción WM_CREATE; de lo contrario, 0.

Comentarios

No llame a esta función miembro directamente.

La implementación predeterminada de esta función miembro solo controla las excepciones generadas a partir de los siguientes mensajes:

Get-Help Acción
WM_CREATE Error.
WM_PAINT Validar la ventana afectada, lo que impide que se genere otro mensaje WM_PAINT.

Invalide esta función miembro para proporcionar un control global de las excepciones. Llame a la funcionalidad base solo si desea mostrar el comportamiento predeterminado.

Esta función miembro solo se usa en subprocesos que tienen suministro de mensajes.

CWinThread::PumpMessage

Contiene el bucle de mensajes del subproceso.

virtual BOOL PumpMessage();

Comentarios

PumpMessage contiene el bucle de mensajes del subproceso. CWinThread llama a PumpMessage para suministrar los mensajes del subproceso. Puede llamar directamente a PumpMessage para forzar que se procesen los mensajes o puede invalidar PumpMessage para cambiar su comportamiento predeterminado.

Llamar directamente a PumpMessage e invalidar su comportamiento predeterminado solo está recomendado para los usuarios avanzados.

CWinThread::ResumeThread

Se le llama para reanudar la ejecución de un subproceso suspendido por la función miembro SuspendThread o un subproceso creado con la marca CREATE_SUSPENDED.

DWORD ResumeThread();

Valor devuelto

Recuento de suspensión anterior del subproceso si se realiza correctamente; de lo contrario, 0xFFFFFFFF. Si el valor devuelto es cero, el subproceso actual no estaba suspendido. Si el valor devuelto es uno, el subproceso estaba suspendido, pero ahora se ha reiniciado. Cualquier valor devuelto mayor que uno significa que el subproceso permanece suspendido.

Comentarios

El recuento de suspensiones del subproceso actual se reduce en uno. Si el recuento de suspensiones se reduce a cero, el subproceso reanuda la ejecución; de lo contrario, el subproceso permanece suspendido.

CWinThread::Run

Proporciona un bucle de mensajes predeterminado para subprocesos de interfaz de usuario.

virtual int Run();

Valor devuelto

Valor int devuelto por el subproceso. Este valor se puede recuperar mediante una llamada a GetExitCodeThread.

Comentarios

Run adquiere y envía mensajes de Windows hasta que la aplicación recibe un mensaje WM_QUIT. Si la cola de mensajes del subproceso no contiene actualmente ningún mensaje, Run llama a OnIdle para realizar el procesamiento de tiempo de inactividad. Los mensajes entrantes van a la función miembro PreTranslateMessage para un procesamiento especial y, a continuación, a la función TranslateMessage de Windows para la traducción de teclado estándar. Por último, se llama a la función DispatchMessage de Windows.

Run rara vez se invalida, pero se puede invalidar para implementar un comportamiento especial.

Esta función miembro solo se usa en subprocesos de interfaz de usuario.

CWinThread::SetThreadPriority

Esta función establece el nivel de prioridad del subproceso actual dentro de su clase de prioridad.

BOOL SetThreadPriority(int nPriority);

Parámetros

nPriority
Especifica el nuevo nivel de prioridad de subproceso dentro de su clase de prioridad. Este parámetro debe ser uno de los siguientes valores, enumerados de la prioridad más alta a la más baja:

  • THREAD_PRIORITY_TIME_CRITICAL

  • THREAD_PRIORITY_HIGHEST

  • THREAD_PRIORITY_ABOVE_NORMAL

  • THREAD_PRIORITY_NORMAL

  • THREAD_PRIORITY_BELOW_NORMAL

  • THREAD_PRIORITY_LOWEST

  • THREAD_PRIORITY_IDLE

Para obtener más información sobre estas prioridades, consulte SetThreadPriority en Windows SDK.

Valor devuelto

Distinto de cero si la función se ha ejecutado correctamente; de lo contrario, 0.

Comentarios

Solo se puede llamar después de que CreateThread vuelva correctamente.

CWinThread::SuspendThread

Incrementa el número de suspensiones del subproceso actual.

DWORD SuspendThread();

Valor devuelto

Recuento de suspensión anterior del subproceso si se realiza correctamente; de lo contrario, 0xFFFFFFFF.

Comentarios

Si algún subproceso tiene un recuento de suspensiones por encima de cero, ese subproceso no se ejecuta. El subproceso se puede reanudar llamando a la función miembro ResumeThread.

Consulte también

CCmdTarget (clase)
Gráfico de jerarquías
CWinApp (clase)
CCmdTarget (clase)