Listing 1: radio.c
Implementation of IsRadioButton() and IsRadioPeer()
#include <windows.h> //////////////////////////////////////////////////////////////////// BOOL IsRadioButton(HWND hwnd) { BOOL bRet; UINT code; code = SendMessage(hwnd, WM_GETDLGCODE, 0, 0L); if(code & DLGC_RADIOBUTTON) { /* Accept dlgCode claim. */ bRet = TRUE; } else { /* Otherwise has to be a button, and either radio-button * or auto-radio-button. */ CHAR szClass[7]; DWORD style; bRet = GetClassNameA(hwnd, szClass, 7) && 0 == lstrcmpiA(szClass, BUTTON) && ( style = GetWindowLong(hwnd, GWL_STYLE), ( (style & 0x0F) == BS_RADIOBUTTON || style == BS_AUTORADIOBUTTON)); } return bRet; } //////////////////////////////////////////////////////////////////// BOOL IsRadioPeer(HWND hwnd1, HWND hwnd2) { BOOL bRet; /* Must both be radio buttons, and siblings. */ if( !IsRadioButton(hwnd1) || !IsRadioButton(hwnd2) || GetParent(hwnd1) != GetParent(hwnd2)) { bRet = FALSE; } else if(hwnd1 == hwnd2) { /* Same window, so peer by definition. */ bRet = TRUE; } else { /* Search forward, then backward, from hwnd1 to hwnd2, * looking for any non-radio peer, or any group marked, * between. */ HWND hwndSearch; int i; UINT nDir; for(bRet = FALSE, i = 0; i < 2; ++i) { nDir = i ? GW_HWNDPREV : GW_HWNDNEXT; /* Iterate until arrive back at search, or no more * windows. */ for(hwndSearch = GetWindow(hwnd1, nDir); hwndSearch != NULL && hwndSearch != hwnd2; hwndSearch = GetWindow(hwndSearch, nDir)) { if(!IsRadioButton(hwndSearch)) { /* Not a radio button, so stop searching */ break; } if(GetWindowLong(hwndSearch, GWL_STYLE) & WS_GROUP) { /* Begin of group, or start of next, so stop * searching */ break; } } if(hwndSearch == hwnd2) { /* The window that broke the search is our target, * so they are indeed peers. */ bRet = TRUE; break; } } } return bRet; } ////////////////////////////////////////////////////////////////////