Compartir a través de


TN003: Asignar identificadores de Windows a objetos

Nota:

La biblioteca Microsoft Foundation Classes (MFC) sigue siendo compatible. Sin embargo, ya no estamos agregando características ni actualizando la documentación.

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

El problema

Los objetos de Windows normalmente se representan mediante varios objetos HANDLE . Las clases MFC encapsulan los identificadores de objetos de Windows con objetos de 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 de C++ y, en estos momentos, el sistema crea un objeto temporal para que actúe como contenedor de C++.

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

  • HWND (CWnd y CWndclases derivadas)

  • 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 llamando al método FromHandleestático . Por ejemplo, dado un HWND denominado hWnd, la siguiente línea devolverá un puntero 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. Esto permite obtener un objeto de C++ válido desde 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 llamando a la función Windows DestroyWindow . Si no se desea, hWnd debe desasociarse de myWnd antes de que myWnd se destruya (normalmente al salir del ámbito en el que se definió myWnd ). El Detach método hace esto.

myWnd.Detach();

Más información sobre los objetos temporales

Los objetos temporales se crean cuando FromHandle se le da un identificador que aún no tiene un objeto envoltorio. Estos objetos temporales se desasocian de su identificador y son eliminados por las funciones DeleteTempMap. De forma predeterminada, CWinThread::OnIdle llama automáticamente a DeleteTempMap para cada clase que admite mapas de identificadores temporales. Esto significa que no se puede suponer que un puntero a un objeto temporal será 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 tener acceso a los 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 envoltorio de C++ de un hilo a otro a menudo provocará resultados inesperados.

Consulte también

Notas técnicas por número
Notas Técnicas por Categoría