Aracılığıyla paylaş


Pencere Yordamlarını Kullanma

Bu bölümde, pencere yordamlarıyla ilişkili aşağıdaki görevlerin nasıl gerçekleştirileceği açıklanmaktadır.

Pencere İşlemi Tasarlama

Aşağıdaki örnekte tipik bir pencere yordamının yapısı gösterilmektedir. Pencere yordamı, ayrı büyük/küçük harf deyimleri tarafından işlenen tek tek iletiler içeren anahtar deyimindeki ileti bağımsız değişkenini kullanır. Her durumun her mesaj için belirli bir değer döndürdüğüne dikkat edin. İşlemediği iletiler için, pencere yordamı DefWindowProc işlevini çağırır.

LRESULT CALLBACK MainWndProc(
    HWND hwnd,        // handle to window
    UINT uMsg,        // message identifier
    WPARAM wParam,    // first message parameter
    LPARAM lParam)    // second message parameter
{ 
 
    switch (uMsg) 
    { 
        case WM_CREATE: 
            // Initialize the window. 
            return 0; 
 
        case WM_PAINT: 
            // Paint the window's client area. 
            return 0; 
 
        case WM_SIZE: 
            // Set the size and position of the window. 
            return 0; 
 
        case WM_DESTROY: 
            // Clean up window-specific data objects. 
            return 0; 
 
        // 
        // Process other messages. 
        // 
 
        default: 
            return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
} 

WM_NCCREATE iletisi, pencereniz oluşturulduktan hemen sonra gönderilir, ancak bir uygulama bu iletiye FALSE döndürerek yanıt verirse, CreateWindowExişlevi başarısız olur. WM_CREATE iletisi, pencereniz zaten oluşturulduktan sonra gönderilir.

pencereniz yok edilmek üzereyken WM_DESTROY iletisi gönderilir. DestroyWindow işlevi, yok edilecek pencerenin sahip olduğu her alt pencerenin yok edilmesi işlemini üstlenir. WM_NCDESTROY iletisi, bir pencere yok edilmeden hemen önce gönderilir.

En azından, bir pencere yordamı, kendisini çizmek için WM_PAINT iletisini işlemelidir. Genellikle fare ve klavye iletilerini de işlemelidir. Pencere yordamınızın bunları işleyip işlemeyeceğini belirlemek için tek tek iletilerin açıklamalarına bakın.

Uygulamanız, bir iletinin işlenmesinin bir parçası olarak DefWindowProc işlevini çağırabilir. Böyle bir durumda uygulama, iletiyi DefWindowProcgeçirmeden önce ileti parametrelerini değiştirebilir veya kendi işlemlerini gerçekleştirdikten sonra varsayılan işlemeye devam edebilir.

İletişim kutusu yordamı, WM_CREATE iletisi yerine WM_INITDIALOG bir ileti alır ve işlenmemiş iletileri DefDlgProc işlevine iletmez. Aksi takdirde, iletişim kutusu yordamı pencere yordamıyla tam olarak aynıdır.

Pencere İşlemini Pencere Sınıfıyla İlişkileştirme

Sınıfı kaydederken pencere yordamını bir pencere sınıfıyla ilişkilendirirsiniz. WNDCLASS yapısını sınıfla ilgili bilgilerle doldurmalısınız ve lpfnWndProc üyesi, pencere yordamının adresini belirtmelidir. sınıfını kaydetmek için WNDCLASS yapısının adresini RegisterClass işlevine geçirin. Pencere sınıfı kaydedildikten sonra, pencere yordamı otomatik olarak bu sınıfla oluşturulan her yeni pencereyle ilişkilendirilir.

Aşağıdaki örnekte, önceki örnekteki pencere yordamının bir pencere sınıfıyla nasıl ilişkilendirileceği gösterilmektedir.

int APIENTRY WinMain( 
    HINSTANCE hinstance,  // handle to current instance 
    HINSTANCE hinstPrev,  // handle to previous instance 
    LPSTR lpCmdLine,      // address of command-line string 
    int nCmdShow)         // show-window type 
{ 
    WNDCLASS wc; 
 
    // Register the main window class. 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = (WNDPROC) MainWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hinstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName =  "MainMenu"; 
    wc.lpszClassName = "MainWindowClass"; 
 
    if (!RegisterClass(&wc)) 
       return FALSE; 
 
    // 
    // Process other messages. 
    // 
 
} 

Pencereyi Alt Sınıflama

Pencerenin bir örneğini alt sınıfa almak için SetWindowLong işlevini çağırın ve GWL_WNDPROC bayrağını alt sınıfa almak için pencere tutamacını ve alt sınıf yordamının işaretçisini belirtin. SetWindowLong özgün pencere yordamına bir işaretçi döndürür; iletileri özgün yordama geçirmek için bu işaretçiyi kullanın. Alt sınıf penceresi yordamı, özgün pencere yordamını çağırmak için CallWindowProc işlevini kullanmalıdır.

Not

Windows'un hem 32 bit hem de 64 bit sürümleriyle uyumlu kod yazmak için SetWindowLongPtrişlevini kullanın.

 

Aşağıdaki örnekte, bir iletişim kutusunda düzenleme denetiminin bir örneğinin nasıl alt sınıfa ekleyebileceğiniz gösterilmektedir. Alt sınıf penceresi yordamı, denetim giriş odağına sahip olduğunda, düzenleme denetiminin ENTER ve SEKME tuşları dahil olmak üzere tüm klavye girişlerini almasını sağlar.

WNDPROC wpOrigEditProc; 
 
LRESULT APIENTRY EditBoxProc(
    HWND hwndDlg, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    HWND hwndEdit; 
 
    switch(uMsg) 
    { 
        case WM_INITDIALOG: 
            // Retrieve the handle to the edit control. 
            hwndEdit = GetDlgItem(hwndDlg, ID_EDIT); 
 
            // Subclass the edit control. 
            wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit, 
                GWL_WNDPROC, (LONG) EditSubclassProc); 
            // 
            // Continue the initialization procedure. 
            // 
            return TRUE; 
 
        case WM_DESTROY: 
            // Remove the subclass from the edit control. 
            SetWindowLong(hwndEdit, GWL_WNDPROC, 
                (LONG) wpOrigEditProc); 
            // 
            // Continue the cleanup procedure. 
            // 
            break; 
    } 
    return FALSE; 
        UNREFERENCED_PARAMETER(lParam); 
} 
 
// Subclass procedure 
LRESULT APIENTRY EditSubclassProc(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    if (uMsg == WM_GETDLGCODE) 
        return DLGC_WANTALLKEYS; 
 
    return CallWindowProc(wpOrigEditProc, hwnd, uMsg, 
        wParam, lParam); 
}