MFC sisteminde tüm pencere işlemleri de sınıflarla yapılır. Temel pencere işlemleri CWnd sınıfı tarafından gerçekleştirilmektedir.
Anımsatma : Bir pencere CreateWindow ya da CreateWindowEx API fonksiyonlarıyla yaratılır. CreateWindow fonksiyonunun önemli parametreleri WNDCLASS ismi, pencere biçimi ve HMENU parametreleridir. Hiçbir pencerenin alt penceresi olmayan masa üstünde görüntülenen pencerelere ana pencereler (top level windows) denir. Ana pencere yaratmak için CreateWindow fonksiyonunun hWndParent parametresi NULL olarak girilmelidir. Alt pencereler ayrıca ID değeri denilen WORD bir değere daha sahiptir. Alt pencere yaratmak için CreateWindow fonksiyonunun hWndParent parametresi üst pencerenin handle değeri olarak girilmelidir. Ayrıca pencere biçimi olarak WS_CHILD eklenmelidir. WS_CHILD eklenmezse pencere owned pencere olur. Owned pencere üst penceresinin sınırları dışına çıkabilir ve her zaman üst pencerenin üzerinde görüntülenir. Üst pencere minimize edildiğinde owned pencereler de gözden kaybolur. Alt – üst pencere ilişkisi üzerinde işlem yapan önemli fonksiyonlar şunlardır: GetParent, GetDlgItem, GetDlgCtrlID. Pencere yaratıldıktan sonra alınan handle değeri pencere ile işlem yapan bütün fonksiyonlara birinci parametre olarak geçirilmektedir. Pencere DestroyWindow API fonksiyonuyla istenildiği zaman yok edilebilir.
CWnd sınıfının yaratılan pencerenin handle değerini tutan HWND m_hWnd isimli bir veri elemanı vardır. Sınıfın Create üye fonksiyonu CreateWindow API fonksiyonunu çağırarak pencereyi yaratır ve handle değerini sınıfın m_hWnd veri elemanına yazar. Sınıfın bütün üye fonksiyonları parametre olarak handle değerini istemezler. Çünkü zaten bu değeri sınıfın veri elemanından alırlar. Tabii bu üye fonksiyonlar aslında API fonksiyonlarını çağırarak işlemlerini yapmaktadır. Örneğin CWnd::UpdateWindow fonksiyonu şöyle yazılmıştır:
void CWnd::UpdateWindow(void)
{
 ::UpdateWindow(m_hWnd);
}
CWnd sınıfının bitiş fonksiyonu kendi içerisinde DestroyWindow API fonksiyonunu çağırarak pencereyi yok etmektedir. Bu nedenle örneğin aşağıdaki gibi bir kodda pencere yaratıldığı gibi yok edilir.

{
 CWnd wnd;

wnd.Create(…..);
} // Blok bitince bitiş fonksiyonu çağrılır ve bitiş fonksiyonu da
// pencereyi yok eder.

CWnd sınıfı handle değeri bilinen her türlü pencere için API fonksiyonlarını çağırarak işlemler yapan üye fonksiyonlara sahiptir. Ancak programın ana penceresi ya da dialog pencereleri ekstra özelliklere sahip olan özelliklerdir. Bu nedenle programın ana penceresi ve dialog pencereleri CWnd sınıfından türetilmiş olan ayrı sınıflarla temsil edilmiştir.
Programın ana penceresini temsil eden sınıf CFrameWnd sınıfıdır (yüksek seviyeli programlama terminolojisinde programın ana penceresi Microsoft tarafından “frame window” terimiyle de belirtilir).
2001-10-16 Salı
Programın ana penceresini yaratabilmek için CFrameWnd sınıfını doğrudan kullanmak yerine bu sınıftan türetme yapmak daha uygun bir yöntemdir. Programın ana penceresi CWnd::Create ile değil CFrameWnd::Create ile yaratılmalıdır. CWnd ve CFrameWnd sınıflarının her ikisinin de Create fonksiyonları vardır. Zaten CFrameWnd::Create birtakım işlemlerden sonra CWnd::Create fonksiyonunu çağırmaktadır.

BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT &rect = rectDefault, CWnd *pParentWnd = NULL, LPCTSTR lpszMenuName = NULL,
DWORD dwExStyle = 0, CCreateContext *pContext = NULL);

Görüldüğü gibi fonksiyonun ilk iki parametresinin dışındaki parametreleri default değer almaktadır. Fonksiyonun birinci parametresi register ettirilmiş bir sınıf ismini alır. Bu parametre NULL olarak girilirse MFC kütüphanesinin içerisinde register ettirilmiş olan bir sınıf kullanılır. Fonksiyonun çağırma akışı şöyledir:

CFrameWnd::Create —-> CWnd::Create —-> ::CreateWindowEx

Programın ana penceresinin yaratılacağı CFrameWnd sınıfından türetilmiş olan sınıfın adresi CWinApp sınıfının m_pMainWnd gösterici elemanında saklanmak zorundadır. Programın ana penceresi yaratıldıktan sonra iskelet API programında olduğu gibi UpdateWindow ve ShowWindow fonksiyonlarının çağrılması gerekir. Tabii bu API fonksiyonlarının doğrudan çağrılması yerine CWnd sınıfının aynı isimli üye fonksiyonlarının çağrılması aynı şeydir.
Bu durumda bir MFC uygulamasında ana pencerenin yaratılması iki biçimde yapılabilir:
1)
BOOL CGenericApp::InitInstance(void)
 {
  m_pMainWnd = new CMainWnd();
  m_pMainWnd->Create(NULL, “Sample Window”);
  m_pMainWnd->ShowWindow(m_nCmdShow);
  m_pMainWnd->UpdateWindow();
  return TRUE;
}

m_pMainWnd, MFC’nin sonraki versiyonlarında (thread kavramı eklendikten sonra) CWinApp sınıfından alınarak CWinThread sınıfına yerleştirilmiştir. m_pMainWnd CFrameWnd sınıfı türünden bir göstericidir.
class CWinThread : public CCmdTarget {
public:
  CFrameWnd *m_pMainWnd;
  // …..
};
m_pMainWnd thread’lerle çalışırken her thread’in kendi ana penceresini tutar.

2) CFrameWnd::Create fonksiyonu InitInstance içerisinde değil de CFrameWnd sınıfından türettiğimiz sınıfın başlangıç fonksiyonu içerisinde de çağrılabilir. Her iki durumda da m_pMainWnd elemanında adresi tutulacak sınıf nesnesinin dinamik olarak yaratılması gerekir.

BOOL CGenericApp::InitInstance(void)
{
  m_pMainWnd = new CMainWnd();
  m_pMainWnd->ShowWindow(m_nCmdShow);
  m_pMainWnd->UpdateWindow();
  return TRUE;
}

CMainWnd::CMainWnd()
{
Create(NULL, “Sample Window”);
}

m_nCmdShow CWinApp sınıfının veri elemanıdır.