Does the record windows deal with "virtualizing" the result set? In other words, is the entire result set loaded into the grid when the query is executed?

Yes, only the current record is loaded.  All changes in the current record are stored in the buffer and when you move to a new record, the buffer is flushed to the recordset.

The grid determines the row count by calling the CRecordset::GetRecordCount() member.  This member function only returns the number of records seen in the record set and will grow when you scroll to the end of the recordset.  Take a look at the MFC ClassReference for the CRecordset::GetRecordCount() member.

You might also determine the record count with a SQL Query like "Select Count(*) from table" and return the value determined through this SQL Query by overriding CGXBrowserGrid::OnGetRecordCount().