Pencere Yordamları Hakkında
Her pencere belirli bir pencere sınıfının üyesidir. Pencere sınıfı, tek bir pencerenin iletilerini işlemek için kullandığı varsayılan pencere yordamını belirler. Aynı sınıfa ait tüm pencereler aynı varsayılan pencere yordamını kullanır. Örneğin, sistem birleşik giriş kutusu sınıfı için bir pencere yordamı tanımlar (COMBOBOX); ardından tüm birleşik giriş kutuları bu pencere yordamını kullanır.
Bir uygulama genellikle en az bir yeni pencere sınıfını ve ilişkili pencere yordamını kaydeder. Bir sınıfı kaydettikten sonra, uygulama bu sınıfın tümü aynı pencere yordamını kullanan birçok pencere oluşturabilir. Bu, birkaç kaynağın aynı kod parçasını aynı anda çağırabileceği anlamına geldiğinden, pencere yordamından paylaşılan kaynakları değiştirirken dikkatli olmanız gerekir. Daha fazla bilgi için bkz. Pencere Sınıfları.
İletişim kutuları için pencere yordamları (iletişim kutusu yordamları olarak adlandırılır) normal pencere yordamlarıyla benzer bir yapıya ve işleve sahiptir. Bu bölümdeki pencere yordamlarına başvuran tüm noktalar iletişim kutusu yordamlarına da uygulanır. Daha fazla bilgi için bkz. İletişim Kutuları.
Bu bölümde aşağıdaki konular ele alınmaktadır.
- Pencere Yordamı Yapısı
- Varsayılan Pencere Yordamı
- Pencere İşlemi Alt Sınıf Oluşturma
- Pencere Yordamı Üst Sınıflama
Pencere Yordamının Yapısı
Pencere yordamı, dört parametresi olan ve imzalı bir değer döndüren bir işlevdir. Parametreler bir pencere tutamacı, UINT ileti tanımlayıcısı ve WPARAM ve LPARAM veri türleriyle bildirilen iki ileti parametresinden oluşur. Daha fazla bilgi için bkz. WindowProc.
İleti parametreleri genellikle hem düşük hem de yüksek sıralı sözcüklerde bilgi içerir. Bir uygulamanın ileti parametrelerinden bilgi ayıklamak için kullanabileceği birkaç makro vardır. Örneğin LOWORD makro, bir ileti parametresinden düşük sıralı sözcüğü (bit 0 ile 15 arasında) ayıklar. Diğer makrolar arasında HIWORD, LOBYTEve HIBYTE makrobulunur.
Dönüş değerinin yorumlanması belirli bir iletiye bağlıdır. Uygun dönüş değerini belirlemek için her iletinin açıklamasına bakın.
Bir pencere yordamını yinelemeli olarak çağırmak mümkün olduğundan, kullandığı yerel değişkenlerin sayısını en aza indirmek önemlidir. Tek tek iletileri işlerken, yerel değişkenlerin aşırı kullanılmasını önlemek ve büyük olasılıkla derin özyineleme sırasında yığının taşmasına neden olmak için uygulamanın pencere yordamı dışındaki işlevleri çağırması gerekir.
Varsayılan Pencere Yordamı
DefWindowProcvarsayılan pencere yordamı işlevi, tüm pencereler tarafından paylaşılan belirli temel davranışları tanımlar. Varsayılan pencere yordamı, bir pencere için en düşük işlevselliği sağlar. Uygulama tanımlı pencere yordamı, işlemediği tüm iletileri varsayılan işleme için DefWindowProc işlevine geçirmelidir.
Pencere Yordamı Alt Sınıflama
Bir uygulama bir pencere oluşturduğunda, sistem pencere için iletileri işleyen pencere yordamının adresi de dahil olmak üzere pencereye özgü bilgileri depolamak için bir bellek bloğu ayırır. Sistemin pencereye bir ileti geçirmesi gerektiğinde, pencere yordamının adresi için pencereye özgü bilgileri arar ve iletiyi bu yordama geçirir.
Alt Sınıf Oluşturma, uygulamanın belirli bir pencereye gönderilen veya yayınlanan iletileri, pencere bunları işleme şansı bulmadan önce kesmesine ve işlemesine olanak tanıyan bir tekniktir. Bir uygulama, bir pencereyi alt sınıfa alarak pencerenin davranışını genişletebilir, değiştirebilir veya izleyebilir. Uygulama, düzenleme denetimi veya liste kutusu gibi sistem genel sınıfına ait bir pencereyi alt sınıfa alabilir. Örneğin, bir uygulama denetimin belirli karakterleri kabul etmesini önlemek için düzenleme denetimini alt sınıfa alabilir. Ancak, başka bir uygulamaya ait bir pencereyi veya sınıfı alt sınıfa alamazsınız. Tüm alt sınıfların aynı işlem içinde gerçekleştirilmesi gerekir.
Uygulama, pencerenin özgün pencere yordamının adresini alt sınıf yordamı olarak adlandırılan yeni bir pencere yordamının adresiyle değiştirerek bir pencereyi alt sınıflar. Bundan sonra, alt sınıf yordamı pencereye gönderilen veya yollanan tüm iletileri alır.
Alt sınıf yordamı, bir iletiyi aldıktan sonra üç eylem gerçekleştirebilir: iletiyi özgün pencere yordamına geçirebilir, iletiyi değiştirebilir ve özgün pencere yordamına geçirebilir veya iletiyi işleyip özgün pencere yordamına geçiremez. Alt sınıf yordamı bir iletiyi işlerse, iletiyi özgün pencere yordamına geçirmeden önce, sonra veya her ikisini birden gerçekleştirebilir.
Sistem iki tür alt sınıflama sağlar: örneği ve genel. örneğinde alt sınıflaştırma, bir uygulama, bir pencere örneğinin pencere yordamı adresini değiştirir. Bir uygulama, var olan bir pencereyi alt sınıfa almak için örnek alt sınıfını kullanmalıdır. genel alt sınıflama, bir uygulama, bir pencere sınıfının WNDCLASSEX yapısındaki pencere yordamının adresini değiştirir. sınıfıyla oluşturulan sonraki tüm pencereler alt sınıf yordamının adresine sahiptir, ancak sınıfın mevcut pencereleri etkilenmez.
Örnek Alt Sınıflama
Uygulama, SetWindowLongPtr işlevini kullanarak bir pencerenin örneğini alt sınıflandırmaktadır. Uygulama, GWL_WNDPROC bayrağını, alt sınıf yapılacak pencere tanıtıcısını ve alt sınıf yordamının adresini SetWindowLongPtrişlevine geçirir. Alt sınıf yordamı, uygulamanın yürütülebilir dosyasında veya DLL'de bulunabilir.
GWL_WNDPROC bayrağı geçirildiğinde, SetWindowLongPtrpencerenin özgün pencere yordamının adresini döndürür. Uygulamanın, kesilen iletileri özgün pencere yordamına geçirmek için CallWindowProc işlevine yapılan sonraki çağrılarda kullanarak bu adresi kaydetmesi gerekir. Uygulama, alt sınıfı pencereden kaldırmak için özgün pencere yordamı adresine de sahip olmalıdır. Alt sınıfı kaldırmak için uygulama, SetWindowLongPtr yeniden çağırır ve özgün pencere yordamının adresini GWL_WNDPROC bayrağıyla ve pencere tanıtıcısını geçirerek iletir.
Sistem, sistemin genel sınıflarının sahibidir ve denetimlerin özellikleri, sistemin bir sürümünden diğerine değişebilir. Uygulamanın sistem genel sınıfına ait bir pencereyi alt sınıfa alması gerekiyorsa, sistemin yeni bir sürümü yayınlandığında geliştiricinin uygulamayı güncelleştirmesi gerekebilir.
Örnek alt sınıfı oluşturma işlemi bir pencere oluşturulduktan sonra gerçekleştiğinden, pencereye ek bayt ekleyemezsiniz. Bir pencereyi alt sınıflandıran uygulamalar, alt sınıflandırılmış pencerenin örneği için gereken verileri depolamak için pencerenin özellik listesini kullanmalıdır. Daha fazla bilgi için bkz. Pencere Özellikleri.
Bir uygulama alt sınıflandırılmış bir pencereyi alt sınıflandırdığında, alt sınıfları gerçekleştirdikleri ters sırada kaldırması gerekir. Kaldırma sırası tersine çevrilmezse, kurtarılamaz bir sistem hatası oluşabilir.
Genel Alt Sınıflama
Bir pencere sınıfının alt sınıfını genel olarak oluşturmak için, uygulamanın sınıfın bir penceresine tanıtıcısı olması gerekir. Alt sınıfı kaldırmak için uygulamanın tanıtıcıya da ihtiyacı vardır. Tanıtıcıyı almak için, bir uygulama genellikle alt sınıflanacak sınıfın gizli bir penceresini oluşturur. Tanıtıcıyı aldıktan sonra, uygulama tanıtıcıyı, GCL_WNDPROC bayrağını ve alt sınıf yordamının adresini belirterek SetClassLongPtr işlevini çağırır. SetClassLongPtr, sınıfın özgün pencere yordamının adresini döndürür.
Özgün pencere yordam adresi, genel alt sınıflamada, örnek alt sınıfında kullanıldığı gibi kullanılır. Alt sınıf yordamı, CallWindowProcçağırarak iletileri özgün pencere yordamına geçirir. Uygulama, SetClassLongPtr yeniden çağırarak, özgün pencere yordamının adresini, GCL_WNDPROC bayrağını ve alt sınıflandırılan sınıfın bir penceresinin tutamacını belirterek alt sınıfı pencere sınıfından kaldırır. Bir denetim sınıfını genel olarak alt sınıfa alan bir uygulamanın, uygulama sonlandırıldığında alt sınıfı kaldırması gerekir; aksi takdirde, kurtarılamaz bir sistem hatası oluşabilir.
Genel alt sınıflama, örnek alt sınıfıyla aynı sınırlamalara ve bazı ek kısıtlamalara sahiptir. Bir uygulama, özgün pencere yordamının bunları tam olarak nasıl kullandığını bilmeden sınıf veya pencere örneği için ek bayt kullanmamalıdır. Uygulamanın verileri bir pencereyle ilişkilendirmesi gerekiyorsa, pencere özelliklerini kullanmalıdır.
Pencere Yordamı Üst Sınıflama
Üst Sınıflama, bir uygulamanın mevcut sınıfın temel işlevlerine ek olarak uygulama tarafından sağlanan iyileştirmelerle yeni bir pencere sınıfı oluşturmasına olanak tanıyan bir tekniktir. Üst sınıf, temel sınıfı olarak adlandırılan mevcut bir pencere sınıfını temel alır. Genellikle, temel sınıf düzenleme denetimi gibi bir sistem genel pencere sınıfıdır, ancak herhangi bir pencere sınıfı olabilir.
Üst sınıf, üst sınıf prosedürü olarak adlandırılan kendi pencere prosedürüne sahiptir. üst sınıf yordamı bir ileti aldıktan sonra üç eylem gerçekleştirebilir: İletiyi özgün pencere yordamına geçirebilir, iletiyi değiştirebilir ve özgün pencere yordamına geçirebilir veya iletiyi işleyip özgün pencere yordamına geçiremez. Üst sınıf yordamı bir iletiyi işlerse, iletiyi özgün pencere yordamına geçirmeden önce, sonra veya her ikisini birden gerçekleştirebilir.
Bir alt sınıf yordamından farklı olarak, bir üst sınıf yordamı pencere oluşturma iletilerini (WM_NCCREATE, WM_CREATEvb.) işleyebilir, ancak temel sınıf pencere yordamının başlatma yordamını gerçekleştirebilmesi için bunları özgün temel sınıf pencere yordamına da geçirmesi gerekir.
Bir pencere sınıfını üst sınıfa almak için, uygulama ilk olarak GetClassInfoEx işlevini çağırarak temel sınıf hakkındaki bilgileri alır. GetClassInfoEx, WNDCLASSEX yapısını temel sınıfın WNDCLASSEX yapısındaki değerlerle doldurur. Ardından, uygulama kendi örnek tanıtıcısını WNDCLASSEX yapısının hInstance üyesine kopyalar ve üst sınıfın adını lpszClassName üyesine kopyalar. Temel sınıfın menüsü varsa, uygulamanın aynı menü tanımlayıcılarına sahip yeni bir menü sağlaması ve menü adını lpszMenuName üyesine kopyalaması gerekir. Üst sınıf yordamı WM_COMMAND iletisini işler ve temel sınıfın pencere yordamına geçirmezse, menüde karşılık gelen tanımlayıcılar olması gerekmez. GetClassInfoEx, WNDCLASSEX yapısının lpszMenuName, lpszClassNameveya hInstance üyesini döndürmez.
Bir uygulamanın ayrıca WNDCLASSEX yapısının lpfnWndProc üyesini ayarlaması gerekir. GetClassInfoEx işlevi bu üyeyi sınıfın özgün pencere yordamının adresiyle doldurur. Uygulamanın, iletileri özgün pencere yordamına geçirmek için bu adresi kaydetmesi ve ardından üst sınıf yordamının adresini lpfnWndProc üyesine kopyalaması gerekir. Uygulama, gerekirse WNDCLASSEX yapısının diğer üyelerini değiştirebilir. WNDCLASSEX yapısını doldurduktan sonra uygulama, yapı adresini RegisterClassEx işlevine geçirerek üst sınıfı kaydeder. Üst sınıf daha sonra pencere oluşturmak için kullanılabilir.
Üst sınıflama yeni bir pencere sınıfını kaydettirdiğinden, bir uygulama hem ek sınıf baytlarına hem de ek pencere baytlarına ekleyebilir. Üst sınıf, bir örnek alt sınıfı veya genel alt sınıfın bunları kullanmaması gereken nedenlerle temel sınıf veya pencere için özgün ek baytları kullanmamalıdır. Ayrıca, uygulama sınıfına veya pencere örneğine kullanımı için ek bayt eklerse, özgün temel sınıf tarafından kullanılan fazladan bayt sayısına göre ek baytlara başvurması gerekir. Temel sınıf tarafından kullanılan bayt sayısı temel sınıfın bir sürümünden diğerine farklılık gösterebileceğinden, üst sınıfın kendi ek baytları için başlangıç uzaklığı da temel sınıfın bir sürümünden diğerine farklılık gösterebilir.