You can use an HTML table.
E.g. I use this code to line up the 'Y's under the corresponding guild rank numbers:
Code:
string Body;
Body += "<br>Ranks: ";
char Temp[100];
for(int i = 1; i <= GUILD_MAX_RANK; ++i)
{
sprintf(Temp, "%i = %s", i, guild_mgr.GetRankName(c->GuildID(), i));
Body += Temp;
if(i != GUILD_MAX_RANK)
Body += ", ";
}
Body += "<br><br><TABLE>";
Body += "<TR><TD> <TD>1<TD>2<TD>3<TD>4<TD>5<TD>6<TD>7<TD>8<TD>";
for(int i = 1; i <= GUILD_PERMISSION_MAX; ++i)
{
sprintf(Temp, "%2i. ", i);
Body += "<TR><TD>";
Body += Temp;
Body += guild_mgr.GetPermissionName(i);
Body += "<TD>";
for(int j = 1; j <= GUILD_MAX_RANK; ++j)
{
if(guild_mgr.CheckPermission(c->GuildID(), j, i))
Body += "Y";
Body += "<TD>";
}
}
Body += "</table><br>The following characters have the old Guild Banker flag:<br>";
c->SendWindow(1,2, 0, "OK", "OK", 0, 2, c, "Title", Body.c_str());