Compartir por


TN003: Asignar identificadores de Windows a objetos

En esta nota se describen las rutinas de MFC que admiten la asignación de identificadores del objeto de Windows a objetos C++.

El problema

Normalmente, los objetos de Windows suelen estar representados en varios objetos IDENTIFICADOR. Las clases MFC encapsulan los identificadores de objeto de Windows con objetos C++. Con las funciones de encapsulado de identificador de la biblioteca de clases MFC, se pueden buscar el objeto C++ que está encapsulando el objeto de Windows que tiene un identificador determinado. Sin embargo, a veces un objeto no tiene un objeto contenedor C++ y en esos casos el sistema crea un objeto temporal para que actúe como contenedor C++.

A continuación se enumeran los objetos de Windows que usan asignaciones de identificadores:

  • HWND (CWnd y clases derivadas de CWnd)

  • HDC (CDC y clases derivadas de CDC)

  • HMENU (CMenu)

  • HPEN (CGdiObject)

  • HBRUSH (CGdiObject)

  • HFONT (CGdiObject)

  • HBITMAP (CGdiObject)

  • HPALETTE (CGdiObject)

  • HRGN (CGdiObject)

  • HIMAGELIST (CImageList)

  • SOCKET (CSocket)

Dado un identificador a cualquiera de estos objetos, puede encontrar el objeto MFC que encapsula el identificador al llamar al método estático FromHandle. Por ejemplo, dado un HWND denominadohWnd, la siguiente línea devolverá un punto al CWnd que encapsula hWnd:

CWnd::FromHandle(hWnd)

Si hWnd no tiene un objeto contenedor específico, se crea un objeto temporal CWnd para encapsular hWnd. Permite obtener un objeto C++ de cualquier identificador.

Después de tener un objeto contenedor, puede recuperar su identificador de una variable miembro pública de la clase contenedora. En el caso de un CWnd, m_hWnd contiene el HWND de ese objeto.

Adjuntar identificadores a objetos MFC

Dado un objeto contenedor de controladores recién creado y un identificador a un objeto de Windows, puede asociar los dos al llamar a la función Attach como se explica en este ejemplo:

CWnd myWnd;
myWnd.Attach(hWnd);

Convierte una entrada en la asignación permanente que se asocia a myWnd y hWnd. La llamada a CWnd::FromHandle(hWnd) ahora devolverá un puntero a myWnd. Cuando se elimina myWnd, el destructor destruirá automáticamente hWnd al llamar a la función DestroyWindow de Windows. Si no es lo que se busca, hWnd debe desasociarse de myWnd antes de que myWnd se destruya, (normalmente al salir del ámbito en el que se definió myWnd). El método Detach lo hace.

myWnd.Detach();

Más información sobre objetos temporales

Los objetos temporales se crean siempre que se proporciona a FromHandle un identificador que aún no tiene un objeto contenedor. Estos objetos temporales se desasocian de su identificador y se eliminan mediante las funciones DeleteTempMap. De forma predeterminada CWinThread::OnIdle llama automáticamente a DeleteTempMap para cada clase que admite asignaciones de identificadores temporales. Lo anterior conlleva que no se puede suponer que un puntero a un objeto temporal sea válido después del punto de salida de la función donde se obtuvo el puntero.

Objetos contenedor y varios subprocesos

Los objetos temporales y permanentes se mantienen por subproceso. Es decir, un subproceso no puede acceder a objetos contenedor de C++ de otro subproceso, independientemente de si es temporal o permanente.

Para pasar estos objetos de un subproceso a otro, envíelos siempre como su tipo nativo HANDLE. Pasar un objeto contenedor de C++ de un subproceso a otro a menudo provocará resultados inesperados.

Consulte también

Notas técnicas por número
Notas técnicas por categoría