El problema es que llamar a GetDlgCtrlID() sobre un HWND inválido provoca errores cuando el foco está fuera del diálogo; por eso conviene comprobar primero el resultado de GetFocus() antes de usarlo.
LOCAL hFocus := GetFocus()
LOCAL nId := 0
IF hFocus != 0
nId := GetDlgCtrlID( hFocus )
ENDIF
// nId contiene el ID del control que tiene el foco (0 si no hay foco en este hilo)
? "Control con foco ID:", nId
Si necesitas detectar si el foco pertenece específicamente a tu diálogo, compara hFocus con el HWND del diálogo o con los HWND de tus controles; otra opción es guardar el último HWND válido y usarlo cuando el diálogo reciba el foco de nuevo.
---
Explicación técnica
GetFocus() devuelve el handle de la ventana que tiene el foco en la cola de mensajes del hilo actual y puede devolver NULL si el foco está en otra aplicación o en otro hilo, por lo que hay que comprobar que no sea 0 antes de usarlo.
Si llamas a GetDlgCtrlID() con un HWND inválido la aplicación puede fallar; esto es un problema conocido cuando el usuario hace clic fuera de la aplicación y el foco pasa a otra ventana, y por eso muchos desarrolladores añaden la comprobación previa para evitar crashes.
En el ecosistema Harbour / FiveWin esta práctica es habitual: usar GetFocus() para saber qué control tiene el foco y luego actuar solo si el HWND es válido, o bien comparar con el HWND del diálogo para asegurarse de que el foco pertenece a la ventana esperada.
---
Puntos clave
- Comprobar GetFocus() != 0 antes de usar su valor.
- No llamar a GetDlgCtrlID() con un HWND inválido; GetDlgCtrlID() devuelve 0 si falla.
- Comparar hFocus con el HWND del diálogo si necesitas limitar la detección al diálogo concreto.
- Guardar el último HWND válido si quieres restaurar o recordar el control activo cuando el diálogo reciba el foco.